[clojure] 03/05: Removed third-party files

Daigo Moriwaki daigo at moszumanska.debian.org
Sat Jun 14 06:09:07 UTC 2014


This is an automated email from the git hooks/post-receive script.

daigo pushed a commit to branch master
in repository clojure.

commit 0c1dab2298b6ee0931ab851d1210607fb633e496
Author: Daigo Moriwaki <daigo at debian.org>
Date:   Sat Jun 14 10:13:16 2014 +0900

    Removed third-party files
---
 src/jvm/clojure/asm/AnnotationVisitor.java         |  169 --
 src/jvm/clojure/asm/AnnotationWriter.java          |  318 ---
 src/jvm/clojure/asm/Attribute.java                 |  255 --
 src/jvm/clojure/asm/ByteVector.java                |  306 ---
 src/jvm/clojure/asm/ClassReader.java               | 2202 ----------------
 src/jvm/clojure/asm/ClassVisitor.java              |  286 ---
 src/jvm/clojure/asm/ClassWriter.java               | 1693 ------------
 src/jvm/clojure/asm/Context.java                   |  110 -
 src/jvm/clojure/asm/Edge.java                      |   75 -
 src/jvm/clojure/asm/FieldVisitor.java              |  121 -
 src/jvm/clojure/asm/FieldWriter.java               |  273 --
 src/jvm/clojure/asm/Frame.java                     | 1453 -----------
 src/jvm/clojure/asm/Handle.java                    |  167 --
 src/jvm/clojure/asm/Handler.java                   |  121 -
 src/jvm/clojure/asm/Item.java                      |  311 ---
 src/jvm/clojure/asm/Label.java                     |  560 ----
 src/jvm/clojure/asm/MethodVisitor.java             |  662 -----
 src/jvm/clojure/asm/MethodWriter.java              | 2685 --------------------
 src/jvm/clojure/asm/Opcodes.java                   |  358 ---
 src/jvm/clojure/asm/Type.java                      |  895 -------
 src/jvm/clojure/asm/commons/AdviceAdapter.java     |  625 -----
 src/jvm/clojure/asm/commons/AnalyzerAdapter.java   |  920 -------
 src/jvm/clojure/asm/commons/CodeSizeEvaluator.java |  217 --
 src/jvm/clojure/asm/commons/GeneratorAdapter.java  | 1623 ------------
 .../clojure/asm/commons/InstructionAdapter.java    | 1090 --------
 .../clojure/asm/commons/LocalVariablesSorter.java  |  360 ---
 src/jvm/clojure/asm/commons/Method.java            |  282 --
 .../clojure/asm/commons/SerialVersionUIDAdder.java |  533 ----
 src/jvm/clojure/asm/commons/StaticInitMerger.java  |   96 -
 .../clojure/asm/commons/TableSwitchGenerator.java  |   57 -
 src/jvm/clojure/asm/commons/package.html           |   48 -
 src/jvm/clojure/asm/package.html                   |   87 -
 32 files changed, 18958 deletions(-)

diff --git a/src/jvm/clojure/asm/AnnotationVisitor.java b/src/jvm/clojure/asm/AnnotationVisitor.java
deleted file mode 100644
index eb01145..0000000
--- a/src/jvm/clojure/asm/AnnotationVisitor.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A visitor to visit a Java annotation. The methods of this class must be
- * called in the following order: ( <tt>visit</tt> | <tt>visitEnum</tt> |
- * <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* <tt>visitEnd</tt>.
- *
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-public abstract class AnnotationVisitor {
-
-    /**
-     * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
-     */
-    protected final int api;
-
-    /**
-     * The annotation visitor to which this visitor must delegate method calls.
-     * May be null.
-     */
-    protected AnnotationVisitor av;
-
-    /**
-     * Constructs a new {@link AnnotationVisitor}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     */
-    public AnnotationVisitor(final int api) {
-        this(api, null);
-    }
-
-    /**
-     * Constructs a new {@link AnnotationVisitor}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param av
-     *            the annotation visitor to which this visitor must delegate
-     *            method calls. May be null.
-     */
-    public AnnotationVisitor(final int api, final AnnotationVisitor av) {
-        if (api != Opcodes.ASM4) {
-            throw new IllegalArgumentException();
-        }
-        this.api = api;
-        this.av = av;
-    }
-
-    /**
-     * Visits a primitive value of the annotation.
-     *
-     * @param name
-     *            the value name.
-     * @param value
-     *            the actual value, whose type must be {@link Byte},
-     *            {@link Boolean}, {@link Character}, {@link Short},
-     *            {@link Integer} , {@link Long}, {@link Float}, {@link Double},
-     *            {@link String} or {@link Type} or OBJECT or ARRAY sort. This
-     *            value can also be an array of byte, boolean, short, char, int,
-     *            long, float or double values (this is equivalent to using
-     *            {@link #visitArray visitArray} and visiting each array element
-     *            in turn, but is more convenient).
-     */
-    public void visit(String name, Object value) {
-        if (av != null) {
-            av.visit(name, value);
-        }
-    }
-
-    /**
-     * Visits an enumeration value of the annotation.
-     *
-     * @param name
-     *            the value name.
-     * @param desc
-     *            the class descriptor of the enumeration class.
-     * @param value
-     *            the actual enumeration value.
-     */
-    public void visitEnum(String name, String desc, String value) {
-        if (av != null) {
-            av.visitEnum(name, desc, value);
-        }
-    }
-
-    /**
-     * Visits a nested annotation value of the annotation.
-     *
-     * @param name
-     *            the value name.
-     * @param desc
-     *            the class descriptor of the nested annotation class.
-     * @return a visitor to visit the actual nested annotation value, or
-     *         <tt>null</tt> if this visitor is not interested in visiting this
-     *         nested annotation. <i>The nested annotation value must be fully
-     *         visited before calling other methods on this annotation
-     *         visitor</i>.
-     */
-    public AnnotationVisitor visitAnnotation(String name, String desc) {
-        if (av != null) {
-            return av.visitAnnotation(name, desc);
-        }
-        return null;
-    }
-
-    /**
-     * Visits an array value of the annotation. Note that arrays of primitive
-     * types (such as byte, boolean, short, char, int, long, float or double)
-     * can be passed as value to {@link #visit visit}. This is what
-     * {@link ClassReader} does.
-     *
-     * @param name
-     *            the value name.
-     * @return a visitor to visit the actual array value elements, or
-     *         <tt>null</tt> if this visitor is not interested in visiting these
-     *         values. The 'name' parameters passed to the methods of this
-     *         visitor are ignored. <i>All the array values must be visited
-     *         before calling other methods on this annotation visitor</i>.
-     */
-    public AnnotationVisitor visitArray(String name) {
-        if (av != null) {
-            return av.visitArray(name);
-        }
-        return null;
-    }
-
-    /**
-     * Visits the end of the annotation.
-     */
-    public void visitEnd() {
-        if (av != null) {
-            av.visitEnd();
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/AnnotationWriter.java b/src/jvm/clojure/asm/AnnotationWriter.java
deleted file mode 100644
index 9a40bf8..0000000
--- a/src/jvm/clojure/asm/AnnotationWriter.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * An {@link AnnotationVisitor} that generates annotations in bytecode form.
- *
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-final class AnnotationWriter extends AnnotationVisitor {
-
-    /**
-     * The class writer to which this annotation must be added.
-     */
-    private final ClassWriter cw;
-
-    /**
-     * The number of values in this annotation.
-     */
-    private int size;
-
-    /**
-     * <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation
-     * writers used for annotation default and annotation arrays use unnamed
-     * values.
-     */
-    private final boolean named;
-
-    /**
-     * The annotation values in bytecode form. This byte vector only contains
-     * the values themselves, i.e. the number of values must be stored as a
-     * unsigned short just before these bytes.
-     */
-    private final ByteVector bv;
-
-    /**
-     * The byte vector to be used to store the number of values of this
-     * annotation. See {@link #bv}.
-     */
-    private final ByteVector parent;
-
-    /**
-     * Where the number of values of this annotation must be stored in
-     * {@link #parent}.
-     */
-    private final int offset;
-
-    /**
-     * Next annotation writer. This field is used to store annotation lists.
-     */
-    AnnotationWriter next;
-
-    /**
-     * Previous annotation writer. This field is used to store annotation lists.
-     */
-    AnnotationWriter prev;
-
-    // ------------------------------------------------------------------------
-    // Constructor
-    // ------------------------------------------------------------------------
-
-    /**
-     * Constructs a new {@link AnnotationWriter}.
-     *
-     * @param cw
-     *            the class writer to which this annotation must be added.
-     * @param named
-     *            <tt>true<tt> if values are named, <tt>false</tt> otherwise.
-     * @param bv
-     *            where the annotation values must be stored.
-     * @param parent
-     *            where the number of annotation values must be stored.
-     * @param offset
-     *            where in <tt>parent</tt> the number of annotation values must
-     *            be stored.
-     */
-    AnnotationWriter(final ClassWriter cw, final boolean named,
-            final ByteVector bv, final ByteVector parent, final int offset) {
-        super(Opcodes.ASM4);
-        this.cw = cw;
-        this.named = named;
-        this.bv = bv;
-        this.parent = parent;
-        this.offset = offset;
-    }
-
-    // ------------------------------------------------------------------------
-    // Implementation of the AnnotationVisitor abstract class
-    // ------------------------------------------------------------------------
-
-    @Override
-    public void visit(final String name, final Object value) {
-        ++size;
-        if (named) {
-            bv.putShort(cw.newUTF8(name));
-        }
-        if (value instanceof String) {
-            bv.put12('s', cw.newUTF8((String) value));
-        } else if (value instanceof Byte) {
-            bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
-        } else if (value instanceof Boolean) {
-            int v = ((Boolean) value).booleanValue() ? 1 : 0;
-            bv.put12('Z', cw.newInteger(v).index);
-        } else if (value instanceof Character) {
-            bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
-        } else if (value instanceof Short) {
-            bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
-        } else if (value instanceof Type) {
-            bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
-        } else if (value instanceof byte[]) {
-            byte[] v = (byte[]) value;
-            bv.put12('[', v.length);
-            for (int i = 0; i < v.length; i++) {
-                bv.put12('B', cw.newInteger(v[i]).index);
-            }
-        } else if (value instanceof boolean[]) {
-            boolean[] v = (boolean[]) value;
-            bv.put12('[', v.length);
-            for (int i = 0; i < v.length; i++) {
-                bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
-            }
-        } else if (value instanceof short[]) {
-            short[] v = (short[]) value;
-            bv.put12('[', v.length);
-            for (int i = 0; i < v.length; i++) {
-                bv.put12('S', cw.newInteger(v[i]).index);
-            }
-        } else if (value instanceof char[]) {
-            char[] v = (char[]) value;
-            bv.put12('[', v.length);
-            for (int i = 0; i < v.length; i++) {
-                bv.put12('C', cw.newInteger(v[i]).index);
-            }
-        } else if (value instanceof int[]) {
-            int[] v = (int[]) value;
-            bv.put12('[', v.length);
-            for (int i = 0; i < v.length; i++) {
-                bv.put12('I', cw.newInteger(v[i]).index);
-            }
-        } else if (value instanceof long[]) {
-            long[] v = (long[]) value;
-            bv.put12('[', v.length);
-            for (int i = 0; i < v.length; i++) {
-                bv.put12('J', cw.newLong(v[i]).index);
-            }
-        } else if (value instanceof float[]) {
-            float[] v = (float[]) value;
-            bv.put12('[', v.length);
-            for (int i = 0; i < v.length; i++) {
-                bv.put12('F', cw.newFloat(v[i]).index);
-            }
-        } else if (value instanceof double[]) {
-            double[] v = (double[]) value;
-            bv.put12('[', v.length);
-            for (int i = 0; i < v.length; i++) {
-                bv.put12('D', cw.newDouble(v[i]).index);
-            }
-        } else {
-            Item i = cw.newConstItem(value);
-            bv.put12(".s.IFJDCS".charAt(i.type), i.index);
-        }
-    }
-
-    @Override
-    public void visitEnum(final String name, final String desc,
-            final String value) {
-        ++size;
-        if (named) {
-            bv.putShort(cw.newUTF8(name));
-        }
-        bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(final String name,
-            final String desc) {
-        ++size;
-        if (named) {
-            bv.putShort(cw.newUTF8(name));
-        }
-        // write tag and type, and reserve space for values count
-        bv.put12('@', cw.newUTF8(desc)).putShort(0);
-        return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
-    }
-
-    @Override
-    public AnnotationVisitor visitArray(final String name) {
-        ++size;
-        if (named) {
-            bv.putShort(cw.newUTF8(name));
-        }
-        // write tag, and reserve space for array size
-        bv.put12('[', 0);
-        return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
-    }
-
-    @Override
-    public void visitEnd() {
-        if (parent != null) {
-            byte[] data = parent.data;
-            data[offset] = (byte) (size >>> 8);
-            data[offset + 1] = (byte) size;
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the size of this annotation writer list.
-     *
-     * @return the size of this annotation writer list.
-     */
-    int getSize() {
-        int size = 0;
-        AnnotationWriter aw = this;
-        while (aw != null) {
-            size += aw.bv.length;
-            aw = aw.next;
-        }
-        return size;
-    }
-
-    /**
-     * Puts the annotations of this annotation writer list into the given byte
-     * vector.
-     *
-     * @param out
-     *            where the annotations must be put.
-     */
-    void put(final ByteVector out) {
-        int n = 0;
-        int size = 2;
-        AnnotationWriter aw = this;
-        AnnotationWriter last = null;
-        while (aw != null) {
-            ++n;
-            size += aw.bv.length;
-            aw.visitEnd(); // in case user forgot to call visitEnd
-            aw.prev = last;
-            last = aw;
-            aw = aw.next;
-        }
-        out.putInt(size);
-        out.putShort(n);
-        aw = last;
-        while (aw != null) {
-            out.putByteArray(aw.bv.data, 0, aw.bv.length);
-            aw = aw.prev;
-        }
-    }
-
-    /**
-     * Puts the given annotation lists into the given byte vector.
-     *
-     * @param panns
-     *            an array of annotation writer lists.
-     * @param off
-     *            index of the first annotation to be written.
-     * @param out
-     *            where the annotations must be put.
-     */
-    static void put(final AnnotationWriter[] panns, final int off,
-            final ByteVector out) {
-        int size = 1 + 2 * (panns.length - off);
-        for (int i = off; i < panns.length; ++i) {
-            size += panns[i] == null ? 0 : panns[i].getSize();
-        }
-        out.putInt(size).putByte(panns.length - off);
-        for (int i = off; i < panns.length; ++i) {
-            AnnotationWriter aw = panns[i];
-            AnnotationWriter last = null;
-            int n = 0;
-            while (aw != null) {
-                ++n;
-                aw.visitEnd(); // in case user forgot to call visitEnd
-                aw.prev = last;
-                last = aw;
-                aw = aw.next;
-            }
-            out.putShort(n);
-            aw = last;
-            while (aw != null) {
-                out.putByteArray(aw.bv.data, 0, aw.bv.length);
-                aw = aw.prev;
-            }
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/Attribute.java b/src/jvm/clojure/asm/Attribute.java
deleted file mode 100644
index 1259c3c..0000000
--- a/src/jvm/clojure/asm/Attribute.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A non standard class, field, method or code attribute.
- *
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-public class Attribute {
-
-    /**
-     * The type of this attribute.
-     */
-    public final String type;
-
-    /**
-     * The raw value of this attribute, used only for unknown attributes.
-     */
-    byte[] value;
-
-    /**
-     * The next attribute in this attribute list. May be <tt>null</tt>.
-     */
-    Attribute next;
-
-    /**
-     * Constructs a new empty attribute.
-     *
-     * @param type
-     *            the type of the attribute.
-     */
-    protected Attribute(final String type) {
-        this.type = type;
-    }
-
-    /**
-     * Returns <tt>true</tt> if this type of attribute is unknown. The default
-     * implementation of this method always returns <tt>true</tt>.
-     *
-     * @return <tt>true</tt> if this type of attribute is unknown.
-     */
-    public boolean isUnknown() {
-        return true;
-    }
-
-    /**
-     * Returns <tt>true</tt> if this type of attribute is a code attribute.
-     *
-     * @return <tt>true</tt> if this type of attribute is a code attribute.
-     */
-    public boolean isCodeAttribute() {
-        return false;
-    }
-
-    /**
-     * Returns the labels corresponding to this attribute.
-     *
-     * @return the labels corresponding to this attribute, or <tt>null</tt> if
-     *         this attribute is not a code attribute that contains labels.
-     */
-    protected Label[] getLabels() {
-        return null;
-    }
-
-    /**
-     * Reads a {@link #type type} attribute. This method must return a
-     * <i>new</i> {@link Attribute} object, of type {@link #type type},
-     * corresponding to the <tt>len</tt> bytes starting at the given offset, in
-     * the given class reader.
-     *
-     * @param cr
-     *            the class that contains the attribute to be read.
-     * @param off
-     *            index of the first byte of the attribute's content in
-     *            {@link ClassReader#b cr.b}. The 6 attribute header bytes,
-     *            containing the type and the length of the attribute, are not
-     *            taken into account here.
-     * @param len
-     *            the length of the attribute's content.
-     * @param buf
-     *            buffer to be used to call {@link ClassReader#readUTF8
-     *            readUTF8}, {@link ClassReader#readClass(int,char[]) readClass}
-     *            or {@link ClassReader#readConst readConst}.
-     * @param codeOff
-     *            index of the first byte of code's attribute content in
-     *            {@link ClassReader#b cr.b}, or -1 if the attribute to be read
-     *            is not a code attribute. The 6 attribute header bytes,
-     *            containing the type and the length of the attribute, are not
-     *            taken into account here.
-     * @param labels
-     *            the labels of the method's code, or <tt>null</tt> if the
-     *            attribute to be read is not a code attribute.
-     * @return a <i>new</i> {@link Attribute} object corresponding to the given
-     *         bytes.
-     */
-    protected Attribute read(final ClassReader cr, final int off,
-            final int len, final char[] buf, final int codeOff,
-            final Label[] labels) {
-        Attribute attr = new Attribute(type);
-        attr.value = new byte[len];
-        System.arraycopy(cr.b, off, attr.value, 0, len);
-        return attr;
-    }
-
-    /**
-     * Returns the byte array form of this attribute.
-     *
-     * @param cw
-     *            the class to which this attribute must be added. This
-     *            parameter can be used to add to the constant pool of this
-     *            class the items that corresponds to this attribute.
-     * @param code
-     *            the bytecode of the method corresponding to this code
-     *            attribute, or <tt>null</tt> if this attribute is not a code
-     *            attributes.
-     * @param len
-     *            the length of the bytecode of the method corresponding to this
-     *            code attribute, or <tt>null</tt> if this attribute is not a
-     *            code attribute.
-     * @param maxStack
-     *            the maximum stack size of the method corresponding to this
-     *            code attribute, or -1 if this attribute is not a code
-     *            attribute.
-     * @param maxLocals
-     *            the maximum number of local variables of the method
-     *            corresponding to this code attribute, or -1 if this attribute
-     *            is not a code attribute.
-     * @return the byte array form of this attribute.
-     */
-    protected ByteVector write(final ClassWriter cw, final byte[] code,
-            final int len, final int maxStack, final int maxLocals) {
-        ByteVector v = new ByteVector();
-        v.data = value;
-        v.length = value.length;
-        return v;
-    }
-
-    /**
-     * Returns the length of the attribute list that begins with this attribute.
-     *
-     * @return the length of the attribute list that begins with this attribute.
-     */
-    final int getCount() {
-        int count = 0;
-        Attribute attr = this;
-        while (attr != null) {
-            count += 1;
-            attr = attr.next;
-        }
-        return count;
-    }
-
-    /**
-     * Returns the size of all the attributes in this attribute list.
-     *
-     * @param cw
-     *            the class writer to be used to convert the attributes into
-     *            byte arrays, with the {@link #write write} method.
-     * @param code
-     *            the bytecode of the method corresponding to these code
-     *            attributes, or <tt>null</tt> if these attributes are not code
-     *            attributes.
-     * @param len
-     *            the length of the bytecode of the method corresponding to
-     *            these code attributes, or <tt>null</tt> if these attributes
-     *            are not code attributes.
-     * @param maxStack
-     *            the maximum stack size of the method corresponding to these
-     *            code attributes, or -1 if these attributes are not code
-     *            attributes.
-     * @param maxLocals
-     *            the maximum number of local variables of the method
-     *            corresponding to these code attributes, or -1 if these
-     *            attributes are not code attributes.
-     * @return the size of all the attributes in this attribute list. This size
-     *         includes the size of the attribute headers.
-     */
-    final int getSize(final ClassWriter cw, final byte[] code, final int len,
-            final int maxStack, final int maxLocals) {
-        Attribute attr = this;
-        int size = 0;
-        while (attr != null) {
-            cw.newUTF8(attr.type);
-            size += attr.write(cw, code, len, maxStack, maxLocals).length + 6;
-            attr = attr.next;
-        }
-        return size;
-    }
-
-    /**
-     * Writes all the attributes of this attribute list in the given byte
-     * vector.
-     *
-     * @param cw
-     *            the class writer to be used to convert the attributes into
-     *            byte arrays, with the {@link #write write} method.
-     * @param code
-     *            the bytecode of the method corresponding to these code
-     *            attributes, or <tt>null</tt> if these attributes are not code
-     *            attributes.
-     * @param len
-     *            the length of the bytecode of the method corresponding to
-     *            these code attributes, or <tt>null</tt> if these attributes
-     *            are not code attributes.
-     * @param maxStack
-     *            the maximum stack size of the method corresponding to these
-     *            code attributes, or -1 if these attributes are not code
-     *            attributes.
-     * @param maxLocals
-     *            the maximum number of local variables of the method
-     *            corresponding to these code attributes, or -1 if these
-     *            attributes are not code attributes.
-     * @param out
-     *            where the attributes must be written.
-     */
-    final void put(final ClassWriter cw, final byte[] code, final int len,
-            final int maxStack, final int maxLocals, final ByteVector out) {
-        Attribute attr = this;
-        while (attr != null) {
-            ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
-            out.putShort(cw.newUTF8(attr.type)).putInt(b.length);
-            out.putByteArray(b.data, 0, b.length);
-            attr = attr.next;
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/ByteVector.java b/src/jvm/clojure/asm/ByteVector.java
deleted file mode 100644
index 0e4f861..0000000
--- a/src/jvm/clojure/asm/ByteVector.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A dynamically extensible vector of bytes. This class is roughly equivalent to
- * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
- *
- * @author Eric Bruneton
- */
-public class ByteVector {
-
-    /**
-     * The content of this vector.
-     */
-    byte[] data;
-
-    /**
-     * Actual number of bytes in this vector.
-     */
-    int length;
-
-    /**
-     * Constructs a new {@link ByteVector ByteVector} with a default initial
-     * size.
-     */
-    public ByteVector() {
-        data = new byte[64];
-    }
-
-    /**
-     * Constructs a new {@link ByteVector ByteVector} with the given initial
-     * size.
-     *
-     * @param initialSize
-     *            the initial size of the byte vector to be constructed.
-     */
-    public ByteVector(final int initialSize) {
-        data = new byte[initialSize];
-    }
-
-    /**
-     * Puts a byte into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param b
-     *            a byte.
-     * @return this byte vector.
-     */
-    public ByteVector putByte(final int b) {
-        int length = this.length;
-        if (length + 1 > data.length) {
-            enlarge(1);
-        }
-        data[length++] = (byte) b;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts two bytes into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param b1
-     *            a byte.
-     * @param b2
-     *            another byte.
-     * @return this byte vector.
-     */
-    ByteVector put11(final int b1, final int b2) {
-        int length = this.length;
-        if (length + 2 > data.length) {
-            enlarge(2);
-        }
-        byte[] data = this.data;
-        data[length++] = (byte) b1;
-        data[length++] = (byte) b2;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts a short into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param s
-     *            a short.
-     * @return this byte vector.
-     */
-    public ByteVector putShort(final int s) {
-        int length = this.length;
-        if (length + 2 > data.length) {
-            enlarge(2);
-        }
-        byte[] data = this.data;
-        data[length++] = (byte) (s >>> 8);
-        data[length++] = (byte) s;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts a byte and a short into this byte vector. The byte vector is
-     * automatically enlarged if necessary.
-     *
-     * @param b
-     *            a byte.
-     * @param s
-     *            a short.
-     * @return this byte vector.
-     */
-    ByteVector put12(final int b, final int s) {
-        int length = this.length;
-        if (length + 3 > data.length) {
-            enlarge(3);
-        }
-        byte[] data = this.data;
-        data[length++] = (byte) b;
-        data[length++] = (byte) (s >>> 8);
-        data[length++] = (byte) s;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts an int into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param i
-     *            an int.
-     * @return this byte vector.
-     */
-    public ByteVector putInt(final int i) {
-        int length = this.length;
-        if (length + 4 > data.length) {
-            enlarge(4);
-        }
-        byte[] data = this.data;
-        data[length++] = (byte) (i >>> 24);
-        data[length++] = (byte) (i >>> 16);
-        data[length++] = (byte) (i >>> 8);
-        data[length++] = (byte) i;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts a long into this byte vector. The byte vector is automatically
-     * enlarged if necessary.
-     *
-     * @param l
-     *            a long.
-     * @return this byte vector.
-     */
-    public ByteVector putLong(final long l) {
-        int length = this.length;
-        if (length + 8 > data.length) {
-            enlarge(8);
-        }
-        byte[] data = this.data;
-        int i = (int) (l >>> 32);
-        data[length++] = (byte) (i >>> 24);
-        data[length++] = (byte) (i >>> 16);
-        data[length++] = (byte) (i >>> 8);
-        data[length++] = (byte) i;
-        i = (int) l;
-        data[length++] = (byte) (i >>> 24);
-        data[length++] = (byte) (i >>> 16);
-        data[length++] = (byte) (i >>> 8);
-        data[length++] = (byte) i;
-        this.length = length;
-        return this;
-    }
-
-    /**
-     * Puts an UTF8 string into this byte vector. The byte vector is
-     * automatically enlarged if necessary.
-     *
-     * @param s
-     *            a String.
-     * @return this byte vector.
-     */
-    public ByteVector putUTF8(final String s) {
-        int charLength = s.length();
-        int len = length;
-        if (len + 2 + charLength > data.length) {
-            enlarge(2 + charLength);
-        }
-        byte[] data = this.data;
-        // optimistic algorithm: instead of computing the byte length and then
-        // serializing the string (which requires two loops), we assume the byte
-        // length is equal to char length (which is the most frequent case), and
-        // we start serializing the string right away. During the serialization,
-        // if we find that this assumption is wrong, we continue with the
-        // general method.
-        data[len++] = (byte) (charLength >>> 8);
-        data[len++] = (byte) charLength;
-        for (int i = 0; i < charLength; ++i) {
-            char c = s.charAt(i);
-            if (c >= '\001' && c <= '\177') {
-                data[len++] = (byte) c;
-            } else {
-                int byteLength = i;
-                for (int j = i; j < charLength; ++j) {
-                    c = s.charAt(j);
-                    if (c >= '\001' && c <= '\177') {
-                        byteLength++;
-                    } else if (c > '\u07FF') {
-                        byteLength += 3;
-                    } else {
-                        byteLength += 2;
-                    }
-                }
-                data[length] = (byte) (byteLength >>> 8);
-                data[length + 1] = (byte) byteLength;
-                if (length + 2 + byteLength > data.length) {
-                    length = len;
-                    enlarge(2 + byteLength);
-                    data = this.data;
-                }
-                for (int j = i; j < charLength; ++j) {
-                    c = s.charAt(j);
-                    if (c >= '\001' && c <= '\177') {
-                        data[len++] = (byte) c;
-                    } else if (c > '\u07FF') {
-                        data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
-                        data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
-                        data[len++] = (byte) (0x80 | c & 0x3F);
-                    } else {
-                        data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
-                        data[len++] = (byte) (0x80 | c & 0x3F);
-                    }
-                }
-                break;
-            }
-        }
-        length = len;
-        return this;
-    }
-
-    /**
-     * Puts an array of bytes into this byte vector. The byte vector is
-     * automatically enlarged if necessary.
-     *
-     * @param b
-     *            an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
-     *            null bytes into this byte vector.
-     * @param off
-     *            index of the fist byte of b that must be copied.
-     * @param len
-     *            number of bytes of b that must be copied.
-     * @return this byte vector.
-     */
-    public ByteVector putByteArray(final byte[] b, final int off, final int len) {
-        if (length + len > data.length) {
-            enlarge(len);
-        }
-        if (b != null) {
-            System.arraycopy(b, off, data, length, len);
-        }
-        length += len;
-        return this;
-    }
-
-    /**
-     * Enlarge this byte vector so that it can receive n more bytes.
-     *
-     * @param size
-     *            number of additional bytes that this byte vector should be
-     *            able to receive.
-     */
-    private void enlarge(final int size) {
-        int length1 = 2 * data.length;
-        int length2 = length + size;
-        byte[] newData = new byte[length1 > length2 ? length1 : length2];
-        System.arraycopy(data, 0, newData, 0, length);
-        data = newData;
-    }
-}
diff --git a/src/jvm/clojure/asm/ClassReader.java b/src/jvm/clojure/asm/ClassReader.java
deleted file mode 100644
index 9265a37..0000000
--- a/src/jvm/clojure/asm/ClassReader.java
+++ /dev/null
@@ -1,2202 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A Java class parser to make a {@link ClassVisitor} visit an existing class.
- * This class parses a byte array conforming to the Java class file format and
- * calls the appropriate visit methods of a given class visitor for each field,
- * method and bytecode instruction encountered.
- *
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-public class ClassReader {
-
-    /**
-     * True to enable signatures support.
-     */
-    static final boolean SIGNATURES = true;
-
-    /**
-     * True to enable annotations support.
-     */
-    static final boolean ANNOTATIONS = true;
-
-    /**
-     * True to enable stack map frames support.
-     */
-    static final boolean FRAMES = true;
-
-    /**
-     * True to enable bytecode writing support.
-     */
-    static final boolean WRITER = true;
-
-    /**
-     * True to enable JSR_W and GOTO_W support.
-     */
-    static final boolean RESIZE = true;
-
-    /**
-     * Flag to skip method code. If this class is set <code>CODE</code>
-     * attribute won't be visited. This can be used, for example, to retrieve
-     * annotations for methods and method parameters.
-     */
-    public static final int SKIP_CODE = 1;
-
-    /**
-     * Flag to skip the debug information in the class. If this flag is set the
-     * debug information of the class is not visited, i.e. the
-     * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
-     * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be
-     * called.
-     */
-    public static final int SKIP_DEBUG = 2;
-
-    /**
-     * Flag to skip the stack map frames in the class. If this flag is set the
-     * stack map frames of the class is not visited, i.e. the
-     * {@link MethodVisitor#visitFrame visitFrame} method will not be called.
-     * This flag is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is
-     * used: it avoids visiting frames that will be ignored and recomputed from
-     * scratch in the class writer.
-     */
-    public static final int SKIP_FRAMES = 4;
-
-    /**
-     * Flag to expand the stack map frames. By default stack map frames are
-     * visited in their original format (i.e. "expanded" for classes whose
-     * version is less than V1_6, and "compressed" for the other classes). If
-     * this flag is set, stack map frames are always visited in expanded format
-     * (this option adds a decompression/recompression step in ClassReader and
-     * ClassWriter which degrades performances quite a lot).
-     */
-    public static final int EXPAND_FRAMES = 8;
-
-    /**
-     * The class to be parsed. <i>The content of this array must not be
-     * modified. This field is intended for {@link Attribute} sub classes, and
-     * is normally not needed by class generators or adapters.</i>
-     */
-    public final byte[] b;
-
-    /**
-     * The start index of each constant pool item in {@link #b b}, plus one. The
-     * one byte offset skips the constant pool item tag that indicates its type.
-     */
-    private final int[] items;
-
-    /**
-     * The String objects corresponding to the CONSTANT_Utf8 items. This cache
-     * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
-     * which GREATLY improves performances (by a factor 2 to 3). This caching
-     * strategy could be extended to all constant pool items, but its benefit
-     * would not be so great for these items (because they are much less
-     * expensive to parse than CONSTANT_Utf8 items).
-     */
-    private final String[] strings;
-
-    /**
-     * Maximum length of the strings contained in the constant pool of the
-     * class.
-     */
-    private final int maxStringLength;
-
-    /**
-     * Start index of the class header information (access, name...) in
-     * {@link #b b}.
-     */
-    public final int header;
-
-    // ------------------------------------------------------------------------
-    // Constructors
-    // ------------------------------------------------------------------------
-
-    /**
-     * Constructs a new {@link ClassReader} object.
-     *
-     * @param b
-     *            the bytecode of the class to be read.
-     */
-    public ClassReader(final byte[] b) {
-        this(b, 0, b.length);
-    }
-
-    /**
-     * Constructs a new {@link ClassReader} object.
-     *
-     * @param b
-     *            the bytecode of the class to be read.
-     * @param off
-     *            the start offset of the class data.
-     * @param len
-     *            the length of the class data.
-     */
-    public ClassReader(final byte[] b, final int off, final int len) {
-        this.b = b;
-        // checks the class version
-        if (readShort(off + 6) > Opcodes.V1_7) {
-            throw new IllegalArgumentException();
-        }
-        // parses the constant pool
-        items = new int[readUnsignedShort(off + 8)];
-        int n = items.length;
-        strings = new String[n];
-        int max = 0;
-        int index = off + 10;
-        for (int i = 1; i < n; ++i) {
-            items[i] = index + 1;
-            int size;
-            switch (b[index]) {
-            case ClassWriter.FIELD:
-            case ClassWriter.METH:
-            case ClassWriter.IMETH:
-            case ClassWriter.INT:
-            case ClassWriter.FLOAT:
-            case ClassWriter.NAME_TYPE:
-            case ClassWriter.INDY:
-                size = 5;
-                break;
-            case ClassWriter.LONG:
-            case ClassWriter.DOUBLE:
-                size = 9;
-                ++i;
-                break;
-            case ClassWriter.UTF8:
-                size = 3 + readUnsignedShort(index + 1);
-                if (size > max) {
-                    max = size;
-                }
-                break;
-            case ClassWriter.HANDLE:
-                size = 4;
-                break;
-            // case ClassWriter.CLASS:
-            // case ClassWriter.STR:
-            // case ClassWriter.MTYPE
-            default:
-                size = 3;
-                break;
-            }
-            index += size;
-        }
-        maxStringLength = max;
-        // the class header information starts just after the constant pool
-        header = index;
-    }
-
-    /**
-     * Returns the class's access flags (see {@link Opcodes}). This value may
-     * not reflect Deprecated and Synthetic flags when bytecode is before 1.5
-     * and those flags are represented by attributes.
-     *
-     * @return the class access flags
-     *
-     * @see ClassVisitor#visit(int, int, String, String, String, String[])
-     */
-    public int getAccess() {
-        return readUnsignedShort(header);
-    }
-
-    /**
-     * Returns the internal name of the class (see
-     * {@link Type#getInternalName() getInternalName}).
-     *
-     * @return the internal class name
-     *
-     * @see ClassVisitor#visit(int, int, String, String, String, String[])
-     */
-    public String getClassName() {
-        return readClass(header + 2, new char[maxStringLength]);
-    }
-
-    /**
-     * Returns the internal of name of the super class (see
-     * {@link Type#getInternalName() getInternalName}). For interfaces, the
-     * super class is {@link Object}.
-     *
-     * @return the internal name of super class, or <tt>null</tt> for
-     *         {@link Object} class.
-     *
-     * @see ClassVisitor#visit(int, int, String, String, String, String[])
-     */
-    public String getSuperName() {
-        return readClass(header + 4, new char[maxStringLength]);
-    }
-
-    /**
-     * Returns the internal names of the class's interfaces (see
-     * {@link Type#getInternalName() getInternalName}).
-     *
-     * @return the array of internal names for all implemented interfaces or
-     *         <tt>null</tt>.
-     *
-     * @see ClassVisitor#visit(int, int, String, String, String, String[])
-     */
-    public String[] getInterfaces() {
-        int index = header + 6;
-        int n = readUnsignedShort(index);
-        String[] interfaces = new String[n];
-        if (n > 0) {
-            char[] buf = new char[maxStringLength];
-            for (int i = 0; i < n; ++i) {
-                index += 2;
-                interfaces[i] = readClass(index, buf);
-            }
-        }
-        return interfaces;
-    }
-
-    /**
-     * Copies the constant pool data into the given {@link ClassWriter}. Should
-     * be called before the {@link #accept(ClassVisitor,int)} method.
-     *
-     * @param classWriter
-     *            the {@link ClassWriter} to copy constant pool into.
-     */
-    void copyPool(final ClassWriter classWriter) {
-        char[] buf = new char[maxStringLength];
-        int ll = items.length;
-        Item[] items2 = new Item[ll];
-        for (int i = 1; i < ll; i++) {
-            int index = items[i];
-            int tag = b[index - 1];
-            Item item = new Item(i);
-            int nameType;
-            switch (tag) {
-            case ClassWriter.FIELD:
-            case ClassWriter.METH:
-            case ClassWriter.IMETH:
-                nameType = items[readUnsignedShort(index + 2)];
-                item.set(tag, readClass(index, buf), readUTF8(nameType, buf),
-                        readUTF8(nameType + 2, buf));
-                break;
-            case ClassWriter.INT:
-                item.set(readInt(index));
-                break;
-            case ClassWriter.FLOAT:
-                item.set(Float.intBitsToFloat(readInt(index)));
-                break;
-            case ClassWriter.NAME_TYPE:
-                item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf),
-                        null);
-                break;
-            case ClassWriter.LONG:
-                item.set(readLong(index));
-                ++i;
-                break;
-            case ClassWriter.DOUBLE:
-                item.set(Double.longBitsToDouble(readLong(index)));
-                ++i;
-                break;
-            case ClassWriter.UTF8: {
-                String s = strings[i];
-                if (s == null) {
-                    index = items[i];
-                    s = strings[i] = readUTF(index + 2,
-                            readUnsignedShort(index), buf);
-                }
-                item.set(tag, s, null, null);
-                break;
-            }
-            case ClassWriter.HANDLE: {
-                int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
-                nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
-                item.set(ClassWriter.HANDLE_BASE + readByte(index),
-                        readClass(fieldOrMethodRef, buf),
-                        readUTF8(nameType, buf), readUTF8(nameType + 2, buf));
-                break;
-            }
-            case ClassWriter.INDY:
-                if (classWriter.bootstrapMethods == null) {
-                    copyBootstrapMethods(classWriter, items2, buf);
-                }
-                nameType = items[readUnsignedShort(index + 2)];
-                item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf),
-                        readUnsignedShort(index));
-                break;
-            // case ClassWriter.STR:
-            // case ClassWriter.CLASS:
-            // case ClassWriter.MTYPE
-            default:
-                item.set(tag, readUTF8(index, buf), null, null);
-                break;
-            }
-
-            int index2 = item.hashCode % items2.length;
-            item.next = items2[index2];
-            items2[index2] = item;
-        }
-
-        int off = items[1] - 1;
-        classWriter.pool.putByteArray(b, off, header - off);
-        classWriter.items = items2;
-        classWriter.threshold = (int) (0.75d * ll);
-        classWriter.index = ll;
-    }
-
-    /**
-     * Copies the bootstrap method data into the given {@link ClassWriter}.
-     * Should be called before the {@link #accept(ClassVisitor,int)} method.
-     *
-     * @param classWriter
-     *            the {@link ClassWriter} to copy bootstrap methods into.
-     */
-    private void copyBootstrapMethods(final ClassWriter classWriter,
-            final Item[] items, final char[] c) {
-        // finds the "BootstrapMethods" attribute
-        int u = getAttributes();
-        boolean found = false;
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            String attrName = readUTF8(u + 2, c);
-            if ("BootstrapMethods".equals(attrName)) {
-                found = true;
-                break;
-            }
-            u += 6 + readInt(u + 4);
-        }
-        if (!found) {
-            return;
-        }
-        // copies the bootstrap methods in the class writer
-        int boostrapMethodCount = readUnsignedShort(u + 8);
-        for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) {
-            int position = v - u - 10;
-            int hashCode = readConst(readUnsignedShort(v), c).hashCode();
-            for (int k = readUnsignedShort(v + 2); k > 0; --k) {
-                hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode();
-                v += 2;
-            }
-            v += 4;
-            Item item = new Item(j);
-            item.set(position, hashCode & 0x7FFFFFFF);
-            int index = item.hashCode % items.length;
-            item.next = items[index];
-            items[index] = item;
-        }
-        int attrSize = readInt(u + 4);
-        ByteVector bootstrapMethods = new ByteVector(attrSize + 62);
-        bootstrapMethods.putByteArray(b, u + 10, attrSize - 2);
-        classWriter.bootstrapMethodsCount = boostrapMethodCount;
-        classWriter.bootstrapMethods = bootstrapMethods;
-    }
-
-    /**
-     * Constructs a new {@link ClassReader} object.
-     *
-     * @param is
-     *            an input stream from which to read the class.
-     * @throws IOException
-     *             if a problem occurs during reading.
-     */
-    public ClassReader(final InputStream is) throws IOException {
-        this(readClass(is, false));
-    }
-
-    /**
-     * Constructs a new {@link ClassReader} object.
-     *
-     * @param name
-     *            the binary qualified name of the class to be read.
-     * @throws IOException
-     *             if an exception occurs during reading.
-     */
-    public ClassReader(final String name) throws IOException {
-        this(readClass(
-                ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
-                        + ".class"), true));
-    }
-
-    /**
-     * Reads the bytecode of a class.
-     *
-     * @param is
-     *            an input stream from which to read the class.
-     * @param close
-     *            true to close the input stream after reading.
-     * @return the bytecode read from the given input stream.
-     * @throws IOException
-     *             if a problem occurs during reading.
-     */
-    private static byte[] readClass(final InputStream is, boolean close)
-            throws IOException {
-        if (is == null) {
-            throw new IOException("Class not found");
-        }
-        try {
-            byte[] b = new byte[is.available()];
-            int len = 0;
-            while (true) {
-                int n = is.read(b, len, b.length - len);
-                if (n == -1) {
-                    if (len < b.length) {
-                        byte[] c = new byte[len];
-                        System.arraycopy(b, 0, c, 0, len);
-                        b = c;
-                    }
-                    return b;
-                }
-                len += n;
-                if (len == b.length) {
-                    int last = is.read();
-                    if (last < 0) {
-                        return b;
-                    }
-                    byte[] c = new byte[b.length + 1000];
-                    System.arraycopy(b, 0, c, 0, len);
-                    c[len++] = (byte) last;
-                    b = c;
-                }
-            }
-        } finally {
-            if (close) {
-                is.close();
-            }
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Public methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Makes the given visitor visit the Java class of this {@link ClassReader}
-     * . This class is the one specified in the constructor (see
-     * {@link #ClassReader(byte[]) ClassReader}).
-     *
-     * @param classVisitor
-     *            the visitor that must visit this class.
-     * @param flags
-     *            option flags that can be used to modify the default behavior
-     *            of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
-     *            , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
-     */
-    public void accept(final ClassVisitor classVisitor, final int flags) {
-        accept(classVisitor, new Attribute[0], flags);
-    }
-
-    /**
-     * Makes the given visitor visit the Java class of this {@link ClassReader}.
-     * This class is the one specified in the constructor (see
-     * {@link #ClassReader(byte[]) ClassReader}).
-     *
-     * @param classVisitor
-     *            the visitor that must visit this class.
-     * @param attrs
-     *            prototypes of the attributes that must be parsed during the
-     *            visit of the class. Any attribute whose type is not equal to
-     *            the type of one the prototypes will not be parsed: its byte
-     *            array value will be passed unchanged to the ClassWriter.
-     *            <i>This may corrupt it if this value contains references to
-     *            the constant pool, or has syntactic or semantic links with a
-     *            class element that has been transformed by a class adapter
-     *            between the reader and the writer</i>.
-     * @param flags
-     *            option flags that can be used to modify the default behavior
-     *            of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
-     *            , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
-     */
-    public void accept(final ClassVisitor classVisitor,
-            final Attribute[] attrs, final int flags) {
-        int u = header; // current offset in the class file
-        char[] c = new char[maxStringLength]; // buffer used to read strings
-
-        Context context = new Context();
-        context.attrs = attrs;
-        context.flags = flags;
-        context.buffer = c;
-
-        // reads the class declaration
-        int access = readUnsignedShort(u);
-        String name = readClass(u + 2, c);
-        String superClass = readClass(u + 4, c);
-        String[] interfaces = new String[readUnsignedShort(u + 6)];
-        u += 8;
-        for (int i = 0; i < interfaces.length; ++i) {
-            interfaces[i] = readClass(u, c);
-            u += 2;
-        }
-
-        // reads the class attributes
-        String signature = null;
-        String sourceFile = null;
-        String sourceDebug = null;
-        String enclosingOwner = null;
-        String enclosingName = null;
-        String enclosingDesc = null;
-        int anns = 0;
-        int ianns = 0;
-        int innerClasses = 0;
-        Attribute attributes = null;
-
-        u = getAttributes();
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            String attrName = readUTF8(u + 2, c);
-            // tests are sorted in decreasing frequency order
-            // (based on frequencies observed on typical classes)
-            if ("SourceFile".equals(attrName)) {
-                sourceFile = readUTF8(u + 8, c);
-            } else if ("InnerClasses".equals(attrName)) {
-                innerClasses = u + 8;
-            } else if ("EnclosingMethod".equals(attrName)) {
-                enclosingOwner = readClass(u + 8, c);
-                int item = readUnsignedShort(u + 10);
-                if (item != 0) {
-                    enclosingName = readUTF8(items[item], c);
-                    enclosingDesc = readUTF8(items[item] + 2, c);
-                }
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
-                signature = readUTF8(u + 8, c);
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
-                anns = u + 8;
-            } else if ("Deprecated".equals(attrName)) {
-                access |= Opcodes.ACC_DEPRECATED;
-            } else if ("Synthetic".equals(attrName)) {
-                access |= Opcodes.ACC_SYNTHETIC
-                        | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-            } else if ("SourceDebugExtension".equals(attrName)) {
-                int len = readInt(u + 4);
-                sourceDebug = readUTF(u + 8, len, new char[len]);
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
-                ianns = u + 8;
-            } else if ("BootstrapMethods".equals(attrName)) {
-                int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
-                for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
-                    bootstrapMethods[j] = v;
-                    v += 2 + readUnsignedShort(v + 2) << 1;
-                }
-                context.bootstrapMethods = bootstrapMethods;
-            } else {
-                Attribute attr = readAttribute(attrs, attrName, u + 8,
-                        readInt(u + 4), c, -1, null);
-                if (attr != null) {
-                    attr.next = attributes;
-                    attributes = attr;
-                }
-            }
-            u += 6 + readInt(u + 4);
-        }
-
-        // visits the class declaration
-        classVisitor.visit(readInt(items[1] - 7), access, name, signature,
-                superClass, interfaces);
-
-        // visits the source and debug info
-        if ((flags & SKIP_DEBUG) == 0
-                && (sourceFile != null || sourceDebug != null)) {
-            classVisitor.visitSource(sourceFile, sourceDebug);
-        }
-
-        // visits the outer class
-        if (enclosingOwner != null) {
-            classVisitor.visitOuterClass(enclosingOwner, enclosingName,
-                    enclosingDesc);
-        }
-
-        // visits the class annotations
-        if (ANNOTATIONS && anns != 0) {
-            for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
-                v = readAnnotationValues(v + 2, c, true,
-                        classVisitor.visitAnnotation(readUTF8(v, c), true));
-            }
-        }
-        if (ANNOTATIONS && ianns != 0) {
-            for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
-                v = readAnnotationValues(v + 2, c, true,
-                        classVisitor.visitAnnotation(readUTF8(v, c), false));
-            }
-        }
-
-        // visits the attributes
-        while (attributes != null) {
-            Attribute attr = attributes.next;
-            attributes.next = null;
-            classVisitor.visitAttribute(attributes);
-            attributes = attr;
-        }
-
-        // visits the inner classes
-        if (innerClasses != 0) {
-            int v = innerClasses + 2;
-            for (int i = readUnsignedShort(innerClasses); i > 0; --i) {
-                classVisitor.visitInnerClass(readClass(v, c),
-                        readClass(v + 2, c), readUTF8(v + 4, c),
-                        readUnsignedShort(v + 6));
-                v += 8;
-            }
-        }
-
-        // visits the fields and methods
-        u = header + 10 + 2 * interfaces.length;
-        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
-            u = readField(classVisitor, context, u);
-        }
-        u += 2;
-        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
-            u = readMethod(classVisitor, context, u);
-        }
-
-        // visits the end of the class
-        classVisitor.visitEnd();
-    }
-
-    /**
-     * Reads a field and makes the given visitor visit it.
-     *
-     * @param classVisitor
-     *            the visitor that must visit the field.
-     * @param context
-     *            information about the class being parsed.
-     * @param u
-     *            the start offset of the field in the class file.
-     * @return the offset of the first byte following the field in the class.
-     */
-    private int readField(final ClassVisitor classVisitor,
-            final Context context, int u) {
-        // reads the field declaration
-        char[] c = context.buffer;
-        int access = readUnsignedShort(u);
-        String name = readUTF8(u + 2, c);
-        String desc = readUTF8(u + 4, c);
-        u += 6;
-
-        // reads the field attributes
-        String signature = null;
-        int anns = 0;
-        int ianns = 0;
-        Object value = null;
-        Attribute attributes = null;
-
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            String attrName = readUTF8(u + 2, c);
-            // tests are sorted in decreasing frequency order
-            // (based on frequencies observed on typical classes)
-            if ("ConstantValue".equals(attrName)) {
-                int item = readUnsignedShort(u + 8);
-                value = item == 0 ? null : readConst(item, c);
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
-                signature = readUTF8(u + 8, c);
-            } else if ("Deprecated".equals(attrName)) {
-                access |= Opcodes.ACC_DEPRECATED;
-            } else if ("Synthetic".equals(attrName)) {
-                access |= Opcodes.ACC_SYNTHETIC
-                        | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
-                anns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
-                ianns = u + 8;
-            } else {
-                Attribute attr = readAttribute(context.attrs, attrName, u + 8,
-                        readInt(u + 4), c, -1, null);
-                if (attr != null) {
-                    attr.next = attributes;
-                    attributes = attr;
-                }
-            }
-            u += 6 + readInt(u + 4);
-        }
-        u += 2;
-
-        // visits the field declaration
-        FieldVisitor fv = classVisitor.visitField(access, name, desc,
-                signature, value);
-        if (fv == null) {
-            return u;
-        }
-
-        // visits the field annotations
-        if (ANNOTATIONS && anns != 0) {
-            for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
-                v = readAnnotationValues(v + 2, c, true,
-                        fv.visitAnnotation(readUTF8(v, c), true));
-            }
-        }
-        if (ANNOTATIONS && ianns != 0) {
-            for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
-                v = readAnnotationValues(v + 2, c, true,
-                        fv.visitAnnotation(readUTF8(v, c), false));
-            }
-        }
-
-        // visits the field attributes
-        while (attributes != null) {
-            Attribute attr = attributes.next;
-            attributes.next = null;
-            fv.visitAttribute(attributes);
-            attributes = attr;
-        }
-
-        // visits the end of the field
-        fv.visitEnd();
-
-        return u;
-    }
-
-    /**
-     * Reads a method and makes the given visitor visit it.
-     *
-     * @param classVisitor
-     *            the visitor that must visit the method.
-     * @param context
-     *            information about the class being parsed.
-     * @param u
-     *            the start offset of the method in the class file.
-     * @return the offset of the first byte following the method in the class.
-     */
-    private int readMethod(final ClassVisitor classVisitor,
-            final Context context, int u) {
-        // reads the method declaration
-        char[] c = context.buffer;
-        int access = readUnsignedShort(u);
-        String name = readUTF8(u + 2, c);
-        String desc = readUTF8(u + 4, c);
-        u += 6;
-
-        // reads the method attributes
-        int code = 0;
-        int exception = 0;
-        String[] exceptions = null;
-        String signature = null;
-        int anns = 0;
-        int ianns = 0;
-        int dann = 0;
-        int mpanns = 0;
-        int impanns = 0;
-        int firstAttribute = u;
-        Attribute attributes = null;
-
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            String attrName = readUTF8(u + 2, c);
-            // tests are sorted in decreasing frequency order
-            // (based on frequencies observed on typical classes)
-            if ("Code".equals(attrName)) {
-                if ((context.flags & SKIP_CODE) == 0) {
-                    code = u + 8;
-                }
-            } else if ("Exceptions".equals(attrName)) {
-                exceptions = new String[readUnsignedShort(u + 8)];
-                exception = u + 10;
-                for (int j = 0; j < exceptions.length; ++j) {
-                    exceptions[j] = readClass(exception, c);
-                    exception += 2;
-                }
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
-                signature = readUTF8(u + 8, c);
-            } else if ("Deprecated".equals(attrName)) {
-                access |= Opcodes.ACC_DEPRECATED;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
-                anns = u + 8;
-            } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
-                dann = u + 8;
-            } else if ("Synthetic".equals(attrName)) {
-                access |= Opcodes.ACC_SYNTHETIC
-                        | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
-                ianns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
-                mpanns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
-                impanns = u + 8;
-            } else {
-                Attribute attr = readAttribute(context.attrs, attrName, u + 8,
-                        readInt(u + 4), c, -1, null);
-                if (attr != null) {
-                    attr.next = attributes;
-                    attributes = attr;
-                }
-            }
-            u += 6 + readInt(u + 4);
-        }
-        u += 2;
-
-        // visits the method declaration
-        MethodVisitor mv = classVisitor.visitMethod(access, name, desc,
-                signature, exceptions);
-        if (mv == null) {
-            return u;
-        }
-
-        /*
-         * if the returned MethodVisitor is in fact a MethodWriter, it means
-         * there is no method adapter between the reader and the writer. If, in
-         * addition, the writer's constant pool was copied from this reader
-         * (mw.cw.cr == this), and the signature and exceptions of the method
-         * have not been changed, then it is possible to skip all visit events
-         * and just copy the original code of the method to the writer (the
-         * access, name and descriptor can have been changed, this is not
-         * important since they are not copied as is from the reader).
-         */
-        if (WRITER && mv instanceof MethodWriter) {
-            MethodWriter mw = (MethodWriter) mv;
-            if (mw.cw.cr == this && signature == mw.signature) {
-                boolean sameExceptions = false;
-                if (exceptions == null) {
-                    sameExceptions = mw.exceptionCount == 0;
-                } else if (exceptions.length == mw.exceptionCount) {
-                    sameExceptions = true;
-                    for (int j = exceptions.length - 1; j >= 0; --j) {
-                        exception -= 2;
-                        if (mw.exceptions[j] != readUnsignedShort(exception)) {
-                            sameExceptions = false;
-                            break;
-                        }
-                    }
-                }
-                if (sameExceptions) {
-                    /*
-                     * we do not copy directly the code into MethodWriter to
-                     * save a byte array copy operation. The real copy will be
-                     * done in ClassWriter.toByteArray().
-                     */
-                    mw.classReaderOffset = firstAttribute;
-                    mw.classReaderLength = u - firstAttribute;
-                    return u;
-                }
-            }
-        }
-
-        // visits the method annotations
-        if (ANNOTATIONS && dann != 0) {
-            AnnotationVisitor dv = mv.visitAnnotationDefault();
-            readAnnotationValue(dann, c, null, dv);
-            if (dv != null) {
-                dv.visitEnd();
-            }
-        }
-        if (ANNOTATIONS && anns != 0) {
-            for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
-                v = readAnnotationValues(v + 2, c, true,
-                        mv.visitAnnotation(readUTF8(v, c), true));
-            }
-        }
-        if (ANNOTATIONS && ianns != 0) {
-            for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
-                v = readAnnotationValues(v + 2, c, true,
-                        mv.visitAnnotation(readUTF8(v, c), false));
-            }
-        }
-        if (ANNOTATIONS && mpanns != 0) {
-            readParameterAnnotations(mpanns, desc, c, true, mv);
-        }
-        if (ANNOTATIONS && impanns != 0) {
-            readParameterAnnotations(impanns, desc, c, false, mv);
-        }
-
-        // visits the method attributes
-        while (attributes != null) {
-            Attribute attr = attributes.next;
-            attributes.next = null;
-            mv.visitAttribute(attributes);
-            attributes = attr;
-        }
-
-        // visits the method code
-        if (code != 0) {
-            context.access = access;
-            context.name = name;
-            context.desc = desc;
-            mv.visitCode();
-            readCode(mv, context, code);
-        }
-
-        // visits the end of the method
-        mv.visitEnd();
-
-        return u;
-    }
-
-    /**
-     * Reads the bytecode of a method and makes the given visitor visit it.
-     *
-     * @param mv
-     *            the visitor that must visit the method's code.
-     * @param context
-     *            information about the class being parsed.
-     * @param u
-     *            the start offset of the code attribute in the class file.
-     */
-    private void readCode(final MethodVisitor mv, final Context context, int u) {
-        // reads the header
-        byte[] b = this.b;
-        char[] c = context.buffer;
-        int maxStack = readUnsignedShort(u);
-        int maxLocals = readUnsignedShort(u + 2);
-        int codeLength = readInt(u + 4);
-        u += 8;
-
-        // reads the bytecode to find the labels
-        int codeStart = u;
-        int codeEnd = u + codeLength;
-        Label[] labels = new Label[codeLength + 2];
-        readLabel(codeLength + 1, labels);
-        while (u < codeEnd) {
-            int offset = u - codeStart;
-            int opcode = b[u] & 0xFF;
-            switch (ClassWriter.TYPE[opcode]) {
-            case ClassWriter.NOARG_INSN:
-            case ClassWriter.IMPLVAR_INSN:
-                u += 1;
-                break;
-            case ClassWriter.LABEL_INSN:
-                readLabel(offset + readShort(u + 1), labels);
-                u += 3;
-                break;
-            case ClassWriter.LABELW_INSN:
-                readLabel(offset + readInt(u + 1), labels);
-                u += 5;
-                break;
-            case ClassWriter.WIDE_INSN:
-                opcode = b[u + 1] & 0xFF;
-                if (opcode == Opcodes.IINC) {
-                    u += 6;
-                } else {
-                    u += 4;
-                }
-                break;
-            case ClassWriter.TABL_INSN:
-                // skips 0 to 3 padding bytes
-                u = u + 4 - (offset & 3);
-                // reads instruction
-                readLabel(offset + readInt(u), labels);
-                for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
-                    readLabel(offset + readInt(u + 12), labels);
-                    u += 4;
-                }
-                u += 12;
-                break;
-            case ClassWriter.LOOK_INSN:
-                // skips 0 to 3 padding bytes
-                u = u + 4 - (offset & 3);
-                // reads instruction
-                readLabel(offset + readInt(u), labels);
-                for (int i = readInt(u + 4); i > 0; --i) {
-                    readLabel(offset + readInt(u + 12), labels);
-                    u += 8;
-                }
-                u += 8;
-                break;
-            case ClassWriter.VAR_INSN:
-            case ClassWriter.SBYTE_INSN:
-            case ClassWriter.LDC_INSN:
-                u += 2;
-                break;
-            case ClassWriter.SHORT_INSN:
-            case ClassWriter.LDCW_INSN:
-            case ClassWriter.FIELDORMETH_INSN:
-            case ClassWriter.TYPE_INSN:
-            case ClassWriter.IINC_INSN:
-                u += 3;
-                break;
-            case ClassWriter.ITFMETH_INSN:
-            case ClassWriter.INDYMETH_INSN:
-                u += 5;
-                break;
-            // case MANA_INSN:
-            default:
-                u += 4;
-                break;
-            }
-        }
-
-        // reads the try catch entries to find the labels, and also visits them
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            Label start = readLabel(readUnsignedShort(u + 2), labels);
-            Label end = readLabel(readUnsignedShort(u + 4), labels);
-            Label handler = readLabel(readUnsignedShort(u + 6), labels);
-            String type = readUTF8(items[readUnsignedShort(u + 8)], c);
-            mv.visitTryCatchBlock(start, end, handler, type);
-            u += 8;
-        }
-        u += 2;
-
-        // reads the code attributes
-        int varTable = 0;
-        int varTypeTable = 0;
-        boolean zip = true;
-        boolean unzip = (context.flags & EXPAND_FRAMES) != 0;
-        int stackMap = 0;
-        int stackMapSize = 0;
-        int frameCount = 0;
-        Context frame = null;
-        Attribute attributes = null;
-
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            String attrName = readUTF8(u + 2, c);
-            if ("LocalVariableTable".equals(attrName)) {
-                if ((context.flags & SKIP_DEBUG) == 0) {
-                    varTable = u + 8;
-                    for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
-                        int label = readUnsignedShort(v + 10);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
-                        label += readUnsignedShort(v + 12);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
-                        v += 10;
-                    }
-                }
-            } else if ("LocalVariableTypeTable".equals(attrName)) {
-                varTypeTable = u + 8;
-            } else if ("LineNumberTable".equals(attrName)) {
-                if ((context.flags & SKIP_DEBUG) == 0) {
-                    for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
-                        int label = readUnsignedShort(v + 10);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
-                        labels[label].line = readUnsignedShort(v + 12);
-                        v += 4;
-                    }
-                }
-            } else if (FRAMES && "StackMapTable".equals(attrName)) {
-                if ((context.flags & SKIP_FRAMES) == 0) {
-                    stackMap = u + 10;
-                    stackMapSize = readInt(u + 4);
-                    frameCount = readUnsignedShort(u + 8);
-                }
-                /*
-                 * here we do not extract the labels corresponding to the
-                 * attribute content. This would require a full parsing of the
-                 * attribute, which would need to be repeated in the second
-                 * phase (see below). Instead the content of the attribute is
-                 * read one frame at a time (i.e. after a frame has been
-                 * visited, the next frame is read), and the labels it contains
-                 * are also extracted one frame at a time. Thanks to the
-                 * ordering of frames, having only a "one frame lookahead" is
-                 * not a problem, i.e. it is not possible to see an offset
-                 * smaller than the offset of the current insn and for which no
-                 * Label exist.
-                 */
-                /*
-                 * This is not true for UNINITIALIZED type offsets. We solve
-                 * this by parsing the stack map table without a full decoding
-                 * (see below).
-                 */
-            } else if (FRAMES && "StackMap".equals(attrName)) {
-                if ((context.flags & SKIP_FRAMES) == 0) {
-                    zip = false;
-                    stackMap = u + 10;
-                    stackMapSize = readInt(u + 4);
-                    frameCount = readUnsignedShort(u + 8);
-                }
-                /*
-                 * IMPORTANT! here we assume that the frames are ordered, as in
-                 * the StackMapTable attribute, although this is not guaranteed
-                 * by the attribute format.
-                 */
-            } else {
-                for (int j = 0; j < context.attrs.length; ++j) {
-                    if (context.attrs[j].type.equals(attrName)) {
-                        Attribute attr = context.attrs[j].read(this, u + 8,
-                                readInt(u + 4), c, codeStart - 8, labels);
-                        if (attr != null) {
-                            attr.next = attributes;
-                            attributes = attr;
-                        }
-                    }
-                }
-            }
-            u += 6 + readInt(u + 4);
-        }
-        u += 2;
-
-        // generates the first (implicit) stack map frame
-        if (FRAMES && stackMap != 0) {
-            /*
-             * for the first explicit frame the offset is not offset_delta + 1
-             * but only offset_delta; setting the implicit frame offset to -1
-             * allow the use of the "offset_delta + 1" rule in all cases
-             */
-            frame = context;
-            frame.offset = -1;
-            frame.mode = 0;
-            frame.localCount = 0;
-            frame.localDiff = 0;
-            frame.stackCount = 0;
-            frame.local = new Object[maxLocals];
-            frame.stack = new Object[maxStack];
-            if (unzip) {
-                getImplicitFrame(context);
-            }
-            /*
-             * Finds labels for UNINITIALIZED frame types. Instead of decoding
-             * each element of the stack map table, we look for 3 consecutive
-             * bytes that "look like" an UNINITIALIZED type (tag 8, offset
-             * within code bounds, NEW instruction at this offset). We may find
-             * false positives (i.e. not real UNINITIALIZED types), but this
-             * should be rare, and the only consequence will be the creation of
-             * an unneeded label. This is better than creating a label for each
-             * NEW instruction, and faster than fully decoding the whole stack
-             * map table.
-             */
-            for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) {
-                if (b[i] == 8) { // UNINITIALIZED FRAME TYPE
-                    int v = readUnsignedShort(i + 1);
-                    if (v >= 0 && v < codeLength) {
-                        if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
-                            readLabel(v, labels);
-                        }
-                    }
-                }
-            }
-        }
-
-        // visits the instructions
-        u = codeStart;
-        while (u < codeEnd) {
-            int offset = u - codeStart;
-
-            // visits the label and line number for this offset, if any
-            Label l = labels[offset];
-            if (l != null) {
-                mv.visitLabel(l);
-                if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
-                    mv.visitLineNumber(l.line, l);
-                }
-            }
-
-            // visits the frame for this offset, if any
-            while (FRAMES && frame != null
-                    && (frame.offset == offset || frame.offset == -1)) {
-                // if there is a frame for this offset, makes the visitor visit
-                // it, and reads the next frame if there is one.
-                if (frame.offset != -1) {
-                    if (!zip || unzip) {
-                        mv.visitFrame(Opcodes.F_NEW, frame.localCount,
-                                frame.local, frame.stackCount, frame.stack);
-                    } else {
-                        mv.visitFrame(frame.mode, frame.localDiff, frame.local,
-                                frame.stackCount, frame.stack);
-                    }
-                }
-                if (frameCount > 0) {
-                    stackMap = readFrame(stackMap, zip, unzip, labels, frame);
-                    --frameCount;
-                } else {
-                    frame = null;
-                }
-            }
-
-            // visits the instruction at this offset
-            int opcode = b[u] & 0xFF;
-            switch (ClassWriter.TYPE[opcode]) {
-            case ClassWriter.NOARG_INSN:
-                mv.visitInsn(opcode);
-                u += 1;
-                break;
-            case ClassWriter.IMPLVAR_INSN:
-                if (opcode > Opcodes.ISTORE) {
-                    opcode -= 59; // ISTORE_0
-                    mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
-                            opcode & 0x3);
-                } else {
-                    opcode -= 26; // ILOAD_0
-                    mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
-                }
-                u += 1;
-                break;
-            case ClassWriter.LABEL_INSN:
-                mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
-                u += 3;
-                break;
-            case ClassWriter.LABELW_INSN:
-                mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
-                u += 5;
-                break;
-            case ClassWriter.WIDE_INSN:
-                opcode = b[u + 1] & 0xFF;
-                if (opcode == Opcodes.IINC) {
-                    mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
-                    u += 6;
-                } else {
-                    mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
-                    u += 4;
-                }
-                break;
-            case ClassWriter.TABL_INSN: {
-                // skips 0 to 3 padding bytes
-                u = u + 4 - (offset & 3);
-                // reads instruction
-                int label = offset + readInt(u);
-                int min = readInt(u + 4);
-                int max = readInt(u + 8);
-                Label[] table = new Label[max - min + 1];
-                u += 12;
-                for (int i = 0; i < table.length; ++i) {
-                    table[i] = labels[offset + readInt(u)];
-                    u += 4;
-                }
-                mv.visitTableSwitchInsn(min, max, labels[label], table);
-                break;
-            }
-            case ClassWriter.LOOK_INSN: {
-                // skips 0 to 3 padding bytes
-                u = u + 4 - (offset & 3);
-                // reads instruction
-                int label = offset + readInt(u);
-                int len = readInt(u + 4);
-                int[] keys = new int[len];
-                Label[] values = new Label[len];
-                u += 8;
-                for (int i = 0; i < len; ++i) {
-                    keys[i] = readInt(u);
-                    values[i] = labels[offset + readInt(u + 4)];
-                    u += 8;
-                }
-                mv.visitLookupSwitchInsn(labels[label], keys, values);
-                break;
-            }
-            case ClassWriter.VAR_INSN:
-                mv.visitVarInsn(opcode, b[u + 1] & 0xFF);
-                u += 2;
-                break;
-            case ClassWriter.SBYTE_INSN:
-                mv.visitIntInsn(opcode, b[u + 1]);
-                u += 2;
-                break;
-            case ClassWriter.SHORT_INSN:
-                mv.visitIntInsn(opcode, readShort(u + 1));
-                u += 3;
-                break;
-            case ClassWriter.LDC_INSN:
-                mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c));
-                u += 2;
-                break;
-            case ClassWriter.LDCW_INSN:
-                mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
-                u += 3;
-                break;
-            case ClassWriter.FIELDORMETH_INSN:
-            case ClassWriter.ITFMETH_INSN: {
-                int cpIndex = items[readUnsignedShort(u + 1)];
-                String iowner = readClass(cpIndex, c);
-                cpIndex = items[readUnsignedShort(cpIndex + 2)];
-                String iname = readUTF8(cpIndex, c);
-                String idesc = readUTF8(cpIndex + 2, c);
-                if (opcode < Opcodes.INVOKEVIRTUAL) {
-                    mv.visitFieldInsn(opcode, iowner, iname, idesc);
-                } else {
-                    mv.visitMethodInsn(opcode, iowner, iname, idesc);
-                }
-                if (opcode == Opcodes.INVOKEINTERFACE) {
-                    u += 5;
-                } else {
-                    u += 3;
-                }
-                break;
-            }
-            case ClassWriter.INDYMETH_INSN: {
-                int cpIndex = items[readUnsignedShort(u + 1)];
-                int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
-                Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);
-                int bsmArgCount = readUnsignedShort(bsmIndex + 2);
-                Object[] bsmArgs = new Object[bsmArgCount];
-                bsmIndex += 4;
-                for (int i = 0; i < bsmArgCount; i++) {
-                    bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);
-                    bsmIndex += 2;
-                }
-                cpIndex = items[readUnsignedShort(cpIndex + 2)];
-                String iname = readUTF8(cpIndex, c);
-                String idesc = readUTF8(cpIndex + 2, c);
-                mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
-                u += 5;
-                break;
-            }
-            case ClassWriter.TYPE_INSN:
-                mv.visitTypeInsn(opcode, readClass(u + 1, c));
-                u += 3;
-                break;
-            case ClassWriter.IINC_INSN:
-                mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]);
-                u += 3;
-                break;
-            // case MANA_INSN:
-            default:
-                mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF);
-                u += 4;
-                break;
-            }
-        }
-        if (labels[codeLength] != null) {
-            mv.visitLabel(labels[codeLength]);
-        }
-
-        // visits the local variable tables
-        if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) {
-            int[] typeTable = null;
-            if (varTypeTable != 0) {
-                u = varTypeTable + 2;
-                typeTable = new int[readUnsignedShort(varTypeTable) * 3];
-                for (int i = typeTable.length; i > 0;) {
-                    typeTable[--i] = u + 6; // signature
-                    typeTable[--i] = readUnsignedShort(u + 8); // index
-                    typeTable[--i] = readUnsignedShort(u); // start
-                    u += 10;
-                }
-            }
-            u = varTable + 2;
-            for (int i = readUnsignedShort(varTable); i > 0; --i) {
-                int start = readUnsignedShort(u);
-                int length = readUnsignedShort(u + 2);
-                int index = readUnsignedShort(u + 8);
-                String vsignature = null;
-                if (typeTable != null) {
-                    for (int j = 0; j < typeTable.length; j += 3) {
-                        if (typeTable[j] == start && typeTable[j + 1] == index) {
-                            vsignature = readUTF8(typeTable[j + 2], c);
-                            break;
-                        }
-                    }
-                }
-                mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c),
-                        vsignature, labels[start], labels[start + length],
-                        index);
-                u += 10;
-            }
-        }
-
-        // visits the code attributes
-        while (attributes != null) {
-            Attribute attr = attributes.next;
-            attributes.next = null;
-            mv.visitAttribute(attributes);
-            attributes = attr;
-        }
-
-        // visits the max stack and max locals values
-        mv.visitMaxs(maxStack, maxLocals);
-    }
-
-    /**
-     * Reads parameter annotations and makes the given visitor visit them.
-     *
-     * @param v
-     *            start offset in {@link #b b} of the annotations to be read.
-     * @param desc
-     *            the method descriptor.
-     * @param buf
-     *            buffer to be used to call {@link #readUTF8 readUTF8},
-     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
-     *            readConst}.
-     * @param visible
-     *            <tt>true</tt> if the annotations to be read are visible at
-     *            runtime.
-     * @param mv
-     *            the visitor that must visit the annotations.
-     */
-    private void readParameterAnnotations(int v, final String desc,
-            final char[] buf, final boolean visible, final MethodVisitor mv) {
-        int i;
-        int n = b[v++] & 0xFF;
-        // workaround for a bug in javac (javac compiler generates a parameter
-        // annotation array whose size is equal to the number of parameters in
-        // the Java source file, while it should generate an array whose size is
-        // equal to the number of parameters in the method descriptor - which
-        // includes the synthetic parameters added by the compiler). This work-
-        // around supposes that the synthetic parameters are the first ones.
-        int synthetics = Type.getArgumentTypes(desc).length - n;
-        AnnotationVisitor av;
-        for (i = 0; i < synthetics; ++i) {
-            // virtual annotation to detect synthetic parameters in MethodWriter
-            av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
-            if (av != null) {
-                av.visitEnd();
-            }
-        }
-        for (; i < n + synthetics; ++i) {
-            int j = readUnsignedShort(v);
-            v += 2;
-            for (; j > 0; --j) {
-                av = mv.visitParameterAnnotation(i, readUTF8(v, buf), visible);
-                v = readAnnotationValues(v + 2, buf, true, av);
-            }
-        }
-    }
-
-    /**
-     * Reads the values of an annotation and makes the given visitor visit them.
-     *
-     * @param v
-     *            the start offset in {@link #b b} of the values to be read
-     *            (including the unsigned short that gives the number of
-     *            values).
-     * @param buf
-     *            buffer to be used to call {@link #readUTF8 readUTF8},
-     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
-     *            readConst}.
-     * @param named
-     *            if the annotation values are named or not.
-     * @param av
-     *            the visitor that must visit the values.
-     * @return the end offset of the annotation values.
-     */
-    private int readAnnotationValues(int v, final char[] buf,
-            final boolean named, final AnnotationVisitor av) {
-        int i = readUnsignedShort(v);
-        v += 2;
-        if (named) {
-            for (; i > 0; --i) {
-                v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
-            }
-        } else {
-            for (; i > 0; --i) {
-                v = readAnnotationValue(v, buf, null, av);
-            }
-        }
-        if (av != null) {
-            av.visitEnd();
-        }
-        return v;
-    }
-
-    /**
-     * Reads a value of an annotation and makes the given visitor visit it.
-     *
-     * @param v
-     *            the start offset in {@link #b b} of the value to be read
-     *            (<i>not including the value name constant pool index</i>).
-     * @param buf
-     *            buffer to be used to call {@link #readUTF8 readUTF8},
-     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
-     *            readConst}.
-     * @param name
-     *            the name of the value to be read.
-     * @param av
-     *            the visitor that must visit the value.
-     * @return the end offset of the annotation value.
-     */
-    private int readAnnotationValue(int v, final char[] buf, final String name,
-            final AnnotationVisitor av) {
-        int i;
-        if (av == null) {
-            switch (b[v] & 0xFF) {
-            case 'e': // enum_const_value
-                return v + 5;
-            case '@': // annotation_value
-                return readAnnotationValues(v + 3, buf, true, null);
-            case '[': // array_value
-                return readAnnotationValues(v + 1, buf, false, null);
-            default:
-                return v + 3;
-            }
-        }
-        switch (b[v++] & 0xFF) {
-        case 'I': // pointer to CONSTANT_Integer
-        case 'J': // pointer to CONSTANT_Long
-        case 'F': // pointer to CONSTANT_Float
-        case 'D': // pointer to CONSTANT_Double
-            av.visit(name, readConst(readUnsignedShort(v), buf));
-            v += 2;
-            break;
-        case 'B': // pointer to CONSTANT_Byte
-            av.visit(name,
-                    new Byte((byte) readInt(items[readUnsignedShort(v)])));
-            v += 2;
-            break;
-        case 'Z': // pointer to CONSTANT_Boolean
-            av.visit(name,
-                    readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE
-                            : Boolean.TRUE);
-            v += 2;
-            break;
-        case 'S': // pointer to CONSTANT_Short
-            av.visit(name, new Short(
-                    (short) readInt(items[readUnsignedShort(v)])));
-            v += 2;
-            break;
-        case 'C': // pointer to CONSTANT_Char
-            av.visit(name, new Character(
-                    (char) readInt(items[readUnsignedShort(v)])));
-            v += 2;
-            break;
-        case 's': // pointer to CONSTANT_Utf8
-            av.visit(name, readUTF8(v, buf));
-            v += 2;
-            break;
-        case 'e': // enum_const_value
-            av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
-            v += 4;
-            break;
-        case 'c': // class_info
-            av.visit(name, Type.getType(readUTF8(v, buf)));
-            v += 2;
-            break;
-        case '@': // annotation_value
-            v = readAnnotationValues(v + 2, buf, true,
-                    av.visitAnnotation(name, readUTF8(v, buf)));
-            break;
-        case '[': // array_value
-            int size = readUnsignedShort(v);
-            v += 2;
-            if (size == 0) {
-                return readAnnotationValues(v - 2, buf, false,
-                        av.visitArray(name));
-            }
-            switch (this.b[v++] & 0xFF) {
-            case 'B':
-                byte[] bv = new byte[size];
-                for (i = 0; i < size; i++) {
-                    bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
-                    v += 3;
-                }
-                av.visit(name, bv);
-                --v;
-                break;
-            case 'Z':
-                boolean[] zv = new boolean[size];
-                for (i = 0; i < size; i++) {
-                    zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
-                    v += 3;
-                }
-                av.visit(name, zv);
-                --v;
-                break;
-            case 'S':
-                short[] sv = new short[size];
-                for (i = 0; i < size; i++) {
-                    sv[i] = (short) readInt(items[readUnsignedShort(v)]);
-                    v += 3;
-                }
-                av.visit(name, sv);
-                --v;
-                break;
-            case 'C':
-                char[] cv = new char[size];
-                for (i = 0; i < size; i++) {
-                    cv[i] = (char) readInt(items[readUnsignedShort(v)]);
-                    v += 3;
-                }
-                av.visit(name, cv);
-                --v;
-                break;
-            case 'I':
-                int[] iv = new int[size];
-                for (i = 0; i < size; i++) {
-                    iv[i] = readInt(items[readUnsignedShort(v)]);
-                    v += 3;
-                }
-                av.visit(name, iv);
-                --v;
-                break;
-            case 'J':
-                long[] lv = new long[size];
-                for (i = 0; i < size; i++) {
-                    lv[i] = readLong(items[readUnsignedShort(v)]);
-                    v += 3;
-                }
-                av.visit(name, lv);
-                --v;
-                break;
-            case 'F':
-                float[] fv = new float[size];
-                for (i = 0; i < size; i++) {
-                    fv[i] = Float
-                            .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
-                    v += 3;
-                }
-                av.visit(name, fv);
-                --v;
-                break;
-            case 'D':
-                double[] dv = new double[size];
-                for (i = 0; i < size; i++) {
-                    dv[i] = Double
-                            .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
-                    v += 3;
-                }
-                av.visit(name, dv);
-                --v;
-                break;
-            default:
-                v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
-            }
-        }
-        return v;
-    }
-
-    /**
-     * Computes the implicit frame of the method currently being parsed (as
-     * defined in the given {@link Context}) and stores it in the given context.
-     *
-     * @param frame
-     *            information about the class being parsed.
-     */
-    private void getImplicitFrame(final Context frame) {
-        String desc = frame.desc;
-        Object[] locals = frame.local;
-        int local = 0;
-        if ((frame.access & Opcodes.ACC_STATIC) == 0) {
-            if ("<init>".equals(frame.name)) {
-                locals[local++] = Opcodes.UNINITIALIZED_THIS;
-            } else {
-                locals[local++] = readClass(header + 2, frame.buffer);
-            }
-        }
-        int i = 1;
-        loop: while (true) {
-            int j = i;
-            switch (desc.charAt(i++)) {
-            case 'Z':
-            case 'C':
-            case 'B':
-            case 'S':
-            case 'I':
-                locals[local++] = Opcodes.INTEGER;
-                break;
-            case 'F':
-                locals[local++] = Opcodes.FLOAT;
-                break;
-            case 'J':
-                locals[local++] = Opcodes.LONG;
-                break;
-            case 'D':
-                locals[local++] = Opcodes.DOUBLE;
-                break;
-            case '[':
-                while (desc.charAt(i) == '[') {
-                    ++i;
-                }
-                if (desc.charAt(i) == 'L') {
-                    ++i;
-                    while (desc.charAt(i) != ';') {
-                        ++i;
-                    }
-                }
-                locals[local++] = desc.substring(j, ++i);
-                break;
-            case 'L':
-                while (desc.charAt(i) != ';') {
-                    ++i;
-                }
-                locals[local++] = desc.substring(j + 1, i++);
-                break;
-            default:
-                break loop;
-            }
-        }
-        frame.localCount = local;
-    }
-
-    /**
-     * Reads a stack map frame and stores the result in the given
-     * {@link Context} object.
-     *
-     * @param stackMap
-     *            the start offset of a stack map frame in the class file.
-     * @param zip
-     *            if the stack map frame at stackMap is compressed or not.
-     * @param unzip
-     *            if the stack map frame must be uncompressed.
-     * @param labels
-     *            the labels of the method currently being parsed, indexed by
-     *            their offset. A new label for the parsed stack map frame is
-     *            stored in this array if it does not already exist.
-     * @param frame
-     *            where the parsed stack map frame must be stored.
-     * @return the offset of the first byte following the parsed frame.
-     */
-    private int readFrame(int stackMap, boolean zip, boolean unzip,
-            Label[] labels, Context frame) {
-        char[] c = frame.buffer;
-        int tag;
-        int delta;
-        if (zip) {
-            tag = b[stackMap++] & 0xFF;
-        } else {
-            tag = MethodWriter.FULL_FRAME;
-            frame.offset = -1;
-        }
-        frame.localDiff = 0;
-        if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
-            delta = tag;
-            frame.mode = Opcodes.F_SAME;
-            frame.stackCount = 0;
-        } else if (tag < MethodWriter.RESERVED) {
-            delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
-            stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
-            frame.mode = Opcodes.F_SAME1;
-            frame.stackCount = 1;
-        } else {
-            delta = readUnsignedShort(stackMap);
-            stackMap += 2;
-            if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
-                stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
-                frame.mode = Opcodes.F_SAME1;
-                frame.stackCount = 1;
-            } else if (tag >= MethodWriter.CHOP_FRAME
-                    && tag < MethodWriter.SAME_FRAME_EXTENDED) {
-                frame.mode = Opcodes.F_CHOP;
-                frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag;
-                frame.localCount -= frame.localDiff;
-                frame.stackCount = 0;
-            } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
-                frame.mode = Opcodes.F_SAME;
-                frame.stackCount = 0;
-            } else if (tag < MethodWriter.FULL_FRAME) {
-                int local = unzip ? frame.localCount : 0;
-                for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) {
-                    stackMap = readFrameType(frame.local, local++, stackMap, c,
-                            labels);
-                }
-                frame.mode = Opcodes.F_APPEND;
-                frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED;
-                frame.localCount += frame.localDiff;
-                frame.stackCount = 0;
-            } else { // if (tag == FULL_FRAME) {
-                frame.mode = Opcodes.F_FULL;
-                int n = readUnsignedShort(stackMap);
-                stackMap += 2;
-                frame.localDiff = n;
-                frame.localCount = n;
-                for (int local = 0; n > 0; n--) {
-                    stackMap = readFrameType(frame.local, local++, stackMap, c,
-                            labels);
-                }
-                n = readUnsignedShort(stackMap);
-                stackMap += 2;
-                frame.stackCount = n;
-                for (int stack = 0; n > 0; n--) {
-                    stackMap = readFrameType(frame.stack, stack++, stackMap, c,
-                            labels);
-                }
-            }
-        }
-        frame.offset += delta + 1;
-        readLabel(frame.offset, labels);
-        return stackMap;
-    }
-
-    /**
-     * Reads a stack map frame type and stores it at the given index in the
-     * given array.
-     *
-     * @param frame
-     *            the array where the parsed type must be stored.
-     * @param index
-     *            the index in 'frame' where the parsed type must be stored.
-     * @param v
-     *            the start offset of the stack map frame type to read.
-     * @param buf
-     *            a buffer to read strings.
-     * @param labels
-     *            the labels of the method currently being parsed, indexed by
-     *            their offset. If the parsed type is an Uninitialized type, a
-     *            new label for the corresponding NEW instruction is stored in
-     *            this array if it does not already exist.
-     * @return the offset of the first byte after the parsed type.
-     */
-    private int readFrameType(final Object[] frame, final int index, int v,
-            final char[] buf, final Label[] labels) {
-        int type = b[v++] & 0xFF;
-        switch (type) {
-        case 0:
-            frame[index] = Opcodes.TOP;
-            break;
-        case 1:
-            frame[index] = Opcodes.INTEGER;
-            break;
-        case 2:
-            frame[index] = Opcodes.FLOAT;
-            break;
-        case 3:
-            frame[index] = Opcodes.DOUBLE;
-            break;
-        case 4:
-            frame[index] = Opcodes.LONG;
-            break;
-        case 5:
-            frame[index] = Opcodes.NULL;
-            break;
-        case 6:
-            frame[index] = Opcodes.UNINITIALIZED_THIS;
-            break;
-        case 7: // Object
-            frame[index] = readClass(v, buf);
-            v += 2;
-            break;
-        default: // Uninitialized
-            frame[index] = readLabel(readUnsignedShort(v), labels);
-            v += 2;
-        }
-        return v;
-    }
-
-    /**
-     * Returns the label corresponding to the given offset. The default
-     * implementation of this method creates a label for the given offset if it
-     * has not been already created.
-     *
-     * @param offset
-     *            a bytecode offset in a method.
-     * @param labels
-     *            the already created labels, indexed by their offset. If a
-     *            label already exists for offset this method must not create a
-     *            new one. Otherwise it must store the new label in this array.
-     * @return a non null Label, which must be equal to labels[offset].
-     */
-    protected Label readLabel(int offset, Label[] labels) {
-        if (labels[offset] == null) {
-            labels[offset] = new Label();
-        }
-        return labels[offset];
-    }
-
-    /**
-     * Returns the start index of the attribute_info structure of this class.
-     *
-     * @return the start index of the attribute_info structure of this class.
-     */
-    private int getAttributes() {
-        // skips the header
-        int u = header + 8 + readUnsignedShort(header + 6) * 2;
-        // skips fields and methods
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            for (int j = readUnsignedShort(u + 8); j > 0; --j) {
-                u += 6 + readInt(u + 12);
-            }
-            u += 8;
-        }
-        u += 2;
-        for (int i = readUnsignedShort(u); i > 0; --i) {
-            for (int j = readUnsignedShort(u + 8); j > 0; --j) {
-                u += 6 + readInt(u + 12);
-            }
-            u += 8;
-        }
-        // the attribute_info structure starts just after the methods
-        return u + 2;
-    }
-
-    /**
-     * Reads an attribute in {@link #b b}.
-     *
-     * @param attrs
-     *            prototypes of the attributes that must be parsed during the
-     *            visit of the class. Any attribute whose type is not equal to
-     *            the type of one the prototypes is ignored (i.e. an empty
-     *            {@link Attribute} instance is returned).
-     * @param type
-     *            the type of the attribute.
-     * @param off
-     *            index of the first byte of the attribute's content in
-     *            {@link #b b}. The 6 attribute header bytes, containing the
-     *            type and the length of the attribute, are not taken into
-     *            account here (they have already been read).
-     * @param len
-     *            the length of the attribute's content.
-     * @param buf
-     *            buffer to be used to call {@link #readUTF8 readUTF8},
-     *            {@link #readClass(int,char[]) readClass} or {@link #readConst
-     *            readConst}.
-     * @param codeOff
-     *            index of the first byte of code's attribute content in
-     *            {@link #b b}, or -1 if the attribute to be read is not a code
-     *            attribute. The 6 attribute header bytes, containing the type
-     *            and the length of the attribute, are not taken into account
-     *            here.
-     * @param labels
-     *            the labels of the method's code, or <tt>null</tt> if the
-     *            attribute to be read is not a code attribute.
-     * @return the attribute that has been read, or <tt>null</tt> to skip this
-     *         attribute.
-     */
-    private Attribute readAttribute(final Attribute[] attrs, final String type,
-            final int off, final int len, final char[] buf, final int codeOff,
-            final Label[] labels) {
-        for (int i = 0; i < attrs.length; ++i) {
-            if (attrs[i].type.equals(type)) {
-                return attrs[i].read(this, off, len, buf, codeOff, labels);
-            }
-        }
-        return new Attribute(type).read(this, off, len, null, -1, null);
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: low level parsing
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the number of constant pool items in {@link #b b}.
-     *
-     * @return the number of constant pool items in {@link #b b}.
-     */
-    public int getItemCount() {
-        return items.length;
-    }
-
-    /**
-     * Returns the start index of the constant pool item in {@link #b b}, plus
-     * one. <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param item
-     *            the index a constant pool item.
-     * @return the start index of the constant pool item in {@link #b b}, plus
-     *         one.
-     */
-    public int getItem(final int item) {
-        return items[item];
-    }
-
-    /**
-     * Returns the maximum length of the strings contained in the constant pool
-     * of the class.
-     *
-     * @return the maximum length of the strings contained in the constant pool
-     *         of the class.
-     */
-    public int getMaxStringLength() {
-        return maxStringLength;
-    }
-
-    /**
-     * Reads a byte value in {@link #b b}. <i>This method is intended for
-     * {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public int readByte(final int index) {
-        return b[index] & 0xFF;
-    }
-
-    /**
-     * Reads an unsigned short value in {@link #b b}. <i>This method is intended
-     * for {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public int readUnsignedShort(final int index) {
-        byte[] b = this.b;
-        return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
-    }
-
-    /**
-     * Reads a signed short value in {@link #b b}. <i>This method is intended
-     * for {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public short readShort(final int index) {
-        byte[] b = this.b;
-        return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
-    }
-
-    /**
-     * Reads a signed int value in {@link #b b}. <i>This method is intended for
-     * {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public int readInt(final int index) {
-        byte[] b = this.b;
-        return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
-                | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
-    }
-
-    /**
-     * Reads a signed long value in {@link #b b}. <i>This method is intended for
-     * {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of the value to be read in {@link #b b}.
-     * @return the read value.
-     */
-    public long readLong(final int index) {
-        long l1 = readInt(index);
-        long l0 = readInt(index + 4) & 0xFFFFFFFFL;
-        return (l1 << 32) | l0;
-    }
-
-    /**
-     * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
-     * is intended for {@link Attribute} sub classes, and is normally not needed
-     * by class generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of an unsigned short value in {@link #b b},
-     *            whose value is the index of an UTF8 constant pool item.
-     * @param buf
-     *            buffer to be used to read the item. This buffer must be
-     *            sufficiently large. It is not automatically resized.
-     * @return the String corresponding to the specified UTF8 item.
-     */
-    public String readUTF8(int index, final char[] buf) {
-        int item = readUnsignedShort(index);
-        if (index == 0 || item == 0) {
-            return null;
-        }
-        String s = strings[item];
-        if (s != null) {
-            return s;
-        }
-        index = items[item];
-        return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
-    }
-
-    /**
-     * Reads UTF8 string in {@link #b b}.
-     *
-     * @param index
-     *            start offset of the UTF8 string to be read.
-     * @param utfLen
-     *            length of the UTF8 string to be read.
-     * @param buf
-     *            buffer to be used to read the string. This buffer must be
-     *            sufficiently large. It is not automatically resized.
-     * @return the String corresponding to the specified UTF8 string.
-     */
-    private String readUTF(int index, final int utfLen, final char[] buf) {
-        int endIndex = index + utfLen;
-        byte[] b = this.b;
-        int strLen = 0;
-        int c;
-        int st = 0;
-        char cc = 0;
-        while (index < endIndex) {
-            c = b[index++];
-            switch (st) {
-            case 0:
-                c = c & 0xFF;
-                if (c < 0x80) { // 0xxxxxxx
-                    buf[strLen++] = (char) c;
-                } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
-                    cc = (char) (c & 0x1F);
-                    st = 1;
-                } else { // 1110 xxxx 10xx xxxx 10xx xxxx
-                    cc = (char) (c & 0x0F);
-                    st = 2;
-                }
-                break;
-
-            case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
-                buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
-                st = 0;
-                break;
-
-            case 2: // byte 2 of 3-byte char
-                cc = (char) ((cc << 6) | (c & 0x3F));
-                st = 1;
-                break;
-            }
-        }
-        return new String(buf, 0, strLen);
-    }
-
-    /**
-     * Reads a class constant pool item in {@link #b b}. <i>This method is
-     * intended for {@link Attribute} sub classes, and is normally not needed by
-     * class generators or adapters.</i>
-     *
-     * @param index
-     *            the start index of an unsigned short value in {@link #b b},
-     *            whose value is the index of a class constant pool item.
-     * @param buf
-     *            buffer to be used to read the item. This buffer must be
-     *            sufficiently large. It is not automatically resized.
-     * @return the String corresponding to the specified class item.
-     */
-    public String readClass(final int index, final char[] buf) {
-        // computes the start index of the CONSTANT_Class item in b
-        // and reads the CONSTANT_Utf8 item designated by
-        // the first two bytes of this CONSTANT_Class item
-        return readUTF8(items[readUnsignedShort(index)], buf);
-    }
-
-    /**
-     * Reads a numeric or string constant pool item in {@link #b b}. <i>This
-     * method is intended for {@link Attribute} sub classes, and is normally not
-     * needed by class generators or adapters.</i>
-     *
-     * @param item
-     *            the index of a constant pool item.
-     * @param buf
-     *            buffer to be used to read the item. This buffer must be
-     *            sufficiently large. It is not automatically resized.
-     * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
-     *         {@link String}, {@link Type} or {@link Handle} corresponding to
-     *         the given constant pool item.
-     */
-    public Object readConst(final int item, final char[] buf) {
-        int index = items[item];
-        switch (b[index - 1]) {
-        case ClassWriter.INT:
-            return new Integer(readInt(index));
-        case ClassWriter.FLOAT:
-            return new Float(Float.intBitsToFloat(readInt(index)));
-        case ClassWriter.LONG:
-            return new Long(readLong(index));
-        case ClassWriter.DOUBLE:
-            return new Double(Double.longBitsToDouble(readLong(index)));
-        case ClassWriter.CLASS:
-            return Type.getObjectType(readUTF8(index, buf));
-        case ClassWriter.STR:
-            return readUTF8(index, buf);
-        case ClassWriter.MTYPE:
-            return Type.getMethodType(readUTF8(index, buf));
-        default: // case ClassWriter.HANDLE_BASE + [1..9]:
-            int tag = readByte(index);
-            int[] items = this.items;
-            int cpIndex = items[readUnsignedShort(index + 1)];
-            String owner = readClass(cpIndex, buf);
-            cpIndex = items[readUnsignedShort(cpIndex + 2)];
-            String name = readUTF8(cpIndex, buf);
-            String desc = readUTF8(cpIndex + 2, buf);
-            return new Handle(tag, owner, name, desc);
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/ClassVisitor.java b/src/jvm/clojure/asm/ClassVisitor.java
deleted file mode 100644
index bc5919b..0000000
--- a/src/jvm/clojure/asm/ClassVisitor.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A visitor to visit a Java class. The methods of this class must be called in
- * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
- * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
- * <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> | <tt>visitField</tt> |
- * <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
- *
- * @author Eric Bruneton
- */
-public abstract class ClassVisitor {
-
-    /**
-     * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
-     */
-    protected final int api;
-
-    /**
-     * The class visitor to which this visitor must delegate method calls. May
-     * be null.
-     */
-    protected ClassVisitor cv;
-
-    /**
-     * Constructs a new {@link ClassVisitor}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     */
-    public ClassVisitor(final int api) {
-        this(api, null);
-    }
-
-    /**
-     * Constructs a new {@link ClassVisitor}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param cv
-     *            the class visitor to which this visitor must delegate method
-     *            calls. May be null.
-     */
-    public ClassVisitor(final int api, final ClassVisitor cv) {
-        if (api != Opcodes.ASM4) {
-            throw new IllegalArgumentException();
-        }
-        this.api = api;
-        this.cv = cv;
-    }
-
-    /**
-     * Visits the header of the class.
-     *
-     * @param version
-     *            the class version.
-     * @param access
-     *            the class's access flags (see {@link Opcodes}). This parameter
-     *            also indicates if the class is deprecated.
-     * @param name
-     *            the internal name of the class (see
-     *            {@link Type#getInternalName() getInternalName}).
-     * @param signature
-     *            the signature of this class. May be <tt>null</tt> if the class
-     *            is not a generic one, and does not extend or implement generic
-     *            classes or interfaces.
-     * @param superName
-     *            the internal of name of the super class (see
-     *            {@link Type#getInternalName() getInternalName}). For
-     *            interfaces, the super class is {@link Object}. May be
-     *            <tt>null</tt>, but only for the {@link Object} class.
-     * @param interfaces
-     *            the internal names of the class's interfaces (see
-     *            {@link Type#getInternalName() getInternalName}). May be
-     *            <tt>null</tt>.
-     */
-    public void visit(int version, int access, String name, String signature,
-            String superName, String[] interfaces) {
-        if (cv != null) {
-            cv.visit(version, access, name, signature, superName, interfaces);
-        }
-    }
-
-    /**
-     * Visits the source of the class.
-     *
-     * @param source
-     *            the name of the source file from which the class was compiled.
-     *            May be <tt>null</tt>.
-     * @param debug
-     *            additional debug information to compute the correspondance
-     *            between source and compiled elements of the class. May be
-     *            <tt>null</tt>.
-     */
-    public void visitSource(String source, String debug) {
-        if (cv != null) {
-            cv.visitSource(source, debug);
-        }
-    }
-
-    /**
-     * Visits the enclosing class of the class. This method must be called only
-     * if the class has an enclosing class.
-     *
-     * @param owner
-     *            internal name of the enclosing class of the class.
-     * @param name
-     *            the name of the method that contains the class, or
-     *            <tt>null</tt> if the class is not enclosed in a method of its
-     *            enclosing class.
-     * @param desc
-     *            the descriptor of the method that contains the class, or
-     *            <tt>null</tt> if the class is not enclosed in a method of its
-     *            enclosing class.
-     */
-    public void visitOuterClass(String owner, String name, String desc) {
-        if (cv != null) {
-            cv.visitOuterClass(owner, name, desc);
-        }
-    }
-
-    /**
-     * Visits an annotation of the class.
-     *
-     * @param desc
-     *            the class descriptor of the annotation class.
-     * @param visible
-     *            <tt>true</tt> if the annotation is visible at runtime.
-     * @return a visitor to visit the annotation values, or <tt>null</tt> if
-     *         this visitor is not interested in visiting this annotation.
-     */
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        if (cv != null) {
-            return cv.visitAnnotation(desc, visible);
-        }
-        return null;
-    }
-
-    /**
-     * Visits a non standard attribute of the class.
-     *
-     * @param attr
-     *            an attribute.
-     */
-    public void visitAttribute(Attribute attr) {
-        if (cv != null) {
-            cv.visitAttribute(attr);
-        }
-    }
-
-    /**
-     * Visits information about an inner class. This inner class is not
-     * necessarily a member of the class being visited.
-     *
-     * @param name
-     *            the internal name of an inner class (see
-     *            {@link Type#getInternalName() getInternalName}).
-     * @param outerName
-     *            the internal name of the class to which the inner class
-     *            belongs (see {@link Type#getInternalName() getInternalName}).
-     *            May be <tt>null</tt> for not member classes.
-     * @param innerName
-     *            the (simple) name of the inner class inside its enclosing
-     *            class. May be <tt>null</tt> for anonymous inner classes.
-     * @param access
-     *            the access flags of the inner class as originally declared in
-     *            the enclosing class.
-     */
-    public void visitInnerClass(String name, String outerName,
-            String innerName, int access) {
-        if (cv != null) {
-            cv.visitInnerClass(name, outerName, innerName, access);
-        }
-    }
-
-    /**
-     * Visits a field of the class.
-     *
-     * @param access
-     *            the field's access flags (see {@link Opcodes}). This parameter
-     *            also indicates if the field is synthetic and/or deprecated.
-     * @param name
-     *            the field's name.
-     * @param desc
-     *            the field's descriptor (see {@link Type Type}).
-     * @param signature
-     *            the field's signature. May be <tt>null</tt> if the field's
-     *            type does not use generic types.
-     * @param value
-     *            the field's initial value. This parameter, which may be
-     *            <tt>null</tt> if the field does not have an initial value,
-     *            must be an {@link Integer}, a {@link Float}, a {@link Long}, a
-     *            {@link Double} or a {@link String} (for <tt>int</tt>,
-     *            <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
-     *            respectively). <i>This parameter is only used for static
-     *            fields</i>. Its value is ignored for non static fields, which
-     *            must be initialized through bytecode instructions in
-     *            constructors or methods.
-     * @return a visitor to visit field annotations and attributes, or
-     *         <tt>null</tt> if this class visitor is not interested in visiting
-     *         these annotations and attributes.
-     */
-    public FieldVisitor visitField(int access, String name, String desc,
-            String signature, Object value) {
-        if (cv != null) {
-            return cv.visitField(access, name, desc, signature, value);
-        }
-        return null;
-    }
-
-    /**
-     * Visits a method of the class. This method <i>must</i> return a new
-     * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is called,
-     * i.e., it should not return a previously returned visitor.
-     *
-     * @param access
-     *            the method's access flags (see {@link Opcodes}). This
-     *            parameter also indicates if the method is synthetic and/or
-     *            deprecated.
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     * @param signature
-     *            the method's signature. May be <tt>null</tt> if the method
-     *            parameters, return type and exceptions do not use generic
-     *            types.
-     * @param exceptions
-     *            the internal names of the method's exception classes (see
-     *            {@link Type#getInternalName() getInternalName}). May be
-     *            <tt>null</tt>.
-     * @return an object to visit the byte code of the method, or <tt>null</tt>
-     *         if this class visitor is not interested in visiting the code of
-     *         this method.
-     */
-    public MethodVisitor visitMethod(int access, String name, String desc,
-            String signature, String[] exceptions) {
-        if (cv != null) {
-            return cv.visitMethod(access, name, desc, signature, exceptions);
-        }
-        return null;
-    }
-
-    /**
-     * Visits the end of the class. This method, which is the last one to be
-     * called, is used to inform the visitor that all the fields and methods of
-     * the class have been visited.
-     */
-    public void visitEnd() {
-        if (cv != null) {
-            cv.visitEnd();
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/ClassWriter.java b/src/jvm/clojure/asm/ClassWriter.java
deleted file mode 100644
index 3d78868..0000000
--- a/src/jvm/clojure/asm/ClassWriter.java
+++ /dev/null
@@ -1,1693 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A {@link ClassVisitor} that generates classes in bytecode form. More
- * precisely this visitor generates a byte array conforming to the Java class
- * file format. It can be used alone, to generate a Java class "from scratch",
- * or with one or more {@link ClassReader ClassReader} and adapter class visitor
- * to generate a modified class from one or more existing Java classes.
- *
- * @author Eric Bruneton
- */
-public class ClassWriter extends ClassVisitor {
-
-    /**
-     * Flag to automatically compute the maximum stack size and the maximum
-     * number of local variables of methods. If this flag is set, then the
-     * arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the
-     * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod}
-     * method will be ignored, and computed automatically from the signature and
-     * the bytecode of each method.
-     *
-     * @see #ClassWriter(int)
-     */
-    public static final int COMPUTE_MAXS = 1;
-
-    /**
-     * Flag to automatically compute the stack map frames of methods from
-     * scratch. If this flag is set, then the calls to the
-     * {@link MethodVisitor#visitFrame} method are ignored, and the stack map
-     * frames are recomputed from the methods bytecode. The arguments of the
-     * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
-     * recomputed from the bytecode. In other words, computeFrames implies
-     * computeMaxs.
-     *
-     * @see #ClassWriter(int)
-     */
-    public static final int COMPUTE_FRAMES = 2;
-
-    /**
-     * Pseudo access flag to distinguish between the synthetic attribute and the
-     * synthetic access flag.
-     */
-    static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
-
-    /**
-     * Factor to convert from ACC_SYNTHETIC_ATTRIBUTE to Opcode.ACC_SYNTHETIC.
-     */
-    static final int TO_ACC_SYNTHETIC = ACC_SYNTHETIC_ATTRIBUTE
-            / Opcodes.ACC_SYNTHETIC;
-
-    /**
-     * The type of instructions without any argument.
-     */
-    static final int NOARG_INSN = 0;
-
-    /**
-     * The type of instructions with an signed byte argument.
-     */
-    static final int SBYTE_INSN = 1;
-
-    /**
-     * The type of instructions with an signed short argument.
-     */
-    static final int SHORT_INSN = 2;
-
-    /**
-     * The type of instructions with a local variable index argument.
-     */
-    static final int VAR_INSN = 3;
-
-    /**
-     * The type of instructions with an implicit local variable index argument.
-     */
-    static final int IMPLVAR_INSN = 4;
-
-    /**
-     * The type of instructions with a type descriptor argument.
-     */
-    static final int TYPE_INSN = 5;
-
-    /**
-     * The type of field and method invocations instructions.
-     */
-    static final int FIELDORMETH_INSN = 6;
-
-    /**
-     * The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction.
-     */
-    static final int ITFMETH_INSN = 7;
-
-    /**
-     * The type of the INVOKEDYNAMIC instruction.
-     */
-    static final int INDYMETH_INSN = 8;
-
-    /**
-     * The type of instructions with a 2 bytes bytecode offset label.
-     */
-    static final int LABEL_INSN = 9;
-
-    /**
-     * The type of instructions with a 4 bytes bytecode offset label.
-     */
-    static final int LABELW_INSN = 10;
-
-    /**
-     * The type of the LDC instruction.
-     */
-    static final int LDC_INSN = 11;
-
-    /**
-     * The type of the LDC_W and LDC2_W instructions.
-     */
-    static final int LDCW_INSN = 12;
-
-    /**
-     * The type of the IINC instruction.
-     */
-    static final int IINC_INSN = 13;
-
-    /**
-     * The type of the TABLESWITCH instruction.
-     */
-    static final int TABL_INSN = 14;
-
-    /**
-     * The type of the LOOKUPSWITCH instruction.
-     */
-    static final int LOOK_INSN = 15;
-
-    /**
-     * The type of the MULTIANEWARRAY instruction.
-     */
-    static final int MANA_INSN = 16;
-
-    /**
-     * The type of the WIDE instruction.
-     */
-    static final int WIDE_INSN = 17;
-
-    /**
-     * The instruction types of all JVM opcodes.
-     */
-    static final byte[] TYPE;
-
-    /**
-     * The type of CONSTANT_Class constant pool items.
-     */
-    static final int CLASS = 7;
-
-    /**
-     * The type of CONSTANT_Fieldref constant pool items.
-     */
-    static final int FIELD = 9;
-
-    /**
-     * The type of CONSTANT_Methodref constant pool items.
-     */
-    static final int METH = 10;
-
-    /**
-     * The type of CONSTANT_InterfaceMethodref constant pool items.
-     */
-    static final int IMETH = 11;
-
-    /**
-     * The type of CONSTANT_String constant pool items.
-     */
-    static final int STR = 8;
-
-    /**
-     * The type of CONSTANT_Integer constant pool items.
-     */
-    static final int INT = 3;
-
-    /**
-     * The type of CONSTANT_Float constant pool items.
-     */
-    static final int FLOAT = 4;
-
-    /**
-     * The type of CONSTANT_Long constant pool items.
-     */
-    static final int LONG = 5;
-
-    /**
-     * The type of CONSTANT_Double constant pool items.
-     */
-    static final int DOUBLE = 6;
-
-    /**
-     * The type of CONSTANT_NameAndType constant pool items.
-     */
-    static final int NAME_TYPE = 12;
-
-    /**
-     * The type of CONSTANT_Utf8 constant pool items.
-     */
-    static final int UTF8 = 1;
-
-    /**
-     * The type of CONSTANT_MethodType constant pool items.
-     */
-    static final int MTYPE = 16;
-
-    /**
-     * The type of CONSTANT_MethodHandle constant pool items.
-     */
-    static final int HANDLE = 15;
-
-    /**
-     * The type of CONSTANT_InvokeDynamic constant pool items.
-     */
-    static final int INDY = 18;
-
-    /**
-     * The base value for all CONSTANT_MethodHandle constant pool items.
-     * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
-     * different items.
-     */
-    static final int HANDLE_BASE = 20;
-
-    /**
-     * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
-     * instead of the constant pool, in order to avoid clashes with normal
-     * constant pool items in the ClassWriter constant pool's hash table.
-     */
-    static final int TYPE_NORMAL = 30;
-
-    /**
-     * Uninitialized type Item stored in the ClassWriter
-     * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
-     * avoid clashes with normal constant pool items in the ClassWriter constant
-     * pool's hash table.
-     */
-    static final int TYPE_UNINIT = 31;
-
-    /**
-     * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
-     * instead of the constant pool, in order to avoid clashes with normal
-     * constant pool items in the ClassWriter constant pool's hash table.
-     */
-    static final int TYPE_MERGED = 32;
-
-    /**
-     * The type of BootstrapMethods items. These items are stored in a special
-     * class attribute named BootstrapMethods and not in the constant pool.
-     */
-    static final int BSM = 33;
-
-    /**
-     * The class reader from which this class writer was constructed, if any.
-     */
-    ClassReader cr;
-
-    /**
-     * Minor and major version numbers of the class to be generated.
-     */
-    int version;
-
-    /**
-     * Index of the next item to be added in the constant pool.
-     */
-    int index;
-
-    /**
-     * The constant pool of this class.
-     */
-    final ByteVector pool;
-
-    /**
-     * The constant pool's hash table data.
-     */
-    Item[] items;
-
-    /**
-     * The threshold of the constant pool's hash table.
-     */
-    int threshold;
-
-    /**
-     * A reusable key used to look for items in the {@link #items} hash table.
-     */
-    final Item key;
-
-    /**
-     * A reusable key used to look for items in the {@link #items} hash table.
-     */
-    final Item key2;
-
-    /**
-     * A reusable key used to look for items in the {@link #items} hash table.
-     */
-    final Item key3;
-
-    /**
-     * A reusable key used to look for items in the {@link #items} hash table.
-     */
-    final Item key4;
-
-    /**
-     * A type table used to temporarily store internal names that will not
-     * necessarily be stored in the constant pool. This type table is used by
-     * the control flow and data flow analysis algorithm used to compute stack
-     * map frames from scratch. This array associates to each index <tt>i</tt>
-     * the Item whose index is <tt>i</tt>. All Item objects stored in this array
-     * are also stored in the {@link #items} hash table. These two arrays allow
-     * to retrieve an Item from its index or, conversely, to get the index of an
-     * Item from its value. Each Item stores an internal name in its
-     * {@link Item#strVal1} field.
-     */
-    Item[] typeTable;
-
-    /**
-     * Number of elements in the {@link #typeTable} array.
-     */
-    private short typeCount;
-
-    /**
-     * The access flags of this class.
-     */
-    private int access;
-
-    /**
-     * The constant pool item that contains the internal name of this class.
-     */
-    private int name;
-
-    /**
-     * The internal name of this class.
-     */
-    String thisName;
-
-    /**
-     * The constant pool item that contains the signature of this class.
-     */
-    private int signature;
-
-    /**
-     * The constant pool item that contains the internal name of the super class
-     * of this class.
-     */
-    private int superName;
-
-    /**
-     * Number of interfaces implemented or extended by this class or interface.
-     */
-    private int interfaceCount;
-
-    /**
-     * The interfaces implemented or extended by this class or interface. More
-     * precisely, this array contains the indexes of the constant pool items
-     * that contain the internal names of these interfaces.
-     */
-    private int[] interfaces;
-
-    /**
-     * The index of the constant pool item that contains the name of the source
-     * file from which this class was compiled.
-     */
-    private int sourceFile;
-
-    /**
-     * The SourceDebug attribute of this class.
-     */
-    private ByteVector sourceDebug;
-
-    /**
-     * The constant pool item that contains the name of the enclosing class of
-     * this class.
-     */
-    private int enclosingMethodOwner;
-
-    /**
-     * The constant pool item that contains the name and descriptor of the
-     * enclosing method of this class.
-     */
-    private int enclosingMethod;
-
-    /**
-     * The runtime visible annotations of this class.
-     */
-    private AnnotationWriter anns;
-
-    /**
-     * The runtime invisible annotations of this class.
-     */
-    private AnnotationWriter ianns;
-
-    /**
-     * The non standard attributes of this class.
-     */
-    private Attribute attrs;
-
-    /**
-     * The number of entries in the InnerClasses attribute.
-     */
-    private int innerClassesCount;
-
-    /**
-     * The InnerClasses attribute.
-     */
-    private ByteVector innerClasses;
-
-    /**
-     * The number of entries in the BootstrapMethods attribute.
-     */
-    int bootstrapMethodsCount;
-
-    /**
-     * The BootstrapMethods attribute.
-     */
-    ByteVector bootstrapMethods;
-
-    /**
-     * The fields of this class. These fields are stored in a linked list of
-     * {@link FieldWriter} objects, linked to each other by their
-     * {@link FieldWriter#fv} field. This field stores the first element of this
-     * list.
-     */
-    FieldWriter firstField;
-
-    /**
-     * The fields of this class. These fields are stored in a linked list of
-     * {@link FieldWriter} objects, linked to each other by their
-     * {@link FieldWriter#fv} field. This field stores the last element of this
-     * list.
-     */
-    FieldWriter lastField;
-
-    /**
-     * The methods of this class. These methods are stored in a linked list of
-     * {@link MethodWriter} objects, linked to each other by their
-     * {@link MethodWriter#mv} field. This field stores the first element of
-     * this list.
-     */
-    MethodWriter firstMethod;
-
-    /**
-     * The methods of this class. These methods are stored in a linked list of
-     * {@link MethodWriter} objects, linked to each other by their
-     * {@link MethodWriter#mv} field. This field stores the last element of this
-     * list.
-     */
-    MethodWriter lastMethod;
-
-    /**
-     * <tt>true</tt> if the maximum stack size and number of local variables
-     * must be automatically computed.
-     */
-    private final boolean computeMaxs;
-
-    /**
-     * <tt>true</tt> if the stack map frames must be recomputed from scratch.
-     */
-    private final boolean computeFrames;
-
-    /**
-     * <tt>true</tt> if the stack map tables of this class are invalid. The
-     * {@link MethodWriter#resizeInstructions} method cannot transform existing
-     * stack map tables, and so produces potentially invalid classes when it is
-     * executed. In this case the class is reread and rewritten with the
-     * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
-     * stack map tables when this option is used).
-     */
-    boolean invalidFrames;
-
-    // ------------------------------------------------------------------------
-    // Static initializer
-    // ------------------------------------------------------------------------
-
-    /**
-     * Computes the instruction types of JVM opcodes.
-     */
-    static {
-        int i;
-        byte[] b = new byte[220];
-        String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
-                + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
-                + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
-                + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
-        for (i = 0; i < b.length; ++i) {
-            b[i] = (byte) (s.charAt(i) - 'A');
-        }
-        TYPE = b;
-
-        // code to generate the above string
-        //
-        // // SBYTE_INSN instructions
-        // b[Constants.NEWARRAY] = SBYTE_INSN;
-        // b[Constants.BIPUSH] = SBYTE_INSN;
-        //
-        // // SHORT_INSN instructions
-        // b[Constants.SIPUSH] = SHORT_INSN;
-        //
-        // // (IMPL)VAR_INSN instructions
-        // b[Constants.RET] = VAR_INSN;
-        // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
-        // b[i] = VAR_INSN;
-        // }
-        // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
-        // b[i] = VAR_INSN;
-        // }
-        // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3
-        // b[i] = IMPLVAR_INSN;
-        // }
-        // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3
-        // b[i] = IMPLVAR_INSN;
-        // }
-        //
-        // // TYPE_INSN instructions
-        // b[Constants.NEW] = TYPE_INSN;
-        // b[Constants.ANEWARRAY] = TYPE_INSN;
-        // b[Constants.CHECKCAST] = TYPE_INSN;
-        // b[Constants.INSTANCEOF] = TYPE_INSN;
-        //
-        // // (Set)FIELDORMETH_INSN instructions
-        // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
-        // b[i] = FIELDORMETH_INSN;
-        // }
-        // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
-        // b[Constants.INVOKEDYNAMIC] = INDYMETH_INSN;
-        //
-        // // LABEL(W)_INSN instructions
-        // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
-        // b[i] = LABEL_INSN;
-        // }
-        // b[Constants.IFNULL] = LABEL_INSN;
-        // b[Constants.IFNONNULL] = LABEL_INSN;
-        // b[200] = LABELW_INSN; // GOTO_W
-        // b[201] = LABELW_INSN; // JSR_W
-        // // temporary opcodes used internally by ASM - see Label and
-        // MethodWriter
-        // for (i = 202; i < 220; ++i) {
-        // b[i] = LABEL_INSN;
-        // }
-        //
-        // // LDC(_W) instructions
-        // b[Constants.LDC] = LDC_INSN;
-        // b[19] = LDCW_INSN; // LDC_W
-        // b[20] = LDCW_INSN; // LDC2_W
-        //
-        // // special instructions
-        // b[Constants.IINC] = IINC_INSN;
-        // b[Constants.TABLESWITCH] = TABL_INSN;
-        // b[Constants.LOOKUPSWITCH] = LOOK_INSN;
-        // b[Constants.MULTIANEWARRAY] = MANA_INSN;
-        // b[196] = WIDE_INSN; // WIDE
-        //
-        // for (i = 0; i < b.length; ++i) {
-        // System.err.print((char)('A' + b[i]));
-        // }
-        // System.err.println();
-    }
-
-    // ------------------------------------------------------------------------
-    // Constructor
-    // ------------------------------------------------------------------------
-
-    /**
-     * Constructs a new {@link ClassWriter} object.
-     *
-     * @param flags
-     *            option flags that can be used to modify the default behavior
-     *            of this class. See {@link #COMPUTE_MAXS},
-     *            {@link #COMPUTE_FRAMES}.
-     */
-    public ClassWriter(final int flags) {
-        super(Opcodes.ASM4);
-        index = 1;
-        pool = new ByteVector();
-        items = new Item[256];
-        threshold = (int) (0.75d * items.length);
-        key = new Item();
-        key2 = new Item();
-        key3 = new Item();
-        key4 = new Item();
-        this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
-        this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
-    }
-
-    /**
-     * Constructs a new {@link ClassWriter} object and enables optimizations for
-     * "mostly add" bytecode transformations. These optimizations are the
-     * following:
-     *
-     * <ul>
-     * <li>The constant pool from the original class is copied as is in the new
-     * class, which saves time. New constant pool entries will be added at the
-     * end if necessary, but unused constant pool entries <i>won't be
-     * removed</i>.</li>
-     * <li>Methods that are not transformed are copied as is in the new class,
-     * directly from the original class bytecode (i.e. without emitting visit
-     * events for all the method instructions), which saves a <i>lot</i> of
-     * time. Untransformed methods are detected by the fact that the
-     * {@link ClassReader} receives {@link MethodVisitor} objects that come from
-     * a {@link ClassWriter} (and not from any other {@link ClassVisitor}
-     * instance).</li>
-     * </ul>
-     *
-     * @param classReader
-     *            the {@link ClassReader} used to read the original class. It
-     *            will be used to copy the entire constant pool from the
-     *            original class and also to copy other fragments of original
-     *            bytecode where applicable.
-     * @param flags
-     *            option flags that can be used to modify the default behavior
-     *            of this class. <i>These option flags do not affect methods
-     *            that are copied as is in the new class. This means that the
-     *            maximum stack size nor the stack frames will be computed for
-     *            these methods</i>. See {@link #COMPUTE_MAXS},
-     *            {@link #COMPUTE_FRAMES}.
-     */
-    public ClassWriter(final ClassReader classReader, final int flags) {
-        this(flags);
-        classReader.copyPool(this);
-        this.cr = classReader;
-    }
-
-    // ------------------------------------------------------------------------
-    // Implementation of the ClassVisitor abstract class
-    // ------------------------------------------------------------------------
-
-    @Override
-    public final void visit(final int version, final int access,
-            final String name, final String signature, final String superName,
-            final String[] interfaces) {
-        this.version = version;
-        this.access = access;
-        this.name = newClass(name);
-        thisName = name;
-        if (ClassReader.SIGNATURES && signature != null) {
-            this.signature = newUTF8(signature);
-        }
-        this.superName = superName == null ? 0 : newClass(superName);
-        if (interfaces != null && interfaces.length > 0) {
-            interfaceCount = interfaces.length;
-            this.interfaces = new int[interfaceCount];
-            for (int i = 0; i < interfaceCount; ++i) {
-                this.interfaces[i] = newClass(interfaces[i]);
-            }
-        }
-    }
-
-    @Override
-    public final void visitSource(final String file, final String debug) {
-        if (file != null) {
-            sourceFile = newUTF8(file);
-        }
-        if (debug != null) {
-            sourceDebug = new ByteVector().putUTF8(debug);
-        }
-    }
-
-    @Override
-    public final void visitOuterClass(final String owner, final String name,
-            final String desc) {
-        enclosingMethodOwner = newClass(owner);
-        if (name != null && desc != null) {
-            enclosingMethod = newNameType(name, desc);
-        }
-    }
-
-    @Override
-    public final AnnotationVisitor visitAnnotation(final String desc,
-            final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
-        ByteVector bv = new ByteVector();
-        // write type, and reserve space for values count
-        bv.putShort(newUTF8(desc)).putShort(0);
-        AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2);
-        if (visible) {
-            aw.next = anns;
-            anns = aw;
-        } else {
-            aw.next = ianns;
-            ianns = aw;
-        }
-        return aw;
-    }
-
-    @Override
-    public final void visitAttribute(final Attribute attr) {
-        attr.next = attrs;
-        attrs = attr;
-    }
-
-    @Override
-    public final void visitInnerClass(final String name,
-            final String outerName, final String innerName, final int access) {
-        if (innerClasses == null) {
-            innerClasses = new ByteVector();
-        }
-        ++innerClassesCount;
-        innerClasses.putShort(name == null ? 0 : newClass(name));
-        innerClasses.putShort(outerName == null ? 0 : newClass(outerName));
-        innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName));
-        innerClasses.putShort(access);
-    }
-
-    @Override
-    public final FieldVisitor visitField(final int access, final String name,
-            final String desc, final String signature, final Object value) {
-        return new FieldWriter(this, access, name, desc, signature, value);
-    }
-
-    @Override
-    public final MethodVisitor visitMethod(final int access, final String name,
-            final String desc, final String signature, final String[] exceptions) {
-        return new MethodWriter(this, access, name, desc, signature,
-                exceptions, computeMaxs, computeFrames);
-    }
-
-    @Override
-    public final void visitEnd() {
-    }
-
-    // ------------------------------------------------------------------------
-    // Other public methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the bytecode of the class that was build with this class writer.
-     *
-     * @return the bytecode of the class that was build with this class writer.
-     */
-    public byte[] toByteArray() {
-        if (index > 0xFFFF) {
-            throw new RuntimeException("Class file too large!");
-        }
-        // computes the real size of the bytecode of this class
-        int size = 24 + 2 * interfaceCount;
-        int nbFields = 0;
-        FieldWriter fb = firstField;
-        while (fb != null) {
-            ++nbFields;
-            size += fb.getSize();
-            fb = (FieldWriter) fb.fv;
-        }
-        int nbMethods = 0;
-        MethodWriter mb = firstMethod;
-        while (mb != null) {
-            ++nbMethods;
-            size += mb.getSize();
-            mb = (MethodWriter) mb.mv;
-        }
-        int attributeCount = 0;
-        if (bootstrapMethods != null) {
-            // we put it as first attribute in order to improve a bit
-            // ClassReader.copyBootstrapMethods
-            ++attributeCount;
-            size += 8 + bootstrapMethods.length;
-            newUTF8("BootstrapMethods");
-        }
-        if (ClassReader.SIGNATURES && signature != 0) {
-            ++attributeCount;
-            size += 8;
-            newUTF8("Signature");
-        }
-        if (sourceFile != 0) {
-            ++attributeCount;
-            size += 8;
-            newUTF8("SourceFile");
-        }
-        if (sourceDebug != null) {
-            ++attributeCount;
-            size += sourceDebug.length + 4;
-            newUTF8("SourceDebugExtension");
-        }
-        if (enclosingMethodOwner != 0) {
-            ++attributeCount;
-            size += 10;
-            newUTF8("EnclosingMethod");
-        }
-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
-            ++attributeCount;
-            size += 6;
-            newUTF8("Deprecated");
-        }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
-            if ((version & 0xFFFF) < Opcodes.V1_5
-                    || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
-                ++attributeCount;
-                size += 6;
-                newUTF8("Synthetic");
-            }
-        }
-        if (innerClasses != null) {
-            ++attributeCount;
-            size += 8 + innerClasses.length;
-            newUTF8("InnerClasses");
-        }
-        if (ClassReader.ANNOTATIONS && anns != null) {
-            ++attributeCount;
-            size += 8 + anns.getSize();
-            newUTF8("RuntimeVisibleAnnotations");
-        }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
-            ++attributeCount;
-            size += 8 + ianns.getSize();
-            newUTF8("RuntimeInvisibleAnnotations");
-        }
-        if (attrs != null) {
-            attributeCount += attrs.getCount();
-            size += attrs.getSize(this, null, 0, -1, -1);
-        }
-        size += pool.length;
-        // allocates a byte vector of this size, in order to avoid unnecessary
-        // arraycopy operations in the ByteVector.enlarge() method
-        ByteVector out = new ByteVector(size);
-        out.putInt(0xCAFEBABE).putInt(version);
-        out.putShort(index).putByteArray(pool.data, 0, pool.length);
-        int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE
-                | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC);
-        out.putShort(access & ~mask).putShort(name).putShort(superName);
-        out.putShort(interfaceCount);
-        for (int i = 0; i < interfaceCount; ++i) {
-            out.putShort(interfaces[i]);
-        }
-        out.putShort(nbFields);
-        fb = firstField;
-        while (fb != null) {
-            fb.put(out);
-            fb = (FieldWriter) fb.fv;
-        }
-        out.putShort(nbMethods);
-        mb = firstMethod;
-        while (mb != null) {
-            mb.put(out);
-            mb = (MethodWriter) mb.mv;
-        }
-        out.putShort(attributeCount);
-        if (bootstrapMethods != null) {
-            out.putShort(newUTF8("BootstrapMethods"));
-            out.putInt(bootstrapMethods.length + 2).putShort(
-                    bootstrapMethodsCount);
-            out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
-        }
-        if (ClassReader.SIGNATURES && signature != 0) {
-            out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
-        }
-        if (sourceFile != 0) {
-            out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
-        }
-        if (sourceDebug != null) {
-            int len = sourceDebug.length - 2;
-            out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
-            out.putByteArray(sourceDebug.data, 2, len);
-        }
-        if (enclosingMethodOwner != 0) {
-            out.putShort(newUTF8("EnclosingMethod")).putInt(4);
-            out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
-        }
-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
-            out.putShort(newUTF8("Deprecated")).putInt(0);
-        }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
-            if ((version & 0xFFFF) < Opcodes.V1_5
-                    || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
-                out.putShort(newUTF8("Synthetic")).putInt(0);
-            }
-        }
-        if (innerClasses != null) {
-            out.putShort(newUTF8("InnerClasses"));
-            out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
-            out.putByteArray(innerClasses.data, 0, innerClasses.length);
-        }
-        if (ClassReader.ANNOTATIONS && anns != null) {
-            out.putShort(newUTF8("RuntimeVisibleAnnotations"));
-            anns.put(out);
-        }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
-            out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
-            ianns.put(out);
-        }
-        if (attrs != null) {
-            attrs.put(this, null, 0, -1, -1, out);
-        }
-        if (invalidFrames) {
-            ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
-            new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES);
-            return cw.toByteArray();
-        }
-        return out.data;
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: constant pool management
-    // ------------------------------------------------------------------------
-
-    /**
-     * Adds a number or string constant to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     *
-     * @param cst
-     *            the value of the constant to be added to the constant pool.
-     *            This parameter must be an {@link Integer}, a {@link Float}, a
-     *            {@link Long}, a {@link Double}, a {@link String} or a
-     *            {@link Type}.
-     * @return a new or already existing constant item with the given value.
-     */
-    Item newConstItem(final Object cst) {
-        if (cst instanceof Integer) {
-            int val = ((Integer) cst).intValue();
-            return newInteger(val);
-        } else if (cst instanceof Byte) {
-            int val = ((Byte) cst).intValue();
-            return newInteger(val);
-        } else if (cst instanceof Character) {
-            int val = ((Character) cst).charValue();
-            return newInteger(val);
-        } else if (cst instanceof Short) {
-            int val = ((Short) cst).intValue();
-            return newInteger(val);
-        } else if (cst instanceof Boolean) {
-            int val = ((Boolean) cst).booleanValue() ? 1 : 0;
-            return newInteger(val);
-        } else if (cst instanceof Float) {
-            float val = ((Float) cst).floatValue();
-            return newFloat(val);
-        } else if (cst instanceof Long) {
-            long val = ((Long) cst).longValue();
-            return newLong(val);
-        } else if (cst instanceof Double) {
-            double val = ((Double) cst).doubleValue();
-            return newDouble(val);
-        } else if (cst instanceof String) {
-            return newString((String) cst);
-        } else if (cst instanceof Type) {
-            Type t = (Type) cst;
-            int s = t.getSort();
-            if (s == Type.OBJECT) {
-                return newClassItem(t.getInternalName());
-            } else if (s == Type.METHOD) {
-                return newMethodTypeItem(t.getDescriptor());
-            } else { // s == primitive type or array
-                return newClassItem(t.getDescriptor());
-            }
-        } else if (cst instanceof Handle) {
-            Handle h = (Handle) cst;
-            return newHandleItem(h.tag, h.owner, h.name, h.desc);
-        } else {
-            throw new IllegalArgumentException("value " + cst);
-        }
-    }
-
-    /**
-     * Adds a number or string constant to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param cst
-     *            the value of the constant to be added to the constant pool.
-     *            This parameter must be an {@link Integer}, a {@link Float}, a
-     *            {@link Long}, a {@link Double} or a {@link String}.
-     * @return the index of a new or already existing constant item with the
-     *         given value.
-     */
-    public int newConst(final Object cst) {
-        return newConstItem(cst).index;
-    }
-
-    /**
-     * Adds an UTF8 string to the constant pool of the class being build. Does
-     * nothing if the constant pool already contains a similar item. <i>This
-     * method is intended for {@link Attribute} sub classes, and is normally not
-     * needed by class generators or adapters.</i>
-     *
-     * @param value
-     *            the String value.
-     * @return the index of a new or already existing UTF8 item.
-     */
-    public int newUTF8(final String value) {
-        key.set(UTF8, value, null, null);
-        Item result = get(key);
-        if (result == null) {
-            pool.putByte(UTF8).putUTF8(value);
-            result = new Item(index++, key);
-            put(result);
-        }
-        return result.index;
-    }
-
-    /**
-     * Adds a class reference to the constant pool of the class being build.
-     * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param value
-     *            the internal name of the class.
-     * @return a new or already existing class reference item.
-     */
-    Item newClassItem(final String value) {
-        key2.set(CLASS, value, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(CLASS, newUTF8(value));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a class reference to the constant pool of the class being build.
-     * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param value
-     *            the internal name of the class.
-     * @return the index of a new or already existing class reference item.
-     */
-    public int newClass(final String value) {
-        return newClassItem(value).index;
-    }
-
-    /**
-     * Adds a method type reference to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param methodDesc
-     *            method descriptor of the method type.
-     * @return a new or already existing method type reference item.
-     */
-    Item newMethodTypeItem(final String methodDesc) {
-        key2.set(MTYPE, methodDesc, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(MTYPE, newUTF8(methodDesc));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a method type reference to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param methodDesc
-     *            method descriptor of the method type.
-     * @return the index of a new or already existing method type reference
-     *         item.
-     */
-    public int newMethodType(final String methodDesc) {
-        return newMethodTypeItem(methodDesc).index;
-    }
-
-    /**
-     * Adds a handle to the constant pool of the class being build. Does nothing
-     * if the constant pool already contains a similar item. <i>This method is
-     * intended for {@link Attribute} sub classes, and is normally not needed by
-     * class generators or adapters.</i>
-     *
-     * @param tag
-     *            the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
-     *            {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
-     *            {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
-     *            {@link Opcodes#H_INVOKESTATIC},
-     *            {@link Opcodes#H_INVOKESPECIAL},
-     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
-     *            {@link Opcodes#H_INVOKEINTERFACE}.
-     * @param owner
-     *            the internal name of the field or method owner class.
-     * @param name
-     *            the name of the field or method.
-     * @param desc
-     *            the descriptor of the field or method.
-     * @return a new or an already existing method type reference item.
-     */
-    Item newHandleItem(final int tag, final String owner, final String name,
-            final String desc) {
-        key4.set(HANDLE_BASE + tag, owner, name, desc);
-        Item result = get(key4);
-        if (result == null) {
-            if (tag <= Opcodes.H_PUTSTATIC) {
-                put112(HANDLE, tag, newField(owner, name, desc));
-            } else {
-                put112(HANDLE,
-                        tag,
-                        newMethod(owner, name, desc,
-                                tag == Opcodes.H_INVOKEINTERFACE));
-            }
-            result = new Item(index++, key4);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a handle to the constant pool of the class being build. Does nothing
-     * if the constant pool already contains a similar item. <i>This method is
-     * intended for {@link Attribute} sub classes, and is normally not needed by
-     * class generators or adapters.</i>
-     *
-     * @param tag
-     *            the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
-     *            {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
-     *            {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
-     *            {@link Opcodes#H_INVOKESTATIC},
-     *            {@link Opcodes#H_INVOKESPECIAL},
-     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
-     *            {@link Opcodes#H_INVOKEINTERFACE}.
-     * @param owner
-     *            the internal name of the field or method owner class.
-     * @param name
-     *            the name of the field or method.
-     * @param desc
-     *            the descriptor of the field or method.
-     * @return the index of a new or already existing method type reference
-     *         item.
-     */
-    public int newHandle(final int tag, final String owner, final String name,
-            final String desc) {
-        return newHandleItem(tag, owner, name, desc).index;
-    }
-
-    /**
-     * Adds an invokedynamic reference to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param name
-     *            name of the invoked method.
-     * @param desc
-     *            descriptor of the invoke method.
-     * @param bsm
-     *            the bootstrap method.
-     * @param bsmArgs
-     *            the bootstrap method constant arguments.
-     *
-     * @return a new or an already existing invokedynamic type reference item.
-     */
-    Item newInvokeDynamicItem(final String name, final String desc,
-            final Handle bsm, final Object... bsmArgs) {
-        // cache for performance
-        ByteVector bootstrapMethods = this.bootstrapMethods;
-        if (bootstrapMethods == null) {
-            bootstrapMethods = this.bootstrapMethods = new ByteVector();
-        }
-
-        int position = bootstrapMethods.length; // record current position
-
-        int hashCode = bsm.hashCode();
-        bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
-                bsm.desc));
-
-        int argsLength = bsmArgs.length;
-        bootstrapMethods.putShort(argsLength);
-
-        for (int i = 0; i < argsLength; i++) {
-            Object bsmArg = bsmArgs[i];
-            hashCode ^= bsmArg.hashCode();
-            bootstrapMethods.putShort(newConst(bsmArg));
-        }
-
-        byte[] data = bootstrapMethods.data;
-        int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
-        hashCode &= 0x7FFFFFFF;
-        Item result = items[hashCode % items.length];
-        loop: while (result != null) {
-            if (result.type != BSM || result.hashCode != hashCode) {
-                result = result.next;
-                continue;
-            }
-
-            // because the data encode the size of the argument
-            // we don't need to test if these size are equals
-            int resultPosition = result.intVal;
-            for (int p = 0; p < length; p++) {
-                if (data[position + p] != data[resultPosition + p]) {
-                    result = result.next;
-                    continue loop;
-                }
-            }
-            break;
-        }
-
-        int bootstrapMethodIndex;
-        if (result != null) {
-            bootstrapMethodIndex = result.index;
-            bootstrapMethods.length = position; // revert to old position
-        } else {
-            bootstrapMethodIndex = bootstrapMethodsCount++;
-            result = new Item(bootstrapMethodIndex);
-            result.set(position, hashCode);
-            put(result);
-        }
-
-        // now, create the InvokeDynamic constant
-        key3.set(name, desc, bootstrapMethodIndex);
-        result = get(key3);
-        if (result == null) {
-            put122(INDY, bootstrapMethodIndex, newNameType(name, desc));
-            result = new Item(index++, key3);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds an invokedynamic reference to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param name
-     *            name of the invoked method.
-     * @param desc
-     *            descriptor of the invoke method.
-     * @param bsm
-     *            the bootstrap method.
-     * @param bsmArgs
-     *            the bootstrap method constant arguments.
-     *
-     * @return the index of a new or already existing invokedynamic reference
-     *         item.
-     */
-    public int newInvokeDynamic(final String name, final String desc,
-            final Handle bsm, final Object... bsmArgs) {
-        return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index;
-    }
-
-    /**
-     * Adds a field reference to the constant pool of the class being build.
-     * Does nothing if the constant pool already contains a similar item.
-     *
-     * @param owner
-     *            the internal name of the field's owner class.
-     * @param name
-     *            the field's name.
-     * @param desc
-     *            the field's descriptor.
-     * @return a new or already existing field reference item.
-     */
-    Item newFieldItem(final String owner, final String name, final String desc) {
-        key3.set(FIELD, owner, name, desc);
-        Item result = get(key3);
-        if (result == null) {
-            put122(FIELD, newClass(owner), newNameType(name, desc));
-            result = new Item(index++, key3);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a field reference to the constant pool of the class being build.
-     * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param owner
-     *            the internal name of the field's owner class.
-     * @param name
-     *            the field's name.
-     * @param desc
-     *            the field's descriptor.
-     * @return the index of a new or already existing field reference item.
-     */
-    public int newField(final String owner, final String name, final String desc) {
-        return newFieldItem(owner, name, desc).index;
-    }
-
-    /**
-     * Adds a method reference to the constant pool of the class being build.
-     * Does nothing if the constant pool already contains a similar item.
-     *
-     * @param owner
-     *            the internal name of the method's owner class.
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor.
-     * @param itf
-     *            <tt>true</tt> if <tt>owner</tt> is an interface.
-     * @return a new or already existing method reference item.
-     */
-    Item newMethodItem(final String owner, final String name,
-            final String desc, final boolean itf) {
-        int type = itf ? IMETH : METH;
-        key3.set(type, owner, name, desc);
-        Item result = get(key3);
-        if (result == null) {
-            put122(type, newClass(owner), newNameType(name, desc));
-            result = new Item(index++, key3);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a method reference to the constant pool of the class being build.
-     * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param owner
-     *            the internal name of the method's owner class.
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor.
-     * @param itf
-     *            <tt>true</tt> if <tt>owner</tt> is an interface.
-     * @return the index of a new or already existing method reference item.
-     */
-    public int newMethod(final String owner, final String name,
-            final String desc, final boolean itf) {
-        return newMethodItem(owner, name, desc, itf).index;
-    }
-
-    /**
-     * Adds an integer to the constant pool of the class being build. Does
-     * nothing if the constant pool already contains a similar item.
-     *
-     * @param value
-     *            the int value.
-     * @return a new or already existing int item.
-     */
-    Item newInteger(final int value) {
-        key.set(value);
-        Item result = get(key);
-        if (result == null) {
-            pool.putByte(INT).putInt(value);
-            result = new Item(index++, key);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a float to the constant pool of the class being build. Does nothing
-     * if the constant pool already contains a similar item.
-     *
-     * @param value
-     *            the float value.
-     * @return a new or already existing float item.
-     */
-    Item newFloat(final float value) {
-        key.set(value);
-        Item result = get(key);
-        if (result == null) {
-            pool.putByte(FLOAT).putInt(key.intVal);
-            result = new Item(index++, key);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a long to the constant pool of the class being build. Does nothing
-     * if the constant pool already contains a similar item.
-     *
-     * @param value
-     *            the long value.
-     * @return a new or already existing long item.
-     */
-    Item newLong(final long value) {
-        key.set(value);
-        Item result = get(key);
-        if (result == null) {
-            pool.putByte(LONG).putLong(value);
-            result = new Item(index, key);
-            index += 2;
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a double to the constant pool of the class being build. Does nothing
-     * if the constant pool already contains a similar item.
-     *
-     * @param value
-     *            the double value.
-     * @return a new or already existing double item.
-     */
-    Item newDouble(final double value) {
-        key.set(value);
-        Item result = get(key);
-        if (result == null) {
-            pool.putByte(DOUBLE).putLong(key.longVal);
-            result = new Item(index, key);
-            index += 2;
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a string to the constant pool of the class being build. Does nothing
-     * if the constant pool already contains a similar item.
-     *
-     * @param value
-     *            the String value.
-     * @return a new or already existing string item.
-     */
-    private Item newString(final String value) {
-        key2.set(STR, value, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(STR, newUTF8(value));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds a name and type to the constant pool of the class being build. Does
-     * nothing if the constant pool already contains a similar item. <i>This
-     * method is intended for {@link Attribute} sub classes, and is normally not
-     * needed by class generators or adapters.</i>
-     *
-     * @param name
-     *            a name.
-     * @param desc
-     *            a type descriptor.
-     * @return the index of a new or already existing name and type item.
-     */
-    public int newNameType(final String name, final String desc) {
-        return newNameTypeItem(name, desc).index;
-    }
-
-    /**
-     * Adds a name and type to the constant pool of the class being build. Does
-     * nothing if the constant pool already contains a similar item.
-     *
-     * @param name
-     *            a name.
-     * @param desc
-     *            a type descriptor.
-     * @return a new or already existing name and type item.
-     */
-    Item newNameTypeItem(final String name, final String desc) {
-        key2.set(NAME_TYPE, name, desc, null);
-        Item result = get(key2);
-        if (result == null) {
-            put122(NAME_TYPE, newUTF8(name), newUTF8(desc));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
-     * Adds the given internal name to {@link #typeTable} and returns its index.
-     * Does nothing if the type table already contains this internal name.
-     *
-     * @param type
-     *            the internal name to be added to the type table.
-     * @return the index of this internal name in the type table.
-     */
-    int addType(final String type) {
-        key.set(TYPE_NORMAL, type, null, null);
-        Item result = get(key);
-        if (result == null) {
-            result = addType(key);
-        }
-        return result.index;
-    }
-
-    /**
-     * Adds the given "uninitialized" type to {@link #typeTable} and returns its
-     * index. This method is used for UNINITIALIZED types, made of an internal
-     * name and a bytecode offset.
-     *
-     * @param type
-     *            the internal name to be added to the type table.
-     * @param offset
-     *            the bytecode offset of the NEW instruction that created this
-     *            UNINITIALIZED type value.
-     * @return the index of this internal name in the type table.
-     */
-    int addUninitializedType(final String type, final int offset) {
-        key.type = TYPE_UNINIT;
-        key.intVal = offset;
-        key.strVal1 = type;
-        key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset);
-        Item result = get(key);
-        if (result == null) {
-            result = addType(key);
-        }
-        return result.index;
-    }
-
-    /**
-     * Adds the given Item to {@link #typeTable}.
-     *
-     * @param item
-     *            the value to be added to the type table.
-     * @return the added Item, which a new Item instance with the same value as
-     *         the given Item.
-     */
-    private Item addType(final Item item) {
-        ++typeCount;
-        Item result = new Item(typeCount, key);
-        put(result);
-        if (typeTable == null) {
-            typeTable = new Item[16];
-        }
-        if (typeCount == typeTable.length) {
-            Item[] newTable = new Item[2 * typeTable.length];
-            System.arraycopy(typeTable, 0, newTable, 0, typeTable.length);
-            typeTable = newTable;
-        }
-        typeTable[typeCount] = result;
-        return result;
-    }
-
-    /**
-     * Returns the index of the common super type of the two given types. This
-     * method calls {@link #getCommonSuperClass} and caches the result in the
-     * {@link #items} hash table to speedup future calls with the same
-     * parameters.
-     *
-     * @param type1
-     *            index of an internal name in {@link #typeTable}.
-     * @param type2
-     *            index of an internal name in {@link #typeTable}.
-     * @return the index of the common super type of the two given types.
-     */
-    int getMergedType(final int type1, final int type2) {
-        key2.type = TYPE_MERGED;
-        key2.longVal = type1 | (((long) type2) << 32);
-        key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2);
-        Item result = get(key2);
-        if (result == null) {
-            String t = typeTable[type1].strVal1;
-            String u = typeTable[type2].strVal1;
-            key2.intVal = addType(getCommonSuperClass(t, u));
-            result = new Item((short) 0, key2);
-            put(result);
-        }
-        return result.intVal;
-    }
-
-    /**
-     * Returns the common super type of the two given types. The default
-     * implementation of this method <i>loads<i> the two given classes and uses
-     * the java.lang.Class methods to find the common super class. It can be
-     * overridden to compute this common super type in other ways, in particular
-     * without actually loading any class, or to take into account the class
-     * that is currently being generated by this ClassWriter, which can of
-     * course not be loaded since it is under construction.
-     *
-     * @param type1
-     *            the internal name of a class.
-     * @param type2
-     *            the internal name of another class.
-     * @return the internal name of the common super class of the two given
-     *         classes.
-     */
-    protected String getCommonSuperClass(final String type1, final String type2) {
-        Class<?> c, d;
-        ClassLoader classLoader = getClass().getClassLoader();
-        try {
-            c = Class.forName(type1.replace('/', '.'), false, classLoader);
-            d = Class.forName(type2.replace('/', '.'), false, classLoader);
-        } catch (Exception e) {
-            throw new RuntimeException(e.toString());
-        }
-        if (c.isAssignableFrom(d)) {
-            return type1;
-        }
-        if (d.isAssignableFrom(c)) {
-            return type2;
-        }
-        if (c.isInterface() || d.isInterface()) {
-            return "java/lang/Object";
-        } else {
-            do {
-                c = c.getSuperclass();
-            } while (!c.isAssignableFrom(d));
-            return c.getName().replace('.', '/');
-        }
-    }
-
-    /**
-     * Returns the constant pool's hash table item which is equal to the given
-     * item.
-     *
-     * @param key
-     *            a constant pool item.
-     * @return the constant pool's hash table item which is equal to the given
-     *         item, or <tt>null</tt> if there is no such item.
-     */
-    private Item get(final Item key) {
-        Item i = items[key.hashCode % items.length];
-        while (i != null && (i.type != key.type || !key.isEqualTo(i))) {
-            i = i.next;
-        }
-        return i;
-    }
-
-    /**
-     * Puts the given item in the constant pool's hash table. The hash table
-     * <i>must</i> not already contains this item.
-     *
-     * @param i
-     *            the item to be added to the constant pool's hash table.
-     */
-    private void put(final Item i) {
-        if (index + typeCount > threshold) {
-            int ll = items.length;
-            int nl = ll * 2 + 1;
-            Item[] newItems = new Item[nl];
-            for (int l = ll - 1; l >= 0; --l) {
-                Item j = items[l];
-                while (j != null) {
-                    int index = j.hashCode % newItems.length;
-                    Item k = j.next;
-                    j.next = newItems[index];
-                    newItems[index] = j;
-                    j = k;
-                }
-            }
-            items = newItems;
-            threshold = (int) (nl * 0.75);
-        }
-        int index = i.hashCode % items.length;
-        i.next = items[index];
-        items[index] = i;
-    }
-
-    /**
-     * Puts one byte and two shorts into the constant pool.
-     *
-     * @param b
-     *            a byte.
-     * @param s1
-     *            a short.
-     * @param s2
-     *            another short.
-     */
-    private void put122(final int b, final int s1, final int s2) {
-        pool.put12(b, s1).putShort(s2);
-    }
-
-    /**
-     * Puts two bytes and one short into the constant pool.
-     *
-     * @param b1
-     *            a byte.
-     * @param b2
-     *            another byte.
-     * @param s
-     *            a short.
-     */
-    private void put112(final int b1, final int b2, final int s) {
-        pool.put11(b1, b2).putShort(s);
-    }
-}
diff --git a/src/jvm/clojure/asm/Context.java b/src/jvm/clojure/asm/Context.java
deleted file mode 100644
index d113ed9..0000000
--- a/src/jvm/clojure/asm/Context.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package clojure.asm;
-
-/**
- * Information about a class being parsed in a {@link ClassReader}.
- *
- * @author Eric Bruneton
- */
-class Context {
-
-    /**
-     * Prototypes of the attributes that must be parsed for this class.
-     */
-    Attribute[] attrs;
-
-    /**
-     * The {@link ClassReader} option flags for the parsing of this class.
-     */
-    int flags;
-
-    /**
-     * The buffer used to read strings.
-     */
-    char[] buffer;
-
-    /**
-     * The start index of each bootstrap method.
-     */
-    int[] bootstrapMethods;
-
-    /**
-     * The access flags of the method currently being parsed.
-     */
-    int access;
-
-    /**
-     * The name of the method currently being parsed.
-     */
-    String name;
-
-    /**
-     * The descriptor of the method currently being parsed.
-     */
-    String desc;
-
-    /**
-     * The offset of the latest stack map frame that has been parsed.
-     */
-    int offset;
-
-    /**
-     * The encoding of the latest stack map frame that has been parsed.
-     */
-    int mode;
-
-    /**
-     * The number of locals in the latest stack map frame that has been parsed.
-     */
-    int localCount;
-
-    /**
-     * The number locals in the latest stack map frame that has been parsed,
-     * minus the number of locals in the previous frame.
-     */
-    int localDiff;
-
-    /**
-     * The local values of the latest stack map frame that has been parsed.
-     */
-    Object[] local;
-
-    /**
-     * The stack size of the latest stack map frame that has been parsed.
-     */
-    int stackCount;
-
-    /**
-     * The stack values of the latest stack map frame that has been parsed.
-     */
-    Object[] stack;
-}
\ No newline at end of file
diff --git a/src/jvm/clojure/asm/Edge.java b/src/jvm/clojure/asm/Edge.java
deleted file mode 100644
index 045cd46..0000000
--- a/src/jvm/clojure/asm/Edge.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * An edge in the control flow graph of a method body. See {@link Label Label}.
- *
- * @author Eric Bruneton
- */
-class Edge {
-
-    /**
-     * Denotes a normal control flow graph edge.
-     */
-    static final int NORMAL = 0;
-
-    /**
-     * Denotes a control flow graph edge corresponding to an exception handler.
-     * More precisely any {@link Edge} whose {@link #info} is strictly positive
-     * corresponds to an exception handler. The actual value of {@link #info} is
-     * the index, in the {@link ClassWriter} type table, of the exception that
-     * is catched.
-     */
-    static final int EXCEPTION = 0x7FFFFFFF;
-
-    /**
-     * Information about this control flow graph edge. If
-     * {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative)
-     * stack size in the basic block from which this edge originates. This size
-     * is equal to the stack size at the "jump" instruction to which this edge
-     * corresponds, relatively to the stack size at the beginning of the
-     * originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used,
-     * this field is the kind of this control flow graph edge (i.e. NORMAL or
-     * EXCEPTION).
-     */
-    int info;
-
-    /**
-     * The successor block of the basic block from which this edge originates.
-     */
-    Label successor;
-
-    /**
-     * The next edge in the list of successors of the originating basic block.
-     * See {@link Label#successors successors}.
-     */
-    Edge next;
-}
diff --git a/src/jvm/clojure/asm/FieldVisitor.java b/src/jvm/clojure/asm/FieldVisitor.java
deleted file mode 100644
index b9df738..0000000
--- a/src/jvm/clojure/asm/FieldVisitor.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A visitor to visit a Java field. The methods of this class must be called in
- * the following order: ( <tt>visitAnnotation</tt> | <tt>visitAttribute</tt> )*
- * <tt>visitEnd</tt>.
- *
- * @author Eric Bruneton
- */
-public abstract class FieldVisitor {
-
-    /**
-     * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
-     */
-    protected final int api;
-
-    /**
-     * The field visitor to which this visitor must delegate method calls. May
-     * be null.
-     */
-    protected FieldVisitor fv;
-
-    /**
-     * Constructs a new {@link FieldVisitor}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     */
-    public FieldVisitor(final int api) {
-        this(api, null);
-    }
-
-    /**
-     * Constructs a new {@link FieldVisitor}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param fv
-     *            the field visitor to which this visitor must delegate method
-     *            calls. May be null.
-     */
-    public FieldVisitor(final int api, final FieldVisitor fv) {
-        if (api != Opcodes.ASM4) {
-            throw new IllegalArgumentException();
-        }
-        this.api = api;
-        this.fv = fv;
-    }
-
-    /**
-     * Visits an annotation of the field.
-     *
-     * @param desc
-     *            the class descriptor of the annotation class.
-     * @param visible
-     *            <tt>true</tt> if the annotation is visible at runtime.
-     * @return a visitor to visit the annotation values, or <tt>null</tt> if
-     *         this visitor is not interested in visiting this annotation.
-     */
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        if (fv != null) {
-            return fv.visitAnnotation(desc, visible);
-        }
-        return null;
-    }
-
-    /**
-     * Visits a non standard attribute of the field.
-     *
-     * @param attr
-     *            an attribute.
-     */
-    public void visitAttribute(Attribute attr) {
-        if (fv != null) {
-            fv.visitAttribute(attr);
-        }
-    }
-
-    /**
-     * Visits the end of the field. This method, which is the last one to be
-     * called, is used to inform the visitor that all the annotations and
-     * attributes of the field have been visited.
-     */
-    public void visitEnd() {
-        if (fv != null) {
-            fv.visitEnd();
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/FieldWriter.java b/src/jvm/clojure/asm/FieldWriter.java
deleted file mode 100644
index ccd32ec..0000000
--- a/src/jvm/clojure/asm/FieldWriter.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * An {@link FieldVisitor} that generates Java fields in bytecode form.
- *
- * @author Eric Bruneton
- */
-final class FieldWriter extends FieldVisitor {
-
-    /**
-     * The class writer to which this field must be added.
-     */
-    private final ClassWriter cw;
-
-    /**
-     * Access flags of this field.
-     */
-    private final int access;
-
-    /**
-     * The index of the constant pool item that contains the name of this
-     * method.
-     */
-    private final int name;
-
-    /**
-     * The index of the constant pool item that contains the descriptor of this
-     * field.
-     */
-    private final int desc;
-
-    /**
-     * The index of the constant pool item that contains the signature of this
-     * field.
-     */
-    private int signature;
-
-    /**
-     * The index of the constant pool item that contains the constant value of
-     * this field.
-     */
-    private int value;
-
-    /**
-     * The runtime visible annotations of this field. May be <tt>null</tt>.
-     */
-    private AnnotationWriter anns;
-
-    /**
-     * The runtime invisible annotations of this field. May be <tt>null</tt>.
-     */
-    private AnnotationWriter ianns;
-
-    /**
-     * The non standard attributes of this field. May be <tt>null</tt>.
-     */
-    private Attribute attrs;
-
-    // ------------------------------------------------------------------------
-    // Constructor
-    // ------------------------------------------------------------------------
-
-    /**
-     * Constructs a new {@link FieldWriter}.
-     *
-     * @param cw
-     *            the class writer to which this field must be added.
-     * @param access
-     *            the field's access flags (see {@link Opcodes}).
-     * @param name
-     *            the field's name.
-     * @param desc
-     *            the field's descriptor (see {@link Type}).
-     * @param signature
-     *            the field's signature. May be <tt>null</tt>.
-     * @param value
-     *            the field's constant value. May be <tt>null</tt>.
-     */
-    FieldWriter(final ClassWriter cw, final int access, final String name,
-            final String desc, final String signature, final Object value) {
-        super(Opcodes.ASM4);
-        if (cw.firstField == null) {
-            cw.firstField = this;
-        } else {
-            cw.lastField.fv = this;
-        }
-        cw.lastField = this;
-        this.cw = cw;
-        this.access = access;
-        this.name = cw.newUTF8(name);
-        this.desc = cw.newUTF8(desc);
-        if (ClassReader.SIGNATURES && signature != null) {
-            this.signature = cw.newUTF8(signature);
-        }
-        if (value != null) {
-            this.value = cw.newConstItem(value).index;
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Implementation of the FieldVisitor abstract class
-    // ------------------------------------------------------------------------
-
-    @Override
-    public AnnotationVisitor visitAnnotation(final String desc,
-            final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
-        ByteVector bv = new ByteVector();
-        // write type, and reserve space for values count
-        bv.putShort(cw.newUTF8(desc)).putShort(0);
-        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
-        if (visible) {
-            aw.next = anns;
-            anns = aw;
-        } else {
-            aw.next = ianns;
-            ianns = aw;
-        }
-        return aw;
-    }
-
-    @Override
-    public void visitAttribute(final Attribute attr) {
-        attr.next = attrs;
-        attrs = attr;
-    }
-
-    @Override
-    public void visitEnd() {
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the size of this field.
-     *
-     * @return the size of this field.
-     */
-    int getSize() {
-        int size = 8;
-        if (value != 0) {
-            cw.newUTF8("ConstantValue");
-            size += 8;
-        }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
-            if ((cw.version & 0xFFFF) < Opcodes.V1_5
-                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
-                cw.newUTF8("Synthetic");
-                size += 6;
-            }
-        }
-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
-            cw.newUTF8("Deprecated");
-            size += 6;
-        }
-        if (ClassReader.SIGNATURES && signature != 0) {
-            cw.newUTF8("Signature");
-            size += 8;
-        }
-        if (ClassReader.ANNOTATIONS && anns != null) {
-            cw.newUTF8("RuntimeVisibleAnnotations");
-            size += 8 + anns.getSize();
-        }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
-            cw.newUTF8("RuntimeInvisibleAnnotations");
-            size += 8 + ianns.getSize();
-        }
-        if (attrs != null) {
-            size += attrs.getSize(cw, null, 0, -1, -1);
-        }
-        return size;
-    }
-
-    /**
-     * Puts the content of this field into the given byte vector.
-     *
-     * @param out
-     *            where the content of this field must be put.
-     */
-    void put(final ByteVector out) {
-        final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
-        int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
-                | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
-        out.putShort(access & ~mask).putShort(name).putShort(desc);
-        int attributeCount = 0;
-        if (value != 0) {
-            ++attributeCount;
-        }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
-            if ((cw.version & 0xFFFF) < Opcodes.V1_5
-                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
-                ++attributeCount;
-            }
-        }
-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
-            ++attributeCount;
-        }
-        if (ClassReader.SIGNATURES && signature != 0) {
-            ++attributeCount;
-        }
-        if (ClassReader.ANNOTATIONS && anns != null) {
-            ++attributeCount;
-        }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
-            ++attributeCount;
-        }
-        if (attrs != null) {
-            attributeCount += attrs.getCount();
-        }
-        out.putShort(attributeCount);
-        if (value != 0) {
-            out.putShort(cw.newUTF8("ConstantValue"));
-            out.putInt(2).putShort(value);
-        }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
-            if ((cw.version & 0xFFFF) < Opcodes.V1_5
-                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
-                out.putShort(cw.newUTF8("Synthetic")).putInt(0);
-            }
-        }
-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
-            out.putShort(cw.newUTF8("Deprecated")).putInt(0);
-        }
-        if (ClassReader.SIGNATURES && signature != 0) {
-            out.putShort(cw.newUTF8("Signature"));
-            out.putInt(2).putShort(signature);
-        }
-        if (ClassReader.ANNOTATIONS && anns != null) {
-            out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
-            anns.put(out);
-        }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
-            out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
-            ianns.put(out);
-        }
-        if (attrs != null) {
-            attrs.put(cw, null, 0, -1, -1, out);
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/Frame.java b/src/jvm/clojure/asm/Frame.java
deleted file mode 100644
index 9c7e61d..0000000
--- a/src/jvm/clojure/asm/Frame.java
+++ /dev/null
@@ -1,1453 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * Information about the input and output stack map frames of a basic block.
- *
- * @author Eric Bruneton
- */
-final class Frame {
-
-    /*
-     * Frames are computed in a two steps process: during the visit of each
-     * instruction, the state of the frame at the end of current basic block is
-     * updated by simulating the action of the instruction on the previous state
-     * of this so called "output frame". In visitMaxs, a fix point algorithm is
-     * used to compute the "input frame" of each basic block, i.e. the stack map
-     * frame at the beginning of the basic block, starting from the input frame
-     * of the first basic block (which is computed from the method descriptor),
-     * and by using the previously computed output frames to compute the input
-     * state of the other blocks.
-     *
-     * All output and input frames are stored as arrays of integers. Reference
-     * and array types are represented by an index into a type table (which is
-     * not the same as the constant pool of the class, in order to avoid adding
-     * unnecessary constants in the pool - not all computed frames will end up
-     * being stored in the stack map table). This allows very fast type
-     * comparisons.
-     *
-     * Output stack map frames are computed relatively to the input frame of the
-     * basic block, which is not yet known when output frames are computed. It
-     * is therefore necessary to be able to represent abstract types such as
-     * "the type at position x in the input frame locals" or "the type at
-     * position x from the top of the input frame stack" or even "the type at
-     * position x in the input frame, with y more (or less) array dimensions".
-     * This explains the rather complicated type format used in output frames.
-     *
-     * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a
-     * signed number of array dimensions (from -8 to 7). KIND is either BASE,
-     * LOCAL or STACK. BASE is used for types that are not relative to the input
-     * frame. LOCAL is used for types that are relative to the input local
-     * variable types. STACK is used for types that are relative to the input
-     * stack types. VALUE depends on KIND. For LOCAL types, it is an index in
-     * the input local variable types. For STACK types, it is a position
-     * relatively to the top of input frame stack. For BASE types, it is either
-     * one of the constants defined in FrameVisitor, or for OBJECT and
-     * UNINITIALIZED types, a tag and an index in the type table.
-     *
-     * Output frames can contain types of any kind and with a positive or
-     * negative dimension (and even unassigned types, represented by 0 - which
-     * does not correspond to any valid type value). Input frames can only
-     * contain BASE types of positive or null dimension. In all cases the type
-     * table contains only internal type names (array type descriptors are
-     * forbidden - dimensions must be represented through the DIM field).
-     *
-     * The LONG and DOUBLE types are always represented by using two slots (LONG
-     * + TOP or DOUBLE + TOP), for local variable types as well as in the
-     * operand stack. This is necessary to be able to simulate DUPx_y
-     * instructions, whose effect would be dependent on the actual type values
-     * if types were always represented by a single slot in the stack (and this
-     * is not possible, since actual type values are not always known - cf LOCAL
-     * and STACK type kinds).
-     */
-
-    /**
-     * Mask to get the dimension of a frame type. This dimension is a signed
-     * integer between -8 and 7.
-     */
-    static final int DIM = 0xF0000000;
-
-    /**
-     * Constant to be added to a type to get a type with one more dimension.
-     */
-    static final int ARRAY_OF = 0x10000000;
-
-    /**
-     * Constant to be added to a type to get a type with one less dimension.
-     */
-    static final int ELEMENT_OF = 0xF0000000;
-
-    /**
-     * Mask to get the kind of a frame type.
-     *
-     * @see #BASE
-     * @see #LOCAL
-     * @see #STACK
-     */
-    static final int KIND = 0xF000000;
-
-    /**
-     * Flag used for LOCAL and STACK types. Indicates that if this type happens
-     * to be a long or double type (during the computations of input frames),
-     * then it must be set to TOP because the second word of this value has been
-     * reused to store other data in the basic block. Hence the first word no
-     * longer stores a valid long or double value.
-     */
-    static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
-
-    /**
-     * Mask to get the value of a frame type.
-     */
-    static final int VALUE = 0x7FFFFF;
-
-    /**
-     * Mask to get the kind of base types.
-     */
-    static final int BASE_KIND = 0xFF00000;
-
-    /**
-     * Mask to get the value of base types.
-     */
-    static final int BASE_VALUE = 0xFFFFF;
-
-    /**
-     * Kind of the types that are not relative to an input stack map frame.
-     */
-    static final int BASE = 0x1000000;
-
-    /**
-     * Base kind of the base reference types. The BASE_VALUE of such types is an
-     * index into the type table.
-     */
-    static final int OBJECT = BASE | 0x700000;
-
-    /**
-     * Base kind of the uninitialized base types. The BASE_VALUE of such types
-     * in an index into the type table (the Item at that index contains both an
-     * instruction offset and an internal class name).
-     */
-    static final int UNINITIALIZED = BASE | 0x800000;
-
-    /**
-     * Kind of the types that are relative to the local variable types of an
-     * input stack map frame. The value of such types is a local variable index.
-     */
-    private static final int LOCAL = 0x2000000;
-
-    /**
-     * Kind of the the types that are relative to the stack of an input stack
-     * map frame. The value of such types is a position relatively to the top of
-     * this stack.
-     */
-    private static final int STACK = 0x3000000;
-
-    /**
-     * The TOP type. This is a BASE type.
-     */
-    static final int TOP = BASE | 0;
-
-    /**
-     * The BOOLEAN type. This is a BASE type mainly used for array types.
-     */
-    static final int BOOLEAN = BASE | 9;
-
-    /**
-     * The BYTE type. This is a BASE type mainly used for array types.
-     */
-    static final int BYTE = BASE | 10;
-
-    /**
-     * The CHAR type. This is a BASE type mainly used for array types.
-     */
-    static final int CHAR = BASE | 11;
-
-    /**
-     * The SHORT type. This is a BASE type mainly used for array types.
-     */
-    static final int SHORT = BASE | 12;
-
-    /**
-     * The INTEGER type. This is a BASE type.
-     */
-    static final int INTEGER = BASE | 1;
-
-    /**
-     * The FLOAT type. This is a BASE type.
-     */
-    static final int FLOAT = BASE | 2;
-
-    /**
-     * The DOUBLE type. This is a BASE type.
-     */
-    static final int DOUBLE = BASE | 3;
-
-    /**
-     * The LONG type. This is a BASE type.
-     */
-    static final int LONG = BASE | 4;
-
-    /**
-     * The NULL type. This is a BASE type.
-     */
-    static final int NULL = BASE | 5;
-
-    /**
-     * The UNINITIALIZED_THIS type. This is a BASE type.
-     */
-    static final int UNINITIALIZED_THIS = BASE | 6;
-
-    /**
-     * The stack size variation corresponding to each JVM instruction. This
-     * stack variation is equal to the size of the values produced by an
-     * instruction, minus the size of the values consumed by this instruction.
-     */
-    static final int[] SIZE;
-
-    /**
-     * Computes the stack size variation corresponding to each JVM instruction.
-     */
-    static {
-        int i;
-        int[] b = new int[202];
-        String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDD"
-                + "CDCDEEEEEEEEEEEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCD"
-                + "CDCEEEEDDDDDDDCDCDCEFEFDDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFED"
-                + "DDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE";
-        for (i = 0; i < b.length; ++i) {
-            b[i] = s.charAt(i) - 'E';
-        }
-        SIZE = b;
-
-        // code to generate the above string
-        //
-        // int NA = 0; // not applicable (unused opcode or variable size opcode)
-        //
-        // b = new int[] {
-        // 0, //NOP, // visitInsn
-        // 1, //ACONST_NULL, // -
-        // 1, //ICONST_M1, // -
-        // 1, //ICONST_0, // -
-        // 1, //ICONST_1, // -
-        // 1, //ICONST_2, // -
-        // 1, //ICONST_3, // -
-        // 1, //ICONST_4, // -
-        // 1, //ICONST_5, // -
-        // 2, //LCONST_0, // -
-        // 2, //LCONST_1, // -
-        // 1, //FCONST_0, // -
-        // 1, //FCONST_1, // -
-        // 1, //FCONST_2, // -
-        // 2, //DCONST_0, // -
-        // 2, //DCONST_1, // -
-        // 1, //BIPUSH, // visitIntInsn
-        // 1, //SIPUSH, // -
-        // 1, //LDC, // visitLdcInsn
-        // NA, //LDC_W, // -
-        // NA, //LDC2_W, // -
-        // 1, //ILOAD, // visitVarInsn
-        // 2, //LLOAD, // -
-        // 1, //FLOAD, // -
-        // 2, //DLOAD, // -
-        // 1, //ALOAD, // -
-        // NA, //ILOAD_0, // -
-        // NA, //ILOAD_1, // -
-        // NA, //ILOAD_2, // -
-        // NA, //ILOAD_3, // -
-        // NA, //LLOAD_0, // -
-        // NA, //LLOAD_1, // -
-        // NA, //LLOAD_2, // -
-        // NA, //LLOAD_3, // -
-        // NA, //FLOAD_0, // -
-        // NA, //FLOAD_1, // -
-        // NA, //FLOAD_2, // -
-        // NA, //FLOAD_3, // -
-        // NA, //DLOAD_0, // -
-        // NA, //DLOAD_1, // -
-        // NA, //DLOAD_2, // -
-        // NA, //DLOAD_3, // -
-        // NA, //ALOAD_0, // -
-        // NA, //ALOAD_1, // -
-        // NA, //ALOAD_2, // -
-        // NA, //ALOAD_3, // -
-        // -1, //IALOAD, // visitInsn
-        // 0, //LALOAD, // -
-        // -1, //FALOAD, // -
-        // 0, //DALOAD, // -
-        // -1, //AALOAD, // -
-        // -1, //BALOAD, // -
-        // -1, //CALOAD, // -
-        // -1, //SALOAD, // -
-        // -1, //ISTORE, // visitVarInsn
-        // -2, //LSTORE, // -
-        // -1, //FSTORE, // -
-        // -2, //DSTORE, // -
-        // -1, //ASTORE, // -
-        // NA, //ISTORE_0, // -
-        // NA, //ISTORE_1, // -
-        // NA, //ISTORE_2, // -
-        // NA, //ISTORE_3, // -
-        // NA, //LSTORE_0, // -
-        // NA, //LSTORE_1, // -
-        // NA, //LSTORE_2, // -
-        // NA, //LSTORE_3, // -
-        // NA, //FSTORE_0, // -
-        // NA, //FSTORE_1, // -
-        // NA, //FSTORE_2, // -
-        // NA, //FSTORE_3, // -
-        // NA, //DSTORE_0, // -
-        // NA, //DSTORE_1, // -
-        // NA, //DSTORE_2, // -
-        // NA, //DSTORE_3, // -
-        // NA, //ASTORE_0, // -
-        // NA, //ASTORE_1, // -
-        // NA, //ASTORE_2, // -
-        // NA, //ASTORE_3, // -
-        // -3, //IASTORE, // visitInsn
-        // -4, //LASTORE, // -
-        // -3, //FASTORE, // -
-        // -4, //DASTORE, // -
-        // -3, //AASTORE, // -
-        // -3, //BASTORE, // -
-        // -3, //CASTORE, // -
-        // -3, //SASTORE, // -
-        // -1, //POP, // -
-        // -2, //POP2, // -
-        // 1, //DUP, // -
-        // 1, //DUP_X1, // -
-        // 1, //DUP_X2, // -
-        // 2, //DUP2, // -
-        // 2, //DUP2_X1, // -
-        // 2, //DUP2_X2, // -
-        // 0, //SWAP, // -
-        // -1, //IADD, // -
-        // -2, //LADD, // -
-        // -1, //FADD, // -
-        // -2, //DADD, // -
-        // -1, //ISUB, // -
-        // -2, //LSUB, // -
-        // -1, //FSUB, // -
-        // -2, //DSUB, // -
-        // -1, //IMUL, // -
-        // -2, //LMUL, // -
-        // -1, //FMUL, // -
-        // -2, //DMUL, // -
-        // -1, //IDIV, // -
-        // -2, //LDIV, // -
-        // -1, //FDIV, // -
-        // -2, //DDIV, // -
-        // -1, //IREM, // -
-        // -2, //LREM, // -
-        // -1, //FREM, // -
-        // -2, //DREM, // -
-        // 0, //INEG, // -
-        // 0, //LNEG, // -
-        // 0, //FNEG, // -
-        // 0, //DNEG, // -
-        // -1, //ISHL, // -
-        // -1, //LSHL, // -
-        // -1, //ISHR, // -
-        // -1, //LSHR, // -
-        // -1, //IUSHR, // -
-        // -1, //LUSHR, // -
-        // -1, //IAND, // -
-        // -2, //LAND, // -
-        // -1, //IOR, // -
-        // -2, //LOR, // -
-        // -1, //IXOR, // -
-        // -2, //LXOR, // -
-        // 0, //IINC, // visitIincInsn
-        // 1, //I2L, // visitInsn
-        // 0, //I2F, // -
-        // 1, //I2D, // -
-        // -1, //L2I, // -
-        // -1, //L2F, // -
-        // 0, //L2D, // -
-        // 0, //F2I, // -
-        // 1, //F2L, // -
-        // 1, //F2D, // -
-        // -1, //D2I, // -
-        // 0, //D2L, // -
-        // -1, //D2F, // -
-        // 0, //I2B, // -
-        // 0, //I2C, // -
-        // 0, //I2S, // -
-        // -3, //LCMP, // -
-        // -1, //FCMPL, // -
-        // -1, //FCMPG, // -
-        // -3, //DCMPL, // -
-        // -3, //DCMPG, // -
-        // -1, //IFEQ, // visitJumpInsn
-        // -1, //IFNE, // -
-        // -1, //IFLT, // -
-        // -1, //IFGE, // -
-        // -1, //IFGT, // -
-        // -1, //IFLE, // -
-        // -2, //IF_ICMPEQ, // -
-        // -2, //IF_ICMPNE, // -
-        // -2, //IF_ICMPLT, // -
-        // -2, //IF_ICMPGE, // -
-        // -2, //IF_ICMPGT, // -
-        // -2, //IF_ICMPLE, // -
-        // -2, //IF_ACMPEQ, // -
-        // -2, //IF_ACMPNE, // -
-        // 0, //GOTO, // -
-        // 1, //JSR, // -
-        // 0, //RET, // visitVarInsn
-        // -1, //TABLESWITCH, // visiTableSwitchInsn
-        // -1, //LOOKUPSWITCH, // visitLookupSwitch
-        // -1, //IRETURN, // visitInsn
-        // -2, //LRETURN, // -
-        // -1, //FRETURN, // -
-        // -2, //DRETURN, // -
-        // -1, //ARETURN, // -
-        // 0, //RETURN, // -
-        // NA, //GETSTATIC, // visitFieldInsn
-        // NA, //PUTSTATIC, // -
-        // NA, //GETFIELD, // -
-        // NA, //PUTFIELD, // -
-        // NA, //INVOKEVIRTUAL, // visitMethodInsn
-        // NA, //INVOKESPECIAL, // -
-        // NA, //INVOKESTATIC, // -
-        // NA, //INVOKEINTERFACE, // -
-        // NA, //INVOKEDYNAMIC, // visitInvokeDynamicInsn
-        // 1, //NEW, // visitTypeInsn
-        // 0, //NEWARRAY, // visitIntInsn
-        // 0, //ANEWARRAY, // visitTypeInsn
-        // 0, //ARRAYLENGTH, // visitInsn
-        // NA, //ATHROW, // -
-        // 0, //CHECKCAST, // visitTypeInsn
-        // 0, //INSTANCEOF, // -
-        // -1, //MONITORENTER, // visitInsn
-        // -1, //MONITOREXIT, // -
-        // NA, //WIDE, // NOT VISITED
-        // NA, //MULTIANEWARRAY, // visitMultiANewArrayInsn
-        // -1, //IFNULL, // visitJumpInsn
-        // -1, //IFNONNULL, // -
-        // NA, //GOTO_W, // -
-        // NA, //JSR_W, // -
-        // };
-        // for (i = 0; i < b.length; ++i) {
-        // System.err.print((char)('E' + b[i]));
-        // }
-        // System.err.println();
-    }
-
-    /**
-     * The label (i.e. basic block) to which these input and output stack map
-     * frames correspond.
-     */
-    Label owner;
-
-    /**
-     * The input stack map frame locals.
-     */
-    int[] inputLocals;
-
-    /**
-     * The input stack map frame stack.
-     */
-    int[] inputStack;
-
-    /**
-     * The output stack map frame locals.
-     */
-    private int[] outputLocals;
-
-    /**
-     * The output stack map frame stack.
-     */
-    private int[] outputStack;
-
-    /**
-     * Relative size of the output stack. The exact semantics of this field
-     * depends on the algorithm that is used.
-     *
-     * When only the maximum stack size is computed, this field is the size of
-     * the output stack relatively to the top of the input stack.
-     *
-     * When the stack map frames are completely computed, this field is the
-     * actual number of types in {@link #outputStack}.
-     */
-    private int outputStackTop;
-
-    /**
-     * Number of types that are initialized in the basic block.
-     *
-     * @see #initializations
-     */
-    private int initializationCount;
-
-    /**
-     * The types that are initialized in the basic block. A constructor
-     * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
-     * <i>every occurence</i> of this type in the local variables and in the
-     * operand stack. This cannot be done during the first phase of the
-     * algorithm since, during this phase, the local variables and the operand
-     * stack are not completely computed. It is therefore necessary to store the
-     * types on which constructors are invoked in the basic block, in order to
-     * do this replacement during the second phase of the algorithm, where the
-     * frames are fully computed. Note that this array can contain types that
-     * are relative to input locals or to the input stack (see below for the
-     * description of the algorithm).
-     */
-    private int[] initializations;
-
-    /**
-     * Returns the output frame local variable type at the given index.
-     *
-     * @param local
-     *            the index of the local that must be returned.
-     * @return the output frame local variable type at the given index.
-     */
-    private int get(final int local) {
-        if (outputLocals == null || local >= outputLocals.length) {
-            // this local has never been assigned in this basic block,
-            // so it is still equal to its value in the input frame
-            return LOCAL | local;
-        } else {
-            int type = outputLocals[local];
-            if (type == 0) {
-                // this local has never been assigned in this basic block,
-                // so it is still equal to its value in the input frame
-                type = outputLocals[local] = LOCAL | local;
-            }
-            return type;
-        }
-    }
-
-    /**
-     * Sets the output frame local variable type at the given index.
-     *
-     * @param local
-     *            the index of the local that must be set.
-     * @param type
-     *            the value of the local that must be set.
-     */
-    private void set(final int local, final int type) {
-        // creates and/or resizes the output local variables array if necessary
-        if (outputLocals == null) {
-            outputLocals = new int[10];
-        }
-        int n = outputLocals.length;
-        if (local >= n) {
-            int[] t = new int[Math.max(local + 1, 2 * n)];
-            System.arraycopy(outputLocals, 0, t, 0, n);
-            outputLocals = t;
-        }
-        // sets the local variable
-        outputLocals[local] = type;
-    }
-
-    /**
-     * Pushes a new type onto the output frame stack.
-     *
-     * @param type
-     *            the type that must be pushed.
-     */
-    private void push(final int type) {
-        // creates and/or resizes the output stack array if necessary
-        if (outputStack == null) {
-            outputStack = new int[10];
-        }
-        int n = outputStack.length;
-        if (outputStackTop >= n) {
-            int[] t = new int[Math.max(outputStackTop + 1, 2 * n)];
-            System.arraycopy(outputStack, 0, t, 0, n);
-            outputStack = t;
-        }
-        // pushes the type on the output stack
-        outputStack[outputStackTop++] = type;
-        // updates the maximun height reached by the output stack, if needed
-        int top = owner.inputStackTop + outputStackTop;
-        if (top > owner.outputStackMax) {
-            owner.outputStackMax = top;
-        }
-    }
-
-    /**
-     * Pushes a new type onto the output frame stack.
-     *
-     * @param cw
-     *            the ClassWriter to which this label belongs.
-     * @param desc
-     *            the descriptor of the type to be pushed. Can also be a method
-     *            descriptor (in this case this method pushes its return type
-     *            onto the output frame stack).
-     */
-    private void push(final ClassWriter cw, final String desc) {
-        int type = type(cw, desc);
-        if (type != 0) {
-            push(type);
-            if (type == LONG || type == DOUBLE) {
-                push(TOP);
-            }
-        }
-    }
-
-    /**
-     * Returns the int encoding of the given type.
-     *
-     * @param cw
-     *            the ClassWriter to which this label belongs.
-     * @param desc
-     *            a type descriptor.
-     * @return the int encoding of the given type.
-     */
-    private static int type(final ClassWriter cw, final String desc) {
-        String t;
-        int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
-        switch (desc.charAt(index)) {
-        case 'V':
-            return 0;
-        case 'Z':
-        case 'C':
-        case 'B':
-        case 'S':
-        case 'I':
-            return INTEGER;
-        case 'F':
-            return FLOAT;
-        case 'J':
-            return LONG;
-        case 'D':
-            return DOUBLE;
-        case 'L':
-            // stores the internal name, not the descriptor!
-            t = desc.substring(index + 1, desc.length() - 1);
-            return OBJECT | cw.addType(t);
-            // case '[':
-        default:
-            // extracts the dimensions and the element type
-            int data;
-            int dims = index + 1;
-            while (desc.charAt(dims) == '[') {
-                ++dims;
-            }
-            switch (desc.charAt(dims)) {
-            case 'Z':
-                data = BOOLEAN;
-                break;
-            case 'C':
-                data = CHAR;
-                break;
-            case 'B':
-                data = BYTE;
-                break;
-            case 'S':
-                data = SHORT;
-                break;
-            case 'I':
-                data = INTEGER;
-                break;
-            case 'F':
-                data = FLOAT;
-                break;
-            case 'J':
-                data = LONG;
-                break;
-            case 'D':
-                data = DOUBLE;
-                break;
-            // case 'L':
-            default:
-                // stores the internal name, not the descriptor
-                t = desc.substring(dims + 1, desc.length() - 1);
-                data = OBJECT | cw.addType(t);
-            }
-            return (dims - index) << 28 | data;
-        }
-    }
-
-    /**
-     * Pops a type from the output frame stack and returns its value.
-     *
-     * @return the type that has been popped from the output frame stack.
-     */
-    private int pop() {
-        if (outputStackTop > 0) {
-            return outputStack[--outputStackTop];
-        } else {
-            // if the output frame stack is empty, pops from the input stack
-            return STACK | -(--owner.inputStackTop);
-        }
-    }
-
-    /**
-     * Pops the given number of types from the output frame stack.
-     *
-     * @param elements
-     *            the number of types that must be popped.
-     */
-    private void pop(final int elements) {
-        if (outputStackTop >= elements) {
-            outputStackTop -= elements;
-        } else {
-            // if the number of elements to be popped is greater than the number
-            // of elements in the output stack, clear it, and pops the remaining
-            // elements from the input stack.
-            owner.inputStackTop -= elements - outputStackTop;
-            outputStackTop = 0;
-        }
-    }
-
-    /**
-     * Pops a type from the output frame stack.
-     *
-     * @param desc
-     *            the descriptor of the type to be popped. Can also be a method
-     *            descriptor (in this case this method pops the types
-     *            corresponding to the method arguments).
-     */
-    private void pop(final String desc) {
-        char c = desc.charAt(0);
-        if (c == '(') {
-            pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);
-        } else if (c == 'J' || c == 'D') {
-            pop(2);
-        } else {
-            pop(1);
-        }
-    }
-
-    /**
-     * Adds a new type to the list of types on which a constructor is invoked in
-     * the basic block.
-     *
-     * @param var
-     *            a type on a which a constructor is invoked.
-     */
-    private void init(final int var) {
-        // creates and/or resizes the initializations array if necessary
-        if (initializations == null) {
-            initializations = new int[2];
-        }
-        int n = initializations.length;
-        if (initializationCount >= n) {
-            int[] t = new int[Math.max(initializationCount + 1, 2 * n)];
-            System.arraycopy(initializations, 0, t, 0, n);
-            initializations = t;
-        }
-        // stores the type to be initialized
-        initializations[initializationCount++] = var;
-    }
-
-    /**
-     * Replaces the given type with the appropriate type if it is one of the
-     * types on which a constructor is invoked in the basic block.
-     *
-     * @param cw
-     *            the ClassWriter to which this label belongs.
-     * @param t
-     *            a type
-     * @return t or, if t is one of the types on which a constructor is invoked
-     *         in the basic block, the type corresponding to this constructor.
-     */
-    private int init(final ClassWriter cw, final int t) {
-        int s;
-        if (t == UNINITIALIZED_THIS) {
-            s = OBJECT | cw.addType(cw.thisName);
-        } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) {
-            String type = cw.typeTable[t & BASE_VALUE].strVal1;
-            s = OBJECT | cw.addType(type);
-        } else {
-            return t;
-        }
-        for (int j = 0; j < initializationCount; ++j) {
-            int u = initializations[j];
-            int dim = u & DIM;
-            int kind = u & KIND;
-            if (kind == LOCAL) {
-                u = dim + inputLocals[u & VALUE];
-            } else if (kind == STACK) {
-                u = dim + inputStack[inputStack.length - (u & VALUE)];
-            }
-            if (t == u) {
-                return s;
-            }
-        }
-        return t;
-    }
-
-    /**
-     * Initializes the input frame of the first basic block from the method
-     * descriptor.
-     *
-     * @param cw
-     *            the ClassWriter to which this label belongs.
-     * @param access
-     *            the access flags of the method to which this label belongs.
-     * @param args
-     *            the formal parameter types of this method.
-     * @param maxLocals
-     *            the maximum number of local variables of this method.
-     */
-    void initInputFrame(final ClassWriter cw, final int access,
-            final Type[] args, final int maxLocals) {
-        inputLocals = new int[maxLocals];
-        inputStack = new int[0];
-        int i = 0;
-        if ((access & Opcodes.ACC_STATIC) == 0) {
-            if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) {
-                inputLocals[i++] = OBJECT | cw.addType(cw.thisName);
-            } else {
-                inputLocals[i++] = UNINITIALIZED_THIS;
-            }
-        }
-        for (int j = 0; j < args.length; ++j) {
-            int t = type(cw, args[j].getDescriptor());
-            inputLocals[i++] = t;
-            if (t == LONG || t == DOUBLE) {
-                inputLocals[i++] = TOP;
-            }
-        }
-        while (i < maxLocals) {
-            inputLocals[i++] = TOP;
-        }
-    }
-
-    /**
-     * Simulates the action of the given instruction on the output stack frame.
-     *
-     * @param opcode
-     *            the opcode of the instruction.
-     * @param arg
-     *            the operand of the instruction, if any.
-     * @param cw
-     *            the class writer to which this label belongs.
-     * @param item
-     *            the operand of the instructions, if any.
-     */
-    void execute(final int opcode, final int arg, final ClassWriter cw,
-            final Item item) {
-        int t1, t2, t3, t4;
-        switch (opcode) {
-        case Opcodes.NOP:
-        case Opcodes.INEG:
-        case Opcodes.LNEG:
-        case Opcodes.FNEG:
-        case Opcodes.DNEG:
-        case Opcodes.I2B:
-        case Opcodes.I2C:
-        case Opcodes.I2S:
-        case Opcodes.GOTO:
-        case Opcodes.RETURN:
-            break;
-        case Opcodes.ACONST_NULL:
-            push(NULL);
-            break;
-        case Opcodes.ICONST_M1:
-        case Opcodes.ICONST_0:
-        case Opcodes.ICONST_1:
-        case Opcodes.ICONST_2:
-        case Opcodes.ICONST_3:
-        case Opcodes.ICONST_4:
-        case Opcodes.ICONST_5:
-        case Opcodes.BIPUSH:
-        case Opcodes.SIPUSH:
-        case Opcodes.ILOAD:
-            push(INTEGER);
-            break;
-        case Opcodes.LCONST_0:
-        case Opcodes.LCONST_1:
-        case Opcodes.LLOAD:
-            push(LONG);
-            push(TOP);
-            break;
-        case Opcodes.FCONST_0:
-        case Opcodes.FCONST_1:
-        case Opcodes.FCONST_2:
-        case Opcodes.FLOAD:
-            push(FLOAT);
-            break;
-        case Opcodes.DCONST_0:
-        case Opcodes.DCONST_1:
-        case Opcodes.DLOAD:
-            push(DOUBLE);
-            push(TOP);
-            break;
-        case Opcodes.LDC:
-            switch (item.type) {
-            case ClassWriter.INT:
-                push(INTEGER);
-                break;
-            case ClassWriter.LONG:
-                push(LONG);
-                push(TOP);
-                break;
-            case ClassWriter.FLOAT:
-                push(FLOAT);
-                break;
-            case ClassWriter.DOUBLE:
-                push(DOUBLE);
-                push(TOP);
-                break;
-            case ClassWriter.CLASS:
-                push(OBJECT | cw.addType("java/lang/Class"));
-                break;
-            case ClassWriter.STR:
-                push(OBJECT | cw.addType("java/lang/String"));
-                break;
-            case ClassWriter.MTYPE:
-                push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
-                break;
-            // case ClassWriter.HANDLE_BASE + [1..9]:
-            default:
-                push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
-            }
-            break;
-        case Opcodes.ALOAD:
-            push(get(arg));
-            break;
-        case Opcodes.IALOAD:
-        case Opcodes.BALOAD:
-        case Opcodes.CALOAD:
-        case Opcodes.SALOAD:
-            pop(2);
-            push(INTEGER);
-            break;
-        case Opcodes.LALOAD:
-        case Opcodes.D2L:
-            pop(2);
-            push(LONG);
-            push(TOP);
-            break;
-        case Opcodes.FALOAD:
-            pop(2);
-            push(FLOAT);
-            break;
-        case Opcodes.DALOAD:
-        case Opcodes.L2D:
-            pop(2);
-            push(DOUBLE);
-            push(TOP);
-            break;
-        case Opcodes.AALOAD:
-            pop(1);
-            t1 = pop();
-            push(ELEMENT_OF + t1);
-            break;
-        case Opcodes.ISTORE:
-        case Opcodes.FSTORE:
-        case Opcodes.ASTORE:
-            t1 = pop();
-            set(arg, t1);
-            if (arg > 0) {
-                t2 = get(arg - 1);
-                // if t2 is of kind STACK or LOCAL we cannot know its size!
-                if (t2 == LONG || t2 == DOUBLE) {
-                    set(arg - 1, TOP);
-                } else if ((t2 & KIND) != BASE) {
-                    set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
-                }
-            }
-            break;
-        case Opcodes.LSTORE:
-        case Opcodes.DSTORE:
-            pop(1);
-            t1 = pop();
-            set(arg, t1);
-            set(arg + 1, TOP);
-            if (arg > 0) {
-                t2 = get(arg - 1);
-                // if t2 is of kind STACK or LOCAL we cannot know its size!
-                if (t2 == LONG || t2 == DOUBLE) {
-                    set(arg - 1, TOP);
-                } else if ((t2 & KIND) != BASE) {
-                    set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
-                }
-            }
-            break;
-        case Opcodes.IASTORE:
-        case Opcodes.BASTORE:
-        case Opcodes.CASTORE:
-        case Opcodes.SASTORE:
-        case Opcodes.FASTORE:
-        case Opcodes.AASTORE:
-            pop(3);
-            break;
-        case Opcodes.LASTORE:
-        case Opcodes.DASTORE:
-            pop(4);
-            break;
-        case Opcodes.POP:
-        case Opcodes.IFEQ:
-        case Opcodes.IFNE:
-        case Opcodes.IFLT:
-        case Opcodes.IFGE:
-        case Opcodes.IFGT:
-        case Opcodes.IFLE:
-        case Opcodes.IRETURN:
-        case Opcodes.FRETURN:
-        case Opcodes.ARETURN:
-        case Opcodes.TABLESWITCH:
-        case Opcodes.LOOKUPSWITCH:
-        case Opcodes.ATHROW:
-        case Opcodes.MONITORENTER:
-        case Opcodes.MONITOREXIT:
-        case Opcodes.IFNULL:
-        case Opcodes.IFNONNULL:
-            pop(1);
-            break;
-        case Opcodes.POP2:
-        case Opcodes.IF_ICMPEQ:
-        case Opcodes.IF_ICMPNE:
-        case Opcodes.IF_ICMPLT:
-        case Opcodes.IF_ICMPGE:
-        case Opcodes.IF_ICMPGT:
-        case Opcodes.IF_ICMPLE:
-        case Opcodes.IF_ACMPEQ:
-        case Opcodes.IF_ACMPNE:
-        case Opcodes.LRETURN:
-        case Opcodes.DRETURN:
-            pop(2);
-            break;
-        case Opcodes.DUP:
-            t1 = pop();
-            push(t1);
-            push(t1);
-            break;
-        case Opcodes.DUP_X1:
-            t1 = pop();
-            t2 = pop();
-            push(t1);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.DUP_X2:
-            t1 = pop();
-            t2 = pop();
-            t3 = pop();
-            push(t1);
-            push(t3);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.DUP2:
-            t1 = pop();
-            t2 = pop();
-            push(t2);
-            push(t1);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.DUP2_X1:
-            t1 = pop();
-            t2 = pop();
-            t3 = pop();
-            push(t2);
-            push(t1);
-            push(t3);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.DUP2_X2:
-            t1 = pop();
-            t2 = pop();
-            t3 = pop();
-            t4 = pop();
-            push(t2);
-            push(t1);
-            push(t4);
-            push(t3);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.SWAP:
-            t1 = pop();
-            t2 = pop();
-            push(t1);
-            push(t2);
-            break;
-        case Opcodes.IADD:
-        case Opcodes.ISUB:
-        case Opcodes.IMUL:
-        case Opcodes.IDIV:
-        case Opcodes.IREM:
-        case Opcodes.IAND:
-        case Opcodes.IOR:
-        case Opcodes.IXOR:
-        case Opcodes.ISHL:
-        case Opcodes.ISHR:
-        case Opcodes.IUSHR:
-        case Opcodes.L2I:
-        case Opcodes.D2I:
-        case Opcodes.FCMPL:
-        case Opcodes.FCMPG:
-            pop(2);
-            push(INTEGER);
-            break;
-        case Opcodes.LADD:
-        case Opcodes.LSUB:
-        case Opcodes.LMUL:
-        case Opcodes.LDIV:
-        case Opcodes.LREM:
-        case Opcodes.LAND:
-        case Opcodes.LOR:
-        case Opcodes.LXOR:
-            pop(4);
-            push(LONG);
-            push(TOP);
-            break;
-        case Opcodes.FADD:
-        case Opcodes.FSUB:
-        case Opcodes.FMUL:
-        case Opcodes.FDIV:
-        case Opcodes.FREM:
-        case Opcodes.L2F:
-        case Opcodes.D2F:
-            pop(2);
-            push(FLOAT);
-            break;
-        case Opcodes.DADD:
-        case Opcodes.DSUB:
-        case Opcodes.DMUL:
-        case Opcodes.DDIV:
-        case Opcodes.DREM:
-            pop(4);
-            push(DOUBLE);
-            push(TOP);
-            break;
-        case Opcodes.LSHL:
-        case Opcodes.LSHR:
-        case Opcodes.LUSHR:
-            pop(3);
-            push(LONG);
-            push(TOP);
-            break;
-        case Opcodes.IINC:
-            set(arg, INTEGER);
-            break;
-        case Opcodes.I2L:
-        case Opcodes.F2L:
-            pop(1);
-            push(LONG);
-            push(TOP);
-            break;
-        case Opcodes.I2F:
-            pop(1);
-            push(FLOAT);
-            break;
-        case Opcodes.I2D:
-        case Opcodes.F2D:
-            pop(1);
-            push(DOUBLE);
-            push(TOP);
-            break;
-        case Opcodes.F2I:
-        case Opcodes.ARRAYLENGTH:
-        case Opcodes.INSTANCEOF:
-            pop(1);
-            push(INTEGER);
-            break;
-        case Opcodes.LCMP:
-        case Opcodes.DCMPL:
-        case Opcodes.DCMPG:
-            pop(4);
-            push(INTEGER);
-            break;
-        case Opcodes.JSR:
-        case Opcodes.RET:
-            throw new RuntimeException(
-                    "JSR/RET are not supported with computeFrames option");
-        case Opcodes.GETSTATIC:
-            push(cw, item.strVal3);
-            break;
-        case Opcodes.PUTSTATIC:
-            pop(item.strVal3);
-            break;
-        case Opcodes.GETFIELD:
-            pop(1);
-            push(cw, item.strVal3);
-            break;
-        case Opcodes.PUTFIELD:
-            pop(item.strVal3);
-            pop();
-            break;
-        case Opcodes.INVOKEVIRTUAL:
-        case Opcodes.INVOKESPECIAL:
-        case Opcodes.INVOKESTATIC:
-        case Opcodes.INVOKEINTERFACE:
-            pop(item.strVal3);
-            if (opcode != Opcodes.INVOKESTATIC) {
-                t1 = pop();
-                if (opcode == Opcodes.INVOKESPECIAL
-                        && item.strVal2.charAt(0) == '<') {
-                    init(t1);
-                }
-            }
-            push(cw, item.strVal3);
-            break;
-        case Opcodes.INVOKEDYNAMIC:
-            pop(item.strVal2);
-            push(cw, item.strVal2);
-            break;
-        case Opcodes.NEW:
-            push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
-            break;
-        case Opcodes.NEWARRAY:
-            pop();
-            switch (arg) {
-            case Opcodes.T_BOOLEAN:
-                push(ARRAY_OF | BOOLEAN);
-                break;
-            case Opcodes.T_CHAR:
-                push(ARRAY_OF | CHAR);
-                break;
-            case Opcodes.T_BYTE:
-                push(ARRAY_OF | BYTE);
-                break;
-            case Opcodes.T_SHORT:
-                push(ARRAY_OF | SHORT);
-                break;
-            case Opcodes.T_INT:
-                push(ARRAY_OF | INTEGER);
-                break;
-            case Opcodes.T_FLOAT:
-                push(ARRAY_OF | FLOAT);
-                break;
-            case Opcodes.T_DOUBLE:
-                push(ARRAY_OF | DOUBLE);
-                break;
-            // case Opcodes.T_LONG:
-            default:
-                push(ARRAY_OF | LONG);
-                break;
-            }
-            break;
-        case Opcodes.ANEWARRAY:
-            String s = item.strVal1;
-            pop();
-            if (s.charAt(0) == '[') {
-                push(cw, '[' + s);
-            } else {
-                push(ARRAY_OF | OBJECT | cw.addType(s));
-            }
-            break;
-        case Opcodes.CHECKCAST:
-            s = item.strVal1;
-            pop();
-            if (s.charAt(0) == '[') {
-                push(cw, s);
-            } else {
-                push(OBJECT | cw.addType(s));
-            }
-            break;
-        // case Opcodes.MULTIANEWARRAY:
-        default:
-            pop(arg);
-            push(cw, item.strVal1);
-            break;
-        }
-    }
-
-    /**
-     * Merges the input frame of the given basic block with the input and output
-     * frames of this basic block. Returns <tt>true</tt> if the input frame of
-     * the given label has been changed by this operation.
-     *
-     * @param cw
-     *            the ClassWriter to which this label belongs.
-     * @param frame
-     *            the basic block whose input frame must be updated.
-     * @param edge
-     *            the kind of the {@link Edge} between this label and 'label'.
-     *            See {@link Edge#info}.
-     * @return <tt>true</tt> if the input frame of the given label has been
-     *         changed by this operation.
-     */
-    boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
-        boolean changed = false;
-        int i, s, dim, kind, t;
-
-        int nLocal = inputLocals.length;
-        int nStack = inputStack.length;
-        if (frame.inputLocals == null) {
-            frame.inputLocals = new int[nLocal];
-            changed = true;
-        }
-
-        for (i = 0; i < nLocal; ++i) {
-            if (outputLocals != null && i < outputLocals.length) {
-                s = outputLocals[i];
-                if (s == 0) {
-                    t = inputLocals[i];
-                } else {
-                    dim = s & DIM;
-                    kind = s & KIND;
-                    if (kind == BASE) {
-                        t = s;
-                    } else {
-                        if (kind == LOCAL) {
-                            t = dim + inputLocals[s & VALUE];
-                        } else {
-                            t = dim + inputStack[nStack - (s & VALUE)];
-                        }
-                        if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
-                                && (t == LONG || t == DOUBLE)) {
-                            t = TOP;
-                        }
-                    }
-                }
-            } else {
-                t = inputLocals[i];
-            }
-            if (initializations != null) {
-                t = init(cw, t);
-            }
-            changed |= merge(cw, t, frame.inputLocals, i);
-        }
-
-        if (edge > 0) {
-            for (i = 0; i < nLocal; ++i) {
-                t = inputLocals[i];
-                changed |= merge(cw, t, frame.inputLocals, i);
-            }
-            if (frame.inputStack == null) {
-                frame.inputStack = new int[1];
-                changed = true;
-            }
-            changed |= merge(cw, edge, frame.inputStack, 0);
-            return changed;
-        }
-
-        int nInputStack = inputStack.length + owner.inputStackTop;
-        if (frame.inputStack == null) {
-            frame.inputStack = new int[nInputStack + outputStackTop];
-            changed = true;
-        }
-
-        for (i = 0; i < nInputStack; ++i) {
-            t = inputStack[i];
-            if (initializations != null) {
-                t = init(cw, t);
-            }
-            changed |= merge(cw, t, frame.inputStack, i);
-        }
-        for (i = 0; i < outputStackTop; ++i) {
-            s = outputStack[i];
-            dim = s & DIM;
-            kind = s & KIND;
-            if (kind == BASE) {
-                t = s;
-            } else {
-                if (kind == LOCAL) {
-                    t = dim + inputLocals[s & VALUE];
-                } else {
-                    t = dim + inputStack[nStack - (s & VALUE)];
-                }
-                if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
-                        && (t == LONG || t == DOUBLE)) {
-                    t = TOP;
-                }
-            }
-            if (initializations != null) {
-                t = init(cw, t);
-            }
-            changed |= merge(cw, t, frame.inputStack, nInputStack + i);
-        }
-        return changed;
-    }
-
-    /**
-     * Merges the type at the given index in the given type array with the given
-     * type. Returns <tt>true</tt> if the type array has been modified by this
-     * operation.
-     *
-     * @param cw
-     *            the ClassWriter to which this label belongs.
-     * @param t
-     *            the type with which the type array element must be merged.
-     * @param types
-     *            an array of types.
-     * @param index
-     *            the index of the type that must be merged in 'types'.
-     * @return <tt>true</tt> if the type array has been modified by this
-     *         operation.
-     */
-    private static boolean merge(final ClassWriter cw, int t,
-            final int[] types, final int index) {
-        int u = types[index];
-        if (u == t) {
-            // if the types are equal, merge(u,t)=u, so there is no change
-            return false;
-        }
-        if ((t & ~DIM) == NULL) {
-            if (u == NULL) {
-                return false;
-            }
-            t = NULL;
-        }
-        if (u == 0) {
-            // if types[index] has never been assigned, merge(u,t)=t
-            types[index] = t;
-            return true;
-        }
-        int v;
-        if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) {
-            // if u is a reference type of any dimension
-            if (t == NULL) {
-                // if t is the NULL type, merge(u,t)=u, so there is no change
-                return false;
-            } else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) {
-                if ((u & BASE_KIND) == OBJECT) {
-                    // if t is also a reference type, and if u and t have the
-                    // same dimension merge(u,t) = dim(t) | common parent of the
-                    // element types of u and t
-                    v = (t & DIM) | OBJECT
-                            | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE);
-                } else {
-                    // if u and t are array types, but not with the same element
-                    // type, merge(u,t)=java/lang/Object
-                    v = OBJECT | cw.addType("java/lang/Object");
-                }
-            } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) {
-                // if t is any other reference or array type,
-                // merge(u,t)=java/lang/Object
-                v = OBJECT | cw.addType("java/lang/Object");
-            } else {
-                // if t is any other type, merge(u,t)=TOP
-                v = TOP;
-            }
-        } else if (u == NULL) {
-            // if u is the NULL type, merge(u,t)=t,
-            // or TOP if t is not a reference type
-            v = (t & BASE_KIND) == OBJECT || (t & DIM) != 0 ? t : TOP;
-        } else {
-            // if u is any other type, merge(u,t)=TOP whatever t
-            v = TOP;
-        }
-        if (u != v) {
-            types[index] = v;
-            return true;
-        }
-        return false;
-    }
-}
diff --git a/src/jvm/clojure/asm/Handle.java b/src/jvm/clojure/asm/Handle.java
deleted file mode 100644
index a147cf1..0000000
--- a/src/jvm/clojure/asm/Handle.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package clojure.asm;
-
-/**
- * A reference to a field or a method.
- *
- * @author Remi Forax
- * @author Eric Bruneton
- */
-public final class Handle {
-
-    /**
-     * The kind of field or method designated by this Handle. Should be
-     * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
-     * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
-     * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
-     * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or
-     * {@link Opcodes#H_INVOKEINTERFACE}.
-     */
-    final int tag;
-
-    /**
-     * The internal name of the field or method designed by this handle.
-     */
-    final String owner;
-
-    /**
-     * The name of the field or method designated by this handle.
-     */
-    final String name;
-
-    /**
-     * The descriptor of the field or method designated by this handle.
-     */
-    final String desc;
-
-    /**
-     * Constructs a new field or method handle.
-     *
-     * @param tag
-     *            the kind of field or method designated by this Handle. Must be
-     *            {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
-     *            {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
-     *            {@link Opcodes#H_INVOKEVIRTUAL},
-     *            {@link Opcodes#H_INVOKESTATIC},
-     *            {@link Opcodes#H_INVOKESPECIAL},
-     *            {@link Opcodes#H_NEWINVOKESPECIAL} or
-     *            {@link Opcodes#H_INVOKEINTERFACE}.
-     * @param owner
-     *            the internal name of the field or method designed by this
-     *            handle.
-     * @param name
-     *            the name of the field or method designated by this handle.
-     * @param desc
-     *            the descriptor of the field or method designated by this
-     *            handle.
-     */
-    public Handle(int tag, String owner, String name, String desc) {
-        this.tag = tag;
-        this.owner = owner;
-        this.name = name;
-        this.desc = desc;
-    }
-
-    /**
-     * Returns the kind of field or method designated by this handle.
-     *
-     * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
-     *         {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
-     *         {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
-     *         {@link Opcodes#H_INVOKESPECIAL},
-     *         {@link Opcodes#H_NEWINVOKESPECIAL} or
-     *         {@link Opcodes#H_INVOKEINTERFACE}.
-     */
-    public int getTag() {
-        return tag;
-    }
-
-    /**
-     * Returns the internal name of the field or method designed by this handle.
-     *
-     * @return the internal name of the field or method designed by this handle.
-     */
-    public String getOwner() {
-        return owner;
-    }
-
-    /**
-     * Returns the name of the field or method designated by this handle.
-     *
-     * @return the name of the field or method designated by this handle.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the descriptor of the field or method designated by this handle.
-     *
-     * @return the descriptor of the field or method designated by this handle.
-     */
-    public String getDesc() {
-        return desc;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == this) {
-            return true;
-        }
-        if (!(obj instanceof Handle)) {
-            return false;
-        }
-        Handle h = (Handle) obj;
-        return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
-                && desc.equals(h.desc);
-    }
-
-    @Override
-    public int hashCode() {
-        return tag + owner.hashCode() * name.hashCode() * desc.hashCode();
-    }
-
-    /**
-     * Returns the textual representation of this handle. The textual
-     * representation is:
-     *
-     * <pre>
-     * owner '.' name desc ' ' '(' tag ')'
-     * </pre>
-     *
-     * . As this format is unambiguous, it can be parsed if necessary.
-     */
-    @Override
-    public String toString() {
-        return owner + '.' + name + desc + " (" + tag + ')';
-    }
-}
diff --git a/src/jvm/clojure/asm/Handler.java b/src/jvm/clojure/asm/Handler.java
deleted file mode 100644
index bc0579e..0000000
--- a/src/jvm/clojure/asm/Handler.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * Information about an exception handler block.
- *
- * @author Eric Bruneton
- */
-class Handler {
-
-    /**
-     * Beginning of the exception handler's scope (inclusive).
-     */
-    Label start;
-
-    /**
-     * End of the exception handler's scope (exclusive).
-     */
-    Label end;
-
-    /**
-     * Beginning of the exception handler's code.
-     */
-    Label handler;
-
-    /**
-     * Internal name of the type of exceptions handled by this handler, or
-     * <tt>null</tt> to catch any exceptions.
-     */
-    String desc;
-
-    /**
-     * Constant pool index of the internal name of the type of exceptions
-     * handled by this handler, or 0 to catch any exceptions.
-     */
-    int type;
-
-    /**
-     * Next exception handler block info.
-     */
-    Handler next;
-
-    /**
-     * Removes the range between start and end from the given exception
-     * handlers.
-     *
-     * @param h
-     *            an exception handler list.
-     * @param start
-     *            the start of the range to be removed.
-     * @param end
-     *            the end of the range to be removed. Maybe null.
-     * @return the exception handler list with the start-end range removed.
-     */
-    static Handler remove(Handler h, Label start, Label end) {
-        if (h == null) {
-            return null;
-        } else {
-            h.next = remove(h.next, start, end);
-        }
-        int hstart = h.start.position;
-        int hend = h.end.position;
-        int s = start.position;
-        int e = end == null ? Integer.MAX_VALUE : end.position;
-        // if [hstart,hend[ and [s,e[ intervals intersect...
-        if (s < hend && e > hstart) {
-            if (s <= hstart) {
-                if (e >= hend) {
-                    // [hstart,hend[ fully included in [s,e[, h removed
-                    h = h.next;
-                } else {
-                    // [hstart,hend[ minus [s,e[ = [e,hend[
-                    h.start = end;
-                }
-            } else if (e >= hend) {
-                // [hstart,hend[ minus [s,e[ = [hstart,s[
-                h.end = start;
-            } else {
-                // [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[
-                Handler g = new Handler();
-                g.start = end;
-                g.end = h.end;
-                g.handler = h.handler;
-                g.desc = h.desc;
-                g.type = h.type;
-                g.next = h.next;
-                h.end = start;
-                h.next = g;
-            }
-        }
-        return h;
-    }
-}
diff --git a/src/jvm/clojure/asm/Item.java b/src/jvm/clojure/asm/Item.java
deleted file mode 100644
index 274a548..0000000
--- a/src/jvm/clojure/asm/Item.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A constant pool item. Constant pool items can be created with the 'newXXX'
- * methods in the {@link ClassWriter} class.
- *
- * @author Eric Bruneton
- */
-final class Item {
-
-    /**
-     * Index of this item in the constant pool.
-     */
-    int index;
-
-    /**
-     * Type of this constant pool item. A single class is used to represent all
-     * constant pool item types, in order to minimize the bytecode size of this
-     * package. The value of this field is one of {@link ClassWriter#INT},
-     * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
-     * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
-     * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
-     * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
-     * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
-     * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
-     *
-     * MethodHandle constant 9 variations are stored using a range of 9 values
-     * from {@link ClassWriter#HANDLE_BASE} + 1 to
-     * {@link ClassWriter#HANDLE_BASE} + 9.
-     *
-     * Special Item types are used for Items that are stored in the ClassWriter
-     * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
-     * avoid clashes with normal constant pool items in the ClassWriter constant
-     * pool's hash table. These special item types are
-     * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
-     * {@link ClassWriter#TYPE_MERGED}.
-     */
-    int type;
-
-    /**
-     * Value of this item, for an integer item.
-     */
-    int intVal;
-
-    /**
-     * Value of this item, for a long item.
-     */
-    long longVal;
-
-    /**
-     * First part of the value of this item, for items that do not hold a
-     * primitive value.
-     */
-    String strVal1;
-
-    /**
-     * Second part of the value of this item, for items that do not hold a
-     * primitive value.
-     */
-    String strVal2;
-
-    /**
-     * Third part of the value of this item, for items that do not hold a
-     * primitive value.
-     */
-    String strVal3;
-
-    /**
-     * The hash code value of this constant pool item.
-     */
-    int hashCode;
-
-    /**
-     * Link to another constant pool item, used for collision lists in the
-     * constant pool's hash table.
-     */
-    Item next;
-
-    /**
-     * Constructs an uninitialized {@link Item}.
-     */
-    Item() {
-    }
-
-    /**
-     * Constructs an uninitialized {@link Item} for constant pool element at
-     * given position.
-     *
-     * @param index
-     *            index of the item to be constructed.
-     */
-    Item(final int index) {
-        this.index = index;
-    }
-
-    /**
-     * Constructs a copy of the given item.
-     *
-     * @param index
-     *            index of the item to be constructed.
-     * @param i
-     *            the item that must be copied into the item to be constructed.
-     */
-    Item(final int index, final Item i) {
-        this.index = index;
-        type = i.type;
-        intVal = i.intVal;
-        longVal = i.longVal;
-        strVal1 = i.strVal1;
-        strVal2 = i.strVal2;
-        strVal3 = i.strVal3;
-        hashCode = i.hashCode;
-    }
-
-    /**
-     * Sets this item to an integer item.
-     *
-     * @param intVal
-     *            the value of this item.
-     */
-    void set(final int intVal) {
-        this.type = ClassWriter.INT;
-        this.intVal = intVal;
-        this.hashCode = 0x7FFFFFFF & (type + intVal);
-    }
-
-    /**
-     * Sets this item to a long item.
-     *
-     * @param longVal
-     *            the value of this item.
-     */
-    void set(final long longVal) {
-        this.type = ClassWriter.LONG;
-        this.longVal = longVal;
-        this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
-    }
-
-    /**
-     * Sets this item to a float item.
-     *
-     * @param floatVal
-     *            the value of this item.
-     */
-    void set(final float floatVal) {
-        this.type = ClassWriter.FLOAT;
-        this.intVal = Float.floatToRawIntBits(floatVal);
-        this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
-    }
-
-    /**
-     * Sets this item to a double item.
-     *
-     * @param doubleVal
-     *            the value of this item.
-     */
-    void set(final double doubleVal) {
-        this.type = ClassWriter.DOUBLE;
-        this.longVal = Double.doubleToRawLongBits(doubleVal);
-        this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
-    }
-
-    /**
-     * Sets this item to an item that do not hold a primitive value.
-     *
-     * @param type
-     *            the type of this item.
-     * @param strVal1
-     *            first part of the value of this item.
-     * @param strVal2
-     *            second part of the value of this item.
-     * @param strVal3
-     *            third part of the value of this item.
-     */
-    void set(final int type, final String strVal1, final String strVal2,
-            final String strVal3) {
-        this.type = type;
-        this.strVal1 = strVal1;
-        this.strVal2 = strVal2;
-        this.strVal3 = strVal3;
-        switch (type) {
-        case ClassWriter.UTF8:
-        case ClassWriter.STR:
-        case ClassWriter.CLASS:
-        case ClassWriter.MTYPE:
-        case ClassWriter.TYPE_NORMAL:
-            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
-            return;
-        case ClassWriter.NAME_TYPE: {
-            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
-                    * strVal2.hashCode());
-            return;
-        }
-        // ClassWriter.FIELD:
-        // ClassWriter.METH:
-        // ClassWriter.IMETH:
-        // ClassWriter.HANDLE_BASE + 1..9
-        default:
-            hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
-                    * strVal2.hashCode() * strVal3.hashCode());
-        }
-    }
-
-    /**
-     * Sets the item to an InvokeDynamic item.
-     *
-     * @param name
-     *            invokedynamic's name.
-     * @param desc
-     *            invokedynamic's desc.
-     * @param bsmIndex
-     *            zero based index into the class attribute BootrapMethods.
-     */
-    void set(String name, String desc, int bsmIndex) {
-        this.type = ClassWriter.INDY;
-        this.longVal = bsmIndex;
-        this.strVal1 = name;
-        this.strVal2 = desc;
-        this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex
-                * strVal1.hashCode() * strVal2.hashCode());
-    }
-
-    /**
-     * Sets the item to a BootstrapMethod item.
-     *
-     * @param position
-     *            position in byte in the class attribute BootrapMethods.
-     * @param hashCode
-     *            hashcode of the item. This hashcode is processed from the
-     *            hashcode of the bootstrap method and the hashcode of all
-     *            bootstrap arguments.
-     */
-    void set(int position, int hashCode) {
-        this.type = ClassWriter.BSM;
-        this.intVal = position;
-        this.hashCode = hashCode;
-    }
-
-    /**
-     * Indicates if the given item is equal to this one. <i>This method assumes
-     * that the two items have the same {@link #type}</i>.
-     *
-     * @param i
-     *            the item to be compared to this one. Both items must have the
-     *            same {@link #type}.
-     * @return <tt>true</tt> if the given item if equal to this one,
-     *         <tt>false</tt> otherwise.
-     */
-    boolean isEqualTo(final Item i) {
-        switch (type) {
-        case ClassWriter.UTF8:
-        case ClassWriter.STR:
-        case ClassWriter.CLASS:
-        case ClassWriter.MTYPE:
-        case ClassWriter.TYPE_NORMAL:
-            return i.strVal1.equals(strVal1);
-        case ClassWriter.TYPE_MERGED:
-        case ClassWriter.LONG:
-        case ClassWriter.DOUBLE:
-            return i.longVal == longVal;
-        case ClassWriter.INT:
-        case ClassWriter.FLOAT:
-            return i.intVal == intVal;
-        case ClassWriter.TYPE_UNINIT:
-            return i.intVal == intVal && i.strVal1.equals(strVal1);
-        case ClassWriter.NAME_TYPE:
-            return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
-        case ClassWriter.INDY: {
-            return i.longVal == longVal && i.strVal1.equals(strVal1)
-                    && i.strVal2.equals(strVal2);
-        }
-        // case ClassWriter.FIELD:
-        // case ClassWriter.METH:
-        // case ClassWriter.IMETH:
-        // case ClassWriter.HANDLE_BASE + 1..9
-        default:
-            return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
-                    && i.strVal3.equals(strVal3);
-        }
-    }
-
-}
diff --git a/src/jvm/clojure/asm/Label.java b/src/jvm/clojure/asm/Label.java
deleted file mode 100644
index 735e1b9..0000000
--- a/src/jvm/clojure/asm/Label.java
+++ /dev/null
@@ -1,560 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A label represents a position in the bytecode of a method. Labels are used
- * for jump, goto, and switch instructions, and for try catch blocks. A label
- * designates the <i>instruction</i> that is just after. Note however that there
- * can be other elements between a label and the instruction it designates (such
- * as other labels, stack map frames, line numbers, etc.).
- *
- * @author Eric Bruneton
- */
-public class Label {
-
-    /**
-     * Indicates if this label is only used for debug attributes. Such a label
-     * is not the start of a basic block, the target of a jump instruction, or
-     * an exception handler. It can be safely ignored in control flow graph
-     * analysis algorithms (for optimization purposes).
-     */
-    static final int DEBUG = 1;
-
-    /**
-     * Indicates if the position of this label is known.
-     */
-    static final int RESOLVED = 2;
-
-    /**
-     * Indicates if this label has been updated, after instruction resizing.
-     */
-    static final int RESIZED = 4;
-
-    /**
-     * Indicates if this basic block has been pushed in the basic block stack.
-     * See {@link MethodWriter#visitMaxs visitMaxs}.
-     */
-    static final int PUSHED = 8;
-
-    /**
-     * Indicates if this label is the target of a jump instruction, or the start
-     * of an exception handler.
-     */
-    static final int TARGET = 16;
-
-    /**
-     * Indicates if a stack map frame must be stored for this label.
-     */
-    static final int STORE = 32;
-
-    /**
-     * Indicates if this label corresponds to a reachable basic block.
-     */
-    static final int REACHABLE = 64;
-
-    /**
-     * Indicates if this basic block ends with a JSR instruction.
-     */
-    static final int JSR = 128;
-
-    /**
-     * Indicates if this basic block ends with a RET instruction.
-     */
-    static final int RET = 256;
-
-    /**
-     * Indicates if this basic block is the start of a subroutine.
-     */
-    static final int SUBROUTINE = 512;
-
-    /**
-     * Indicates if this subroutine basic block has been visited by a
-     * visitSubroutine(null, ...) call.
-     */
-    static final int VISITED = 1024;
-
-    /**
-     * Indicates if this subroutine basic block has been visited by a
-     * visitSubroutine(!null, ...) call.
-     */
-    static final int VISITED2 = 2048;
-
-    /**
-     * Field used to associate user information to a label. Warning: this field
-     * is used by the ASM tree package. In order to use it with the ASM tree
-     * package you must override the
-     * {@link clojure.asm.tree.MethodNode#getLabelNode} method.
-     */
-    public Object info;
-
-    /**
-     * Flags that indicate the status of this label.
-     *
-     * @see #DEBUG
-     * @see #RESOLVED
-     * @see #RESIZED
-     * @see #PUSHED
-     * @see #TARGET
-     * @see #STORE
-     * @see #REACHABLE
-     * @see #JSR
-     * @see #RET
-     */
-    int status;
-
-    /**
-     * The line number corresponding to this label, if known.
-     */
-    int line;
-
-    /**
-     * The position of this label in the code, if known.
-     */
-    int position;
-
-    /**
-     * Number of forward references to this label, times two.
-     */
-    private int referenceCount;
-
-    /**
-     * Informations about forward references. Each forward reference is
-     * described by two consecutive integers in this array: the first one is the
-     * position of the first byte of the bytecode instruction that contains the
-     * forward reference, while the second is the position of the first byte of
-     * the forward reference itself. In fact the sign of the first integer
-     * indicates if this reference uses 2 or 4 bytes, and its absolute value
-     * gives the position of the bytecode instruction. This array is also used
-     * as a bitset to store the subroutines to which a basic block belongs. This
-     * information is needed in {@linked MethodWriter#visitMaxs}, after all
-     * forward references have been resolved. Hence the same array can be used
-     * for both purposes without problems.
-     */
-    private int[] srcAndRefPositions;
-
-    // ------------------------------------------------------------------------
-
-    /*
-     * Fields for the control flow and data flow graph analysis algorithms (used
-     * to compute the maximum stack size or the stack map frames). A control
-     * flow graph contains one node per "basic block", and one edge per "jump"
-     * from one basic block to another. Each node (i.e., each basic block) is
-     * represented by the Label object that corresponds to the first instruction
-     * of this basic block. Each node also stores the list of its successors in
-     * the graph, as a linked list of Edge objects.
-     *
-     * The control flow analysis algorithms used to compute the maximum stack
-     * size or the stack map frames are similar and use two steps. The first
-     * step, during the visit of each instruction, builds information about the
-     * state of the local variables and the operand stack at the end of each
-     * basic block, called the "output frame", <i>relatively</i> to the frame
-     * state at the beginning of the basic block, which is called the "input
-     * frame", and which is <i>unknown</i> during this step. The second step, in
-     * {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes
-     * information about the input frame of each basic block, from the input
-     * state of the first basic block (known from the method signature), and by
-     * the using the previously computed relative output frames.
-     *
-     * The algorithm used to compute the maximum stack size only computes the
-     * relative output and absolute input stack heights, while the algorithm
-     * used to compute stack map frames computes relative output frames and
-     * absolute input frames.
-     */
-
-    /**
-     * Start of the output stack relatively to the input stack. The exact
-     * semantics of this field depends on the algorithm that is used.
-     *
-     * When only the maximum stack size is computed, this field is the number of
-     * elements in the input stack.
-     *
-     * When the stack map frames are completely computed, this field is the
-     * offset of the first output stack element relatively to the top of the
-     * input stack. This offset is always negative or null. A null offset means
-     * that the output stack must be appended to the input stack. A -n offset
-     * means that the first n output stack elements must replace the top n input
-     * stack elements, and that the other elements must be appended to the input
-     * stack.
-     */
-    int inputStackTop;
-
-    /**
-     * Maximum height reached by the output stack, relatively to the top of the
-     * input stack. This maximum is always positive or null.
-     */
-    int outputStackMax;
-
-    /**
-     * Information about the input and output stack map frames of this basic
-     * block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES}
-     * option is used.
-     */
-    Frame frame;
-
-    /**
-     * The successor of this label, in the order they are visited. This linked
-     * list does not include labels used for debug info only. If
-     * {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it
-     * does not contain successive labels that denote the same bytecode position
-     * (in this case only the first label appears in this list).
-     */
-    Label successor;
-
-    /**
-     * The successors of this node in the control flow graph. These successors
-     * are stored in a linked list of {@link Edge Edge} objects, linked to each
-     * other by their {@link Edge#next} field.
-     */
-    Edge successors;
-
-    /**
-     * The next basic block in the basic block stack. This stack is used in the
-     * main loop of the fix point algorithm used in the second step of the
-     * control flow analysis algorithms. It is also used in
-     * {@link #visitSubroutine} to avoid using a recursive method.
-     *
-     * @see MethodWriter#visitMaxs
-     */
-    Label next;
-
-    // ------------------------------------------------------------------------
-    // Constructor
-    // ------------------------------------------------------------------------
-
-    /**
-     * Constructs a new label.
-     */
-    public Label() {
-    }
-
-    // ------------------------------------------------------------------------
-    // Methods to compute offsets and to manage forward references
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the offset corresponding to this label. This offset is computed
-     * from the start of the method's bytecode. <i>This method is intended for
-     * {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
-     *
-     * @return the offset corresponding to this label.
-     * @throws IllegalStateException
-     *             if this label is not resolved yet.
-     */
-    public int getOffset() {
-        if ((status & RESOLVED) == 0) {
-            throw new IllegalStateException(
-                    "Label offset position has not been resolved yet");
-        }
-        return position;
-    }
-
-    /**
-     * Puts a reference to this label in the bytecode of a method. If the
-     * position of the label is known, the offset is computed and written
-     * directly. Otherwise, a null offset is written and a new forward reference
-     * is declared for this label.
-     *
-     * @param owner
-     *            the code writer that calls this method.
-     * @param out
-     *            the bytecode of the method.
-     * @param source
-     *            the position of first byte of the bytecode instruction that
-     *            contains this label.
-     * @param wideOffset
-     *            <tt>true</tt> if the reference must be stored in 4 bytes, or
-     *            <tt>false</tt> if it must be stored with 2 bytes.
-     * @throws IllegalArgumentException
-     *             if this label has not been created by the given code writer.
-     */
-    void put(final MethodWriter owner, final ByteVector out, final int source,
-            final boolean wideOffset) {
-        if ((status & RESOLVED) == 0) {
-            if (wideOffset) {
-                addReference(-1 - source, out.length);
-                out.putInt(-1);
-            } else {
-                addReference(source, out.length);
-                out.putShort(-1);
-            }
-        } else {
-            if (wideOffset) {
-                out.putInt(position - source);
-            } else {
-                out.putShort(position - source);
-            }
-        }
-    }
-
-    /**
-     * Adds a forward reference to this label. This method must be called only
-     * for a true forward reference, i.e. only if this label is not resolved
-     * yet. For backward references, the offset of the reference can be, and
-     * must be, computed and stored directly.
-     *
-     * @param sourcePosition
-     *            the position of the referencing instruction. This position
-     *            will be used to compute the offset of this forward reference.
-     * @param referencePosition
-     *            the position where the offset for this forward reference must
-     *            be stored.
-     */
-    private void addReference(final int sourcePosition,
-            final int referencePosition) {
-        if (srcAndRefPositions == null) {
-            srcAndRefPositions = new int[6];
-        }
-        if (referenceCount >= srcAndRefPositions.length) {
-            int[] a = new int[srcAndRefPositions.length + 6];
-            System.arraycopy(srcAndRefPositions, 0, a, 0,
-                    srcAndRefPositions.length);
-            srcAndRefPositions = a;
-        }
-        srcAndRefPositions[referenceCount++] = sourcePosition;
-        srcAndRefPositions[referenceCount++] = referencePosition;
-    }
-
-    /**
-     * Resolves all forward references to this label. This method must be called
-     * when this label is added to the bytecode of the method, i.e. when its
-     * position becomes known. This method fills in the blanks that where left
-     * in the bytecode by each forward reference previously added to this label.
-     *
-     * @param owner
-     *            the code writer that calls this method.
-     * @param position
-     *            the position of this label in the bytecode.
-     * @param data
-     *            the bytecode of the method.
-     * @return <tt>true</tt> if a blank that was left for this label was to
-     *         small to store the offset. In such a case the corresponding jump
-     *         instruction is replaced with a pseudo instruction (using unused
-     *         opcodes) using an unsigned two bytes offset. These pseudo
-     *         instructions will need to be replaced with true instructions with
-     *         wider offsets (4 bytes instead of 2). This is done in
-     *         {@link MethodWriter#resizeInstructions}.
-     * @throws IllegalArgumentException
-     *             if this label has already been resolved, or if it has not
-     *             been created by the given code writer.
-     */
-    boolean resolve(final MethodWriter owner, final int position,
-            final byte[] data) {
-        boolean needUpdate = false;
-        this.status |= RESOLVED;
-        this.position = position;
-        int i = 0;
-        while (i < referenceCount) {
-            int source = srcAndRefPositions[i++];
-            int reference = srcAndRefPositions[i++];
-            int offset;
-            if (source >= 0) {
-                offset = position - source;
-                if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) {
-                    /*
-                     * changes the opcode of the jump instruction, in order to
-                     * be able to find it later (see resizeInstructions in
-                     * MethodWriter). These temporary opcodes are similar to
-                     * jump instruction opcodes, except that the 2 bytes offset
-                     * is unsigned (and can therefore represent values from 0 to
-                     * 65535, which is sufficient since the size of a method is
-                     * limited to 65535 bytes).
-                     */
-                    int opcode = data[reference - 1] & 0xFF;
-                    if (opcode <= Opcodes.JSR) {
-                        // changes IFEQ ... JSR to opcodes 202 to 217
-                        data[reference - 1] = (byte) (opcode + 49);
-                    } else {
-                        // changes IFNULL and IFNONNULL to opcodes 218 and 219
-                        data[reference - 1] = (byte) (opcode + 20);
-                    }
-                    needUpdate = true;
-                }
-                data[reference++] = (byte) (offset >>> 8);
-                data[reference] = (byte) offset;
-            } else {
-                offset = position + source + 1;
-                data[reference++] = (byte) (offset >>> 24);
-                data[reference++] = (byte) (offset >>> 16);
-                data[reference++] = (byte) (offset >>> 8);
-                data[reference] = (byte) offset;
-            }
-        }
-        return needUpdate;
-    }
-
-    /**
-     * Returns the first label of the series to which this label belongs. For an
-     * isolated label or for the first label in a series of successive labels,
-     * this method returns the label itself. For other labels it returns the
-     * first label of the series.
-     *
-     * @return the first label of the series to which this label belongs.
-     */
-    Label getFirst() {
-        return !ClassReader.FRAMES || frame == null ? this : frame.owner;
-    }
-
-    // ------------------------------------------------------------------------
-    // Methods related to subroutines
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns true is this basic block belongs to the given subroutine.
-     *
-     * @param id
-     *            a subroutine id.
-     * @return true is this basic block belongs to the given subroutine.
-     */
-    boolean inSubroutine(final long id) {
-        if ((status & Label.VISITED) != 0) {
-            return (srcAndRefPositions[(int) (id >>> 32)] & (int) id) != 0;
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if this basic block and the given one belong to a common
-     * subroutine.
-     *
-     * @param block
-     *            another basic block.
-     * @return true if this basic block and the given one belong to a common
-     *         subroutine.
-     */
-    boolean inSameSubroutine(final Label block) {
-        if ((status & VISITED) == 0 || (block.status & VISITED) == 0) {
-            return false;
-        }
-        for (int i = 0; i < srcAndRefPositions.length; ++i) {
-            if ((srcAndRefPositions[i] & block.srcAndRefPositions[i]) != 0) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Marks this basic block as belonging to the given subroutine.
-     *
-     * @param id
-     *            a subroutine id.
-     * @param nbSubroutines
-     *            the total number of subroutines in the method.
-     */
-    void addToSubroutine(final long id, final int nbSubroutines) {
-        if ((status & VISITED) == 0) {
-            status |= VISITED;
-            srcAndRefPositions = new int[(nbSubroutines - 1) / 32 + 1];
-        }
-        srcAndRefPositions[(int) (id >>> 32)] |= (int) id;
-    }
-
-    /**
-     * Finds the basic blocks that belong to a given subroutine, and marks these
-     * blocks as belonging to this subroutine. This method follows the control
-     * flow graph to find all the blocks that are reachable from the current
-     * block WITHOUT following any JSR target.
-     *
-     * @param JSR
-     *            a JSR block that jumps to this subroutine. If this JSR is not
-     *            null it is added to the successor of the RET blocks found in
-     *            the subroutine.
-     * @param id
-     *            the id of this subroutine.
-     * @param nbSubroutines
-     *            the total number of subroutines in the method.
-     */
-    void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) {
-        // user managed stack of labels, to avoid using a recursive method
-        // (recursivity can lead to stack overflow with very large methods)
-        Label stack = this;
-        while (stack != null) {
-            // removes a label l from the stack
-            Label l = stack;
-            stack = l.next;
-            l.next = null;
-
-            if (JSR != null) {
-                if ((l.status & VISITED2) != 0) {
-                    continue;
-                }
-                l.status |= VISITED2;
-                // adds JSR to the successors of l, if it is a RET block
-                if ((l.status & RET) != 0) {
-                    if (!l.inSameSubroutine(JSR)) {
-                        Edge e = new Edge();
-                        e.info = l.inputStackTop;
-                        e.successor = JSR.successors.successor;
-                        e.next = l.successors;
-                        l.successors = e;
-                    }
-                }
-            } else {
-                // if the l block already belongs to subroutine 'id', continue
-                if (l.inSubroutine(id)) {
-                    continue;
-                }
-                // marks the l block as belonging to subroutine 'id'
-                l.addToSubroutine(id, nbSubroutines);
-            }
-            // pushes each successor of l on the stack, except JSR targets
-            Edge e = l.successors;
-            while (e != null) {
-                // if the l block is a JSR block, then 'l.successors.next' leads
-                // to the JSR target (see {@link #visitJumpInsn}) and must
-                // therefore not be followed
-                if ((l.status & Label.JSR) == 0 || e != l.successors.next) {
-                    // pushes e.successor on the stack if it not already added
-                    if (e.successor.next == null) {
-                        e.successor.next = stack;
-                        stack = e.successor;
-                    }
-                }
-                e = e.next;
-            }
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Overriden Object methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns a string representation of this label.
-     *
-     * @return a string representation of this label.
-     */
-    @Override
-    public String toString() {
-        return "L" + System.identityHashCode(this);
-    }
-}
diff --git a/src/jvm/clojure/asm/MethodVisitor.java b/src/jvm/clojure/asm/MethodVisitor.java
deleted file mode 100644
index 347455e..0000000
--- a/src/jvm/clojure/asm/MethodVisitor.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A visitor to visit a Java method. The methods of this class must be called in
- * the following order: [ <tt>visitAnnotationDefault</tt> ] (
- * <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
- * <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
- * <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> |
- * <tt>visitTryCatchBlock</tt> | <tt>visitLocalVariable</tt> |
- * <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In
- * addition, the <tt>visit</tt><i>X</i>Insn</tt> and <tt>visitLabel</tt> methods
- * must be called in the sequential order of the bytecode instructions of the
- * visited code, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the
- * labels passed as arguments have been visited, and the
- * <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt> methods must be
- * called <i>after</i> the labels passed as arguments have been visited.
- *
- * @author Eric Bruneton
- */
-public abstract class MethodVisitor {
-
-    /**
-     * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4}.
-     */
-    protected final int api;
-
-    /**
-     * The method visitor to which this visitor must delegate method calls. May
-     * be null.
-     */
-    protected MethodVisitor mv;
-
-    /**
-     * Constructs a new {@link MethodVisitor}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     */
-    public MethodVisitor(final int api) {
-        this(api, null);
-    }
-
-    /**
-     * Constructs a new {@link MethodVisitor}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param mv
-     *            the method visitor to which this visitor must delegate method
-     *            calls. May be null.
-     */
-    public MethodVisitor(final int api, final MethodVisitor mv) {
-        if (api != Opcodes.ASM4) {
-            throw new IllegalArgumentException();
-        }
-        this.api = api;
-        this.mv = mv;
-    }
-
-    // -------------------------------------------------------------------------
-    // Annotations and non standard attributes
-    // -------------------------------------------------------------------------
-
-    /**
-     * Visits the default value of this annotation interface method.
-     *
-     * @return a visitor to the visit the actual default value of this
-     *         annotation interface method, or <tt>null</tt> if this visitor is
-     *         not interested in visiting this default value. The 'name'
-     *         parameters passed to the methods of this annotation visitor are
-     *         ignored. Moreover, exacly one visit method must be called on this
-     *         annotation visitor, followed by visitEnd.
-     */
-    public AnnotationVisitor visitAnnotationDefault() {
-        if (mv != null) {
-            return mv.visitAnnotationDefault();
-        }
-        return null;
-    }
-
-    /**
-     * Visits an annotation of this method.
-     *
-     * @param desc
-     *            the class descriptor of the annotation class.
-     * @param visible
-     *            <tt>true</tt> if the annotation is visible at runtime.
-     * @return a visitor to visit the annotation values, or <tt>null</tt> if
-     *         this visitor is not interested in visiting this annotation.
-     */
-    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
-        if (mv != null) {
-            return mv.visitAnnotation(desc, visible);
-        }
-        return null;
-    }
-
-    /**
-     * Visits an annotation of a parameter this method.
-     *
-     * @param parameter
-     *            the parameter index.
-     * @param desc
-     *            the class descriptor of the annotation class.
-     * @param visible
-     *            <tt>true</tt> if the annotation is visible at runtime.
-     * @return a visitor to visit the annotation values, or <tt>null</tt> if
-     *         this visitor is not interested in visiting this annotation.
-     */
-    public AnnotationVisitor visitParameterAnnotation(int parameter,
-            String desc, boolean visible) {
-        if (mv != null) {
-            return mv.visitParameterAnnotation(parameter, desc, visible);
-        }
-        return null;
-    }
-
-    /**
-     * Visits a non standard attribute of this method.
-     *
-     * @param attr
-     *            an attribute.
-     */
-    public void visitAttribute(Attribute attr) {
-        if (mv != null) {
-            mv.visitAttribute(attr);
-        }
-    }
-
-    /**
-     * Starts the visit of the method's code, if any (i.e. non abstract method).
-     */
-    public void visitCode() {
-        if (mv != null) {
-            mv.visitCode();
-        }
-    }
-
-    /**
-     * Visits the current state of the local variables and operand stack
-     * elements. This method must(*) be called <i>just before</i> any
-     * instruction <b>i</b> that follows an unconditional branch instruction
-     * such as GOTO or THROW, that is the target of a jump instruction, or that
-     * starts an exception handler block. The visited types must describe the
-     * values of the local variables and of the operand stack elements <i>just
-     * before</i> <b>i</b> is executed.<br>
-     * <br>
-     * (*) this is mandatory only for classes whose version is greater than or
-     * equal to {@link Opcodes#V1_6 V1_6}. <br>
-     * <br>
-     * The frames of a method must be given either in expanded form, or in
-     * compressed form (all frames must use the same format, i.e. you must not
-     * mix expanded and compressed frames within a single method):
-     * <ul>
-     * <li>In expanded form, all frames must have the F_NEW type.</li>
-     * <li>In compressed form, frames are basically "deltas" from the state of
-     * the previous frame:
-     * <ul>
-     * <li>{@link Opcodes#F_SAME} representing frame with exactly the same
-     * locals as the previous frame and with the empty stack.</li>
-     * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same
-     * locals as the previous frame and with single value on the stack (
-     * <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the
-     * type of the stack item).</li>
-     * <li>{@link Opcodes#F_APPEND} representing frame with current locals are
-     * the same as the locals in the previous frame, except that additional
-     * locals are defined (<code>nLocal</code> is 1, 2 or 3 and
-     * <code>local</code> elements contains values representing added types).</li>
-     * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the
-     * same as the locals in the previous frame, except that the last 1-3 locals
-     * are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
-     * <li>{@link Opcodes#F_FULL} representing complete frame data.</li></li>
-     * </ul>
-     * </ul> <br>
-     * In both cases the first frame, corresponding to the method's parameters
-     * and access flags, is implicit and must not be visited. Also, it is
-     * illegal to visit two or more frames for the same code location (i.e., at
-     * least one instruction must be visited between two calls to visitFrame).
-     *
-     * @param type
-     *            the type of this stack map frame. Must be
-     *            {@link Opcodes#F_NEW} for expanded frames, or
-     *            {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
-     *            {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
-     *            {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
-     *            compressed frames.
-     * @param nLocal
-     *            the number of local variables in the visited frame.
-     * @param local
-     *            the local variable types in this frame. This array must not be
-     *            modified. Primitive types are represented by
-     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
-     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
-     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
-     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
-     *            represented by a single element). Reference types are
-     *            represented by String objects (representing internal names),
-     *            and uninitialized types by Label objects (this label
-     *            designates the NEW instruction that created this uninitialized
-     *            value).
-     * @param nStack
-     *            the number of operand stack elements in the visited frame.
-     * @param stack
-     *            the operand stack types in this frame. This array must not be
-     *            modified. Its content has the same format as the "local"
-     *            array.
-     * @throws IllegalStateException
-     *             if a frame is visited just after another one, without any
-     *             instruction between the two (unless this frame is a
-     *             Opcodes#F_SAME frame, in which case it is silently ignored).
-     */
-    public void visitFrame(int type, int nLocal, Object[] local, int nStack,
-            Object[] stack) {
-        if (mv != null) {
-            mv.visitFrame(type, nLocal, local, nStack, stack);
-        }
-    }
-
-    // -------------------------------------------------------------------------
-    // Normal instructions
-    // -------------------------------------------------------------------------
-
-    /**
-     * Visits a zero operand instruction.
-     *
-     * @param opcode
-     *            the opcode of the instruction to be visited. This opcode is
-     *            either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
-     *            ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
-     *            FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
-     *            LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
-     *            IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
-     *            SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
-     *            DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
-     *            IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
-     *            FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
-     *            IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
-     *            L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
-     *            LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
-     *            DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
-     *            or MONITOREXIT.
-     */
-    public void visitInsn(int opcode) {
-        if (mv != null) {
-            mv.visitInsn(opcode);
-        }
-    }
-
-    /**
-     * Visits an instruction with a single int operand.
-     *
-     * @param opcode
-     *            the opcode of the instruction to be visited. This opcode is
-     *            either BIPUSH, SIPUSH or NEWARRAY.
-     * @param operand
-     *            the operand of the instruction to be visited.<br>
-     *            When opcode is BIPUSH, operand value should be between
-     *            Byte.MIN_VALUE and Byte.MAX_VALUE.<br>
-     *            When opcode is SIPUSH, operand value should be between
-     *            Short.MIN_VALUE and Short.MAX_VALUE.<br>
-     *            When opcode is NEWARRAY, operand value should be one of
-     *            {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
-     *            {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
-     *            {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
-     *            {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
-     */
-    public void visitIntInsn(int opcode, int operand) {
-        if (mv != null) {
-            mv.visitIntInsn(opcode, operand);
-        }
-    }
-
-    /**
-     * Visits a local variable instruction. A local variable instruction is an
-     * instruction that loads or stores the value of a local variable.
-     *
-     * @param opcode
-     *            the opcode of the local variable instruction to be visited.
-     *            This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
-     *            ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
-     * @param var
-     *            the operand of the instruction to be visited. This operand is
-     *            the index of a local variable.
-     */
-    public void visitVarInsn(int opcode, int var) {
-        if (mv != null) {
-            mv.visitVarInsn(opcode, var);
-        }
-    }
-
-    /**
-     * Visits a type instruction. A type instruction is an instruction that
-     * takes the internal name of a class as parameter.
-     *
-     * @param opcode
-     *            the opcode of the type instruction to be visited. This opcode
-     *            is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
-     * @param type
-     *            the operand of the instruction to be visited. This operand
-     *            must be the internal name of an object or array class (see
-     *            {@link Type#getInternalName() getInternalName}).
-     */
-    public void visitTypeInsn(int opcode, String type) {
-        if (mv != null) {
-            mv.visitTypeInsn(opcode, type);
-        }
-    }
-
-    /**
-     * Visits a field instruction. A field instruction is an instruction that
-     * loads or stores the value of a field of an object.
-     *
-     * @param opcode
-     *            the opcode of the type instruction to be visited. This opcode
-     *            is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
-     * @param owner
-     *            the internal name of the field's owner class (see
-     *            {@link Type#getInternalName() getInternalName}).
-     * @param name
-     *            the field's name.
-     * @param desc
-     *            the field's descriptor (see {@link Type Type}).
-     */
-    public void visitFieldInsn(int opcode, String owner, String name,
-            String desc) {
-        if (mv != null) {
-            mv.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    /**
-     * Visits a method instruction. A method instruction is an instruction that
-     * invokes a method.
-     *
-     * @param opcode
-     *            the opcode of the type instruction to be visited. This opcode
-     *            is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
-     *            INVOKEINTERFACE.
-     * @param owner
-     *            the internal name of the method's owner class (see
-     *            {@link Type#getInternalName() getInternalName}).
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     */
-    public void visitMethodInsn(int opcode, String owner, String name,
-            String desc) {
-        if (mv != null) {
-            mv.visitMethodInsn(opcode, owner, name, desc);
-        }
-    }
-
-    /**
-     * Visits an invokedynamic instruction.
-     *
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     * @param bsm
-     *            the bootstrap method.
-     * @param bsmArgs
-     *            the bootstrap method constant arguments. Each argument must be
-     *            an {@link Integer}, {@link Float}, {@link Long},
-     *            {@link Double}, {@link String}, {@link Type} or {@link Handle}
-     *            value. This method is allowed to modify the content of the
-     *            array so a caller should expect that this array may change.
-     */
-    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
-            Object... bsmArgs) {
-        if (mv != null) {
-            mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-        }
-    }
-
-    /**
-     * Visits a jump instruction. A jump instruction is an instruction that may
-     * jump to another instruction.
-     *
-     * @param opcode
-     *            the opcode of the type instruction to be visited. This opcode
-     *            is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
-     *            IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
-     *            IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
-     * @param label
-     *            the operand of the instruction to be visited. This operand is
-     *            a label that designates the instruction to which the jump
-     *            instruction may jump.
-     */
-    public void visitJumpInsn(int opcode, Label label) {
-        if (mv != null) {
-            mv.visitJumpInsn(opcode, label);
-        }
-    }
-
-    /**
-     * Visits a label. A label designates the instruction that will be visited
-     * just after it.
-     *
-     * @param label
-     *            a {@link Label Label} object.
-     */
-    public void visitLabel(Label label) {
-        if (mv != null) {
-            mv.visitLabel(label);
-        }
-    }
-
-    // -------------------------------------------------------------------------
-    // Special instructions
-    // -------------------------------------------------------------------------
-
-    /**
-     * Visits a LDC instruction. Note that new constant types may be added in
-     * future versions of the Java Virtual Machine. To easily detect new
-     * constant types, implementations of this method should check for
-     * unexpected constant types, like this:
-     *
-     * <pre>
-     * if (cst instanceof Integer) {
-     *     // ...
-     * } else if (cst instanceof Float) {
-     *     // ...
-     * } else if (cst instanceof Long) {
-     *     // ...
-     * } else if (cst instanceof Double) {
-     *     // ...
-     * } else if (cst instanceof String) {
-     *     // ...
-     * } else if (cst instanceof Type) {
-     *     int sort = ((Type) cst).getSort();
-     *     if (sort == Type.OBJECT) {
-     *         // ...
-     *     } else if (sort == Type.ARRAY) {
-     *         // ...
-     *     } else if (sort == Type.METHOD) {
-     *         // ...
-     *     } else {
-     *         // throw an exception
-     *     }
-     * } else if (cst instanceof Handle) {
-     *     // ...
-     * } else {
-     *     // throw an exception
-     * }
-     * </pre>
-     *
-     * @param cst
-     *            the constant to be loaded on the stack. This parameter must be
-     *            a non null {@link Integer}, a {@link Float}, a {@link Long}, a
-     *            {@link Double}, a {@link String}, a {@link Type} of OBJECT or
-     *            ARRAY sort for <tt>.class</tt> constants, for classes whose
-     *            version is 49.0, a {@link Type} of METHOD sort or a
-     *            {@link Handle} for MethodType and MethodHandle constants, for
-     *            classes whose version is 51.0.
-     */
-    public void visitLdcInsn(Object cst) {
-        if (mv != null) {
-            mv.visitLdcInsn(cst);
-        }
-    }
-
-    /**
-     * Visits an IINC instruction.
-     *
-     * @param var
-     *            index of the local variable to be incremented.
-     * @param increment
-     *            amount to increment the local variable by.
-     */
-    public void visitIincInsn(int var, int increment) {
-        if (mv != null) {
-            mv.visitIincInsn(var, increment);
-        }
-    }
-
-    /**
-     * Visits a TABLESWITCH instruction.
-     *
-     * @param min
-     *            the minimum key value.
-     * @param max
-     *            the maximum key value.
-     * @param dflt
-     *            beginning of the default handler block.
-     * @param labels
-     *            beginnings of the handler blocks. <tt>labels[i]</tt> is the
-     *            beginning of the handler block for the <tt>min + i</tt> key.
-     */
-    public void visitTableSwitchInsn(int min, int max, Label dflt,
-            Label... labels) {
-        if (mv != null) {
-            mv.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    /**
-     * Visits a LOOKUPSWITCH instruction.
-     *
-     * @param dflt
-     *            beginning of the default handler block.
-     * @param keys
-     *            the values of the keys.
-     * @param labels
-     *            beginnings of the handler blocks. <tt>labels[i]</tt> is the
-     *            beginning of the handler block for the <tt>keys[i]</tt> key.
-     */
-    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
-        if (mv != null) {
-            mv.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    /**
-     * Visits a MULTIANEWARRAY instruction.
-     *
-     * @param desc
-     *            an array type descriptor (see {@link Type Type}).
-     * @param dims
-     *            number of dimensions of the array to allocate.
-     */
-    public void visitMultiANewArrayInsn(String desc, int dims) {
-        if (mv != null) {
-            mv.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-
-    // -------------------------------------------------------------------------
-    // Exceptions table entries, debug information, max stack and max locals
-    // -------------------------------------------------------------------------
-
-    /**
-     * Visits a try catch block.
-     *
-     * @param start
-     *            beginning of the exception handler's scope (inclusive).
-     * @param end
-     *            end of the exception handler's scope (exclusive).
-     * @param handler
-     *            beginning of the exception handler's code.
-     * @param type
-     *            internal name of the type of exceptions handled by the
-     *            handler, or <tt>null</tt> to catch any exceptions (for
-     *            "finally" blocks).
-     * @throws IllegalArgumentException
-     *             if one of the labels has already been visited by this visitor
-     *             (by the {@link #visitLabel visitLabel} method).
-     */
-    public void visitTryCatchBlock(Label start, Label end, Label handler,
-            String type) {
-        if (mv != null) {
-            mv.visitTryCatchBlock(start, end, handler, type);
-        }
-    }
-
-    /**
-     * Visits a local variable declaration.
-     *
-     * @param name
-     *            the name of a local variable.
-     * @param desc
-     *            the type descriptor of this local variable.
-     * @param signature
-     *            the type signature of this local variable. May be
-     *            <tt>null</tt> if the local variable type does not use generic
-     *            types.
-     * @param start
-     *            the first instruction corresponding to the scope of this local
-     *            variable (inclusive).
-     * @param end
-     *            the last instruction corresponding to the scope of this local
-     *            variable (exclusive).
-     * @param index
-     *            the local variable's index.
-     * @throws IllegalArgumentException
-     *             if one of the labels has not already been visited by this
-     *             visitor (by the {@link #visitLabel visitLabel} method).
-     */
-    public void visitLocalVariable(String name, String desc, String signature,
-            Label start, Label end, int index) {
-        if (mv != null) {
-            mv.visitLocalVariable(name, desc, signature, start, end, index);
-        }
-    }
-
-    /**
-     * Visits a line number declaration.
-     *
-     * @param line
-     *            a line number. This number refers to the source file from
-     *            which the class was compiled.
-     * @param start
-     *            the first instruction corresponding to this line number.
-     * @throws IllegalArgumentException
-     *             if <tt>start</tt> has not already been visited by this
-     *             visitor (by the {@link #visitLabel visitLabel} method).
-     */
-    public void visitLineNumber(int line, Label start) {
-        if (mv != null) {
-            mv.visitLineNumber(line, start);
-        }
-    }
-
-    /**
-     * Visits the maximum stack size and the maximum number of local variables
-     * of the method.
-     *
-     * @param maxStack
-     *            maximum stack size of the method.
-     * @param maxLocals
-     *            maximum number of local variables for the method.
-     */
-    public void visitMaxs(int maxStack, int maxLocals) {
-        if (mv != null) {
-            mv.visitMaxs(maxStack, maxLocals);
-        }
-    }
-
-    /**
-     * Visits the end of the method. This method, which is the last one to be
-     * called, is used to inform the visitor that all the annotations and
-     * attributes of the method have been visited.
-     */
-    public void visitEnd() {
-        if (mv != null) {
-            mv.visitEnd();
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/MethodWriter.java b/src/jvm/clojure/asm/MethodWriter.java
deleted file mode 100644
index 9197318..0000000
--- a/src/jvm/clojure/asm/MethodWriter.java
+++ /dev/null
@@ -1,2685 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * A {@link MethodVisitor} that generates methods in bytecode form. Each visit
- * method of this class appends the bytecode corresponding to the visited
- * instruction to a byte vector, in the order these methods are called.
- *
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-class MethodWriter extends MethodVisitor {
-
-    /**
-     * Pseudo access flag used to denote constructors.
-     */
-    static final int ACC_CONSTRUCTOR = 0x80000;
-
-    /**
-     * Frame has exactly the same locals as the previous stack map frame and
-     * number of stack items is zero.
-     */
-    static final int SAME_FRAME = 0; // to 63 (0-3f)
-
-    /**
-     * Frame has exactly the same locals as the previous stack map frame and
-     * number of stack items is 1
-     */
-    static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; // to 127 (40-7f)
-
-    /**
-     * Reserved for future use
-     */
-    static final int RESERVED = 128;
-
-    /**
-     * Frame has exactly the same locals as the previous stack map frame and
-     * number of stack items is 1. Offset is bigger then 63;
-     */
-    static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; // f7
-
-    /**
-     * Frame where current locals are the same as the locals in the previous
-     * frame, except that the k last locals are absent. The value of k is given
-     * by the formula 251-frame_type.
-     */
-    static final int CHOP_FRAME = 248; // to 250 (f8-fA)
-
-    /**
-     * Frame has exactly the same locals as the previous stack map frame and
-     * number of stack items is zero. Offset is bigger then 63;
-     */
-    static final int SAME_FRAME_EXTENDED = 251; // fb
-
-    /**
-     * Frame where current locals are the same as the locals in the previous
-     * frame, except that k additional locals are defined. The value of k is
-     * given by the formula frame_type-251.
-     */
-    static final int APPEND_FRAME = 252; // to 254 // fc-fe
-
-    /**
-     * Full frame
-     */
-    static final int FULL_FRAME = 255; // ff
-
-    /**
-     * Indicates that the stack map frames must be recomputed from scratch. In
-     * this case the maximum stack size and number of local variables is also
-     * recomputed from scratch.
-     *
-     * @see #compute
-     */
-    private static final int FRAMES = 0;
-
-    /**
-     * Indicates that the maximum stack size and number of local variables must
-     * be automatically computed.
-     *
-     * @see #compute
-     */
-    private static final int MAXS = 1;
-
-    /**
-     * Indicates that nothing must be automatically computed.
-     *
-     * @see #compute
-     */
-    private static final int NOTHING = 2;
-
-    /**
-     * The class writer to which this method must be added.
-     */
-    final ClassWriter cw;
-
-    /**
-     * Access flags of this method.
-     */
-    private int access;
-
-    /**
-     * The index of the constant pool item that contains the name of this
-     * method.
-     */
-    private final int name;
-
-    /**
-     * The index of the constant pool item that contains the descriptor of this
-     * method.
-     */
-    private final int desc;
-
-    /**
-     * The descriptor of this method.
-     */
-    private final String descriptor;
-
-    /**
-     * The signature of this method.
-     */
-    String signature;
-
-    /**
-     * If not zero, indicates that the code of this method must be copied from
-     * the ClassReader associated to this writer in <code>cw.cr</code>. More
-     * precisely, this field gives the index of the first byte to copied from
-     * <code>cw.cr.b</code>.
-     */
-    int classReaderOffset;
-
-    /**
-     * If not zero, indicates that the code of this method must be copied from
-     * the ClassReader associated to this writer in <code>cw.cr</code>. More
-     * precisely, this field gives the number of bytes to copied from
-     * <code>cw.cr.b</code>.
-     */
-    int classReaderLength;
-
-    /**
-     * Number of exceptions that can be thrown by this method.
-     */
-    int exceptionCount;
-
-    /**
-     * The exceptions that can be thrown by this method. More precisely, this
-     * array contains the indexes of the constant pool items that contain the
-     * internal names of these exception classes.
-     */
-    int[] exceptions;
-
-    /**
-     * The annotation default attribute of this method. May be <tt>null</tt>.
-     */
-    private ByteVector annd;
-
-    /**
-     * The runtime visible annotations of this method. May be <tt>null</tt>.
-     */
-    private AnnotationWriter anns;
-
-    /**
-     * The runtime invisible annotations of this method. May be <tt>null</tt>.
-     */
-    private AnnotationWriter ianns;
-
-    /**
-     * The runtime visible parameter annotations of this method. May be
-     * <tt>null</tt>.
-     */
-    private AnnotationWriter[] panns;
-
-    /**
-     * The runtime invisible parameter annotations of this method. May be
-     * <tt>null</tt>.
-     */
-    private AnnotationWriter[] ipanns;
-
-    /**
-     * The number of synthetic parameters of this method.
-     */
-    private int synthetics;
-
-    /**
-     * The non standard attributes of the method.
-     */
-    private Attribute attrs;
-
-    /**
-     * The bytecode of this method.
-     */
-    private ByteVector code = new ByteVector();
-
-    /**
-     * Maximum stack size of this method.
-     */
-    private int maxStack;
-
-    /**
-     * Maximum number of local variables for this method.
-     */
-    private int maxLocals;
-
-    /**
-     * Number of local variables in the current stack map frame.
-     */
-    private int currentLocals;
-
-    /**
-     * Number of stack map frames in the StackMapTable attribute.
-     */
-    private int frameCount;
-
-    /**
-     * The StackMapTable attribute.
-     */
-    private ByteVector stackMap;
-
-    /**
-     * The offset of the last frame that was written in the StackMapTable
-     * attribute.
-     */
-    private int previousFrameOffset;
-
-    /**
-     * The last frame that was written in the StackMapTable attribute.
-     *
-     * @see #frame
-     */
-    private int[] previousFrame;
-
-    /**
-     * The current stack map frame. The first element contains the offset of the
-     * instruction to which the frame corresponds, the second element is the
-     * number of locals and the third one is the number of stack elements. The
-     * local variables start at index 3 and are followed by the operand stack
-     * values. In summary frame[0] = offset, frame[1] = nLocal, frame[2] =
-     * nStack, frame[3] = nLocal. All types are encoded as integers, with the
-     * same format as the one used in {@link Label}, but limited to BASE types.
-     */
-    private int[] frame;
-
-    /**
-     * Number of elements in the exception handler list.
-     */
-    private int handlerCount;
-
-    /**
-     * The first element in the exception handler list.
-     */
-    private Handler firstHandler;
-
-    /**
-     * The last element in the exception handler list.
-     */
-    private Handler lastHandler;
-
-    /**
-     * Number of entries in the LocalVariableTable attribute.
-     */
-    private int localVarCount;
-
-    /**
-     * The LocalVariableTable attribute.
-     */
-    private ByteVector localVar;
-
-    /**
-     * Number of entries in the LocalVariableTypeTable attribute.
-     */
-    private int localVarTypeCount;
-
-    /**
-     * The LocalVariableTypeTable attribute.
-     */
-    private ByteVector localVarType;
-
-    /**
-     * Number of entries in the LineNumberTable attribute.
-     */
-    private int lineNumberCount;
-
-    /**
-     * The LineNumberTable attribute.
-     */
-    private ByteVector lineNumber;
-
-    /**
-     * The non standard attributes of the method's code.
-     */
-    private Attribute cattrs;
-
-    /**
-     * Indicates if some jump instructions are too small and need to be resized.
-     */
-    private boolean resize;
-
-    /**
-     * The number of subroutines in this method.
-     */
-    private int subroutines;
-
-    // ------------------------------------------------------------------------
-
-    /*
-     * Fields for the control flow graph analysis algorithm (used to compute the
-     * maximum stack size). A control flow graph contains one node per "basic
-     * block", and one edge per "jump" from one basic block to another. Each
-     * node (i.e., each basic block) is represented by the Label object that
-     * corresponds to the first instruction of this basic block. Each node also
-     * stores the list of its successors in the graph, as a linked list of Edge
-     * objects.
-     */
-
-    /**
-     * Indicates what must be automatically computed.
-     *
-     * @see #FRAMES
-     * @see #MAXS
-     * @see #NOTHING
-     */
-    private final int compute;
-
-    /**
-     * A list of labels. This list is the list of basic blocks in the method,
-     * i.e. a list of Label objects linked to each other by their
-     * {@link Label#successor} field, in the order they are visited by
-     * {@link MethodVisitor#visitLabel}, and starting with the first basic
-     * block.
-     */
-    private Label labels;
-
-    /**
-     * The previous basic block.
-     */
-    private Label previousBlock;
-
-    /**
-     * The current basic block.
-     */
-    private Label currentBlock;
-
-    /**
-     * The (relative) stack size after the last visited instruction. This size
-     * is relative to the beginning of the current basic block, i.e., the true
-     * stack size after the last visited instruction is equal to the
-     * {@link Label#inputStackTop beginStackSize} of the current basic block
-     * plus <tt>stackSize</tt>.
-     */
-    private int stackSize;
-
-    /**
-     * The (relative) maximum stack size after the last visited instruction.
-     * This size is relative to the beginning of the current basic block, i.e.,
-     * the true maximum stack size after the last visited instruction is equal
-     * to the {@link Label#inputStackTop beginStackSize} of the current basic
-     * block plus <tt>stackSize</tt>.
-     */
-    private int maxStackSize;
-
-    // ------------------------------------------------------------------------
-    // Constructor
-    // ------------------------------------------------------------------------
-
-    /**
-     * Constructs a new {@link MethodWriter}.
-     *
-     * @param cw
-     *            the class writer in which the method must be added.
-     * @param access
-     *            the method's access flags (see {@link Opcodes}).
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type}).
-     * @param signature
-     *            the method's signature. May be <tt>null</tt>.
-     * @param exceptions
-     *            the internal names of the method's exceptions. May be
-     *            <tt>null</tt>.
-     * @param computeMaxs
-     *            <tt>true</tt> if the maximum stack size and number of local
-     *            variables must be automatically computed.
-     * @param computeFrames
-     *            <tt>true</tt> if the stack map tables must be recomputed from
-     *            scratch.
-     */
-    MethodWriter(final ClassWriter cw, final int access, final String name,
-            final String desc, final String signature,
-            final String[] exceptions, final boolean computeMaxs,
-            final boolean computeFrames) {
-        super(Opcodes.ASM4);
-        if (cw.firstMethod == null) {
-            cw.firstMethod = this;
-        } else {
-            cw.lastMethod.mv = this;
-        }
-        cw.lastMethod = this;
-        this.cw = cw;
-        this.access = access;
-        if ("<init>".equals(name)) {
-            this.access |= ACC_CONSTRUCTOR;
-        }
-        this.name = cw.newUTF8(name);
-        this.desc = cw.newUTF8(desc);
-        this.descriptor = desc;
-        if (ClassReader.SIGNATURES) {
-            this.signature = signature;
-        }
-        if (exceptions != null && exceptions.length > 0) {
-            exceptionCount = exceptions.length;
-            this.exceptions = new int[exceptionCount];
-            for (int i = 0; i < exceptionCount; ++i) {
-                this.exceptions[i] = cw.newClass(exceptions[i]);
-            }
-        }
-        this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
-        if (computeMaxs || computeFrames) {
-            // updates maxLocals
-            int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
-            if ((access & Opcodes.ACC_STATIC) != 0) {
-                --size;
-            }
-            maxLocals = size;
-            currentLocals = size;
-            // creates and visits the label for the first basic block
-            labels = new Label();
-            labels.status |= Label.PUSHED;
-            visitLabel(labels);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Implementation of the MethodVisitor abstract class
-    // ------------------------------------------------------------------------
-
-    @Override
-    public AnnotationVisitor visitAnnotationDefault() {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
-        annd = new ByteVector();
-        return new AnnotationWriter(cw, false, annd, null, 0);
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(final String desc,
-            final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
-        ByteVector bv = new ByteVector();
-        // write type, and reserve space for values count
-        bv.putShort(cw.newUTF8(desc)).putShort(0);
-        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
-        if (visible) {
-            aw.next = anns;
-            anns = aw;
-        } else {
-            aw.next = ianns;
-            ianns = aw;
-        }
-        return aw;
-    }
-
-    @Override
-    public AnnotationVisitor visitParameterAnnotation(final int parameter,
-            final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
-        ByteVector bv = new ByteVector();
-        if ("Ljava/lang/Synthetic;".equals(desc)) {
-            // workaround for a bug in javac with synthetic parameters
-            // see ClassReader.readParameterAnnotations
-            synthetics = Math.max(synthetics, parameter + 1);
-            return new AnnotationWriter(cw, false, bv, null, 0);
-        }
-        // write type, and reserve space for values count
-        bv.putShort(cw.newUTF8(desc)).putShort(0);
-        AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
-        if (visible) {
-            if (panns == null) {
-                panns = new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
-            }
-            aw.next = panns[parameter];
-            panns[parameter] = aw;
-        } else {
-            if (ipanns == null) {
-                ipanns = new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
-            }
-            aw.next = ipanns[parameter];
-            ipanns[parameter] = aw;
-        }
-        return aw;
-    }
-
-    @Override
-    public void visitAttribute(final Attribute attr) {
-        if (attr.isCodeAttribute()) {
-            attr.next = cattrs;
-            cattrs = attr;
-        } else {
-            attr.next = attrs;
-            attrs = attr;
-        }
-    }
-
-    @Override
-    public void visitCode() {
-    }
-
-    @Override
-    public void visitFrame(final int type, final int nLocal,
-            final Object[] local, final int nStack, final Object[] stack) {
-        if (!ClassReader.FRAMES || compute == FRAMES) {
-            return;
-        }
-
-        if (type == Opcodes.F_NEW) {
-            if (previousFrame == null) {
-                visitImplicitFirstFrame();
-            }
-            currentLocals = nLocal;
-            int frameIndex = startFrame(code.length, nLocal, nStack);
-            for (int i = 0; i < nLocal; ++i) {
-                if (local[i] instanceof String) {
-                    frame[frameIndex++] = Frame.OBJECT
-                            | cw.addType((String) local[i]);
-                } else if (local[i] instanceof Integer) {
-                    frame[frameIndex++] = ((Integer) local[i]).intValue();
-                } else {
-                    frame[frameIndex++] = Frame.UNINITIALIZED
-                            | cw.addUninitializedType("",
-                                    ((Label) local[i]).position);
-                }
-            }
-            for (int i = 0; i < nStack; ++i) {
-                if (stack[i] instanceof String) {
-                    frame[frameIndex++] = Frame.OBJECT
-                            | cw.addType((String) stack[i]);
-                } else if (stack[i] instanceof Integer) {
-                    frame[frameIndex++] = ((Integer) stack[i]).intValue();
-                } else {
-                    frame[frameIndex++] = Frame.UNINITIALIZED
-                            | cw.addUninitializedType("",
-                                    ((Label) stack[i]).position);
-                }
-            }
-            endFrame();
-        } else {
-            int delta;
-            if (stackMap == null) {
-                stackMap = new ByteVector();
-                delta = code.length;
-            } else {
-                delta = code.length - previousFrameOffset - 1;
-                if (delta < 0) {
-                    if (type == Opcodes.F_SAME) {
-                        return;
-                    } else {
-                        throw new IllegalStateException();
-                    }
-                }
-            }
-
-            switch (type) {
-            case Opcodes.F_FULL:
-                currentLocals = nLocal;
-                stackMap.putByte(FULL_FRAME).putShort(delta).putShort(nLocal);
-                for (int i = 0; i < nLocal; ++i) {
-                    writeFrameType(local[i]);
-                }
-                stackMap.putShort(nStack);
-                for (int i = 0; i < nStack; ++i) {
-                    writeFrameType(stack[i]);
-                }
-                break;
-            case Opcodes.F_APPEND:
-                currentLocals += nLocal;
-                stackMap.putByte(SAME_FRAME_EXTENDED + nLocal).putShort(delta);
-                for (int i = 0; i < nLocal; ++i) {
-                    writeFrameType(local[i]);
-                }
-                break;
-            case Opcodes.F_CHOP:
-                currentLocals -= nLocal;
-                stackMap.putByte(SAME_FRAME_EXTENDED - nLocal).putShort(delta);
-                break;
-            case Opcodes.F_SAME:
-                if (delta < 64) {
-                    stackMap.putByte(delta);
-                } else {
-                    stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
-                }
-                break;
-            case Opcodes.F_SAME1:
-                if (delta < 64) {
-                    stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
-                } else {
-                    stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
-                            .putShort(delta);
-                }
-                writeFrameType(stack[0]);
-                break;
-            }
-
-            previousFrameOffset = code.length;
-            ++frameCount;
-        }
-
-        maxStack = Math.max(maxStack, nStack);
-        maxLocals = Math.max(maxLocals, currentLocals);
-    }
-
-    @Override
-    public void visitInsn(final int opcode) {
-        // adds the instruction to the bytecode of the method
-        code.putByte(opcode);
-        // update currentBlock
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(opcode, 0, null, null);
-            } else {
-                // updates current and max stack sizes
-                int size = stackSize + Frame.SIZE[opcode];
-                if (size > maxStackSize) {
-                    maxStackSize = size;
-                }
-                stackSize = size;
-            }
-            // if opcode == ATHROW or xRETURN, ends current block (no successor)
-            if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
-                    || opcode == Opcodes.ATHROW) {
-                noSuccessor();
-            }
-        }
-    }
-
-    @Override
-    public void visitIntInsn(final int opcode, final int operand) {
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(opcode, operand, null, null);
-            } else if (opcode != Opcodes.NEWARRAY) {
-                // updates current and max stack sizes only for NEWARRAY
-                // (stack size variation = 0 for BIPUSH or SIPUSH)
-                int size = stackSize + 1;
-                if (size > maxStackSize) {
-                    maxStackSize = size;
-                }
-                stackSize = size;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        if (opcode == Opcodes.SIPUSH) {
-            code.put12(opcode, operand);
-        } else { // BIPUSH or NEWARRAY
-            code.put11(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(final int opcode, final int var) {
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(opcode, var, null, null);
-            } else {
-                // updates current and max stack sizes
-                if (opcode == Opcodes.RET) {
-                    // no stack change, but end of current block (no successor)
-                    currentBlock.status |= Label.RET;
-                    // save 'stackSize' here for future use
-                    // (see {@link #findSubroutineSuccessors})
-                    currentBlock.inputStackTop = stackSize;
-                    noSuccessor();
-                } else { // xLOAD or xSTORE
-                    int size = stackSize + Frame.SIZE[opcode];
-                    if (size > maxStackSize) {
-                        maxStackSize = size;
-                    }
-                    stackSize = size;
-                }
-            }
-        }
-        if (compute != NOTHING) {
-            // updates max locals
-            int n;
-            if (opcode == Opcodes.LLOAD || opcode == Opcodes.DLOAD
-                    || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE) {
-                n = var + 2;
-            } else {
-                n = var + 1;
-            }
-            if (n > maxLocals) {
-                maxLocals = n;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        if (var < 4 && opcode != Opcodes.RET) {
-            int opt;
-            if (opcode < Opcodes.ISTORE) {
-                /* ILOAD_0 */
-                opt = 26 + ((opcode - Opcodes.ILOAD) << 2) + var;
-            } else {
-                /* ISTORE_0 */
-                opt = 59 + ((opcode - Opcodes.ISTORE) << 2) + var;
-            }
-            code.putByte(opt);
-        } else if (var >= 256) {
-            code.putByte(196 /* WIDE */).put12(opcode, var);
-        } else {
-            code.put11(opcode, var);
-        }
-        if (opcode >= Opcodes.ISTORE && compute == FRAMES && handlerCount > 0) {
-            visitLabel(new Label());
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(final int opcode, final String type) {
-        Item i = cw.newClassItem(type);
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(opcode, code.length, cw, i);
-            } else if (opcode == Opcodes.NEW) {
-                // updates current and max stack sizes only if opcode == NEW
-                // (no stack change for ANEWARRAY, CHECKCAST, INSTANCEOF)
-                int size = stackSize + 1;
-                if (size > maxStackSize) {
-                    maxStackSize = size;
-                }
-                stackSize = size;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        code.put12(opcode, i.index);
-    }
-
-    @Override
-    public void visitFieldInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        Item i = cw.newFieldItem(owner, name, desc);
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(opcode, 0, cw, i);
-            } else {
-                int size;
-                // computes the stack size variation
-                char c = desc.charAt(0);
-                switch (opcode) {
-                case Opcodes.GETSTATIC:
-                    size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
-                    break;
-                case Opcodes.PUTSTATIC:
-                    size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
-                    break;
-                case Opcodes.GETFIELD:
-                    size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
-                    break;
-                // case Constants.PUTFIELD:
-                default:
-                    size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
-                    break;
-                }
-                // updates current and max stack sizes
-                if (size > maxStackSize) {
-                    maxStackSize = size;
-                }
-                stackSize = size;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        code.put12(opcode, i.index);
-    }
-
-    @Override
-    public void visitMethodInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        boolean itf = opcode == Opcodes.INVOKEINTERFACE;
-        Item i = cw.newMethodItem(owner, name, desc, itf);
-        int argSize = i.intVal;
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(opcode, 0, cw, i);
-            } else {
-                /*
-                 * computes the stack size variation. In order not to recompute
-                 * several times this variation for the same Item, we use the
-                 * intVal field of this item to store this variation, once it
-                 * has been computed. More precisely this intVal field stores
-                 * the sizes of the arguments and of the return value
-                 * corresponding to desc.
-                 */
-                if (argSize == 0) {
-                    // the above sizes have not been computed yet,
-                    // so we compute them...
-                    argSize = Type.getArgumentsAndReturnSizes(desc);
-                    // ... and we save them in order
-                    // not to recompute them in the future
-                    i.intVal = argSize;
-                }
-                int size;
-                if (opcode == Opcodes.INVOKESTATIC) {
-                    size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1;
-                } else {
-                    size = stackSize - (argSize >> 2) + (argSize & 0x03);
-                }
-                // updates current and max stack sizes
-                if (size > maxStackSize) {
-                    maxStackSize = size;
-                }
-                stackSize = size;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        if (itf) {
-            if (argSize == 0) {
-                argSize = Type.getArgumentsAndReturnSizes(desc);
-                i.intVal = argSize;
-            }
-            code.put12(Opcodes.INVOKEINTERFACE, i.index).put11(argSize >> 2, 0);
-        } else {
-            code.put12(opcode, i.index);
-        }
-    }
-
-    @Override
-    public void visitInvokeDynamicInsn(final String name, final String desc,
-            final Handle bsm, final Object... bsmArgs) {
-        Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
-        int argSize = i.intVal;
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
-            } else {
-                /*
-                 * computes the stack size variation. In order not to recompute
-                 * several times this variation for the same Item, we use the
-                 * intVal field of this item to store this variation, once it
-                 * has been computed. More precisely this intVal field stores
-                 * the sizes of the arguments and of the return value
-                 * corresponding to desc.
-                 */
-                if (argSize == 0) {
-                    // the above sizes have not been computed yet,
-                    // so we compute them...
-                    argSize = Type.getArgumentsAndReturnSizes(desc);
-                    // ... and we save them in order
-                    // not to recompute them in the future
-                    i.intVal = argSize;
-                }
-                int size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1;
-
-                // updates current and max stack sizes
-                if (size > maxStackSize) {
-                    maxStackSize = size;
-                }
-                stackSize = size;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        code.put12(Opcodes.INVOKEDYNAMIC, i.index);
-        code.putShort(0);
-    }
-
-    @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
-        Label nextInsn = null;
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(opcode, 0, null, null);
-                // 'label' is the target of a jump instruction
-                label.getFirst().status |= Label.TARGET;
-                // adds 'label' as a successor of this basic block
-                addSuccessor(Edge.NORMAL, label);
-                if (opcode != Opcodes.GOTO) {
-                    // creates a Label for the next basic block
-                    nextInsn = new Label();
-                }
-            } else {
-                if (opcode == Opcodes.JSR) {
-                    if ((label.status & Label.SUBROUTINE) == 0) {
-                        label.status |= Label.SUBROUTINE;
-                        ++subroutines;
-                    }
-                    currentBlock.status |= Label.JSR;
-                    addSuccessor(stackSize + 1, label);
-                    // creates a Label for the next basic block
-                    nextInsn = new Label();
-                    /*
-                     * note that, by construction in this method, a JSR block
-                     * has at least two successors in the control flow graph:
-                     * the first one leads the next instruction after the JSR,
-                     * while the second one leads to the JSR target.
-                     */
-                } else {
-                    // updates current stack size (max stack size unchanged
-                    // because stack size variation always negative in this
-                    // case)
-                    stackSize += Frame.SIZE[opcode];
-                    addSuccessor(stackSize, label);
-                }
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        if ((label.status & Label.RESOLVED) != 0
-                && label.position - code.length < Short.MIN_VALUE) {
-            /*
-             * case of a backward jump with an offset < -32768. In this case we
-             * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
-             * <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the
-             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <l'>
-             * designates the instruction just after the GOTO_W.
-             */
-            if (opcode == Opcodes.GOTO) {
-                code.putByte(200); // GOTO_W
-            } else if (opcode == Opcodes.JSR) {
-                code.putByte(201); // JSR_W
-            } else {
-                // if the IF instruction is transformed into IFNOT GOTO_W the
-                // next instruction becomes the target of the IFNOT instruction
-                if (nextInsn != null) {
-                    nextInsn.status |= Label.TARGET;
-                }
-                code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
-                        : opcode ^ 1);
-                code.putShort(8); // jump offset
-                code.putByte(200); // GOTO_W
-            }
-            label.put(this, code, code.length - 1, true);
-        } else {
-            /*
-             * case of a backward jump with an offset >= -32768, or of a forward
-             * jump with, of course, an unknown offset. In these cases we store
-             * the offset in 2 bytes (which will be increased in
-             * resizeInstructions, if needed).
-             */
-            code.putByte(opcode);
-            label.put(this, code, code.length - 1, false);
-        }
-        if (currentBlock != null) {
-            if (nextInsn != null) {
-                // if the jump instruction is not a GOTO, the next instruction
-                // is also a successor of this instruction. Calling visitLabel
-                // adds the label of this next instruction as a successor of the
-                // current block, and starts a new basic block
-                visitLabel(nextInsn);
-            }
-            if (opcode == Opcodes.GOTO) {
-                noSuccessor();
-            }
-        }
-    }
-
-    @Override
-    public void visitLabel(final Label label) {
-        // resolves previous forward references to label, if any
-        resize |= label.resolve(this, code.length, code.data);
-        // updates currentBlock
-        if ((label.status & Label.DEBUG) != 0) {
-            return;
-        }
-        if (compute == FRAMES) {
-            if (currentBlock != null) {
-                if (label.position == currentBlock.position) {
-                    // successive labels, do not start a new basic block
-                    currentBlock.status |= (label.status & Label.TARGET);
-                    label.frame = currentBlock.frame;
-                    return;
-                }
-                // ends current block (with one new successor)
-                addSuccessor(Edge.NORMAL, label);
-            }
-            // begins a new current block
-            currentBlock = label;
-            if (label.frame == null) {
-                label.frame = new Frame();
-                label.frame.owner = label;
-            }
-            // updates the basic block list
-            if (previousBlock != null) {
-                if (label.position == previousBlock.position) {
-                    previousBlock.status |= (label.status & Label.TARGET);
-                    label.frame = previousBlock.frame;
-                    currentBlock = previousBlock;
-                    return;
-                }
-                previousBlock.successor = label;
-            }
-            previousBlock = label;
-        } else if (compute == MAXS) {
-            if (currentBlock != null) {
-                // ends current block (with one new successor)
-                currentBlock.outputStackMax = maxStackSize;
-                addSuccessor(stackSize, label);
-            }
-            // begins a new current block
-            currentBlock = label;
-            // resets the relative current and max stack sizes
-            stackSize = 0;
-            maxStackSize = 0;
-            // updates the basic block list
-            if (previousBlock != null) {
-                previousBlock.successor = label;
-            }
-            previousBlock = label;
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(final Object cst) {
-        Item i = cw.newConstItem(cst);
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(Opcodes.LDC, 0, cw, i);
-            } else {
-                int size;
-                // computes the stack size variation
-                if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
-                    size = stackSize + 2;
-                } else {
-                    size = stackSize + 1;
-                }
-                // updates current and max stack sizes
-                if (size > maxStackSize) {
-                    maxStackSize = size;
-                }
-                stackSize = size;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        int index = i.index;
-        if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
-            code.put12(20 /* LDC2_W */, index);
-        } else if (index >= 256) {
-            code.put12(19 /* LDC_W */, index);
-        } else {
-            code.put11(Opcodes.LDC, index);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(final int var, final int increment) {
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(Opcodes.IINC, var, null, null);
-            }
-        }
-        if (compute != NOTHING) {
-            // updates max locals
-            int n = var + 1;
-            if (n > maxLocals) {
-                maxLocals = n;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        if ((var > 255) || (increment > 127) || (increment < -128)) {
-            code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var)
-                    .putShort(increment);
-        } else {
-            code.putByte(Opcodes.IINC).put11(var, increment);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(final int min, final int max,
-            final Label dflt, final Label... labels) {
-        // adds the instruction to the bytecode of the method
-        int source = code.length;
-        code.putByte(Opcodes.TABLESWITCH);
-        code.putByteArray(null, 0, (4 - code.length % 4) % 4);
-        dflt.put(this, code, source, true);
-        code.putInt(min).putInt(max);
-        for (int i = 0; i < labels.length; ++i) {
-            labels[i].put(this, code, source, true);
-        }
-        // updates currentBlock
-        visitSwitchInsn(dflt, labels);
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
-            final Label[] labels) {
-        // adds the instruction to the bytecode of the method
-        int source = code.length;
-        code.putByte(Opcodes.LOOKUPSWITCH);
-        code.putByteArray(null, 0, (4 - code.length % 4) % 4);
-        dflt.put(this, code, source, true);
-        code.putInt(labels.length);
-        for (int i = 0; i < labels.length; ++i) {
-            code.putInt(keys[i]);
-            labels[i].put(this, code, source, true);
-        }
-        // updates currentBlock
-        visitSwitchInsn(dflt, labels);
-    }
-
-    private void visitSwitchInsn(final Label dflt, final Label[] labels) {
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(Opcodes.LOOKUPSWITCH, 0, null, null);
-                // adds current block successors
-                addSuccessor(Edge.NORMAL, dflt);
-                dflt.getFirst().status |= Label.TARGET;
-                for (int i = 0; i < labels.length; ++i) {
-                    addSuccessor(Edge.NORMAL, labels[i]);
-                    labels[i].getFirst().status |= Label.TARGET;
-                }
-            } else {
-                // updates current stack size (max stack size unchanged)
-                --stackSize;
-                // adds current block successors
-                addSuccessor(stackSize, dflt);
-                for (int i = 0; i < labels.length; ++i) {
-                    addSuccessor(stackSize, labels[i]);
-                }
-            }
-            // ends current block
-            noSuccessor();
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
-        Item i = cw.newClassItem(desc);
-        // Label currentBlock = this.currentBlock;
-        if (currentBlock != null) {
-            if (compute == FRAMES) {
-                currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i);
-            } else {
-                // updates current stack size (max stack size unchanged because
-                // stack size variation always negative or null)
-                stackSize += 1 - dims;
-            }
-        }
-        // adds the instruction to the bytecode of the method
-        code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims);
-    }
-
-    @Override
-    public void visitTryCatchBlock(final Label start, final Label end,
-            final Label handler, final String type) {
-        ++handlerCount;
-        Handler h = new Handler();
-        h.start = start;
-        h.end = end;
-        h.handler = handler;
-        h.desc = type;
-        h.type = type != null ? cw.newClass(type) : 0;
-        if (lastHandler == null) {
-            firstHandler = h;
-        } else {
-            lastHandler.next = h;
-        }
-        lastHandler = h;
-    }
-
-    @Override
-    public void visitLocalVariable(final String name, final String desc,
-            final String signature, final Label start, final Label end,
-            final int index) {
-        if (signature != null) {
-            if (localVarType == null) {
-                localVarType = new ByteVector();
-            }
-            ++localVarTypeCount;
-            localVarType.putShort(start.position)
-                    .putShort(end.position - start.position)
-                    .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(signature))
-                    .putShort(index);
-        }
-        if (localVar == null) {
-            localVar = new ByteVector();
-        }
-        ++localVarCount;
-        localVar.putShort(start.position)
-                .putShort(end.position - start.position)
-                .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(desc))
-                .putShort(index);
-        if (compute != NOTHING) {
-            // updates max locals
-            char c = desc.charAt(0);
-            int n = index + (c == 'J' || c == 'D' ? 2 : 1);
-            if (n > maxLocals) {
-                maxLocals = n;
-            }
-        }
-    }
-
-    @Override
-    public void visitLineNumber(final int line, final Label start) {
-        if (lineNumber == null) {
-            lineNumber = new ByteVector();
-        }
-        ++lineNumberCount;
-        lineNumber.putShort(start.position);
-        lineNumber.putShort(line);
-    }
-
-    @Override
-    public void visitMaxs(final int maxStack, final int maxLocals) {
-        if (ClassReader.FRAMES && compute == FRAMES) {
-            // completes the control flow graph with exception handler blocks
-            Handler handler = firstHandler;
-            while (handler != null) {
-                Label l = handler.start.getFirst();
-                Label h = handler.handler.getFirst();
-                Label e = handler.end.getFirst();
-                // computes the kind of the edges to 'h'
-                String t = handler.desc == null ? "java/lang/Throwable"
-                        : handler.desc;
-                int kind = Frame.OBJECT | cw.addType(t);
-                // h is an exception handler
-                h.status |= Label.TARGET;
-                // adds 'h' as a successor of labels between 'start' and 'end'
-                while (l != e) {
-                    // creates an edge to 'h'
-                    Edge b = new Edge();
-                    b.info = kind;
-                    b.successor = h;
-                    // adds it to the successors of 'l'
-                    b.next = l.successors;
-                    l.successors = b;
-                    // goes to the next label
-                    l = l.successor;
-                }
-                handler = handler.next;
-            }
-
-            // creates and visits the first (implicit) frame
-            Frame f = labels.frame;
-            Type[] args = Type.getArgumentTypes(descriptor);
-            f.initInputFrame(cw, access, args, this.maxLocals);
-            visitFrame(f);
-
-            /*
-             * fix point algorithm: mark the first basic block as 'changed'
-             * (i.e. put it in the 'changed' list) and, while there are changed
-             * basic blocks, choose one, mark it as unchanged, and update its
-             * successors (which can be changed in the process).
-             */
-            int max = 0;
-            Label changed = labels;
-            while (changed != null) {
-                // removes a basic block from the list of changed basic blocks
-                Label l = changed;
-                changed = changed.next;
-                l.next = null;
-                f = l.frame;
-                // a reachable jump target must be stored in the stack map
-                if ((l.status & Label.TARGET) != 0) {
-                    l.status |= Label.STORE;
-                }
-                // all visited labels are reachable, by definition
-                l.status |= Label.REACHABLE;
-                // updates the (absolute) maximum stack size
-                int blockMax = f.inputStack.length + l.outputStackMax;
-                if (blockMax > max) {
-                    max = blockMax;
-                }
-                // updates the successors of the current basic block
-                Edge e = l.successors;
-                while (e != null) {
-                    Label n = e.successor.getFirst();
-                    boolean change = f.merge(cw, n.frame, e.info);
-                    if (change && n.next == null) {
-                        // if n has changed and is not already in the 'changed'
-                        // list, adds it to this list
-                        n.next = changed;
-                        changed = n;
-                    }
-                    e = e.next;
-                }
-            }
-
-            // visits all the frames that must be stored in the stack map
-            Label l = labels;
-            while (l != null) {
-                f = l.frame;
-                if ((l.status & Label.STORE) != 0) {
-                    visitFrame(f);
-                }
-                if ((l.status & Label.REACHABLE) == 0) {
-                    // finds start and end of dead basic block
-                    Label k = l.successor;
-                    int start = l.position;
-                    int end = (k == null ? code.length : k.position) - 1;
-                    // if non empty basic block
-                    if (end >= start) {
-                        max = Math.max(max, 1);
-                        // replaces instructions with NOP ... NOP ATHROW
-                        for (int i = start; i < end; ++i) {
-                            code.data[i] = Opcodes.NOP;
-                        }
-                        code.data[end] = (byte) Opcodes.ATHROW;
-                        // emits a frame for this unreachable block
-                        int frameIndex = startFrame(start, 0, 1);
-                        frame[frameIndex] = Frame.OBJECT
-                                | cw.addType("java/lang/Throwable");
-                        endFrame();
-                        // removes the start-end range from the exception
-                        // handlers
-                        firstHandler = Handler.remove(firstHandler, l, k);
-                    }
-                }
-                l = l.successor;
-            }
-
-            handler = firstHandler;
-            handlerCount = 0;
-            while (handler != null) {
-                handlerCount += 1;
-                handler = handler.next;
-            }
-
-            this.maxStack = max;
-        } else if (compute == MAXS) {
-            // completes the control flow graph with exception handler blocks
-            Handler handler = firstHandler;
-            while (handler != null) {
-                Label l = handler.start;
-                Label h = handler.handler;
-                Label e = handler.end;
-                // adds 'h' as a successor of labels between 'start' and 'end'
-                while (l != e) {
-                    // creates an edge to 'h'
-                    Edge b = new Edge();
-                    b.info = Edge.EXCEPTION;
-                    b.successor = h;
-                    // adds it to the successors of 'l'
-                    if ((l.status & Label.JSR) == 0) {
-                        b.next = l.successors;
-                        l.successors = b;
-                    } else {
-                        // if l is a JSR block, adds b after the first two edges
-                        // to preserve the hypothesis about JSR block successors
-                        // order (see {@link #visitJumpInsn})
-                        b.next = l.successors.next.next;
-                        l.successors.next.next = b;
-                    }
-                    // goes to the next label
-                    l = l.successor;
-                }
-                handler = handler.next;
-            }
-
-            if (subroutines > 0) {
-                // completes the control flow graph with the RET successors
-                /*
-                 * first step: finds the subroutines. This step determines, for
-                 * each basic block, to which subroutine(s) it belongs.
-                 */
-                // finds the basic blocks that belong to the "main" subroutine
-                int id = 0;
-                labels.visitSubroutine(null, 1, subroutines);
-                // finds the basic blocks that belong to the real subroutines
-                Label l = labels;
-                while (l != null) {
-                    if ((l.status & Label.JSR) != 0) {
-                        // the subroutine is defined by l's TARGET, not by l
-                        Label subroutine = l.successors.next.successor;
-                        // if this subroutine has not been visited yet...
-                        if ((subroutine.status & Label.VISITED) == 0) {
-                            // ...assigns it a new id and finds its basic blocks
-                            id += 1;
-                            subroutine.visitSubroutine(null, (id / 32L) << 32
-                                    | (1L << (id % 32)), subroutines);
-                        }
-                    }
-                    l = l.successor;
-                }
-                // second step: finds the successors of RET blocks
-                l = labels;
-                while (l != null) {
-                    if ((l.status & Label.JSR) != 0) {
-                        Label L = labels;
-                        while (L != null) {
-                            L.status &= ~Label.VISITED2;
-                            L = L.successor;
-                        }
-                        // the subroutine is defined by l's TARGET, not by l
-                        Label subroutine = l.successors.next.successor;
-                        subroutine.visitSubroutine(l, 0, subroutines);
-                    }
-                    l = l.successor;
-                }
-            }
-
-            /*
-             * control flow analysis algorithm: while the block stack is not
-             * empty, pop a block from this stack, update the max stack size,
-             * compute the true (non relative) begin stack size of the
-             * successors of this block, and push these successors onto the
-             * stack (unless they have already been pushed onto the stack).
-             * Note: by hypothesis, the {@link Label#inputStackTop} of the
-             * blocks in the block stack are the true (non relative) beginning
-             * stack sizes of these blocks.
-             */
-            int max = 0;
-            Label stack = labels;
-            while (stack != null) {
-                // pops a block from the stack
-                Label l = stack;
-                stack = stack.next;
-                // computes the true (non relative) max stack size of this block
-                int start = l.inputStackTop;
-                int blockMax = start + l.outputStackMax;
-                // updates the global max stack size
-                if (blockMax > max) {
-                    max = blockMax;
-                }
-                // analyzes the successors of the block
-                Edge b = l.successors;
-                if ((l.status & Label.JSR) != 0) {
-                    // ignores the first edge of JSR blocks (virtual successor)
-                    b = b.next;
-                }
-                while (b != null) {
-                    l = b.successor;
-                    // if this successor has not already been pushed...
-                    if ((l.status & Label.PUSHED) == 0) {
-                        // computes its true beginning stack size...
-                        l.inputStackTop = b.info == Edge.EXCEPTION ? 1 : start
-                                + b.info;
-                        // ...and pushes it onto the stack
-                        l.status |= Label.PUSHED;
-                        l.next = stack;
-                        stack = l;
-                    }
-                    b = b.next;
-                }
-            }
-            this.maxStack = Math.max(maxStack, max);
-        } else {
-            this.maxStack = maxStack;
-            this.maxLocals = maxLocals;
-        }
-    }
-
-    @Override
-    public void visitEnd() {
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: control flow analysis algorithm
-    // ------------------------------------------------------------------------
-
-    /**
-     * Adds a successor to the {@link #currentBlock currentBlock} block.
-     *
-     * @param info
-     *            information about the control flow edge to be added.
-     * @param successor
-     *            the successor block to be added to the current block.
-     */
-    private void addSuccessor(final int info, final Label successor) {
-        // creates and initializes an Edge object...
-        Edge b = new Edge();
-        b.info = info;
-        b.successor = successor;
-        // ...and adds it to the successor list of the currentBlock block
-        b.next = currentBlock.successors;
-        currentBlock.successors = b;
-    }
-
-    /**
-     * Ends the current basic block. This method must be used in the case where
-     * the current basic block does not have any successor.
-     */
-    private void noSuccessor() {
-        if (compute == FRAMES) {
-            Label l = new Label();
-            l.frame = new Frame();
-            l.frame.owner = l;
-            l.resolve(this, code.length, code.data);
-            previousBlock.successor = l;
-            previousBlock = l;
-        } else {
-            currentBlock.outputStackMax = maxStackSize;
-        }
-        currentBlock = null;
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: stack map frames
-    // ------------------------------------------------------------------------
-
-    /**
-     * Visits a frame that has been computed from scratch.
-     *
-     * @param f
-     *            the frame that must be visited.
-     */
-    private void visitFrame(final Frame f) {
-        int i, t;
-        int nTop = 0;
-        int nLocal = 0;
-        int nStack = 0;
-        int[] locals = f.inputLocals;
-        int[] stacks = f.inputStack;
-        // computes the number of locals (ignores TOP types that are just after
-        // a LONG or a DOUBLE, and all trailing TOP types)
-        for (i = 0; i < locals.length; ++i) {
-            t = locals[i];
-            if (t == Frame.TOP) {
-                ++nTop;
-            } else {
-                nLocal += nTop + 1;
-                nTop = 0;
-            }
-            if (t == Frame.LONG || t == Frame.DOUBLE) {
-                ++i;
-            }
-        }
-        // computes the stack size (ignores TOP types that are just after
-        // a LONG or a DOUBLE)
-        for (i = 0; i < stacks.length; ++i) {
-            t = stacks[i];
-            ++nStack;
-            if (t == Frame.LONG || t == Frame.DOUBLE) {
-                ++i;
-            }
-        }
-        // visits the frame and its content
-        int frameIndex = startFrame(f.owner.position, nLocal, nStack);
-        for (i = 0; nLocal > 0; ++i, --nLocal) {
-            t = locals[i];
-            frame[frameIndex++] = t;
-            if (t == Frame.LONG || t == Frame.DOUBLE) {
-                ++i;
-            }
-        }
-        for (i = 0; i < stacks.length; ++i) {
-            t = stacks[i];
-            frame[frameIndex++] = t;
-            if (t == Frame.LONG || t == Frame.DOUBLE) {
-                ++i;
-            }
-        }
-        endFrame();
-    }
-
-    /**
-     * Visit the implicit first frame of this method.
-     */
-    private void visitImplicitFirstFrame() {
-        // There can be at most descriptor.length() + 1 locals
-        int frameIndex = startFrame(0, descriptor.length() + 1, 0);
-        if ((access & Opcodes.ACC_STATIC) == 0) {
-            if ((access & ACC_CONSTRUCTOR) == 0) {
-                frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
-            } else {
-                frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
-            }
-        }
-        int i = 1;
-        loop: while (true) {
-            int j = i;
-            switch (descriptor.charAt(i++)) {
-            case 'Z':
-            case 'C':
-            case 'B':
-            case 'S':
-            case 'I':
-                frame[frameIndex++] = 1; // Opcodes.INTEGER;
-                break;
-            case 'F':
-                frame[frameIndex++] = 2; // Opcodes.FLOAT;
-                break;
-            case 'J':
-                frame[frameIndex++] = 4; // Opcodes.LONG;
-                break;
-            case 'D':
-                frame[frameIndex++] = 3; // Opcodes.DOUBLE;
-                break;
-            case '[':
-                while (descriptor.charAt(i) == '[') {
-                    ++i;
-                }
-                if (descriptor.charAt(i) == 'L') {
-                    ++i;
-                    while (descriptor.charAt(i) != ';') {
-                        ++i;
-                    }
-                }
-                frame[frameIndex++] = Frame.OBJECT
-                        | cw.addType(descriptor.substring(j, ++i));
-                break;
-            case 'L':
-                while (descriptor.charAt(i) != ';') {
-                    ++i;
-                }
-                frame[frameIndex++] = Frame.OBJECT
-                        | cw.addType(descriptor.substring(j + 1, i++));
-                break;
-            default:
-                break loop;
-            }
-        }
-        frame[1] = frameIndex - 3;
-        endFrame();
-    }
-
-    /**
-     * Starts the visit of a stack map frame.
-     *
-     * @param offset
-     *            the offset of the instruction to which the frame corresponds.
-     * @param nLocal
-     *            the number of local variables in the frame.
-     * @param nStack
-     *            the number of stack elements in the frame.
-     * @return the index of the next element to be written in this frame.
-     */
-    private int startFrame(final int offset, final int nLocal, final int nStack) {
-        int n = 3 + nLocal + nStack;
-        if (frame == null || frame.length < n) {
-            frame = new int[n];
-        }
-        frame[0] = offset;
-        frame[1] = nLocal;
-        frame[2] = nStack;
-        return 3;
-    }
-
-    /**
-     * Checks if the visit of the current frame {@link #frame} is finished, and
-     * if yes, write it in the StackMapTable attribute.
-     */
-    private void endFrame() {
-        if (previousFrame != null) { // do not write the first frame
-            if (stackMap == null) {
-                stackMap = new ByteVector();
-            }
-            writeFrame();
-            ++frameCount;
-        }
-        previousFrame = frame;
-        frame = null;
-    }
-
-    /**
-     * Compress and writes the current frame {@link #frame} in the StackMapTable
-     * attribute.
-     */
-    private void writeFrame() {
-        int clocalsSize = frame[1];
-        int cstackSize = frame[2];
-        if ((cw.version & 0xFFFF) < Opcodes.V1_6) {
-            stackMap.putShort(frame[0]).putShort(clocalsSize);
-            writeFrameTypes(3, 3 + clocalsSize);
-            stackMap.putShort(cstackSize);
-            writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
-            return;
-        }
-        int localsSize = previousFrame[1];
-        int type = FULL_FRAME;
-        int k = 0;
-        int delta;
-        if (frameCount == 0) {
-            delta = frame[0];
-        } else {
-            delta = frame[0] - previousFrame[0] - 1;
-        }
-        if (cstackSize == 0) {
-            k = clocalsSize - localsSize;
-            switch (k) {
-            case -3:
-            case -2:
-            case -1:
-                type = CHOP_FRAME;
-                localsSize = clocalsSize;
-                break;
-            case 0:
-                type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
-                break;
-            case 1:
-            case 2:
-            case 3:
-                type = APPEND_FRAME;
-                break;
-            }
-        } else if (clocalsSize == localsSize && cstackSize == 1) {
-            type = delta < 63 ? SAME_LOCALS_1_STACK_ITEM_FRAME
-                    : SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
-        }
-        if (type != FULL_FRAME) {
-            // verify if locals are the same
-            int l = 3;
-            for (int j = 0; j < localsSize; j++) {
-                if (frame[l] != previousFrame[l]) {
-                    type = FULL_FRAME;
-                    break;
-                }
-                l++;
-            }
-        }
-        switch (type) {
-        case SAME_FRAME:
-            stackMap.putByte(delta);
-            break;
-        case SAME_LOCALS_1_STACK_ITEM_FRAME:
-            stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
-            writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
-            break;
-        case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
-            stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED).putShort(
-                    delta);
-            writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
-            break;
-        case SAME_FRAME_EXTENDED:
-            stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
-            break;
-        case CHOP_FRAME:
-            stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
-            break;
-        case APPEND_FRAME:
-            stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
-            writeFrameTypes(3 + localsSize, 3 + clocalsSize);
-            break;
-        // case FULL_FRAME:
-        default:
-            stackMap.putByte(FULL_FRAME).putShort(delta).putShort(clocalsSize);
-            writeFrameTypes(3, 3 + clocalsSize);
-            stackMap.putShort(cstackSize);
-            writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
-        }
-    }
-
-    /**
-     * Writes some types of the current frame {@link #frame} into the
-     * StackMapTableAttribute. This method converts types from the format used
-     * in {@link Label} to the format used in StackMapTable attributes. In
-     * particular, it converts type table indexes to constant pool indexes.
-     *
-     * @param start
-     *            index of the first type in {@link #frame} to write.
-     * @param end
-     *            index of last type in {@link #frame} to write (exclusive).
-     */
-    private void writeFrameTypes(final int start, final int end) {
-        for (int i = start; i < end; ++i) {
-            int t = frame[i];
-            int d = t & Frame.DIM;
-            if (d == 0) {
-                int v = t & Frame.BASE_VALUE;
-                switch (t & Frame.BASE_KIND) {
-                case Frame.OBJECT:
-                    stackMap.putByte(7).putShort(
-                            cw.newClass(cw.typeTable[v].strVal1));
-                    break;
-                case Frame.UNINITIALIZED:
-                    stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
-                    break;
-                default:
-                    stackMap.putByte(v);
-                }
-            } else {
-                StringBuffer buf = new StringBuffer();
-                d >>= 28;
-                while (d-- > 0) {
-                    buf.append('[');
-                }
-                if ((t & Frame.BASE_KIND) == Frame.OBJECT) {
-                    buf.append('L');
-                    buf.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1);
-                    buf.append(';');
-                } else {
-                    switch (t & 0xF) {
-                    case 1:
-                        buf.append('I');
-                        break;
-                    case 2:
-                        buf.append('F');
-                        break;
-                    case 3:
-                        buf.append('D');
-                        break;
-                    case 9:
-                        buf.append('Z');
-                        break;
-                    case 10:
-                        buf.append('B');
-                        break;
-                    case 11:
-                        buf.append('C');
-                        break;
-                    case 12:
-                        buf.append('S');
-                        break;
-                    default:
-                        buf.append('J');
-                    }
-                }
-                stackMap.putByte(7).putShort(cw.newClass(buf.toString()));
-            }
-        }
-    }
-
-    private void writeFrameType(final Object type) {
-        if (type instanceof String) {
-            stackMap.putByte(7).putShort(cw.newClass((String) type));
-        } else if (type instanceof Integer) {
-            stackMap.putByte(((Integer) type).intValue());
-        } else {
-            stackMap.putByte(8).putShort(((Label) type).position);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: dump bytecode array
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the size of the bytecode of this method.
-     *
-     * @return the size of the bytecode of this method.
-     */
-    final int getSize() {
-        if (classReaderOffset != 0) {
-            return 6 + classReaderLength;
-        }
-        if (resize) {
-            // replaces the temporary jump opcodes introduced by Label.resolve.
-            if (ClassReader.RESIZE) {
-                resizeInstructions();
-            } else {
-                throw new RuntimeException("Method code too large!");
-            }
-        }
-        int size = 8;
-        if (code.length > 0) {
-            if (code.length > 65536) {
-                throw new RuntimeException("Method code too large!");
-            }
-            cw.newUTF8("Code");
-            size += 18 + code.length + 8 * handlerCount;
-            if (localVar != null) {
-                cw.newUTF8("LocalVariableTable");
-                size += 8 + localVar.length;
-            }
-            if (localVarType != null) {
-                cw.newUTF8("LocalVariableTypeTable");
-                size += 8 + localVarType.length;
-            }
-            if (lineNumber != null) {
-                cw.newUTF8("LineNumberTable");
-                size += 8 + lineNumber.length;
-            }
-            if (stackMap != null) {
-                boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6;
-                cw.newUTF8(zip ? "StackMapTable" : "StackMap");
-                size += 8 + stackMap.length;
-            }
-            if (cattrs != null) {
-                size += cattrs.getSize(cw, code.data, code.length, maxStack,
-                        maxLocals);
-            }
-        }
-        if (exceptionCount > 0) {
-            cw.newUTF8("Exceptions");
-            size += 8 + 2 * exceptionCount;
-        }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
-            if ((cw.version & 0xFFFF) < Opcodes.V1_5
-                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
-                cw.newUTF8("Synthetic");
-                size += 6;
-            }
-        }
-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
-            cw.newUTF8("Deprecated");
-            size += 6;
-        }
-        if (ClassReader.SIGNATURES && signature != null) {
-            cw.newUTF8("Signature");
-            cw.newUTF8(signature);
-            size += 8;
-        }
-        if (ClassReader.ANNOTATIONS && annd != null) {
-            cw.newUTF8("AnnotationDefault");
-            size += 6 + annd.length;
-        }
-        if (ClassReader.ANNOTATIONS && anns != null) {
-            cw.newUTF8("RuntimeVisibleAnnotations");
-            size += 8 + anns.getSize();
-        }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
-            cw.newUTF8("RuntimeInvisibleAnnotations");
-            size += 8 + ianns.getSize();
-        }
-        if (ClassReader.ANNOTATIONS && panns != null) {
-            cw.newUTF8("RuntimeVisibleParameterAnnotations");
-            size += 7 + 2 * (panns.length - synthetics);
-            for (int i = panns.length - 1; i >= synthetics; --i) {
-                size += panns[i] == null ? 0 : panns[i].getSize();
-            }
-        }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
-            cw.newUTF8("RuntimeInvisibleParameterAnnotations");
-            size += 7 + 2 * (ipanns.length - synthetics);
-            for (int i = ipanns.length - 1; i >= synthetics; --i) {
-                size += ipanns[i] == null ? 0 : ipanns[i].getSize();
-            }
-        }
-        if (attrs != null) {
-            size += attrs.getSize(cw, null, 0, -1, -1);
-        }
-        return size;
-    }
-
-    /**
-     * Puts the bytecode of this method in the given byte vector.
-     *
-     * @param out
-     *            the byte vector into which the bytecode of this method must be
-     *            copied.
-     */
-    final void put(final ByteVector out) {
-        final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
-        int mask = ACC_CONSTRUCTOR | Opcodes.ACC_DEPRECATED
-                | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
-                | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
-        out.putShort(access & ~mask).putShort(name).putShort(desc);
-        if (classReaderOffset != 0) {
-            out.putByteArray(cw.cr.b, classReaderOffset, classReaderLength);
-            return;
-        }
-        int attributeCount = 0;
-        if (code.length > 0) {
-            ++attributeCount;
-        }
-        if (exceptionCount > 0) {
-            ++attributeCount;
-        }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
-            if ((cw.version & 0xFFFF) < Opcodes.V1_5
-                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
-                ++attributeCount;
-            }
-        }
-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
-            ++attributeCount;
-        }
-        if (ClassReader.SIGNATURES && signature != null) {
-            ++attributeCount;
-        }
-        if (ClassReader.ANNOTATIONS && annd != null) {
-            ++attributeCount;
-        }
-        if (ClassReader.ANNOTATIONS && anns != null) {
-            ++attributeCount;
-        }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
-            ++attributeCount;
-        }
-        if (ClassReader.ANNOTATIONS && panns != null) {
-            ++attributeCount;
-        }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
-            ++attributeCount;
-        }
-        if (attrs != null) {
-            attributeCount += attrs.getCount();
-        }
-        out.putShort(attributeCount);
-        if (code.length > 0) {
-            int size = 12 + code.length + 8 * handlerCount;
-            if (localVar != null) {
-                size += 8 + localVar.length;
-            }
-            if (localVarType != null) {
-                size += 8 + localVarType.length;
-            }
-            if (lineNumber != null) {
-                size += 8 + lineNumber.length;
-            }
-            if (stackMap != null) {
-                size += 8 + stackMap.length;
-            }
-            if (cattrs != null) {
-                size += cattrs.getSize(cw, code.data, code.length, maxStack,
-                        maxLocals);
-            }
-            out.putShort(cw.newUTF8("Code")).putInt(size);
-            out.putShort(maxStack).putShort(maxLocals);
-            out.putInt(code.length).putByteArray(code.data, 0, code.length);
-            out.putShort(handlerCount);
-            if (handlerCount > 0) {
-                Handler h = firstHandler;
-                while (h != null) {
-                    out.putShort(h.start.position).putShort(h.end.position)
-                            .putShort(h.handler.position).putShort(h.type);
-                    h = h.next;
-                }
-            }
-            attributeCount = 0;
-            if (localVar != null) {
-                ++attributeCount;
-            }
-            if (localVarType != null) {
-                ++attributeCount;
-            }
-            if (lineNumber != null) {
-                ++attributeCount;
-            }
-            if (stackMap != null) {
-                ++attributeCount;
-            }
-            if (cattrs != null) {
-                attributeCount += cattrs.getCount();
-            }
-            out.putShort(attributeCount);
-            if (localVar != null) {
-                out.putShort(cw.newUTF8("LocalVariableTable"));
-                out.putInt(localVar.length + 2).putShort(localVarCount);
-                out.putByteArray(localVar.data, 0, localVar.length);
-            }
-            if (localVarType != null) {
-                out.putShort(cw.newUTF8("LocalVariableTypeTable"));
-                out.putInt(localVarType.length + 2).putShort(localVarTypeCount);
-                out.putByteArray(localVarType.data, 0, localVarType.length);
-            }
-            if (lineNumber != null) {
-                out.putShort(cw.newUTF8("LineNumberTable"));
-                out.putInt(lineNumber.length + 2).putShort(lineNumberCount);
-                out.putByteArray(lineNumber.data, 0, lineNumber.length);
-            }
-            if (stackMap != null) {
-                boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6;
-                out.putShort(cw.newUTF8(zip ? "StackMapTable" : "StackMap"));
-                out.putInt(stackMap.length + 2).putShort(frameCount);
-                out.putByteArray(stackMap.data, 0, stackMap.length);
-            }
-            if (cattrs != null) {
-                cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out);
-            }
-        }
-        if (exceptionCount > 0) {
-            out.putShort(cw.newUTF8("Exceptions")).putInt(
-                    2 * exceptionCount + 2);
-            out.putShort(exceptionCount);
-            for (int i = 0; i < exceptionCount; ++i) {
-                out.putShort(exceptions[i]);
-            }
-        }
-        if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
-            if ((cw.version & 0xFFFF) < Opcodes.V1_5
-                    || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
-                out.putShort(cw.newUTF8("Synthetic")).putInt(0);
-            }
-        }
-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
-            out.putShort(cw.newUTF8("Deprecated")).putInt(0);
-        }
-        if (ClassReader.SIGNATURES && signature != null) {
-            out.putShort(cw.newUTF8("Signature")).putInt(2)
-                    .putShort(cw.newUTF8(signature));
-        }
-        if (ClassReader.ANNOTATIONS && annd != null) {
-            out.putShort(cw.newUTF8("AnnotationDefault"));
-            out.putInt(annd.length);
-            out.putByteArray(annd.data, 0, annd.length);
-        }
-        if (ClassReader.ANNOTATIONS && anns != null) {
-            out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
-            anns.put(out);
-        }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
-            out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
-            ianns.put(out);
-        }
-        if (ClassReader.ANNOTATIONS && panns != null) {
-            out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
-            AnnotationWriter.put(panns, synthetics, out);
-        }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
-            out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
-            AnnotationWriter.put(ipanns, synthetics, out);
-        }
-        if (attrs != null) {
-            attrs.put(cw, null, 0, -1, -1, out);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W)
-    // ------------------------------------------------------------------------
-
-    /**
-     * Resizes and replaces the temporary instructions inserted by
-     * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
-     * and instruction addresses consistent. This may require to resize other
-     * existing instructions, or even to introduce new instructions: for
-     * example, increasing the size of an instruction by 2 at the middle of a
-     * method can increases the offset of an IFEQ instruction from 32766 to
-     * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
-     * 32765. This, in turn, may require to increase the size of another jump
-     * instruction, and so on... All these operations are handled automatically
-     * by this method.
-     * <p>
-     * <i>This method must be called after all the method that is being built
-     * has been visited</i>. In particular, the {@link Label Label} objects used
-     * to construct the method are no longer valid after this method has been
-     * called.
-     */
-    private void resizeInstructions() {
-        byte[] b = code.data; // bytecode of the method
-        int u, v, label; // indexes in b
-        int i, j; // loop indexes
-        /*
-         * 1st step: As explained above, resizing an instruction may require to
-         * resize another one, which may require to resize yet another one, and
-         * so on. The first step of the algorithm consists in finding all the
-         * instructions that need to be resized, without modifying the code.
-         * This is done by the following "fix point" algorithm:
-         *
-         * Parse the code to find the jump instructions whose offset will need
-         * more than 2 bytes to be stored (the future offset is computed from
-         * the current offset and from the number of bytes that will be inserted
-         * or removed between the source and target instructions). For each such
-         * instruction, adds an entry in (a copy of) the indexes and sizes
-         * arrays (if this has not already been done in a previous iteration!).
-         *
-         * If at least one entry has been added during the previous step, go
-         * back to the beginning, otherwise stop.
-         *
-         * In fact the real algorithm is complicated by the fact that the size
-         * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
-         * position in the bytecode (because of padding). In order to ensure the
-         * convergence of the algorithm, the number of bytes to be added or
-         * removed from these instructions is over estimated during the previous
-         * loop, and computed exactly only after the loop is finished (this
-         * requires another pass to parse the bytecode of the method).
-         */
-        int[] allIndexes = new int[0]; // copy of indexes
-        int[] allSizes = new int[0]; // copy of sizes
-        boolean[] resize; // instructions to be resized
-        int newOffset; // future offset of a jump instruction
-
-        resize = new boolean[code.length];
-
-        // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
-        int state = 3;
-        do {
-            if (state == 3) {
-                state = 2;
-            }
-            u = 0;
-            while (u < b.length) {
-                int opcode = b[u] & 0xFF; // opcode of current instruction
-                int insert = 0; // bytes to be added after this instruction
-
-                switch (ClassWriter.TYPE[opcode]) {
-                case ClassWriter.NOARG_INSN:
-                case ClassWriter.IMPLVAR_INSN:
-                    u += 1;
-                    break;
-                case ClassWriter.LABEL_INSN:
-                    if (opcode > 201) {
-                        // converts temporary opcodes 202 to 217, 218 and
-                        // 219 to IFEQ ... JSR (inclusive), IFNULL and
-                        // IFNONNULL
-                        opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                        label = u + readUnsignedShort(b, u + 1);
-                    } else {
-                        label = u + readShort(b, u + 1);
-                    }
-                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                    if (newOffset < Short.MIN_VALUE
-                            || newOffset > Short.MAX_VALUE) {
-                        if (!resize[u]) {
-                            if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
-                                // two additional bytes will be required to
-                                // replace this GOTO or JSR instruction with
-                                // a GOTO_W or a JSR_W
-                                insert = 2;
-                            } else {
-                                // five additional bytes will be required to
-                                // replace this IFxxx <l> instruction with
-                                // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
-                                // is the "opposite" opcode of IFxxx (i.e.,
-                                // IFNE for IFEQ) and where <l'> designates
-                                // the instruction just after the GOTO_W.
-                                insert = 5;
-                            }
-                            resize[u] = true;
-                        }
-                    }
-                    u += 3;
-                    break;
-                case ClassWriter.LABELW_INSN:
-                    u += 5;
-                    break;
-                case ClassWriter.TABL_INSN:
-                    if (state == 1) {
-                        // true number of bytes to be added (or removed)
-                        // from this instruction = (future number of padding
-                        // bytes - current number of padding byte) -
-                        // previously over estimated variation =
-                        // = ((3 - newOffset%4) - (3 - u%4)) - u%4
-                        // = (-newOffset%4 + u%4) - u%4
-                        // = -(newOffset & 3)
-                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                        insert = -(newOffset & 3);
-                    } else if (!resize[u]) {
-                        // over estimation of the number of bytes to be
-                        // added to this instruction = 3 - current number
-                        // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
-                        insert = u & 3;
-                        resize[u] = true;
-                    }
-                    // skips instruction
-                    u = u + 4 - (u & 3);
-                    u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
-                    break;
-                case ClassWriter.LOOK_INSN:
-                    if (state == 1) {
-                        // like TABL_INSN
-                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                        insert = -(newOffset & 3);
-                    } else if (!resize[u]) {
-                        // like TABL_INSN
-                        insert = u & 3;
-                        resize[u] = true;
-                    }
-                    // skips instruction
-                    u = u + 4 - (u & 3);
-                    u += 8 * readInt(b, u + 4) + 8;
-                    break;
-                case ClassWriter.WIDE_INSN:
-                    opcode = b[u + 1] & 0xFF;
-                    if (opcode == Opcodes.IINC) {
-                        u += 6;
-                    } else {
-                        u += 4;
-                    }
-                    break;
-                case ClassWriter.VAR_INSN:
-                case ClassWriter.SBYTE_INSN:
-                case ClassWriter.LDC_INSN:
-                    u += 2;
-                    break;
-                case ClassWriter.SHORT_INSN:
-                case ClassWriter.LDCW_INSN:
-                case ClassWriter.FIELDORMETH_INSN:
-                case ClassWriter.TYPE_INSN:
-                case ClassWriter.IINC_INSN:
-                    u += 3;
-                    break;
-                case ClassWriter.ITFMETH_INSN:
-                case ClassWriter.INDYMETH_INSN:
-                    u += 5;
-                    break;
-                // case ClassWriter.MANA_INSN:
-                default:
-                    u += 4;
-                    break;
-                }
-                if (insert != 0) {
-                    // adds a new (u, insert) entry in the allIndexes and
-                    // allSizes arrays
-                    int[] newIndexes = new int[allIndexes.length + 1];
-                    int[] newSizes = new int[allSizes.length + 1];
-                    System.arraycopy(allIndexes, 0, newIndexes, 0,
-                            allIndexes.length);
-                    System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
-                    newIndexes[allIndexes.length] = u;
-                    newSizes[allSizes.length] = insert;
-                    allIndexes = newIndexes;
-                    allSizes = newSizes;
-                    if (insert > 0) {
-                        state = 3;
-                    }
-                }
-            }
-            if (state < 3) {
-                --state;
-            }
-        } while (state != 0);
-
-        // 2nd step:
-        // copies the bytecode of the method into a new bytevector, updates the
-        // offsets, and inserts (or removes) bytes as requested.
-
-        ByteVector newCode = new ByteVector(code.length);
-
-        u = 0;
-        while (u < code.length) {
-            int opcode = b[u] & 0xFF;
-            switch (ClassWriter.TYPE[opcode]) {
-            case ClassWriter.NOARG_INSN:
-            case ClassWriter.IMPLVAR_INSN:
-                newCode.putByte(opcode);
-                u += 1;
-                break;
-            case ClassWriter.LABEL_INSN:
-                if (opcode > 201) {
-                    // changes temporary opcodes 202 to 217 (inclusive), 218
-                    // and 219 to IFEQ ... JSR (inclusive), IFNULL and
-                    // IFNONNULL
-                    opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                    label = u + readUnsignedShort(b, u + 1);
-                } else {
-                    label = u + readShort(b, u + 1);
-                }
-                newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                if (resize[u]) {
-                    // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
-                    // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
-                    // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
-                    // and where <l'> designates the instruction just after
-                    // the GOTO_W.
-                    if (opcode == Opcodes.GOTO) {
-                        newCode.putByte(200); // GOTO_W
-                    } else if (opcode == Opcodes.JSR) {
-                        newCode.putByte(201); // JSR_W
-                    } else {
-                        newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
-                                : opcode ^ 1);
-                        newCode.putShort(8); // jump offset
-                        newCode.putByte(200); // GOTO_W
-                        // newOffset now computed from start of GOTO_W
-                        newOffset -= 3;
-                    }
-                    newCode.putInt(newOffset);
-                } else {
-                    newCode.putByte(opcode);
-                    newCode.putShort(newOffset);
-                }
-                u += 3;
-                break;
-            case ClassWriter.LABELW_INSN:
-                label = u + readInt(b, u + 1);
-                newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                newCode.putByte(opcode);
-                newCode.putInt(newOffset);
-                u += 5;
-                break;
-            case ClassWriter.TABL_INSN:
-                // skips 0 to 3 padding bytes
-                v = u;
-                u = u + 4 - (v & 3);
-                // reads and copies instruction
-                newCode.putByte(Opcodes.TABLESWITCH);
-                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
-                label = v + readInt(b, u);
-                u += 4;
-                newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                newCode.putInt(newOffset);
-                j = readInt(b, u);
-                u += 4;
-                newCode.putInt(j);
-                j = readInt(b, u) - j + 1;
-                u += 4;
-                newCode.putInt(readInt(b, u - 4));
-                for (; j > 0; --j) {
-                    label = v + readInt(b, u);
-                    u += 4;
-                    newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                    newCode.putInt(newOffset);
-                }
-                break;
-            case ClassWriter.LOOK_INSN:
-                // skips 0 to 3 padding bytes
-                v = u;
-                u = u + 4 - (v & 3);
-                // reads and copies instruction
-                newCode.putByte(Opcodes.LOOKUPSWITCH);
-                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
-                label = v + readInt(b, u);
-                u += 4;
-                newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                newCode.putInt(newOffset);
-                j = readInt(b, u);
-                u += 4;
-                newCode.putInt(j);
-                for (; j > 0; --j) {
-                    newCode.putInt(readInt(b, u));
-                    u += 4;
-                    label = v + readInt(b, u);
-                    u += 4;
-                    newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                    newCode.putInt(newOffset);
-                }
-                break;
-            case ClassWriter.WIDE_INSN:
-                opcode = b[u + 1] & 0xFF;
-                if (opcode == Opcodes.IINC) {
-                    newCode.putByteArray(b, u, 6);
-                    u += 6;
-                } else {
-                    newCode.putByteArray(b, u, 4);
-                    u += 4;
-                }
-                break;
-            case ClassWriter.VAR_INSN:
-            case ClassWriter.SBYTE_INSN:
-            case ClassWriter.LDC_INSN:
-                newCode.putByteArray(b, u, 2);
-                u += 2;
-                break;
-            case ClassWriter.SHORT_INSN:
-            case ClassWriter.LDCW_INSN:
-            case ClassWriter.FIELDORMETH_INSN:
-            case ClassWriter.TYPE_INSN:
-            case ClassWriter.IINC_INSN:
-                newCode.putByteArray(b, u, 3);
-                u += 3;
-                break;
-            case ClassWriter.ITFMETH_INSN:
-            case ClassWriter.INDYMETH_INSN:
-                newCode.putByteArray(b, u, 5);
-                u += 5;
-                break;
-            // case MANA_INSN:
-            default:
-                newCode.putByteArray(b, u, 4);
-                u += 4;
-                break;
-            }
-        }
-
-        // recomputes the stack map frames
-        if (frameCount > 0) {
-            if (compute == FRAMES) {
-                frameCount = 0;
-                stackMap = null;
-                previousFrame = null;
-                frame = null;
-                Frame f = new Frame();
-                f.owner = labels;
-                Type[] args = Type.getArgumentTypes(descriptor);
-                f.initInputFrame(cw, access, args, maxLocals);
-                visitFrame(f);
-                Label l = labels;
-                while (l != null) {
-                    /*
-                     * here we need the original label position. getNewOffset
-                     * must therefore never have been called for this label.
-                     */
-                    u = l.position - 3;
-                    if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) {
-                        getNewOffset(allIndexes, allSizes, l);
-                        // TODO update offsets in UNINITIALIZED values
-                        visitFrame(l.frame);
-                    }
-                    l = l.successor;
-                }
-            } else {
-                /*
-                 * Resizing an existing stack map frame table is really hard.
-                 * Not only the table must be parsed to update the offets, but
-                 * new frames may be needed for jump instructions that were
-                 * inserted by this method. And updating the offsets or
-                 * inserting frames can change the format of the following
-                 * frames, in case of packed frames. In practice the whole table
-                 * must be recomputed. For this the frames are marked as
-                 * potentially invalid. This will cause the whole class to be
-                 * reread and rewritten with the COMPUTE_FRAMES option (see the
-                 * ClassWriter.toByteArray method). This is not very efficient
-                 * but is much easier and requires much less code than any other
-                 * method I can think of.
-                 */
-                cw.invalidFrames = true;
-            }
-        }
-        // updates the exception handler block labels
-        Handler h = firstHandler;
-        while (h != null) {
-            getNewOffset(allIndexes, allSizes, h.start);
-            getNewOffset(allIndexes, allSizes, h.end);
-            getNewOffset(allIndexes, allSizes, h.handler);
-            h = h.next;
-        }
-        // updates the instructions addresses in the
-        // local var and line number tables
-        for (i = 0; i < 2; ++i) {
-            ByteVector bv = i == 0 ? localVar : localVarType;
-            if (bv != null) {
-                b = bv.data;
-                u = 0;
-                while (u < bv.length) {
-                    label = readUnsignedShort(b, u);
-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label);
-                    writeShort(b, u, newOffset);
-                    label += readUnsignedShort(b, u + 2);
-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label)
-                            - newOffset;
-                    writeShort(b, u + 2, newOffset);
-                    u += 10;
-                }
-            }
-        }
-        if (lineNumber != null) {
-            b = lineNumber.data;
-            u = 0;
-            while (u < lineNumber.length) {
-                writeShort(
-                        b,
-                        u,
-                        getNewOffset(allIndexes, allSizes, 0,
-                                readUnsignedShort(b, u)));
-                u += 4;
-            }
-        }
-        // updates the labels of the other attributes
-        Attribute attr = cattrs;
-        while (attr != null) {
-            Label[] labels = attr.getLabels();
-            if (labels != null) {
-                for (i = labels.length - 1; i >= 0; --i) {
-                    getNewOffset(allIndexes, allSizes, labels[i]);
-                }
-            }
-            attr = attr.next;
-        }
-
-        // replaces old bytecodes with new ones
-        code = newCode;
-    }
-
-    /**
-     * Reads an unsigned short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static int readUnsignedShort(final byte[] b, final int index) {
-        return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
-    }
-
-    /**
-     * Reads a signed short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static short readShort(final byte[] b, final int index) {
-        return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
-    }
-
-    /**
-     * Reads a signed int value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static int readInt(final byte[] b, final int index) {
-        return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
-                | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
-    }
-
-    /**
-     * Writes a short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            where the first byte of the short value must be written.
-     * @param s
-     *            the value to be written in the given byte array.
-     */
-    static void writeShort(final byte[] b, final int index, final int s) {
-        b[index] = (byte) (s >>> 8);
-        b[index + 1] = (byte) s;
-    }
-
-    /**
-     * Computes the future value of a bytecode offset.
-     * <p>
-     * Note: it is possible to have several entries for the same instruction in
-     * the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b) and
-     * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
-     *
-     * @param indexes
-     *            current positions of the instructions to be resized. Each
-     *            instruction must be designated by the index of its <i>last</i>
-     *            byte, plus one (or, in other words, by the index of the
-     *            <i>first</i> byte of the <i>next</i> instruction).
-     * @param sizes
-     *            the number of bytes to be <i>added</i> to the above
-     *            instructions. More precisely, for each i < <tt>len</tt>,
-     *            <tt>sizes</tt>[i] bytes will be added at the end of the
-     *            instruction designated by <tt>indexes</tt>[i] or, if
-     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
-     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
-     *            (the instruction size <i>must not</i> become negative or
-     *            null).
-     * @param begin
-     *            index of the first byte of the source instruction.
-     * @param end
-     *            index of the first byte of the target instruction.
-     * @return the future value of the given bytecode offset.
-     */
-    static int getNewOffset(final int[] indexes, final int[] sizes,
-            final int begin, final int end) {
-        int offset = end - begin;
-        for (int i = 0; i < indexes.length; ++i) {
-            if (begin < indexes[i] && indexes[i] <= end) {
-                // forward jump
-                offset += sizes[i];
-            } else if (end < indexes[i] && indexes[i] <= begin) {
-                // backward jump
-                offset -= sizes[i];
-            }
-        }
-        return offset;
-    }
-
-    /**
-     * Updates the offset of the given label.
-     *
-     * @param indexes
-     *            current positions of the instructions to be resized. Each
-     *            instruction must be designated by the index of its <i>last</i>
-     *            byte, plus one (or, in other words, by the index of the
-     *            <i>first</i> byte of the <i>next</i> instruction).
-     * @param sizes
-     *            the number of bytes to be <i>added</i> to the above
-     *            instructions. More precisely, for each i < <tt>len</tt>,
-     *            <tt>sizes</tt>[i] bytes will be added at the end of the
-     *            instruction designated by <tt>indexes</tt>[i] or, if
-     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
-     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
-     *            (the instruction size <i>must not</i> become negative or
-     *            null).
-     * @param label
-     *            the label whose offset must be updated.
-     */
-    static void getNewOffset(final int[] indexes, final int[] sizes,
-            final Label label) {
-        if ((label.status & Label.RESIZED) == 0) {
-            label.position = getNewOffset(indexes, sizes, 0, label.position);
-            label.status |= Label.RESIZED;
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/Opcodes.java b/src/jvm/clojure/asm/Opcodes.java
deleted file mode 100644
index b126807..0000000
--- a/src/jvm/clojure/asm/Opcodes.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-/**
- * Defines the JVM opcodes, access flags and array type codes. This interface
- * does not define all the JVM opcodes because some opcodes are automatically
- * handled. For example, the xLOAD and xSTORE opcodes are automatically replaced
- * by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n
- * opcodes are therefore not defined in this interface. Likewise for LDC,
- * automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and
- * JSR_W.
- *
- * @author Eric Bruneton
- * @author Eugene Kuleshov
- */
-public interface Opcodes {
-
-    // ASM API versions
-
-    int ASM4 = 4 << 16 | 0 << 8 | 0;
-
-    // versions
-
-    int V1_1 = 3 << 16 | 45;
-    int V1_2 = 0 << 16 | 46;
-    int V1_3 = 0 << 16 | 47;
-    int V1_4 = 0 << 16 | 48;
-    int V1_5 = 0 << 16 | 49;
-    int V1_6 = 0 << 16 | 50;
-    int V1_7 = 0 << 16 | 51;
-
-    // access flags
-
-    int ACC_PUBLIC = 0x0001; // class, field, method
-    int ACC_PRIVATE = 0x0002; // class, field, method
-    int ACC_PROTECTED = 0x0004; // class, field, method
-    int ACC_STATIC = 0x0008; // field, method
-    int ACC_FINAL = 0x0010; // class, field, method
-    int ACC_SUPER = 0x0020; // class
-    int ACC_SYNCHRONIZED = 0x0020; // method
-    int ACC_VOLATILE = 0x0040; // field
-    int ACC_BRIDGE = 0x0040; // method
-    int ACC_VARARGS = 0x0080; // method
-    int ACC_TRANSIENT = 0x0080; // field
-    int ACC_NATIVE = 0x0100; // method
-    int ACC_INTERFACE = 0x0200; // class
-    int ACC_ABSTRACT = 0x0400; // class, method
-    int ACC_STRICT = 0x0800; // method
-    int ACC_SYNTHETIC = 0x1000; // class, field, method
-    int ACC_ANNOTATION = 0x2000; // class
-    int ACC_ENUM = 0x4000; // class(?) field inner
-
-    // ASM specific pseudo access flags
-
-    int ACC_DEPRECATED = 0x20000; // class, field, method
-
-    // types for NEWARRAY
-
-    int T_BOOLEAN = 4;
-    int T_CHAR = 5;
-    int T_FLOAT = 6;
-    int T_DOUBLE = 7;
-    int T_BYTE = 8;
-    int T_SHORT = 9;
-    int T_INT = 10;
-    int T_LONG = 11;
-
-    // tags for Handle
-
-    int H_GETFIELD = 1;
-    int H_GETSTATIC = 2;
-    int H_PUTFIELD = 3;
-    int H_PUTSTATIC = 4;
-    int H_INVOKEVIRTUAL = 5;
-    int H_INVOKESTATIC = 6;
-    int H_INVOKESPECIAL = 7;
-    int H_NEWINVOKESPECIAL = 8;
-    int H_INVOKEINTERFACE = 9;
-
-    // stack map frame types
-
-    /**
-     * Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}.
-     */
-    int F_NEW = -1;
-
-    /**
-     * Represents a compressed frame with complete frame data.
-     */
-    int F_FULL = 0;
-
-    /**
-     * Represents a compressed frame where locals are the same as the locals in
-     * the previous frame, except that additional 1-3 locals are defined, and
-     * with an empty stack.
-     */
-    int F_APPEND = 1;
-
-    /**
-     * Represents a compressed frame where locals are the same as the locals in
-     * the previous frame, except that the last 1-3 locals are absent and with
-     * an empty stack.
-     */
-    int F_CHOP = 2;
-
-    /**
-     * Represents a compressed frame with exactly the same locals as the
-     * previous frame and with an empty stack.
-     */
-    int F_SAME = 3;
-
-    /**
-     * Represents a compressed frame with exactly the same locals as the
-     * previous frame and with a single value on the stack.
-     */
-    int F_SAME1 = 4;
-
-    Integer TOP = new Integer(0);
-    Integer INTEGER = new Integer(1);
-    Integer FLOAT = new Integer(2);
-    Integer DOUBLE = new Integer(3);
-    Integer LONG = new Integer(4);
-    Integer NULL = new Integer(5);
-    Integer UNINITIALIZED_THIS = new Integer(6);
-
-    // opcodes // visit method (- = idem)
-
-    int NOP = 0; // visitInsn
-    int ACONST_NULL = 1; // -
-    int ICONST_M1 = 2; // -
-    int ICONST_0 = 3; // -
-    int ICONST_1 = 4; // -
-    int ICONST_2 = 5; // -
-    int ICONST_3 = 6; // -
-    int ICONST_4 = 7; // -
-    int ICONST_5 = 8; // -
-    int LCONST_0 = 9; // -
-    int LCONST_1 = 10; // -
-    int FCONST_0 = 11; // -
-    int FCONST_1 = 12; // -
-    int FCONST_2 = 13; // -
-    int DCONST_0 = 14; // -
-    int DCONST_1 = 15; // -
-    int BIPUSH = 16; // visitIntInsn
-    int SIPUSH = 17; // -
-    int LDC = 18; // visitLdcInsn
-    // int LDC_W = 19; // -
-    // int LDC2_W = 20; // -
-    int ILOAD = 21; // visitVarInsn
-    int LLOAD = 22; // -
-    int FLOAD = 23; // -
-    int DLOAD = 24; // -
-    int ALOAD = 25; // -
-    // int ILOAD_0 = 26; // -
-    // int ILOAD_1 = 27; // -
-    // int ILOAD_2 = 28; // -
-    // int ILOAD_3 = 29; // -
-    // int LLOAD_0 = 30; // -
-    // int LLOAD_1 = 31; // -
-    // int LLOAD_2 = 32; // -
-    // int LLOAD_3 = 33; // -
-    // int FLOAD_0 = 34; // -
-    // int FLOAD_1 = 35; // -
-    // int FLOAD_2 = 36; // -
-    // int FLOAD_3 = 37; // -
-    // int DLOAD_0 = 38; // -
-    // int DLOAD_1 = 39; // -
-    // int DLOAD_2 = 40; // -
-    // int DLOAD_3 = 41; // -
-    // int ALOAD_0 = 42; // -
-    // int ALOAD_1 = 43; // -
-    // int ALOAD_2 = 44; // -
-    // int ALOAD_3 = 45; // -
-    int IALOAD = 46; // visitInsn
-    int LALOAD = 47; // -
-    int FALOAD = 48; // -
-    int DALOAD = 49; // -
-    int AALOAD = 50; // -
-    int BALOAD = 51; // -
-    int CALOAD = 52; // -
-    int SALOAD = 53; // -
-    int ISTORE = 54; // visitVarInsn
-    int LSTORE = 55; // -
-    int FSTORE = 56; // -
-    int DSTORE = 57; // -
-    int ASTORE = 58; // -
-    // int ISTORE_0 = 59; // -
-    // int ISTORE_1 = 60; // -
-    // int ISTORE_2 = 61; // -
-    // int ISTORE_3 = 62; // -
-    // int LSTORE_0 = 63; // -
-    // int LSTORE_1 = 64; // -
-    // int LSTORE_2 = 65; // -
-    // int LSTORE_3 = 66; // -
-    // int FSTORE_0 = 67; // -
-    // int FSTORE_1 = 68; // -
-    // int FSTORE_2 = 69; // -
-    // int FSTORE_3 = 70; // -
-    // int DSTORE_0 = 71; // -
-    // int DSTORE_1 = 72; // -
-    // int DSTORE_2 = 73; // -
-    // int DSTORE_3 = 74; // -
-    // int ASTORE_0 = 75; // -
-    // int ASTORE_1 = 76; // -
-    // int ASTORE_2 = 77; // -
-    // int ASTORE_3 = 78; // -
-    int IASTORE = 79; // visitInsn
-    int LASTORE = 80; // -
-    int FASTORE = 81; // -
-    int DASTORE = 82; // -
-    int AASTORE = 83; // -
-    int BASTORE = 84; // -
-    int CASTORE = 85; // -
-    int SASTORE = 86; // -
-    int POP = 87; // -
-    int POP2 = 88; // -
-    int DUP = 89; // -
-    int DUP_X1 = 90; // -
-    int DUP_X2 = 91; // -
-    int DUP2 = 92; // -
-    int DUP2_X1 = 93; // -
-    int DUP2_X2 = 94; // -
-    int SWAP = 95; // -
-    int IADD = 96; // -
-    int LADD = 97; // -
-    int FADD = 98; // -
-    int DADD = 99; // -
-    int ISUB = 100; // -
-    int LSUB = 101; // -
-    int FSUB = 102; // -
-    int DSUB = 103; // -
-    int IMUL = 104; // -
-    int LMUL = 105; // -
-    int FMUL = 106; // -
-    int DMUL = 107; // -
-    int IDIV = 108; // -
-    int LDIV = 109; // -
-    int FDIV = 110; // -
-    int DDIV = 111; // -
-    int IREM = 112; // -
-    int LREM = 113; // -
-    int FREM = 114; // -
-    int DREM = 115; // -
-    int INEG = 116; // -
-    int LNEG = 117; // -
-    int FNEG = 118; // -
-    int DNEG = 119; // -
-    int ISHL = 120; // -
-    int LSHL = 121; // -
-    int ISHR = 122; // -
-    int LSHR = 123; // -
-    int IUSHR = 124; // -
-    int LUSHR = 125; // -
-    int IAND = 126; // -
-    int LAND = 127; // -
-    int IOR = 128; // -
-    int LOR = 129; // -
-    int IXOR = 130; // -
-    int LXOR = 131; // -
-    int IINC = 132; // visitIincInsn
-    int I2L = 133; // visitInsn
-    int I2F = 134; // -
-    int I2D = 135; // -
-    int L2I = 136; // -
-    int L2F = 137; // -
-    int L2D = 138; // -
-    int F2I = 139; // -
-    int F2L = 140; // -
-    int F2D = 141; // -
-    int D2I = 142; // -
-    int D2L = 143; // -
-    int D2F = 144; // -
-    int I2B = 145; // -
-    int I2C = 146; // -
-    int I2S = 147; // -
-    int LCMP = 148; // -
-    int FCMPL = 149; // -
-    int FCMPG = 150; // -
-    int DCMPL = 151; // -
-    int DCMPG = 152; // -
-    int IFEQ = 153; // visitJumpInsn
-    int IFNE = 154; // -
-    int IFLT = 155; // -
-    int IFGE = 156; // -
-    int IFGT = 157; // -
-    int IFLE = 158; // -
-    int IF_ICMPEQ = 159; // -
-    int IF_ICMPNE = 160; // -
-    int IF_ICMPLT = 161; // -
-    int IF_ICMPGE = 162; // -
-    int IF_ICMPGT = 163; // -
-    int IF_ICMPLE = 164; // -
-    int IF_ACMPEQ = 165; // -
-    int IF_ACMPNE = 166; // -
-    int GOTO = 167; // -
-    int JSR = 168; // -
-    int RET = 169; // visitVarInsn
-    int TABLESWITCH = 170; // visiTableSwitchInsn
-    int LOOKUPSWITCH = 171; // visitLookupSwitch
-    int IRETURN = 172; // visitInsn
-    int LRETURN = 173; // -
-    int FRETURN = 174; // -
-    int DRETURN = 175; // -
-    int ARETURN = 176; // -
-    int RETURN = 177; // -
-    int GETSTATIC = 178; // visitFieldInsn
-    int PUTSTATIC = 179; // -
-    int GETFIELD = 180; // -
-    int PUTFIELD = 181; // -
-    int INVOKEVIRTUAL = 182; // visitMethodInsn
-    int INVOKESPECIAL = 183; // -
-    int INVOKESTATIC = 184; // -
-    int INVOKEINTERFACE = 185; // -
-    int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
-    int NEW = 187; // visitTypeInsn
-    int NEWARRAY = 188; // visitIntInsn
-    int ANEWARRAY = 189; // visitTypeInsn
-    int ARRAYLENGTH = 190; // visitInsn
-    int ATHROW = 191; // -
-    int CHECKCAST = 192; // visitTypeInsn
-    int INSTANCEOF = 193; // -
-    int MONITORENTER = 194; // visitInsn
-    int MONITOREXIT = 195; // -
-    // int WIDE = 196; // NOT VISITED
-    int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
-    int IFNULL = 198; // visitJumpInsn
-    int IFNONNULL = 199; // -
-    // int GOTO_W = 200; // -
-    // int JSR_W = 201; // -
-}
diff --git a/src/jvm/clojure/asm/Type.java b/src/jvm/clojure/asm/Type.java
deleted file mode 100644
index 31db08d..0000000
--- a/src/jvm/clojure/asm/Type.java
+++ /dev/null
@@ -1,895 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-
-/**
- * A Java field or method type. This class can be used to make it easier to
- * manipulate type and method descriptors.
- *
- * @author Eric Bruneton
- * @author Chris Nokleberg
- */
-public class Type {
-
-    /**
-     * The sort of the <tt>void</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int VOID = 0;
-
-    /**
-     * The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int BOOLEAN = 1;
-
-    /**
-     * The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int CHAR = 2;
-
-    /**
-     * The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int BYTE = 3;
-
-    /**
-     * The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int SHORT = 4;
-
-    /**
-     * The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int INT = 5;
-
-    /**
-     * The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int FLOAT = 6;
-
-    /**
-     * The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int LONG = 7;
-
-    /**
-     * The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
-     */
-    public static final int DOUBLE = 8;
-
-    /**
-     * The sort of array reference types. See {@link #getSort getSort}.
-     */
-    public static final int ARRAY = 9;
-
-    /**
-     * The sort of object reference types. See {@link #getSort getSort}.
-     */
-    public static final int OBJECT = 10;
-
-    /**
-     * The sort of method types. See {@link #getSort getSort}.
-     */
-    public static final int METHOD = 11;
-
-    /**
-     * The <tt>void</tt> type.
-     */
-    public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24)
-            | (5 << 16) | (0 << 8) | 0, 1);
-
-    /**
-     * The <tt>boolean</tt> type.
-     */
-    public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24)
-            | (0 << 16) | (5 << 8) | 1, 1);
-
-    /**
-     * The <tt>char</tt> type.
-     */
-    public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24)
-            | (0 << 16) | (6 << 8) | 1, 1);
-
-    /**
-     * The <tt>byte</tt> type.
-     */
-    public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24)
-            | (0 << 16) | (5 << 8) | 1, 1);
-
-    /**
-     * The <tt>short</tt> type.
-     */
-    public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24)
-            | (0 << 16) | (7 << 8) | 1, 1);
-
-    /**
-     * The <tt>int</tt> type.
-     */
-    public static final Type INT_TYPE = new Type(INT, null, ('I' << 24)
-            | (0 << 16) | (0 << 8) | 1, 1);
-
-    /**
-     * The <tt>float</tt> type.
-     */
-    public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24)
-            | (2 << 16) | (2 << 8) | 1, 1);
-
-    /**
-     * The <tt>long</tt> type.
-     */
-    public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24)
-            | (1 << 16) | (1 << 8) | 2, 1);
-
-    /**
-     * The <tt>double</tt> type.
-     */
-    public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24)
-            | (3 << 16) | (3 << 8) | 2, 1);
-
-    // ------------------------------------------------------------------------
-    // Fields
-    // ------------------------------------------------------------------------
-
-    /**
-     * The sort of this Java type.
-     */
-    private final int sort;
-
-    /**
-     * A buffer containing the internal name of this Java type. This field is
-     * only used for reference types.
-     */
-    private final char[] buf;
-
-    /**
-     * The offset of the internal name of this Java type in {@link #buf buf} or,
-     * for primitive types, the size, descriptor and getOpcode offsets for this
-     * type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset
-     * for IALOAD or IASTORE, byte 3 the offset for all other instructions).
-     */
-    private final int off;
-
-    /**
-     * The length of the internal name of this Java type.
-     */
-    private final int len;
-
-    // ------------------------------------------------------------------------
-    // Constructors
-    // ------------------------------------------------------------------------
-
-    /**
-     * Constructs a reference type.
-     *
-     * @param sort
-     *            the sort of the reference type to be constructed.
-     * @param buf
-     *            a buffer containing the descriptor of the previous type.
-     * @param off
-     *            the offset of this descriptor in the previous buffer.
-     * @param len
-     *            the length of this descriptor.
-     */
-    private Type(final int sort, final char[] buf, final int off, final int len) {
-        this.sort = sort;
-        this.buf = buf;
-        this.off = off;
-        this.len = len;
-    }
-
-    /**
-     * Returns the Java type corresponding to the given type descriptor.
-     *
-     * @param typeDescriptor
-     *            a field or method type descriptor.
-     * @return the Java type corresponding to the given type descriptor.
-     */
-    public static Type getType(final String typeDescriptor) {
-        return getType(typeDescriptor.toCharArray(), 0);
-    }
-
-    /**
-     * Returns the Java type corresponding to the given internal name.
-     *
-     * @param internalName
-     *            an internal name.
-     * @return the Java type corresponding to the given internal name.
-     */
-    public static Type getObjectType(final String internalName) {
-        char[] buf = internalName.toCharArray();
-        return new Type(buf[0] == '[' ? ARRAY : OBJECT, buf, 0, buf.length);
-    }
-
-    /**
-     * Returns the Java type corresponding to the given method descriptor.
-     * Equivalent to <code>Type.getType(methodDescriptor)</code>.
-     *
-     * @param methodDescriptor
-     *            a method descriptor.
-     * @return the Java type corresponding to the given method descriptor.
-     */
-    public static Type getMethodType(final String methodDescriptor) {
-        return getType(methodDescriptor.toCharArray(), 0);
-    }
-
-    /**
-     * Returns the Java method type corresponding to the given argument and
-     * return types.
-     *
-     * @param returnType
-     *            the return type of the method.
-     * @param argumentTypes
-     *            the argument types of the method.
-     * @return the Java type corresponding to the given argument and return
-     *         types.
-     */
-    public static Type getMethodType(final Type returnType,
-            final Type... argumentTypes) {
-        return getType(getMethodDescriptor(returnType, argumentTypes));
-    }
-
-    /**
-     * Returns the Java type corresponding to the given class.
-     *
-     * @param c
-     *            a class.
-     * @return the Java type corresponding to the given class.
-     */
-    public static Type getType(final Class<?> c) {
-        if (c.isPrimitive()) {
-            if (c == Integer.TYPE) {
-                return INT_TYPE;
-            } else if (c == Void.TYPE) {
-                return VOID_TYPE;
-            } else if (c == Boolean.TYPE) {
-                return BOOLEAN_TYPE;
-            } else if (c == Byte.TYPE) {
-                return BYTE_TYPE;
-            } else if (c == Character.TYPE) {
-                return CHAR_TYPE;
-            } else if (c == Short.TYPE) {
-                return SHORT_TYPE;
-            } else if (c == Double.TYPE) {
-                return DOUBLE_TYPE;
-            } else if (c == Float.TYPE) {
-                return FLOAT_TYPE;
-            } else /* if (c == Long.TYPE) */{
-                return LONG_TYPE;
-            }
-        } else {
-            return getType(getDescriptor(c));
-        }
-    }
-
-    /**
-     * Returns the Java method type corresponding to the given constructor.
-     *
-     * @param c
-     *            a {@link Constructor Constructor} object.
-     * @return the Java method type corresponding to the given constructor.
-     */
-    public static Type getType(final Constructor<?> c) {
-        return getType(getConstructorDescriptor(c));
-    }
-
-    /**
-     * Returns the Java method type corresponding to the given method.
-     *
-     * @param m
-     *            a {@link Method Method} object.
-     * @return the Java method type corresponding to the given method.
-     */
-    public static Type getType(final Method m) {
-        return getType(getMethodDescriptor(m));
-    }
-
-    /**
-     * Returns the Java types corresponding to the argument types of the given
-     * method descriptor.
-     *
-     * @param methodDescriptor
-     *            a method descriptor.
-     * @return the Java types corresponding to the argument types of the given
-     *         method descriptor.
-     */
-    public static Type[] getArgumentTypes(final String methodDescriptor) {
-        char[] buf = methodDescriptor.toCharArray();
-        int off = 1;
-        int size = 0;
-        while (true) {
-            char car = buf[off++];
-            if (car == ')') {
-                break;
-            } else if (car == 'L') {
-                while (buf[off++] != ';') {
-                }
-                ++size;
-            } else if (car != '[') {
-                ++size;
-            }
-        }
-        Type[] args = new Type[size];
-        off = 1;
-        size = 0;
-        while (buf[off] != ')') {
-            args[size] = getType(buf, off);
-            off += args[size].len + (args[size].sort == OBJECT ? 2 : 0);
-            size += 1;
-        }
-        return args;
-    }
-
-    /**
-     * Returns the Java types corresponding to the argument types of the given
-     * method.
-     *
-     * @param method
-     *            a method.
-     * @return the Java types corresponding to the argument types of the given
-     *         method.
-     */
-    public static Type[] getArgumentTypes(final Method method) {
-        Class<?>[] classes = method.getParameterTypes();
-        Type[] types = new Type[classes.length];
-        for (int i = classes.length - 1; i >= 0; --i) {
-            types[i] = getType(classes[i]);
-        }
-        return types;
-    }
-
-    /**
-     * Returns the Java type corresponding to the return type of the given
-     * method descriptor.
-     *
-     * @param methodDescriptor
-     *            a method descriptor.
-     * @return the Java type corresponding to the return type of the given
-     *         method descriptor.
-     */
-    public static Type getReturnType(final String methodDescriptor) {
-        char[] buf = methodDescriptor.toCharArray();
-        return getType(buf, methodDescriptor.indexOf(')') + 1);
-    }
-
-    /**
-     * Returns the Java type corresponding to the return type of the given
-     * method.
-     *
-     * @param method
-     *            a method.
-     * @return the Java type corresponding to the return type of the given
-     *         method.
-     */
-    public static Type getReturnType(final Method method) {
-        return getType(method.getReturnType());
-    }
-
-    /**
-     * Computes the size of the arguments and of the return value of a method.
-     *
-     * @param desc
-     *            the descriptor of a method.
-     * @return the size of the arguments of the method (plus one for the
-     *         implicit this argument), argSize, and the size of its return
-     *         value, retSize, packed into a single int i =
-     *         <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to
-     *         <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
-     */
-    public static int getArgumentsAndReturnSizes(final String desc) {
-        int n = 1;
-        int c = 1;
-        while (true) {
-            char car = desc.charAt(c++);
-            if (car == ')') {
-                car = desc.charAt(c);
-                return n << 2
-                        | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
-            } else if (car == 'L') {
-                while (desc.charAt(c++) != ';') {
-                }
-                n += 1;
-            } else if (car == '[') {
-                while ((car = desc.charAt(c)) == '[') {
-                    ++c;
-                }
-                if (car == 'D' || car == 'J') {
-                    n -= 1;
-                }
-            } else if (car == 'D' || car == 'J') {
-                n += 2;
-            } else {
-                n += 1;
-            }
-        }
-    }
-
-    /**
-     * Returns the Java type corresponding to the given type descriptor. For
-     * method descriptors, buf is supposed to contain nothing more than the
-     * descriptor itself.
-     *
-     * @param buf
-     *            a buffer containing a type descriptor.
-     * @param off
-     *            the offset of this descriptor in the previous buffer.
-     * @return the Java type corresponding to the given type descriptor.
-     */
-    private static Type getType(final char[] buf, final int off) {
-        int len;
-        switch (buf[off]) {
-        case 'V':
-            return VOID_TYPE;
-        case 'Z':
-            return BOOLEAN_TYPE;
-        case 'C':
-            return CHAR_TYPE;
-        case 'B':
-            return BYTE_TYPE;
-        case 'S':
-            return SHORT_TYPE;
-        case 'I':
-            return INT_TYPE;
-        case 'F':
-            return FLOAT_TYPE;
-        case 'J':
-            return LONG_TYPE;
-        case 'D':
-            return DOUBLE_TYPE;
-        case '[':
-            len = 1;
-            while (buf[off + len] == '[') {
-                ++len;
-            }
-            if (buf[off + len] == 'L') {
-                ++len;
-                while (buf[off + len] != ';') {
-                    ++len;
-                }
-            }
-            return new Type(ARRAY, buf, off, len + 1);
-        case 'L':
-            len = 1;
-            while (buf[off + len] != ';') {
-                ++len;
-            }
-            return new Type(OBJECT, buf, off + 1, len - 1);
-            // case '(':
-        default:
-            return new Type(METHOD, buf, off, buf.length - off);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Accessors
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the sort of this Java type.
-     *
-     * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR},
-     *         {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT},
-     *         {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE},
-     *         {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD
-     *         METHOD}.
-     */
-    public int getSort() {
-        return sort;
-    }
-
-    /**
-     * Returns the number of dimensions of this array type. This method should
-     * only be used for an array type.
-     *
-     * @return the number of dimensions of this array type.
-     */
-    public int getDimensions() {
-        int i = 1;
-        while (buf[off + i] == '[') {
-            ++i;
-        }
-        return i;
-    }
-
-    /**
-     * Returns the type of the elements of this array type. This method should
-     * only be used for an array type.
-     *
-     * @return Returns the type of the elements of this array type.
-     */
-    public Type getElementType() {
-        return getType(buf, off + getDimensions());
-    }
-
-    /**
-     * Returns the binary name of the class corresponding to this type. This
-     * method must not be used on method types.
-     *
-     * @return the binary name of the class corresponding to this type.
-     */
-    public String getClassName() {
-        switch (sort) {
-        case VOID:
-            return "void";
-        case BOOLEAN:
-            return "boolean";
-        case CHAR:
-            return "char";
-        case BYTE:
-            return "byte";
-        case SHORT:
-            return "short";
-        case INT:
-            return "int";
-        case FLOAT:
-            return "float";
-        case LONG:
-            return "long";
-        case DOUBLE:
-            return "double";
-        case ARRAY:
-            StringBuffer b = new StringBuffer(getElementType().getClassName());
-            for (int i = getDimensions(); i > 0; --i) {
-                b.append("[]");
-            }
-            return b.toString();
-        case OBJECT:
-            return new String(buf, off, len).replace('/', '.');
-        default:
-            return null;
-        }
-    }
-
-    /**
-     * Returns the internal name of the class corresponding to this object or
-     * array type. The internal name of a class is its fully qualified name (as
-     * returned by Class.getName(), where '.' are replaced by '/'. This method
-     * should only be used for an object or array type.
-     *
-     * @return the internal name of the class corresponding to this object type.
-     */
-    public String getInternalName() {
-        return new String(buf, off, len);
-    }
-
-    /**
-     * Returns the argument types of methods of this type. This method should
-     * only be used for method types.
-     *
-     * @return the argument types of methods of this type.
-     */
-    public Type[] getArgumentTypes() {
-        return getArgumentTypes(getDescriptor());
-    }
-
-    /**
-     * Returns the return type of methods of this type. This method should only
-     * be used for method types.
-     *
-     * @return the return type of methods of this type.
-     */
-    public Type getReturnType() {
-        return getReturnType(getDescriptor());
-    }
-
-    /**
-     * Returns the size of the arguments and of the return value of methods of
-     * this type. This method should only be used for method types.
-     *
-     * @return the size of the arguments (plus one for the implicit this
-     *         argument), argSize, and the size of the return value, retSize,
-     *         packed into a single int i = <tt>(argSize << 2) | retSize</tt>
-     *         (argSize is therefore equal to <tt>i >> 2</tt>, and retSize to
-     *         <tt>i & 0x03</tt>).
-     */
-    public int getArgumentsAndReturnSizes() {
-        return getArgumentsAndReturnSizes(getDescriptor());
-    }
-
-    // ------------------------------------------------------------------------
-    // Conversion to type descriptors
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the descriptor corresponding to this Java type.
-     *
-     * @return the descriptor corresponding to this Java type.
-     */
-    public String getDescriptor() {
-        StringBuffer buf = new StringBuffer();
-        getDescriptor(buf);
-        return buf.toString();
-    }
-
-    /**
-     * Returns the descriptor corresponding to the given argument and return
-     * types.
-     *
-     * @param returnType
-     *            the return type of the method.
-     * @param argumentTypes
-     *            the argument types of the method.
-     * @return the descriptor corresponding to the given argument and return
-     *         types.
-     */
-    public static String getMethodDescriptor(final Type returnType,
-            final Type... argumentTypes) {
-        StringBuffer buf = new StringBuffer();
-        buf.append('(');
-        for (int i = 0; i < argumentTypes.length; ++i) {
-            argumentTypes[i].getDescriptor(buf);
-        }
-        buf.append(')');
-        returnType.getDescriptor(buf);
-        return buf.toString();
-    }
-
-    /**
-     * Appends the descriptor corresponding to this Java type to the given
-     * string buffer.
-     *
-     * @param buf
-     *            the string buffer to which the descriptor must be appended.
-     */
-    private void getDescriptor(final StringBuffer buf) {
-        if (this.buf == null) {
-            // descriptor is in byte 3 of 'off' for primitive types (buf ==
-            // null)
-            buf.append((char) ((off & 0xFF000000) >>> 24));
-        } else if (sort == OBJECT) {
-            buf.append('L');
-            buf.append(this.buf, off, len);
-            buf.append(';');
-        } else { // sort == ARRAY || sort == METHOD
-            buf.append(this.buf, off, len);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Direct conversion from classes to type descriptors,
-    // without intermediate Type objects
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the internal name of the given class. The internal name of a
-     * class is its fully qualified name, as returned by Class.getName(), where
-     * '.' are replaced by '/'.
-     *
-     * @param c
-     *            an object or array class.
-     * @return the internal name of the given class.
-     */
-    public static String getInternalName(final Class<?> c) {
-        return c.getName().replace('.', '/');
-    }
-
-    /**
-     * Returns the descriptor corresponding to the given Java type.
-     *
-     * @param c
-     *            an object class, a primitive class or an array class.
-     * @return the descriptor corresponding to the given class.
-     */
-    public static String getDescriptor(final Class<?> c) {
-        StringBuffer buf = new StringBuffer();
-        getDescriptor(buf, c);
-        return buf.toString();
-    }
-
-    /**
-     * Returns the descriptor corresponding to the given constructor.
-     *
-     * @param c
-     *            a {@link Constructor Constructor} object.
-     * @return the descriptor of the given constructor.
-     */
-    public static String getConstructorDescriptor(final Constructor<?> c) {
-        Class<?>[] parameters = c.getParameterTypes();
-        StringBuffer buf = new StringBuffer();
-        buf.append('(');
-        for (int i = 0; i < parameters.length; ++i) {
-            getDescriptor(buf, parameters[i]);
-        }
-        return buf.append(")V").toString();
-    }
-
-    /**
-     * Returns the descriptor corresponding to the given method.
-     *
-     * @param m
-     *            a {@link Method Method} object.
-     * @return the descriptor of the given method.
-     */
-    public static String getMethodDescriptor(final Method m) {
-        Class<?>[] parameters = m.getParameterTypes();
-        StringBuffer buf = new StringBuffer();
-        buf.append('(');
-        for (int i = 0; i < parameters.length; ++i) {
-            getDescriptor(buf, parameters[i]);
-        }
-        buf.append(')');
-        getDescriptor(buf, m.getReturnType());
-        return buf.toString();
-    }
-
-    /**
-     * Appends the descriptor of the given class to the given string buffer.
-     *
-     * @param buf
-     *            the string buffer to which the descriptor must be appended.
-     * @param c
-     *            the class whose descriptor must be computed.
-     */
-    private static void getDescriptor(final StringBuffer buf, final Class<?> c) {
-        Class<?> d = c;
-        while (true) {
-            if (d.isPrimitive()) {
-                char car;
-                if (d == Integer.TYPE) {
-                    car = 'I';
-                } else if (d == Void.TYPE) {
-                    car = 'V';
-                } else if (d == Boolean.TYPE) {
-                    car = 'Z';
-                } else if (d == Byte.TYPE) {
-                    car = 'B';
-                } else if (d == Character.TYPE) {
-                    car = 'C';
-                } else if (d == Short.TYPE) {
-                    car = 'S';
-                } else if (d == Double.TYPE) {
-                    car = 'D';
-                } else if (d == Float.TYPE) {
-                    car = 'F';
-                } else /* if (d == Long.TYPE) */{
-                    car = 'J';
-                }
-                buf.append(car);
-                return;
-            } else if (d.isArray()) {
-                buf.append('[');
-                d = d.getComponentType();
-            } else {
-                buf.append('L');
-                String name = d.getName();
-                int len = name.length();
-                for (int i = 0; i < len; ++i) {
-                    char car = name.charAt(i);
-                    buf.append(car == '.' ? '/' : car);
-                }
-                buf.append(';');
-                return;
-            }
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Corresponding size and opcodes
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the size of values of this type. This method must not be used for
-     * method types.
-     *
-     * @return the size of values of this type, i.e., 2 for <tt>long</tt> and
-     *         <tt>double</tt>, 0 for <tt>void</tt> and 1 otherwise.
-     */
-    public int getSize() {
-        // the size is in byte 0 of 'off' for primitive types (buf == null)
-        return buf == null ? (off & 0xFF) : 1;
-    }
-
-    /**
-     * Returns a JVM instruction opcode adapted to this Java type. This method
-     * must not be used for method types.
-     *
-     * @param opcode
-     *            a JVM instruction opcode. This opcode must be one of ILOAD,
-     *            ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG,
-     *            ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
-     * @return an opcode that is similar to the given opcode, but adapted to
-     *         this Java type. For example, if this type is <tt>float</tt> and
-     *         <tt>opcode</tt> is IRETURN, this method returns FRETURN.
-     */
-    public int getOpcode(final int opcode) {
-        if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
-            // the offset for IALOAD or IASTORE is in byte 1 of 'off' for
-            // primitive types (buf == null)
-            return opcode + (buf == null ? (off & 0xFF00) >> 8 : 4);
-        } else {
-            // the offset for other instructions is in byte 2 of 'off' for
-            // primitive types (buf == null)
-            return opcode + (buf == null ? (off & 0xFF0000) >> 16 : 4);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Equals, hashCode and toString
-    // ------------------------------------------------------------------------
-
-    /**
-     * Tests if the given object is equal to this type.
-     *
-     * @param o
-     *            the object to be compared to this type.
-     * @return <tt>true</tt> if the given object is equal to this type.
-     */
-    @Override
-    public boolean equals(final Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof Type)) {
-            return false;
-        }
-        Type t = (Type) o;
-        if (sort != t.sort) {
-            return false;
-        }
-        if (sort >= ARRAY) {
-            if (len != t.len) {
-                return false;
-            }
-            for (int i = off, j = t.off, end = i + len; i < end; i++, j++) {
-                if (buf[i] != t.buf[j]) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Returns a hash code value for this type.
-     *
-     * @return a hash code value for this type.
-     */
-    @Override
-    public int hashCode() {
-        int hc = 13 * sort;
-        if (sort >= ARRAY) {
-            for (int i = off, end = i + len; i < end; i++) {
-                hc = 17 * (hc + buf[i]);
-            }
-        }
-        return hc;
-    }
-
-    /**
-     * Returns a string representation of this type.
-     *
-     * @return the descriptor of this type.
-     */
-    @Override
-    public String toString() {
-        return getDescriptor();
-    }
-}
diff --git a/src/jvm/clojure/asm/commons/AdviceAdapter.java b/src/jvm/clojure/asm/commons/AdviceAdapter.java
deleted file mode 100644
index 8ec38d2..0000000
--- a/src/jvm/clojure/asm/commons/AdviceAdapter.java
+++ /dev/null
@@ -1,625 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import clojure.asm.Handle;
-import clojure.asm.Label;
-import clojure.asm.MethodVisitor;
-import clojure.asm.Opcodes;
-import clojure.asm.Type;
-
-/**
- * A {@link clojure.asm.MethodVisitor} to insert before, after and around
- * advices in methods and constructors.
- * <p>
- * The behavior for constructors is like this:
- * <ol>
- *
- * <li>as long as the INVOKESPECIAL for the object initialization has not been
- * reached, every bytecode instruction is dispatched in the ctor code visitor</li>
- *
- * <li>when this one is reached, it is only added in the ctor code visitor and a
- * JP invoke is added</li>
- *
- * <li>after that, only the other code visitor receives the instructions</li>
- *
- * </ol>
- *
- * @author Eugene Kuleshov
- * @author Eric Bruneton
- */
-public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes {
-
-    private static final Object THIS = new Object();
-
-    private static final Object OTHER = new Object();
-
-    protected int methodAccess;
-
-    protected String methodDesc;
-
-    private boolean constructor;
-
-    private boolean superInitialized;
-
-    private List<Object> stackFrame;
-
-    private Map<Label, List<Object>> branches;
-
-    /**
-     * Creates a new {@link AdviceAdapter}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param mv
-     *            the method visitor to which this adapter delegates calls.
-     * @param access
-     *            the method's access flags (see {@link Opcodes}).
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     */
-    protected AdviceAdapter(final int api, final MethodVisitor mv,
-            final int access, final String name, final String desc) {
-        super(api, mv, access, name, desc);
-        methodAccess = access;
-        methodDesc = desc;
-        constructor = "<init>".equals(name);
-    }
-
-    @Override
-    public void visitCode() {
-        mv.visitCode();
-        if (constructor) {
-            stackFrame = new ArrayList<Object>();
-            branches = new HashMap<Label, List<Object>>();
-        } else {
-            superInitialized = true;
-            onMethodEnter();
-        }
-    }
-
-    @Override
-    public void visitLabel(final Label label) {
-        mv.visitLabel(label);
-        if (constructor && branches != null) {
-            List<Object> frame = branches.get(label);
-            if (frame != null) {
-                stackFrame = frame;
-                branches.remove(label);
-            }
-        }
-    }
-
-    @Override
-    public void visitInsn(final int opcode) {
-        if (constructor) {
-            int s;
-            switch (opcode) {
-            case RETURN: // empty stack
-                onMethodExit(opcode);
-                break;
-            case IRETURN: // 1 before n/a after
-            case FRETURN: // 1 before n/a after
-            case ARETURN: // 1 before n/a after
-            case ATHROW: // 1 before n/a after
-                popValue();
-                onMethodExit(opcode);
-                break;
-            case LRETURN: // 2 before n/a after
-            case DRETURN: // 2 before n/a after
-                popValue();
-                popValue();
-                onMethodExit(opcode);
-                break;
-            case NOP:
-            case LALOAD: // remove 2 add 2
-            case DALOAD: // remove 2 add 2
-            case LNEG:
-            case DNEG:
-            case FNEG:
-            case INEG:
-            case L2D:
-            case D2L:
-            case F2I:
-            case I2B:
-            case I2C:
-            case I2S:
-            case I2F:
-            case ARRAYLENGTH:
-                break;
-            case ACONST_NULL:
-            case ICONST_M1:
-            case ICONST_0:
-            case ICONST_1:
-            case ICONST_2:
-            case ICONST_3:
-            case ICONST_4:
-            case ICONST_5:
-            case FCONST_0:
-            case FCONST_1:
-            case FCONST_2:
-            case F2L: // 1 before 2 after
-            case F2D:
-            case I2L:
-            case I2D:
-                pushValue(OTHER);
-                break;
-            case LCONST_0:
-            case LCONST_1:
-            case DCONST_0:
-            case DCONST_1:
-                pushValue(OTHER);
-                pushValue(OTHER);
-                break;
-            case IALOAD: // remove 2 add 1
-            case FALOAD: // remove 2 add 1
-            case AALOAD: // remove 2 add 1
-            case BALOAD: // remove 2 add 1
-            case CALOAD: // remove 2 add 1
-            case SALOAD: // remove 2 add 1
-            case POP:
-            case IADD:
-            case FADD:
-            case ISUB:
-            case LSHL: // 3 before 2 after
-            case LSHR: // 3 before 2 after
-            case LUSHR: // 3 before 2 after
-            case L2I: // 2 before 1 after
-            case L2F: // 2 before 1 after
-            case D2I: // 2 before 1 after
-            case D2F: // 2 before 1 after
-            case FSUB:
-            case FMUL:
-            case FDIV:
-            case FREM:
-            case FCMPL: // 2 before 1 after
-            case FCMPG: // 2 before 1 after
-            case IMUL:
-            case IDIV:
-            case IREM:
-            case ISHL:
-            case ISHR:
-            case IUSHR:
-            case IAND:
-            case IOR:
-            case IXOR:
-            case MONITORENTER:
-            case MONITOREXIT:
-                popValue();
-                break;
-            case POP2:
-            case LSUB:
-            case LMUL:
-            case LDIV:
-            case LREM:
-            case LADD:
-            case LAND:
-            case LOR:
-            case LXOR:
-            case DADD:
-            case DMUL:
-            case DSUB:
-            case DDIV:
-            case DREM:
-                popValue();
-                popValue();
-                break;
-            case IASTORE:
-            case FASTORE:
-            case AASTORE:
-            case BASTORE:
-            case CASTORE:
-            case SASTORE:
-            case LCMP: // 4 before 1 after
-            case DCMPL:
-            case DCMPG:
-                popValue();
-                popValue();
-                popValue();
-                break;
-            case LASTORE:
-            case DASTORE:
-                popValue();
-                popValue();
-                popValue();
-                popValue();
-                break;
-            case DUP:
-                pushValue(peekValue());
-                break;
-            case DUP_X1:
-                s = stackFrame.size();
-                stackFrame.add(s - 2, stackFrame.get(s - 1));
-                break;
-            case DUP_X2:
-                s = stackFrame.size();
-                stackFrame.add(s - 3, stackFrame.get(s - 1));
-                break;
-            case DUP2:
-                s = stackFrame.size();
-                stackFrame.add(s - 2, stackFrame.get(s - 1));
-                stackFrame.add(s - 2, stackFrame.get(s - 1));
-                break;
-            case DUP2_X1:
-                s = stackFrame.size();
-                stackFrame.add(s - 3, stackFrame.get(s - 1));
-                stackFrame.add(s - 3, stackFrame.get(s - 1));
-                break;
-            case DUP2_X2:
-                s = stackFrame.size();
-                stackFrame.add(s - 4, stackFrame.get(s - 1));
-                stackFrame.add(s - 4, stackFrame.get(s - 1));
-                break;
-            case SWAP:
-                s = stackFrame.size();
-                stackFrame.add(s - 2, stackFrame.get(s - 1));
-                stackFrame.remove(s);
-                break;
-            }
-        } else {
-            switch (opcode) {
-            case RETURN:
-            case IRETURN:
-            case FRETURN:
-            case ARETURN:
-            case LRETURN:
-            case DRETURN:
-            case ATHROW:
-                onMethodExit(opcode);
-                break;
-            }
-        }
-        mv.visitInsn(opcode);
-    }
-
-    @Override
-    public void visitVarInsn(final int opcode, final int var) {
-        super.visitVarInsn(opcode, var);
-        if (constructor) {
-            switch (opcode) {
-            case ILOAD:
-            case FLOAD:
-                pushValue(OTHER);
-                break;
-            case LLOAD:
-            case DLOAD:
-                pushValue(OTHER);
-                pushValue(OTHER);
-                break;
-            case ALOAD:
-                pushValue(var == 0 ? THIS : OTHER);
-                break;
-            case ASTORE:
-            case ISTORE:
-            case FSTORE:
-                popValue();
-                break;
-            case LSTORE:
-            case DSTORE:
-                popValue();
-                popValue();
-                break;
-            }
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        mv.visitFieldInsn(opcode, owner, name, desc);
-        if (constructor) {
-            char c = desc.charAt(0);
-            boolean longOrDouble = c == 'J' || c == 'D';
-            switch (opcode) {
-            case GETSTATIC:
-                pushValue(OTHER);
-                if (longOrDouble) {
-                    pushValue(OTHER);
-                }
-                break;
-            case PUTSTATIC:
-                popValue();
-                if (longOrDouble) {
-                    popValue();
-                }
-                break;
-            case PUTFIELD:
-                popValue();
-                if (longOrDouble) {
-                    popValue();
-                    popValue();
-                }
-                break;
-            // case GETFIELD:
-            default:
-                if (longOrDouble) {
-                    pushValue(OTHER);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void visitIntInsn(final int opcode, final int operand) {
-        mv.visitIntInsn(opcode, operand);
-        if (constructor && opcode != NEWARRAY) {
-            pushValue(OTHER);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(final Object cst) {
-        mv.visitLdcInsn(cst);
-        if (constructor) {
-            pushValue(OTHER);
-            if (cst instanceof Double || cst instanceof Long) {
-                pushValue(OTHER);
-            }
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
-        mv.visitMultiANewArrayInsn(desc, dims);
-        if (constructor) {
-            for (int i = 0; i < dims; i++) {
-                popValue();
-            }
-            pushValue(OTHER);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(final int opcode, final String type) {
-        mv.visitTypeInsn(opcode, type);
-        // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack
-        if (constructor && opcode == NEW) {
-            pushValue(OTHER);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        mv.visitMethodInsn(opcode, owner, name, desc);
-        if (constructor) {
-            Type[] types = Type.getArgumentTypes(desc);
-            for (int i = 0; i < types.length; i++) {
-                popValue();
-                if (types[i].getSize() == 2) {
-                    popValue();
-                }
-            }
-            switch (opcode) {
-            // case INVOKESTATIC:
-            // break;
-            case INVOKEINTERFACE:
-            case INVOKEVIRTUAL:
-                popValue(); // objectref
-                break;
-            case INVOKESPECIAL:
-                Object type = popValue(); // objectref
-                if (type == THIS && !superInitialized) {
-                    onMethodEnter();
-                    superInitialized = true;
-                    // once super has been initialized it is no longer
-                    // necessary to keep track of stack state
-                    constructor = false;
-                }
-                break;
-            }
-
-            Type returnType = Type.getReturnType(desc);
-            if (returnType != Type.VOID_TYPE) {
-                pushValue(OTHER);
-                if (returnType.getSize() == 2) {
-                    pushValue(OTHER);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
-            Object... bsmArgs) {
-        mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-        if (constructor) {
-            Type[] types = Type.getArgumentTypes(desc);
-            for (int i = 0; i < types.length; i++) {
-                popValue();
-                if (types[i].getSize() == 2) {
-                    popValue();
-                }
-            }
-
-            Type returnType = Type.getReturnType(desc);
-            if (returnType != Type.VOID_TYPE) {
-                pushValue(OTHER);
-                if (returnType.getSize() == 2) {
-                    pushValue(OTHER);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
-        mv.visitJumpInsn(opcode, label);
-        if (constructor) {
-            switch (opcode) {
-            case IFEQ:
-            case IFNE:
-            case IFLT:
-            case IFGE:
-            case IFGT:
-            case IFLE:
-            case IFNULL:
-            case IFNONNULL:
-                popValue();
-                break;
-            case IF_ICMPEQ:
-            case IF_ICMPNE:
-            case IF_ICMPLT:
-            case IF_ICMPGE:
-            case IF_ICMPGT:
-            case IF_ICMPLE:
-            case IF_ACMPEQ:
-            case IF_ACMPNE:
-                popValue();
-                popValue();
-                break;
-            case JSR:
-                pushValue(OTHER);
-                break;
-            }
-            addBranch(label);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
-            final Label[] labels) {
-        mv.visitLookupSwitchInsn(dflt, keys, labels);
-        if (constructor) {
-            popValue();
-            addBranches(dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(final int min, final int max,
-            final Label dflt, final Label... labels) {
-        mv.visitTableSwitchInsn(min, max, dflt, labels);
-        if (constructor) {
-            popValue();
-            addBranches(dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitTryCatchBlock(Label start, Label end, Label handler,
-            String type) {
-        super.visitTryCatchBlock(start, end, handler, type);
-        if (constructor && !branches.containsKey(handler)) {
-            List<Object> stackFrame = new ArrayList<Object>();
-            stackFrame.add(OTHER);
-            branches.put(handler, stackFrame);
-        }
-    }
-
-    private void addBranches(final Label dflt, final Label[] labels) {
-        addBranch(dflt);
-        for (int i = 0; i < labels.length; i++) {
-            addBranch(labels[i]);
-        }
-    }
-
-    private void addBranch(final Label label) {
-        if (branches.containsKey(label)) {
-            return;
-        }
-        branches.put(label, new ArrayList<Object>(stackFrame));
-    }
-
-    private Object popValue() {
-        return stackFrame.remove(stackFrame.size() - 1);
-    }
-
-    private Object peekValue() {
-        return stackFrame.get(stackFrame.size() - 1);
-    }
-
-    private void pushValue(final Object o) {
-        stackFrame.add(o);
-    }
-
-    /**
-     * Called at the beginning of the method or after super class class call in
-     * the constructor. <br>
-     * <br>
-     *
-     * <i>Custom code can use or change all the local variables, but should not
-     * change state of the stack.</i>
-     */
-    protected void onMethodEnter() {
-    }
-
-    /**
-     * Called before explicit exit from the method using either return or throw.
-     * Top element on the stack contains the return value or exception instance.
-     * For example:
-     *
-     * <pre>
-     *   public void onMethodExit(int opcode) {
-     *     if(opcode==RETURN) {
-     *         visitInsn(ACONST_NULL);
-     *     } else if(opcode==ARETURN || opcode==ATHROW) {
-     *         dup();
-     *     } else {
-     *         if(opcode==LRETURN || opcode==DRETURN) {
-     *             dup2();
-     *         } else {
-     *             dup();
-     *         }
-     *         box(Type.getReturnType(this.methodDesc));
-     *     }
-     *     visitIntInsn(SIPUSH, opcode);
-     *     visitMethodInsn(INVOKESTATIC, owner, "onExit", "(Ljava/lang/Object;I)V");
-     *   }
-     *
-     *   // an actual call back method
-     *   public static void onExit(Object param, int opcode) {
-     *     ...
-     * </pre>
-     *
-     * <br>
-     * <br>
-     *
-     * <i>Custom code can use or change all the local variables, but should not
-     * change state of the stack.</i>
-     *
-     * @param opcode
-     *            one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN, DRETURN
-     *            or ATHROW
-     *
-     */
-    protected void onMethodExit(int opcode) {
-    }
-
-    // TODO onException, onMethodCall
-}
diff --git a/src/jvm/clojure/asm/commons/AnalyzerAdapter.java b/src/jvm/clojure/asm/commons/AnalyzerAdapter.java
deleted file mode 100644
index 429d8db..0000000
--- a/src/jvm/clojure/asm/commons/AnalyzerAdapter.java
+++ /dev/null
@@ -1,920 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import clojure.asm.Handle;
-import clojure.asm.Label;
-import clojure.asm.MethodVisitor;
-import clojure.asm.Opcodes;
-import clojure.asm.Type;
-
-/**
- * A {@link MethodVisitor} that keeps track of stack map frame changes between
- * {@link #visitFrame(int, int, Object[], int, Object[]) visitFrame} calls. This
- * adapter must be used with the
- * {@link clojure.asm.ClassReader#EXPAND_FRAMES} option. Each
- * visit<i>X</i> instruction delegates to the next visitor in the chain, if any,
- * and then simulates the effect of this instruction on the stack map frame,
- * represented by {@link #locals} and {@link #stack}. The next visitor in the
- * chain can get the state of the stack map frame <i>before</i> each instruction
- * by reading the value of these fields in its visit<i>X</i> methods (this
- * requires a reference to the AnalyzerAdapter that is before it in the chain).
- * If this adapter is used with a class that does not contain stack map table
- * attributes (i.e., pre Java 6 classes) then this adapter may not be able to
- * compute the stack map frame for each instruction. In this case no exception
- * is thrown but the {@link #locals} and {@link #stack} fields will be null for
- * these instructions.
- *
- * @author Eric Bruneton
- */
-public class AnalyzerAdapter extends MethodVisitor {
-
-    /**
-     * <code>List</code> of the local variable slots for current execution
-     * frame. Primitive types are represented by {@link Opcodes#TOP},
-     * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
-     * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
-     * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by
-     * two elements, the second one being TOP). Reference types are represented
-     * by String objects (representing internal names), and uninitialized types
-     * by Label objects (this label designates the NEW instruction that created
-     * this uninitialized value). This field is <tt>null</tt> for unreachable
-     * instructions.
-     */
-    public List<Object> locals;
-
-    /**
-     * <code>List</code> of the operand stack slots for current execution frame.
-     * Primitive types are represented by {@link Opcodes#TOP},
-     * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
-     * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
-     * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by
-     * two elements, the second one being TOP). Reference types are represented
-     * by String objects (representing internal names), and uninitialized types
-     * by Label objects (this label designates the NEW instruction that created
-     * this uninitialized value). This field is <tt>null</tt> for unreachable
-     * instructions.
-     */
-    public List<Object> stack;
-
-    /**
-     * The labels that designate the next instruction to be visited. May be
-     * <tt>null</tt>.
-     */
-    private List<Label> labels;
-
-    /**
-     * Information about uninitialized types in the current execution frame.
-     * This map associates internal names to Label objects. Each label
-     * designates a NEW instruction that created the currently uninitialized
-     * types, and the associated internal name represents the NEW operand, i.e.
-     * the final, initialized type value.
-     */
-    public Map<Object, Object> uninitializedTypes;
-
-    /**
-     * The maximum stack size of this method.
-     */
-    private int maxStack;
-
-    /**
-     * The maximum number of local variables of this method.
-     */
-    private int maxLocals;
-
-    /**
-     * The owner's class name.
-     */
-    private String owner;
-
-    /**
-     * Creates a new {@link AnalyzerAdapter}. <i>Subclasses must not use this
-     * constructor</i>. Instead, they must use the
-     * {@link #AnalyzerAdapter(int, String, int, String, String, MethodVisitor)}
-     * version.
-     *
-     * @param owner
-     *            the owner's class name.
-     * @param access
-     *            the method's access flags (see {@link Opcodes}).
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     * @param mv
-     *            the method visitor to which this adapter delegates calls. May
-     *            be <tt>null</tt>.
-     */
-    public AnalyzerAdapter(final String owner, final int access,
-            final String name, final String desc, final MethodVisitor mv) {
-        this(Opcodes.ASM4, owner, access, name, desc, mv);
-    }
-
-    /**
-     * Creates a new {@link AnalyzerAdapter}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param owner
-     *            the owner's class name.
-     * @param access
-     *            the method's access flags (see {@link Opcodes}).
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     * @param mv
-     *            the method visitor to which this adapter delegates calls. May
-     *            be <tt>null</tt>.
-     */
-    protected AnalyzerAdapter(final int api, final String owner,
-            final int access, final String name, final String desc,
-            final MethodVisitor mv) {
-        super(api, mv);
-        this.owner = owner;
-        locals = new ArrayList<Object>();
-        stack = new ArrayList<Object>();
-        uninitializedTypes = new HashMap<Object, Object>();
-
-        if ((access & Opcodes.ACC_STATIC) == 0) {
-            if ("<init>".equals(name)) {
-                locals.add(Opcodes.UNINITIALIZED_THIS);
-            } else {
-                locals.add(owner);
-            }
-        }
-        Type[] types = Type.getArgumentTypes(desc);
-        for (int i = 0; i < types.length; ++i) {
-            Type type = types[i];
-            switch (type.getSort()) {
-            case Type.BOOLEAN:
-            case Type.CHAR:
-            case Type.BYTE:
-            case Type.SHORT:
-            case Type.INT:
-                locals.add(Opcodes.INTEGER);
-                break;
-            case Type.FLOAT:
-                locals.add(Opcodes.FLOAT);
-                break;
-            case Type.LONG:
-                locals.add(Opcodes.LONG);
-                locals.add(Opcodes.TOP);
-                break;
-            case Type.DOUBLE:
-                locals.add(Opcodes.DOUBLE);
-                locals.add(Opcodes.TOP);
-                break;
-            case Type.ARRAY:
-                locals.add(types[i].getDescriptor());
-                break;
-            // case Type.OBJECT:
-            default:
-                locals.add(types[i].getInternalName());
-            }
-        }
-    }
-
-    @Override
-    public void visitFrame(final int type, final int nLocal,
-            final Object[] local, final int nStack, final Object[] stack) {
-        if (type != Opcodes.F_NEW) { // uncompressed frame
-            throw new IllegalStateException(
-                    "ClassReader.accept() should be called with EXPAND_FRAMES flag");
-        }
-
-        if (mv != null) {
-            mv.visitFrame(type, nLocal, local, nStack, stack);
-        }
-
-        if (this.locals != null) {
-            this.locals.clear();
-            this.stack.clear();
-        } else {
-            this.locals = new ArrayList<Object>();
-            this.stack = new ArrayList<Object>();
-        }
-        visitFrameTypes(nLocal, local, this.locals);
-        visitFrameTypes(nStack, stack, this.stack);
-        maxStack = Math.max(maxStack, this.stack.size());
-    }
-
-    private static void visitFrameTypes(final int n, final Object[] types,
-            final List<Object> result) {
-        for (int i = 0; i < n; ++i) {
-            Object type = types[i];
-            result.add(type);
-            if (type == Opcodes.LONG || type == Opcodes.DOUBLE) {
-                result.add(Opcodes.TOP);
-            }
-        }
-    }
-
-    @Override
-    public void visitInsn(final int opcode) {
-        if (mv != null) {
-            mv.visitInsn(opcode);
-        }
-        execute(opcode, 0, null);
-        if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
-                || opcode == Opcodes.ATHROW) {
-            this.locals = null;
-            this.stack = null;
-        }
-    }
-
-    @Override
-    public void visitIntInsn(final int opcode, final int operand) {
-        if (mv != null) {
-            mv.visitIntInsn(opcode, operand);
-        }
-        execute(opcode, operand, null);
-    }
-
-    @Override
-    public void visitVarInsn(final int opcode, final int var) {
-        if (mv != null) {
-            mv.visitVarInsn(opcode, var);
-        }
-        execute(opcode, var, null);
-    }
-
-    @Override
-    public void visitTypeInsn(final int opcode, final String type) {
-        if (opcode == Opcodes.NEW) {
-            if (labels == null) {
-                Label l = new Label();
-                labels = new ArrayList<Label>(3);
-                labels.add(l);
-                if (mv != null) {
-                    mv.visitLabel(l);
-                }
-            }
-            for (int i = 0; i < labels.size(); ++i) {
-                uninitializedTypes.put(labels.get(i), type);
-            }
-        }
-        if (mv != null) {
-            mv.visitTypeInsn(opcode, type);
-        }
-        execute(opcode, 0, type);
-    }
-
-    @Override
-    public void visitFieldInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        if (mv != null) {
-            mv.visitFieldInsn(opcode, owner, name, desc);
-        }
-        execute(opcode, 0, desc);
-    }
-
-    @Override
-    public void visitMethodInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        if (mv != null) {
-            mv.visitMethodInsn(opcode, owner, name, desc);
-        }
-        if (this.locals == null) {
-            labels = null;
-            return;
-        }
-        pop(desc);
-        if (opcode != Opcodes.INVOKESTATIC) {
-            Object t = pop();
-            if (opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') {
-                Object u;
-                if (t == Opcodes.UNINITIALIZED_THIS) {
-                    u = this.owner;
-                } else {
-                    u = uninitializedTypes.get(t);
-                }
-                for (int i = 0; i < locals.size(); ++i) {
-                    if (locals.get(i) == t) {
-                        locals.set(i, u);
-                    }
-                }
-                for (int i = 0; i < stack.size(); ++i) {
-                    if (stack.get(i) == t) {
-                        stack.set(i, u);
-                    }
-                }
-            }
-        }
-        pushDesc(desc);
-        labels = null;
-    }
-
-    @Override
-    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
-            Object... bsmArgs) {
-        if (mv != null) {
-            mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-        }
-        if (this.locals == null) {
-            labels = null;
-            return;
-        }
-        pop(desc);
-        pushDesc(desc);
-        labels = null;
-    }
-
-    @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
-        if (mv != null) {
-            mv.visitJumpInsn(opcode, label);
-        }
-        execute(opcode, 0, null);
-        if (opcode == Opcodes.GOTO) {
-            this.locals = null;
-            this.stack = null;
-        }
-    }
-
-    @Override
-    public void visitLabel(final Label label) {
-        if (mv != null) {
-            mv.visitLabel(label);
-        }
-        if (labels == null) {
-            labels = new ArrayList<Label>(3);
-        }
-        labels.add(label);
-    }
-
-    @Override
-    public void visitLdcInsn(final Object cst) {
-        if (mv != null) {
-            mv.visitLdcInsn(cst);
-        }
-        if (this.locals == null) {
-            labels = null;
-            return;
-        }
-        if (cst instanceof Integer) {
-            push(Opcodes.INTEGER);
-        } else if (cst instanceof Long) {
-            push(Opcodes.LONG);
-            push(Opcodes.TOP);
-        } else if (cst instanceof Float) {
-            push(Opcodes.FLOAT);
-        } else if (cst instanceof Double) {
-            push(Opcodes.DOUBLE);
-            push(Opcodes.TOP);
-        } else if (cst instanceof String) {
-            push("java/lang/String");
-        } else if (cst instanceof Type) {
-            int sort = ((Type) cst).getSort();
-            if (sort == Type.OBJECT || sort == Type.ARRAY) {
-                push("java/lang/Class");
-            } else if (sort == Type.METHOD) {
-                push("java/lang/invoke/MethodType");
-            } else {
-                throw new IllegalArgumentException();
-            }
-        } else if (cst instanceof Handle) {
-            push("java/lang/invoke/MethodHandle");
-        } else {
-            throw new IllegalArgumentException();
-        }
-        labels = null;
-    }
-
-    @Override
-    public void visitIincInsn(final int var, final int increment) {
-        if (mv != null) {
-            mv.visitIincInsn(var, increment);
-        }
-        execute(Opcodes.IINC, var, null);
-    }
-
-    @Override
-    public void visitTableSwitchInsn(final int min, final int max,
-            final Label dflt, final Label... labels) {
-        if (mv != null) {
-            mv.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-        execute(Opcodes.TABLESWITCH, 0, null);
-        this.locals = null;
-        this.stack = null;
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
-            final Label[] labels) {
-        if (mv != null) {
-            mv.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-        execute(Opcodes.LOOKUPSWITCH, 0, null);
-        this.locals = null;
-        this.stack = null;
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
-        if (mv != null) {
-            mv.visitMultiANewArrayInsn(desc, dims);
-        }
-        execute(Opcodes.MULTIANEWARRAY, dims, desc);
-    }
-
-    @Override
-    public void visitMaxs(final int maxStack, final int maxLocals) {
-        if (mv != null) {
-            this.maxStack = Math.max(this.maxStack, maxStack);
-            this.maxLocals = Math.max(this.maxLocals, maxLocals);
-            mv.visitMaxs(this.maxStack, this.maxLocals);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-
-    private Object get(final int local) {
-        maxLocals = Math.max(maxLocals, local);
-        return local < locals.size() ? locals.get(local) : Opcodes.TOP;
-    }
-
-    private void set(final int local, final Object type) {
-        maxLocals = Math.max(maxLocals, local);
-        while (local >= locals.size()) {
-            locals.add(Opcodes.TOP);
-        }
-        locals.set(local, type);
-    }
-
-    private void push(final Object type) {
-        stack.add(type);
-        maxStack = Math.max(maxStack, stack.size());
-    }
-
-    private void pushDesc(final String desc) {
-        int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
-        switch (desc.charAt(index)) {
-        case 'V':
-            return;
-        case 'Z':
-        case 'C':
-        case 'B':
-        case 'S':
-        case 'I':
-            push(Opcodes.INTEGER);
-            return;
-        case 'F':
-            push(Opcodes.FLOAT);
-            return;
-        case 'J':
-            push(Opcodes.LONG);
-            push(Opcodes.TOP);
-            return;
-        case 'D':
-            push(Opcodes.DOUBLE);
-            push(Opcodes.TOP);
-            return;
-        case '[':
-            if (index == 0) {
-                push(desc);
-            } else {
-                push(desc.substring(index, desc.length()));
-            }
-            break;
-        // case 'L':
-        default:
-            if (index == 0) {
-                push(desc.substring(1, desc.length() - 1));
-            } else {
-                push(desc.substring(index + 1, desc.length() - 1));
-            }
-        }
-    }
-
-    private Object pop() {
-        return stack.remove(stack.size() - 1);
-    }
-
-    private void pop(final int n) {
-        int size = stack.size();
-        int end = size - n;
-        for (int i = size - 1; i >= end; --i) {
-            stack.remove(i);
-        }
-    }
-
-    private void pop(final String desc) {
-        char c = desc.charAt(0);
-        if (c == '(') {
-            int n = 0;
-            Type[] types = Type.getArgumentTypes(desc);
-            for (int i = 0; i < types.length; ++i) {
-                n += types[i].getSize();
-            }
-            pop(n);
-        } else if (c == 'J' || c == 'D') {
-            pop(2);
-        } else {
-            pop(1);
-        }
-    }
-
-    private void execute(final int opcode, final int iarg, final String sarg) {
-        if (this.locals == null) {
-            labels = null;
-            return;
-        }
-        Object t1, t2, t3, t4;
-        switch (opcode) {
-        case Opcodes.NOP:
-        case Opcodes.INEG:
-        case Opcodes.LNEG:
-        case Opcodes.FNEG:
-        case Opcodes.DNEG:
-        case Opcodes.I2B:
-        case Opcodes.I2C:
-        case Opcodes.I2S:
-        case Opcodes.GOTO:
-        case Opcodes.RETURN:
-            break;
-        case Opcodes.ACONST_NULL:
-            push(Opcodes.NULL);
-            break;
-        case Opcodes.ICONST_M1:
-        case Opcodes.ICONST_0:
-        case Opcodes.ICONST_1:
-        case Opcodes.ICONST_2:
-        case Opcodes.ICONST_3:
-        case Opcodes.ICONST_4:
-        case Opcodes.ICONST_5:
-        case Opcodes.BIPUSH:
-        case Opcodes.SIPUSH:
-            push(Opcodes.INTEGER);
-            break;
-        case Opcodes.LCONST_0:
-        case Opcodes.LCONST_1:
-            push(Opcodes.LONG);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.FCONST_0:
-        case Opcodes.FCONST_1:
-        case Opcodes.FCONST_2:
-            push(Opcodes.FLOAT);
-            break;
-        case Opcodes.DCONST_0:
-        case Opcodes.DCONST_1:
-            push(Opcodes.DOUBLE);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.ILOAD:
-        case Opcodes.FLOAD:
-        case Opcodes.ALOAD:
-            push(get(iarg));
-            break;
-        case Opcodes.LLOAD:
-        case Opcodes.DLOAD:
-            push(get(iarg));
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.IALOAD:
-        case Opcodes.BALOAD:
-        case Opcodes.CALOAD:
-        case Opcodes.SALOAD:
-            pop(2);
-            push(Opcodes.INTEGER);
-            break;
-        case Opcodes.LALOAD:
-        case Opcodes.D2L:
-            pop(2);
-            push(Opcodes.LONG);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.FALOAD:
-            pop(2);
-            push(Opcodes.FLOAT);
-            break;
-        case Opcodes.DALOAD:
-        case Opcodes.L2D:
-            pop(2);
-            push(Opcodes.DOUBLE);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.AALOAD:
-            pop(1);
-            t1 = pop();
-            if (t1 instanceof String) {
-                pushDesc(((String) t1).substring(1));
-            } else {
-                push("java/lang/Object");
-            }
-            break;
-        case Opcodes.ISTORE:
-        case Opcodes.FSTORE:
-        case Opcodes.ASTORE:
-            t1 = pop();
-            set(iarg, t1);
-            if (iarg > 0) {
-                t2 = get(iarg - 1);
-                if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
-                    set(iarg - 1, Opcodes.TOP);
-                }
-            }
-            break;
-        case Opcodes.LSTORE:
-        case Opcodes.DSTORE:
-            pop(1);
-            t1 = pop();
-            set(iarg, t1);
-            set(iarg + 1, Opcodes.TOP);
-            if (iarg > 0) {
-                t2 = get(iarg - 1);
-                if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
-                    set(iarg - 1, Opcodes.TOP);
-                }
-            }
-            break;
-        case Opcodes.IASTORE:
-        case Opcodes.BASTORE:
-        case Opcodes.CASTORE:
-        case Opcodes.SASTORE:
-        case Opcodes.FASTORE:
-        case Opcodes.AASTORE:
-            pop(3);
-            break;
-        case Opcodes.LASTORE:
-        case Opcodes.DASTORE:
-            pop(4);
-            break;
-        case Opcodes.POP:
-        case Opcodes.IFEQ:
-        case Opcodes.IFNE:
-        case Opcodes.IFLT:
-        case Opcodes.IFGE:
-        case Opcodes.IFGT:
-        case Opcodes.IFLE:
-        case Opcodes.IRETURN:
-        case Opcodes.FRETURN:
-        case Opcodes.ARETURN:
-        case Opcodes.TABLESWITCH:
-        case Opcodes.LOOKUPSWITCH:
-        case Opcodes.ATHROW:
-        case Opcodes.MONITORENTER:
-        case Opcodes.MONITOREXIT:
-        case Opcodes.IFNULL:
-        case Opcodes.IFNONNULL:
-            pop(1);
-            break;
-        case Opcodes.POP2:
-        case Opcodes.IF_ICMPEQ:
-        case Opcodes.IF_ICMPNE:
-        case Opcodes.IF_ICMPLT:
-        case Opcodes.IF_ICMPGE:
-        case Opcodes.IF_ICMPGT:
-        case Opcodes.IF_ICMPLE:
-        case Opcodes.IF_ACMPEQ:
-        case Opcodes.IF_ACMPNE:
-        case Opcodes.LRETURN:
-        case Opcodes.DRETURN:
-            pop(2);
-            break;
-        case Opcodes.DUP:
-            t1 = pop();
-            push(t1);
-            push(t1);
-            break;
-        case Opcodes.DUP_X1:
-            t1 = pop();
-            t2 = pop();
-            push(t1);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.DUP_X2:
-            t1 = pop();
-            t2 = pop();
-            t3 = pop();
-            push(t1);
-            push(t3);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.DUP2:
-            t1 = pop();
-            t2 = pop();
-            push(t2);
-            push(t1);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.DUP2_X1:
-            t1 = pop();
-            t2 = pop();
-            t3 = pop();
-            push(t2);
-            push(t1);
-            push(t3);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.DUP2_X2:
-            t1 = pop();
-            t2 = pop();
-            t3 = pop();
-            t4 = pop();
-            push(t2);
-            push(t1);
-            push(t4);
-            push(t3);
-            push(t2);
-            push(t1);
-            break;
-        case Opcodes.SWAP:
-            t1 = pop();
-            t2 = pop();
-            push(t1);
-            push(t2);
-            break;
-        case Opcodes.IADD:
-        case Opcodes.ISUB:
-        case Opcodes.IMUL:
-        case Opcodes.IDIV:
-        case Opcodes.IREM:
-        case Opcodes.IAND:
-        case Opcodes.IOR:
-        case Opcodes.IXOR:
-        case Opcodes.ISHL:
-        case Opcodes.ISHR:
-        case Opcodes.IUSHR:
-        case Opcodes.L2I:
-        case Opcodes.D2I:
-        case Opcodes.FCMPL:
-        case Opcodes.FCMPG:
-            pop(2);
-            push(Opcodes.INTEGER);
-            break;
-        case Opcodes.LADD:
-        case Opcodes.LSUB:
-        case Opcodes.LMUL:
-        case Opcodes.LDIV:
-        case Opcodes.LREM:
-        case Opcodes.LAND:
-        case Opcodes.LOR:
-        case Opcodes.LXOR:
-            pop(4);
-            push(Opcodes.LONG);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.FADD:
-        case Opcodes.FSUB:
-        case Opcodes.FMUL:
-        case Opcodes.FDIV:
-        case Opcodes.FREM:
-        case Opcodes.L2F:
-        case Opcodes.D2F:
-            pop(2);
-            push(Opcodes.FLOAT);
-            break;
-        case Opcodes.DADD:
-        case Opcodes.DSUB:
-        case Opcodes.DMUL:
-        case Opcodes.DDIV:
-        case Opcodes.DREM:
-            pop(4);
-            push(Opcodes.DOUBLE);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.LSHL:
-        case Opcodes.LSHR:
-        case Opcodes.LUSHR:
-            pop(3);
-            push(Opcodes.LONG);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.IINC:
-            set(iarg, Opcodes.INTEGER);
-            break;
-        case Opcodes.I2L:
-        case Opcodes.F2L:
-            pop(1);
-            push(Opcodes.LONG);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.I2F:
-            pop(1);
-            push(Opcodes.FLOAT);
-            break;
-        case Opcodes.I2D:
-        case Opcodes.F2D:
-            pop(1);
-            push(Opcodes.DOUBLE);
-            push(Opcodes.TOP);
-            break;
-        case Opcodes.F2I:
-        case Opcodes.ARRAYLENGTH:
-        case Opcodes.INSTANCEOF:
-            pop(1);
-            push(Opcodes.INTEGER);
-            break;
-        case Opcodes.LCMP:
-        case Opcodes.DCMPL:
-        case Opcodes.DCMPG:
-            pop(4);
-            push(Opcodes.INTEGER);
-            break;
-        case Opcodes.JSR:
-        case Opcodes.RET:
-            throw new RuntimeException("JSR/RET are not supported");
-        case Opcodes.GETSTATIC:
-            pushDesc(sarg);
-            break;
-        case Opcodes.PUTSTATIC:
-            pop(sarg);
-            break;
-        case Opcodes.GETFIELD:
-            pop(1);
-            pushDesc(sarg);
-            break;
-        case Opcodes.PUTFIELD:
-            pop(sarg);
-            pop();
-            break;
-        case Opcodes.NEW:
-            push(labels.get(0));
-            break;
-        case Opcodes.NEWARRAY:
-            pop();
-            switch (iarg) {
-            case Opcodes.T_BOOLEAN:
-                pushDesc("[Z");
-                break;
-            case Opcodes.T_CHAR:
-                pushDesc("[C");
-                break;
-            case Opcodes.T_BYTE:
-                pushDesc("[B");
-                break;
-            case Opcodes.T_SHORT:
-                pushDesc("[S");
-                break;
-            case Opcodes.T_INT:
-                pushDesc("[I");
-                break;
-            case Opcodes.T_FLOAT:
-                pushDesc("[F");
-                break;
-            case Opcodes.T_DOUBLE:
-                pushDesc("[D");
-                break;
-            // case Opcodes.T_LONG:
-            default:
-                pushDesc("[J");
-                break;
-            }
-            break;
-        case Opcodes.ANEWARRAY:
-            pop();
-            pushDesc("[" + Type.getObjectType(sarg));
-            break;
-        case Opcodes.CHECKCAST:
-            pop();
-            pushDesc(Type.getObjectType(sarg).getDescriptor());
-            break;
-        // case Opcodes.MULTIANEWARRAY:
-        default:
-            pop(iarg);
-            pushDesc(sarg);
-            break;
-        }
-        labels = null;
-    }
-}
diff --git a/src/jvm/clojure/asm/commons/CodeSizeEvaluator.java b/src/jvm/clojure/asm/commons/CodeSizeEvaluator.java
deleted file mode 100644
index 5a35bbf..0000000
--- a/src/jvm/clojure/asm/commons/CodeSizeEvaluator.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import clojure.asm.Handle;
-import clojure.asm.Label;
-import clojure.asm.MethodVisitor;
-import clojure.asm.Opcodes;
-
-/**
- * A {@link MethodVisitor} that can be used to approximate method size.
- *
- * @author Eugene Kuleshov
- */
-public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
-
-    private int minSize;
-
-    private int maxSize;
-
-    public CodeSizeEvaluator(final MethodVisitor mv) {
-        this(Opcodes.ASM4, mv);
-    }
-
-    protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
-        super(api, mv);
-    }
-
-    public int getMinSize() {
-        return this.minSize;
-    }
-
-    public int getMaxSize() {
-        return this.maxSize;
-    }
-
-    @Override
-    public void visitInsn(final int opcode) {
-        minSize += 1;
-        maxSize += 1;
-        if (mv != null) {
-            mv.visitInsn(opcode);
-        }
-    }
-
-    @Override
-    public void visitIntInsn(final int opcode, final int operand) {
-        if (opcode == SIPUSH) {
-            minSize += 3;
-            maxSize += 3;
-        } else {
-            minSize += 2;
-            maxSize += 2;
-        }
-        if (mv != null) {
-            mv.visitIntInsn(opcode, operand);
-        }
-    }
-
-    @Override
-    public void visitVarInsn(final int opcode, final int var) {
-        if (var < 4 && opcode != RET) {
-            minSize += 1;
-            maxSize += 1;
-        } else if (var >= 256) {
-            minSize += 4;
-            maxSize += 4;
-        } else {
-            minSize += 2;
-            maxSize += 2;
-        }
-        if (mv != null) {
-            mv.visitVarInsn(opcode, var);
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(final int opcode, final String type) {
-        minSize += 3;
-        maxSize += 3;
-        if (mv != null) {
-            mv.visitTypeInsn(opcode, type);
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        minSize += 3;
-        maxSize += 3;
-        if (mv != null) {
-            mv.visitFieldInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        if (opcode == INVOKEINTERFACE) {
-            minSize += 5;
-            maxSize += 5;
-        } else {
-            minSize += 3;
-            maxSize += 3;
-        }
-        if (mv != null) {
-            mv.visitMethodInsn(opcode, owner, name, desc);
-        }
-    }
-
-    @Override
-    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
-            Object... bsmArgs) {
-        minSize += 5;
-        maxSize += 5;
-        if (mv != null) {
-            mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-        }
-    }
-
-    @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
-        minSize += 3;
-        if (opcode == GOTO || opcode == JSR) {
-            maxSize += 5;
-        } else {
-            maxSize += 8;
-        }
-        if (mv != null) {
-            mv.visitJumpInsn(opcode, label);
-        }
-    }
-
-    @Override
-    public void visitLdcInsn(final Object cst) {
-        if (cst instanceof Long || cst instanceof Double) {
-            minSize += 3;
-            maxSize += 3;
-        } else {
-            minSize += 2;
-            maxSize += 3;
-        }
-        if (mv != null) {
-            mv.visitLdcInsn(cst);
-        }
-    }
-
-    @Override
-    public void visitIincInsn(final int var, final int increment) {
-        if (var > 255 || increment > 127 || increment < -128) {
-            minSize += 6;
-            maxSize += 6;
-        } else {
-            minSize += 3;
-            maxSize += 3;
-        }
-        if (mv != null) {
-            mv.visitIincInsn(var, increment);
-        }
-    }
-
-    @Override
-    public void visitTableSwitchInsn(final int min, final int max,
-            final Label dflt, final Label... labels) {
-        minSize += 13 + labels.length * 4;
-        maxSize += 16 + labels.length * 4;
-        if (mv != null) {
-            mv.visitTableSwitchInsn(min, max, dflt, labels);
-        }
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
-            final Label[] labels) {
-        minSize += 9 + keys.length * 8;
-        maxSize += 12 + keys.length * 8;
-        if (mv != null) {
-            mv.visitLookupSwitchInsn(dflt, keys, labels);
-        }
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
-        minSize += 4;
-        maxSize += 4;
-        if (mv != null) {
-            mv.visitMultiANewArrayInsn(desc, dims);
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/commons/GeneratorAdapter.java b/src/jvm/clojure/asm/commons/GeneratorAdapter.java
deleted file mode 100644
index 8727478..0000000
--- a/src/jvm/clojure/asm/commons/GeneratorAdapter.java
+++ /dev/null
@@ -1,1623 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import clojure.asm.ClassVisitor;
-import clojure.asm.Handle;
-import clojure.asm.Label;
-import clojure.asm.MethodVisitor;
-import clojure.asm.Opcodes;
-import clojure.asm.Type;
-
-/**
- * A {@link clojure.asm.MethodVisitor} with convenient methods to generate
- * code. For example, using this adapter, the class below
- *
- * <pre>
- * public class Example {
- *     public static void main(String[] args) {
- *         System.out.println("Hello world!");
- *     }
- * }
- * </pre>
- *
- * can be generated as follows:
- *
- * <pre>
- * ClassWriter cw = new ClassWriter(true);
- * cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
- *
- * Method m = Method.getMethod("void <init> ()");
- * GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);
- * mg.loadThis();
- * mg.invokeConstructor(Type.getType(Object.class), m);
- * mg.returnValue();
- * mg.endMethod();
- *
- * m = Method.getMethod("void main (String[])");
- * mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
- * mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
- * mg.push("Hello world!");
- * mg.invokeVirtual(Type.getType(PrintStream.class),
- *         Method.getMethod("void println (String)"));
- * mg.returnValue();
- * mg.endMethod();
- *
- * cw.visitEnd();
- * </pre>
- *
- * @author Juozas Baliuka
- * @author Chris Nokleberg
- * @author Eric Bruneton
- * @author Prashant Deva
- */
-public class GeneratorAdapter extends LocalVariablesSorter {
-
-    private static final String CLDESC = "Ljava/lang/Class;";
-
-    private static final Type BYTE_TYPE = Type.getObjectType("java/lang/Byte");
-
-    private static final Type BOOLEAN_TYPE = Type
-            .getObjectType("java/lang/Boolean");
-
-    private static final Type SHORT_TYPE = Type
-            .getObjectType("java/lang/Short");
-
-    private static final Type CHARACTER_TYPE = Type
-            .getObjectType("java/lang/Character");
-
-    private static final Type INTEGER_TYPE = Type
-            .getObjectType("java/lang/Integer");
-
-    private static final Type FLOAT_TYPE = Type
-            .getObjectType("java/lang/Float");
-
-    private static final Type LONG_TYPE = Type.getObjectType("java/lang/Long");
-
-    private static final Type DOUBLE_TYPE = Type
-            .getObjectType("java/lang/Double");
-
-    private static final Type NUMBER_TYPE = Type
-            .getObjectType("java/lang/Number");
-
-    private static final Type OBJECT_TYPE = Type
-            .getObjectType("java/lang/Object");
-
-    private static final Method BOOLEAN_VALUE = Method
-            .getMethod("boolean booleanValue()");
-
-    private static final Method CHAR_VALUE = Method
-            .getMethod("char charValue()");
-
-    private static final Method INT_VALUE = Method.getMethod("int intValue()");
-
-    private static final Method FLOAT_VALUE = Method
-            .getMethod("float floatValue()");
-
-    private static final Method LONG_VALUE = Method
-            .getMethod("long longValue()");
-
-    private static final Method DOUBLE_VALUE = Method
-            .getMethod("double doubleValue()");
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int ADD = Opcodes.IADD;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int SUB = Opcodes.ISUB;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int MUL = Opcodes.IMUL;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int DIV = Opcodes.IDIV;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int REM = Opcodes.IREM;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int NEG = Opcodes.INEG;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int SHL = Opcodes.ISHL;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int SHR = Opcodes.ISHR;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int USHR = Opcodes.IUSHR;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int AND = Opcodes.IAND;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int OR = Opcodes.IOR;
-
-    /**
-     * Constant for the {@link #math math} method.
-     */
-    public static final int XOR = Opcodes.IXOR;
-
-    /**
-     * Constant for the {@link #ifCmp ifCmp} method.
-     */
-    public static final int EQ = Opcodes.IFEQ;
-
-    /**
-     * Constant for the {@link #ifCmp ifCmp} method.
-     */
-    public static final int NE = Opcodes.IFNE;
-
-    /**
-     * Constant for the {@link #ifCmp ifCmp} method.
-     */
-    public static final int LT = Opcodes.IFLT;
-
-    /**
-     * Constant for the {@link #ifCmp ifCmp} method.
-     */
-    public static final int GE = Opcodes.IFGE;
-
-    /**
-     * Constant for the {@link #ifCmp ifCmp} method.
-     */
-    public static final int GT = Opcodes.IFGT;
-
-    /**
-     * Constant for the {@link #ifCmp ifCmp} method.
-     */
-    public static final int LE = Opcodes.IFLE;
-
-    /**
-     * Access flags of the method visited by this adapter.
-     */
-    private final int access;
-
-    /**
-     * Return type of the method visited by this adapter.
-     */
-    private final Type returnType;
-
-    /**
-     * Argument types of the method visited by this adapter.
-     */
-    private final Type[] argumentTypes;
-
-    /**
-     * Types of the local variables of the method visited by this adapter.
-     */
-    private final List<Type> localTypes = new ArrayList<Type>();
-
-    /**
-     * Creates a new {@link GeneratorAdapter}. <i>Subclasses must not use this
-     * constructor</i>. Instead, they must use the
-     * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
-     * version.
-     *
-     * @param mv
-     *            the method visitor to which this adapter delegates calls.
-     * @param access
-     *            the method's access flags (see {@link Opcodes}).
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     */
-    public GeneratorAdapter(final MethodVisitor mv, final int access,
-            final String name, final String desc) {
-        this(Opcodes.ASM4, mv, access, name, desc);
-    }
-
-    /**
-     * Creates a new {@link GeneratorAdapter}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param mv
-     *            the method visitor to which this adapter delegates calls.
-     * @param access
-     *            the method's access flags (see {@link Opcodes}).
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     */
-    protected GeneratorAdapter(final int api, final MethodVisitor mv,
-            final int access, final String name, final String desc) {
-        super(api, access, desc, mv);
-        this.access = access;
-        this.returnType = Type.getReturnType(desc);
-        this.argumentTypes = Type.getArgumentTypes(desc);
-    }
-
-    /**
-     * Creates a new {@link GeneratorAdapter}. <i>Subclasses must not use this
-     * constructor</i>. Instead, they must use the
-     * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
-     * version.
-     *
-     * @param access
-     *            access flags of the adapted method.
-     * @param method
-     *            the adapted method.
-     * @param mv
-     *            the method visitor to which this adapter delegates calls.
-     */
-    public GeneratorAdapter(final int access, final Method method,
-            final MethodVisitor mv) {
-        this(mv, access, null, method.getDescriptor());
-    }
-
-    /**
-     * Creates a new {@link GeneratorAdapter}. <i>Subclasses must not use this
-     * constructor</i>. Instead, they must use the
-     * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
-     * version.
-     *
-     * @param access
-     *            access flags of the adapted method.
-     * @param method
-     *            the adapted method.
-     * @param signature
-     *            the signature of the adapted method (may be <tt>null</tt>).
-     * @param exceptions
-     *            the exceptions thrown by the adapted method (may be
-     *            <tt>null</tt>).
-     * @param cv
-     *            the class visitor to which this adapter delegates calls.
-     */
-    public GeneratorAdapter(final int access, final Method method,
-            final String signature, final Type[] exceptions,
-            final ClassVisitor cv) {
-        this(access, method, cv
-                .visitMethod(access, method.getName(), method.getDescriptor(),
-                        signature, getInternalNames(exceptions)));
-    }
-
-    /**
-     * Returns the internal names of the given types.
-     *
-     * @param types
-     *            a set of types.
-     * @return the internal names of the given types.
-     */
-    private static String[] getInternalNames(final Type[] types) {
-        if (types == null) {
-            return null;
-        }
-        String[] names = new String[types.length];
-        for (int i = 0; i < names.length; ++i) {
-            names[i] = types[i].getInternalName();
-        }
-        return names;
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to push constants on the stack
-    // ------------------------------------------------------------------------
-
-    /**
-     * Generates the instruction to push the given value on the stack.
-     *
-     * @param value
-     *            the value to be pushed on the stack.
-     */
-    public void push(final boolean value) {
-        push(value ? 1 : 0);
-    }
-
-    /**
-     * Generates the instruction to push the given value on the stack.
-     *
-     * @param value
-     *            the value to be pushed on the stack.
-     */
-    public void push(final int value) {
-        if (value >= -1 && value <= 5) {
-            mv.visitInsn(Opcodes.ICONST_0 + value);
-        } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
-            mv.visitIntInsn(Opcodes.BIPUSH, value);
-        } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
-            mv.visitIntInsn(Opcodes.SIPUSH, value);
-        } else {
-            mv.visitLdcInsn(new Integer(value));
-        }
-    }
-
-    /**
-     * Generates the instruction to push the given value on the stack.
-     *
-     * @param value
-     *            the value to be pushed on the stack.
-     */
-    public void push(final long value) {
-        if (value == 0L || value == 1L) {
-            mv.visitInsn(Opcodes.LCONST_0 + (int) value);
-        } else {
-            mv.visitLdcInsn(new Long(value));
-        }
-    }
-
-    /**
-     * Generates the instruction to push the given value on the stack.
-     *
-     * @param value
-     *            the value to be pushed on the stack.
-     */
-    public void push(final float value) {
-        int bits = Float.floatToIntBits(value);
-        if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2
-            mv.visitInsn(Opcodes.FCONST_0 + (int) value);
-        } else {
-            mv.visitLdcInsn(new Float(value));
-        }
-    }
-
-    /**
-     * Generates the instruction to push the given value on the stack.
-     *
-     * @param value
-     *            the value to be pushed on the stack.
-     */
-    public void push(final double value) {
-        long bits = Double.doubleToLongBits(value);
-        if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d
-            mv.visitInsn(Opcodes.DCONST_0 + (int) value);
-        } else {
-            mv.visitLdcInsn(new Double(value));
-        }
-    }
-
-    /**
-     * Generates the instruction to push the given value on the stack.
-     *
-     * @param value
-     *            the value to be pushed on the stack. May be <tt>null</tt>.
-     */
-    public void push(final String value) {
-        if (value == null) {
-            mv.visitInsn(Opcodes.ACONST_NULL);
-        } else {
-            mv.visitLdcInsn(value);
-        }
-    }
-
-    /**
-     * Generates the instruction to push the given value on the stack.
-     *
-     * @param value
-     *            the value to be pushed on the stack.
-     */
-    public void push(final Type value) {
-        if (value == null) {
-            mv.visitInsn(Opcodes.ACONST_NULL);
-        } else {
-            switch (value.getSort()) {
-            case Type.BOOLEAN:
-                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean",
-                        "TYPE", CLDESC);
-                break;
-            case Type.CHAR:
-                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Character",
-                        "TYPE", CLDESC);
-                break;
-            case Type.BYTE:
-                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE",
-                        CLDESC);
-                break;
-            case Type.SHORT:
-                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Short", "TYPE",
-                        CLDESC);
-                break;
-            case Type.INT:
-                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Integer",
-                        "TYPE", CLDESC);
-                break;
-            case Type.FLOAT:
-                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Float", "TYPE",
-                        CLDESC);
-                break;
-            case Type.LONG:
-                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "TYPE",
-                        CLDESC);
-                break;
-            case Type.DOUBLE:
-                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Double",
-                        "TYPE", CLDESC);
-                break;
-            default:
-                mv.visitLdcInsn(value);
-            }
-        }
-    }
-
-    /**
-     * Generates the instruction to push a handle on the stack.
-     *
-     * @param handle
-     *            the handle to be pushed on the stack.
-     */
-    public void push(final Handle handle) {
-        mv.visitLdcInsn(handle);
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to load and store method arguments
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the index of the given method argument in the frame's local
-     * variables array.
-     *
-     * @param arg
-     *            the index of a method argument.
-     * @return the index of the given method argument in the frame's local
-     *         variables array.
-     */
-    private int getArgIndex(final int arg) {
-        int index = (access & Opcodes.ACC_STATIC) == 0 ? 1 : 0;
-        for (int i = 0; i < arg; i++) {
-            index += argumentTypes[i].getSize();
-        }
-        return index;
-    }
-
-    /**
-     * Generates the instruction to push a local variable on the stack.
-     *
-     * @param type
-     *            the type of the local variable to be loaded.
-     * @param index
-     *            an index in the frame's local variables array.
-     */
-    private void loadInsn(final Type type, final int index) {
-        mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), index);
-    }
-
-    /**
-     * Generates the instruction to store the top stack value in a local
-     * variable.
-     *
-     * @param type
-     *            the type of the local variable to be stored.
-     * @param index
-     *            an index in the frame's local variables array.
-     */
-    private void storeInsn(final Type type, final int index) {
-        mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), index);
-    }
-
-    /**
-     * Generates the instruction to load 'this' on the stack.
-     */
-    public void loadThis() {
-        if ((access & Opcodes.ACC_STATIC) != 0) {
-            throw new IllegalStateException(
-                    "no 'this' pointer within static method");
-        }
-        mv.visitVarInsn(Opcodes.ALOAD, 0);
-    }
-
-    /**
-     * Generates the instruction to load the given method argument on the stack.
-     *
-     * @param arg
-     *            the index of a method argument.
-     */
-    public void loadArg(final int arg) {
-        loadInsn(argumentTypes[arg], getArgIndex(arg));
-    }
-
-    /**
-     * Generates the instructions to load the given method arguments on the
-     * stack.
-     *
-     * @param arg
-     *            the index of the first method argument to be loaded.
-     * @param count
-     *            the number of method arguments to be loaded.
-     */
-    public void loadArgs(final int arg, final int count) {
-        int index = getArgIndex(arg);
-        for (int i = 0; i < count; ++i) {
-            Type t = argumentTypes[arg + i];
-            loadInsn(t, index);
-            index += t.getSize();
-        }
-    }
-
-    /**
-     * Generates the instructions to load all the method arguments on the stack.
-     */
-    public void loadArgs() {
-        loadArgs(0, argumentTypes.length);
-    }
-
-    /**
-     * Generates the instructions to load all the method arguments on the stack,
-     * as a single object array.
-     */
-    public void loadArgArray() {
-        push(argumentTypes.length);
-        newArray(OBJECT_TYPE);
-        for (int i = 0; i < argumentTypes.length; i++) {
-            dup();
-            push(i);
-            loadArg(i);
-            box(argumentTypes[i]);
-            arrayStore(OBJECT_TYPE);
-        }
-    }
-
-    /**
-     * Generates the instruction to store the top stack value in the given
-     * method argument.
-     *
-     * @param arg
-     *            the index of a method argument.
-     */
-    public void storeArg(final int arg) {
-        storeInsn(argumentTypes[arg], getArgIndex(arg));
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to load and store local variables
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns the type of the given local variable.
-     *
-     * @param local
-     *            a local variable identifier, as returned by
-     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
-     * @return the type of the given local variable.
-     */
-    public Type getLocalType(final int local) {
-        return localTypes.get(local - firstLocal);
-    }
-
-    @Override
-    protected void setLocalType(final int local, final Type type) {
-        int index = local - firstLocal;
-        while (localTypes.size() < index + 1) {
-            localTypes.add(null);
-        }
-        localTypes.set(index, type);
-    }
-
-    /**
-     * Generates the instruction to load the given local variable on the stack.
-     *
-     * @param local
-     *            a local variable identifier, as returned by
-     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
-     */
-    public void loadLocal(final int local) {
-        loadInsn(getLocalType(local), local);
-    }
-
-    /**
-     * Generates the instruction to load the given local variable on the stack.
-     *
-     * @param local
-     *            a local variable identifier, as returned by
-     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
-     * @param type
-     *            the type of this local variable.
-     */
-    public void loadLocal(final int local, final Type type) {
-        setLocalType(local, type);
-        loadInsn(type, local);
-    }
-
-    /**
-     * Generates the instruction to store the top stack value in the given local
-     * variable.
-     *
-     * @param local
-     *            a local variable identifier, as returned by
-     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
-     */
-    public void storeLocal(final int local) {
-        storeInsn(getLocalType(local), local);
-    }
-
-    /**
-     * Generates the instruction to store the top stack value in the given local
-     * variable.
-     *
-     * @param local
-     *            a local variable identifier, as returned by
-     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
-     * @param type
-     *            the type of this local variable.
-     */
-    public void storeLocal(final int local, final Type type) {
-        setLocalType(local, type);
-        storeInsn(type, local);
-    }
-
-    /**
-     * Generates the instruction to load an element from an array.
-     *
-     * @param type
-     *            the type of the array element to be loaded.
-     */
-    public void arrayLoad(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IALOAD));
-    }
-
-    /**
-     * Generates the instruction to store an element in an array.
-     *
-     * @param type
-     *            the type of the array element to be stored.
-     */
-    public void arrayStore(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IASTORE));
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to manage the stack
-    // ------------------------------------------------------------------------
-
-    /**
-     * Generates a POP instruction.
-     */
-    public void pop() {
-        mv.visitInsn(Opcodes.POP);
-    }
-
-    /**
-     * Generates a POP2 instruction.
-     */
-    public void pop2() {
-        mv.visitInsn(Opcodes.POP2);
-    }
-
-    /**
-     * Generates a DUP instruction.
-     */
-    public void dup() {
-        mv.visitInsn(Opcodes.DUP);
-    }
-
-    /**
-     * Generates a DUP2 instruction.
-     */
-    public void dup2() {
-        mv.visitInsn(Opcodes.DUP2);
-    }
-
-    /**
-     * Generates a DUP_X1 instruction.
-     */
-    public void dupX1() {
-        mv.visitInsn(Opcodes.DUP_X1);
-    }
-
-    /**
-     * Generates a DUP_X2 instruction.
-     */
-    public void dupX2() {
-        mv.visitInsn(Opcodes.DUP_X2);
-    }
-
-    /**
-     * Generates a DUP2_X1 instruction.
-     */
-    public void dup2X1() {
-        mv.visitInsn(Opcodes.DUP2_X1);
-    }
-
-    /**
-     * Generates a DUP2_X2 instruction.
-     */
-    public void dup2X2() {
-        mv.visitInsn(Opcodes.DUP2_X2);
-    }
-
-    /**
-     * Generates a SWAP instruction.
-     */
-    public void swap() {
-        mv.visitInsn(Opcodes.SWAP);
-    }
-
-    /**
-     * Generates the instructions to swap the top two stack values.
-     *
-     * @param prev
-     *            type of the top - 1 stack value.
-     * @param type
-     *            type of the top stack value.
-     */
-    public void swap(final Type prev, final Type type) {
-        if (type.getSize() == 1) {
-            if (prev.getSize() == 1) {
-                swap(); // same as dupX1(), pop();
-            } else {
-                dupX2();
-                pop();
-            }
-        } else {
-            if (prev.getSize() == 1) {
-                dup2X1();
-                pop2();
-            } else {
-                dup2X2();
-                pop2();
-            }
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to do mathematical and logical operations
-    // ------------------------------------------------------------------------
-
-    /**
-     * Generates the instruction to do the specified mathematical or logical
-     * operation.
-     *
-     * @param op
-     *            a mathematical or logical operation. Must be one of ADD, SUB,
-     *            MUL, DIV, REM, NEG, SHL, SHR, USHR, AND, OR, XOR.
-     * @param type
-     *            the type of the operand(s) for this operation.
-     */
-    public void math(final int op, final Type type) {
-        mv.visitInsn(type.getOpcode(op));
-    }
-
-    /**
-     * Generates the instructions to compute the bitwise negation of the top
-     * stack value.
-     */
-    public void not() {
-        mv.visitInsn(Opcodes.ICONST_1);
-        mv.visitInsn(Opcodes.IXOR);
-    }
-
-    /**
-     * Generates the instruction to increment the given local variable.
-     *
-     * @param local
-     *            the local variable to be incremented.
-     * @param amount
-     *            the amount by which the local variable must be incremented.
-     */
-    public void iinc(final int local, final int amount) {
-        mv.visitIincInsn(local, amount);
-    }
-
-    /**
-     * Generates the instructions to cast a numerical value from one type to
-     * another.
-     *
-     * @param from
-     *            the type of the top stack value
-     * @param to
-     *            the type into which this value must be cast.
-     */
-    public void cast(final Type from, final Type to) {
-        if (from != to) {
-            if (from == Type.DOUBLE_TYPE) {
-                if (to == Type.FLOAT_TYPE) {
-                    mv.visitInsn(Opcodes.D2F);
-                } else if (to == Type.LONG_TYPE) {
-                    mv.visitInsn(Opcodes.D2L);
-                } else {
-                    mv.visitInsn(Opcodes.D2I);
-                    cast(Type.INT_TYPE, to);
-                }
-            } else if (from == Type.FLOAT_TYPE) {
-                if (to == Type.DOUBLE_TYPE) {
-                    mv.visitInsn(Opcodes.F2D);
-                } else if (to == Type.LONG_TYPE) {
-                    mv.visitInsn(Opcodes.F2L);
-                } else {
-                    mv.visitInsn(Opcodes.F2I);
-                    cast(Type.INT_TYPE, to);
-                }
-            } else if (from == Type.LONG_TYPE) {
-                if (to == Type.DOUBLE_TYPE) {
-                    mv.visitInsn(Opcodes.L2D);
-                } else if (to == Type.FLOAT_TYPE) {
-                    mv.visitInsn(Opcodes.L2F);
-                } else {
-                    mv.visitInsn(Opcodes.L2I);
-                    cast(Type.INT_TYPE, to);
-                }
-            } else {
-                if (to == Type.BYTE_TYPE) {
-                    mv.visitInsn(Opcodes.I2B);
-                } else if (to == Type.CHAR_TYPE) {
-                    mv.visitInsn(Opcodes.I2C);
-                } else if (to == Type.DOUBLE_TYPE) {
-                    mv.visitInsn(Opcodes.I2D);
-                } else if (to == Type.FLOAT_TYPE) {
-                    mv.visitInsn(Opcodes.I2F);
-                } else if (to == Type.LONG_TYPE) {
-                    mv.visitInsn(Opcodes.I2L);
-                } else if (to == Type.SHORT_TYPE) {
-                    mv.visitInsn(Opcodes.I2S);
-                }
-            }
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to do boxing and unboxing operations
-    // ------------------------------------------------------------------------
-
-    private static Type getBoxedType(final Type type) {
-        switch (type.getSort()) {
-        case Type.BYTE:
-            return BYTE_TYPE;
-        case Type.BOOLEAN:
-            return BOOLEAN_TYPE;
-        case Type.SHORT:
-            return SHORT_TYPE;
-        case Type.CHAR:
-            return CHARACTER_TYPE;
-        case Type.INT:
-            return INTEGER_TYPE;
-        case Type.FLOAT:
-            return FLOAT_TYPE;
-        case Type.LONG:
-            return LONG_TYPE;
-        case Type.DOUBLE:
-            return DOUBLE_TYPE;
-        }
-        return type;
-    }
-
-    /**
-     * Generates the instructions to box the top stack value. This value is
-     * replaced by its boxed equivalent on top of the stack.
-     *
-     * @param type
-     *            the type of the top stack value.
-     */
-    public void box(final Type type) {
-        if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
-            return;
-        }
-        if (type == Type.VOID_TYPE) {
-            push((String) null);
-        } else {
-            Type boxed = getBoxedType(type);
-            newInstance(boxed);
-            if (type.getSize() == 2) {
-                // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
-                dupX2();
-                dupX2();
-                pop();
-            } else {
-                // p -> po -> opo -> oop -> o
-                dupX1();
-                swap();
-            }
-            invokeConstructor(boxed, new Method("<init>", Type.VOID_TYPE,
-                    new Type[] { type }));
-        }
-    }
-
-    /**
-     * Generates the instructions to box the top stack value using Java 5's
-     * valueOf() method. This value is replaced by its boxed equivalent on top
-     * of the stack.
-     *
-     * @param type
-     *            the type of the top stack value.
-     */
-    public void valueOf(final Type type) {
-        if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
-            return;
-        }
-        if (type == Type.VOID_TYPE) {
-            push((String) null);
-        } else {
-            Type boxed = getBoxedType(type);
-            invokeStatic(boxed, new Method("valueOf", boxed,
-                    new Type[] { type }));
-        }
-    }
-
-    /**
-     * Generates the instructions to unbox the top stack value. This value is
-     * replaced by its unboxed equivalent on top of the stack.
-     *
-     * @param type
-     *            the type of the top stack value.
-     */
-    public void unbox(final Type type) {
-        Type t = NUMBER_TYPE;
-        Method sig = null;
-        switch (type.getSort()) {
-        case Type.VOID:
-            return;
-        case Type.CHAR:
-            t = CHARACTER_TYPE;
-            sig = CHAR_VALUE;
-            break;
-        case Type.BOOLEAN:
-            t = BOOLEAN_TYPE;
-            sig = BOOLEAN_VALUE;
-            break;
-        case Type.DOUBLE:
-            sig = DOUBLE_VALUE;
-            break;
-        case Type.FLOAT:
-            sig = FLOAT_VALUE;
-            break;
-        case Type.LONG:
-            sig = LONG_VALUE;
-            break;
-        case Type.INT:
-        case Type.SHORT:
-        case Type.BYTE:
-            sig = INT_VALUE;
-        }
-        if (sig == null) {
-            checkCast(type);
-        } else {
-            checkCast(t);
-            invokeVirtual(t, sig);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to jump to other instructions
-    // ------------------------------------------------------------------------
-
-    /**
-     * Creates a new {@link Label}.
-     *
-     * @return a new {@link Label}.
-     */
-    public Label newLabel() {
-        return new Label();
-    }
-
-    /**
-     * Marks the current code position with the given label.
-     *
-     * @param label
-     *            a label.
-     */
-    public void mark(final Label label) {
-        mv.visitLabel(label);
-    }
-
-    /**
-     * Marks the current code position with a new label.
-     *
-     * @return the label that was created to mark the current code position.
-     */
-    public Label mark() {
-        Label label = new Label();
-        mv.visitLabel(label);
-        return label;
-    }
-
-    /**
-     * Generates the instructions to jump to a label based on the comparison of
-     * the top two stack values.
-     *
-     * @param type
-     *            the type of the top two stack values.
-     * @param mode
-     *            how these values must be compared. One of EQ, NE, LT, GE, GT,
-     *            LE.
-     * @param label
-     *            where to jump if the comparison result is <tt>true</tt>.
-     */
-    public void ifCmp(final Type type, final int mode, final Label label) {
-        switch (type.getSort()) {
-        case Type.LONG:
-            mv.visitInsn(Opcodes.LCMP);
-            break;
-        case Type.DOUBLE:
-            mv.visitInsn(mode == GE || mode == GT ? Opcodes.DCMPL
-                    : Opcodes.DCMPG);
-            break;
-        case Type.FLOAT:
-            mv.visitInsn(mode == GE || mode == GT ? Opcodes.FCMPL
-                    : Opcodes.FCMPG);
-            break;
-        case Type.ARRAY:
-        case Type.OBJECT:
-            switch (mode) {
-            case EQ:
-                mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
-                return;
-            case NE:
-                mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
-                return;
-            }
-            throw new IllegalArgumentException("Bad comparison for type "
-                    + type);
-        default:
-            int intOp = -1;
-            switch (mode) {
-            case EQ:
-                intOp = Opcodes.IF_ICMPEQ;
-                break;
-            case NE:
-                intOp = Opcodes.IF_ICMPNE;
-                break;
-            case GE:
-                intOp = Opcodes.IF_ICMPGE;
-                break;
-            case LT:
-                intOp = Opcodes.IF_ICMPLT;
-                break;
-            case LE:
-                intOp = Opcodes.IF_ICMPLE;
-                break;
-            case GT:
-                intOp = Opcodes.IF_ICMPGT;
-                break;
-            }
-            mv.visitJumpInsn(intOp, label);
-            return;
-        }
-        mv.visitJumpInsn(mode, label);
-    }
-
-    /**
-     * Generates the instructions to jump to a label based on the comparison of
-     * the top two integer stack values.
-     *
-     * @param mode
-     *            how these values must be compared. One of EQ, NE, LT, GE, GT,
-     *            LE.
-     * @param label
-     *            where to jump if the comparison result is <tt>true</tt>.
-     */
-    public void ifICmp(final int mode, final Label label) {
-        ifCmp(Type.INT_TYPE, mode, label);
-    }
-
-    /**
-     * Generates the instructions to jump to a label based on the comparison of
-     * the top integer stack value with zero.
-     *
-     * @param mode
-     *            how these values must be compared. One of EQ, NE, LT, GE, GT,
-     *            LE.
-     * @param label
-     *            where to jump if the comparison result is <tt>true</tt>.
-     */
-    public void ifZCmp(final int mode, final Label label) {
-        mv.visitJumpInsn(mode, label);
-    }
-
-    /**
-     * Generates the instruction to jump to the given label if the top stack
-     * value is null.
-     *
-     * @param label
-     *            where to jump if the condition is <tt>true</tt>.
-     */
-    public void ifNull(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFNULL, label);
-    }
-
-    /**
-     * Generates the instruction to jump to the given label if the top stack
-     * value is not null.
-     *
-     * @param label
-     *            where to jump if the condition is <tt>true</tt>.
-     */
-    public void ifNonNull(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFNONNULL, label);
-    }
-
-    /**
-     * Generates the instruction to jump to the given label.
-     *
-     * @param label
-     *            where to jump if the condition is <tt>true</tt>.
-     */
-    public void goTo(final Label label) {
-        mv.visitJumpInsn(Opcodes.GOTO, label);
-    }
-
-    /**
-     * Generates a RET instruction.
-     *
-     * @param local
-     *            a local variable identifier, as returned by
-     *            {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
-     */
-    public void ret(final int local) {
-        mv.visitVarInsn(Opcodes.RET, local);
-    }
-
-    /**
-     * Generates the instructions for a switch statement.
-     *
-     * @param keys
-     *            the switch case keys.
-     * @param generator
-     *            a generator to generate the code for the switch cases.
-     */
-    public void tableSwitch(final int[] keys,
-            final TableSwitchGenerator generator) {
-        float density;
-        if (keys.length == 0) {
-            density = 0;
-        } else {
-            density = (float) keys.length
-                    / (keys[keys.length - 1] - keys[0] + 1);
-        }
-        tableSwitch(keys, generator, density >= 0.5f);
-    }
-
-    /**
-     * Generates the instructions for a switch statement.
-     *
-     * @param keys
-     *            the switch case keys.
-     * @param generator
-     *            a generator to generate the code for the switch cases.
-     * @param useTable
-     *            <tt>true</tt> to use a TABLESWITCH instruction, or
-     *            <tt>false</tt> to use a LOOKUPSWITCH instruction.
-     */
-    public void tableSwitch(final int[] keys,
-            final TableSwitchGenerator generator, final boolean useTable) {
-        for (int i = 1; i < keys.length; ++i) {
-            if (keys[i] < keys[i - 1]) {
-                throw new IllegalArgumentException(
-                        "keys must be sorted ascending");
-            }
-        }
-        Label def = newLabel();
-        Label end = newLabel();
-        if (keys.length > 0) {
-            int len = keys.length;
-            int min = keys[0];
-            int max = keys[len - 1];
-            int range = max - min + 1;
-            if (useTable) {
-                Label[] labels = new Label[range];
-                Arrays.fill(labels, def);
-                for (int i = 0; i < len; ++i) {
-                    labels[keys[i] - min] = newLabel();
-                }
-                mv.visitTableSwitchInsn(min, max, def, labels);
-                for (int i = 0; i < range; ++i) {
-                    Label label = labels[i];
-                    if (label != def) {
-                        mark(label);
-                        generator.generateCase(i + min, end);
-                    }
-                }
-            } else {
-                Label[] labels = new Label[len];
-                for (int i = 0; i < len; ++i) {
-                    labels[i] = newLabel();
-                }
-                mv.visitLookupSwitchInsn(def, keys, labels);
-                for (int i = 0; i < len; ++i) {
-                    mark(labels[i]);
-                    generator.generateCase(keys[i], end);
-                }
-            }
-        }
-        mark(def);
-        generator.generateDefault();
-        mark(end);
-    }
-
-    /**
-     * Generates the instruction to return the top stack value to the caller.
-     */
-    public void returnValue() {
-        mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to load and store fields
-    // ------------------------------------------------------------------------
-
-    /**
-     * Generates a get field or set field instruction.
-     *
-     * @param opcode
-     *            the instruction's opcode.
-     * @param ownerType
-     *            the class in which the field is defined.
-     * @param name
-     *            the name of the field.
-     * @param fieldType
-     *            the type of the field.
-     */
-    private void fieldInsn(final int opcode, final Type ownerType,
-            final String name, final Type fieldType) {
-        mv.visitFieldInsn(opcode, ownerType.getInternalName(), name,
-                fieldType.getDescriptor());
-    }
-
-    /**
-     * Generates the instruction to push the value of a static field on the
-     * stack.
-     *
-     * @param owner
-     *            the class in which the field is defined.
-     * @param name
-     *            the name of the field.
-     * @param type
-     *            the type of the field.
-     */
-    public void getStatic(final Type owner, final String name, final Type type) {
-        fieldInsn(Opcodes.GETSTATIC, owner, name, type);
-    }
-
-    /**
-     * Generates the instruction to store the top stack value in a static field.
-     *
-     * @param owner
-     *            the class in which the field is defined.
-     * @param name
-     *            the name of the field.
-     * @param type
-     *            the type of the field.
-     */
-    public void putStatic(final Type owner, final String name, final Type type) {
-        fieldInsn(Opcodes.PUTSTATIC, owner, name, type);
-    }
-
-    /**
-     * Generates the instruction to push the value of a non static field on the
-     * stack.
-     *
-     * @param owner
-     *            the class in which the field is defined.
-     * @param name
-     *            the name of the field.
-     * @param type
-     *            the type of the field.
-     */
-    public void getField(final Type owner, final String name, final Type type) {
-        fieldInsn(Opcodes.GETFIELD, owner, name, type);
-    }
-
-    /**
-     * Generates the instruction to store the top stack value in a non static
-     * field.
-     *
-     * @param owner
-     *            the class in which the field is defined.
-     * @param name
-     *            the name of the field.
-     * @param type
-     *            the type of the field.
-     */
-    public void putField(final Type owner, final String name, final Type type) {
-        fieldInsn(Opcodes.PUTFIELD, owner, name, type);
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to invoke methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Generates an invoke method instruction.
-     *
-     * @param opcode
-     *            the instruction's opcode.
-     * @param type
-     *            the class in which the method is defined.
-     * @param method
-     *            the method to be invoked.
-     */
-    private void invokeInsn(final int opcode, final Type type,
-            final Method method) {
-        String owner = type.getSort() == Type.ARRAY ? type.getDescriptor()
-                : type.getInternalName();
-        mv.visitMethodInsn(opcode, owner, method.getName(),
-                method.getDescriptor());
-    }
-
-    /**
-     * Generates the instruction to invoke a normal method.
-     *
-     * @param owner
-     *            the class in which the method is defined.
-     * @param method
-     *            the method to be invoked.
-     */
-    public void invokeVirtual(final Type owner, final Method method) {
-        invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method);
-    }
-
-    /**
-     * Generates the instruction to invoke a constructor.
-     *
-     * @param type
-     *            the class in which the constructor is defined.
-     * @param method
-     *            the constructor to be invoked.
-     */
-    public void invokeConstructor(final Type type, final Method method) {
-        invokeInsn(Opcodes.INVOKESPECIAL, type, method);
-    }
-
-    /**
-     * Generates the instruction to invoke a static method.
-     *
-     * @param owner
-     *            the class in which the method is defined.
-     * @param method
-     *            the method to be invoked.
-     */
-    public void invokeStatic(final Type owner, final Method method) {
-        invokeInsn(Opcodes.INVOKESTATIC, owner, method);
-    }
-
-    /**
-     * Generates the instruction to invoke an interface method.
-     *
-     * @param owner
-     *            the class in which the method is defined.
-     * @param method
-     *            the method to be invoked.
-     */
-    public void invokeInterface(final Type owner, final Method method) {
-        invokeInsn(Opcodes.INVOKEINTERFACE, owner, method);
-    }
-
-    /**
-     * Generates an invokedynamic instruction.
-     *
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     * @param bsm
-     *            the bootstrap method.
-     * @param bsmArgs
-     *            the bootstrap method constant arguments. Each argument must be
-     *            an {@link Integer}, {@link Float}, {@link Long},
-     *            {@link Double}, {@link String}, {@link Type} or {@link Handle}
-     *            value. This method is allowed to modify the content of the
-     *            array so a caller should expect that this array may change.
-     */
-    public void invokeDynamic(String name, String desc, Handle bsm,
-            Object... bsmArgs) {
-        mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-    }
-
-    // ------------------------------------------------------------------------
-    // Instructions to create objects and arrays
-    // ------------------------------------------------------------------------
-
-    /**
-     * Generates a type dependent instruction.
-     *
-     * @param opcode
-     *            the instruction's opcode.
-     * @param type
-     *            the instruction's operand.
-     */
-    private void typeInsn(final int opcode, final Type type) {
-        mv.visitTypeInsn(opcode, type.getInternalName());
-    }
-
-    /**
-     * Generates the instruction to create a new object.
-     *
-     * @param type
-     *            the class of the object to be created.
-     */
-    public void newInstance(final Type type) {
-        typeInsn(Opcodes.NEW, type);
-    }
-
-    /**
-     * Generates the instruction to create a new array.
-     *
-     * @param type
-     *            the type of the array elements.
-     */
-    public void newArray(final Type type) {
-        int typ;
-        switch (type.getSort()) {
-        case Type.BOOLEAN:
-            typ = Opcodes.T_BOOLEAN;
-            break;
-        case Type.CHAR:
-            typ = Opcodes.T_CHAR;
-            break;
-        case Type.BYTE:
-            typ = Opcodes.T_BYTE;
-            break;
-        case Type.SHORT:
-            typ = Opcodes.T_SHORT;
-            break;
-        case Type.INT:
-            typ = Opcodes.T_INT;
-            break;
-        case Type.FLOAT:
-            typ = Opcodes.T_FLOAT;
-            break;
-        case Type.LONG:
-            typ = Opcodes.T_LONG;
-            break;
-        case Type.DOUBLE:
-            typ = Opcodes.T_DOUBLE;
-            break;
-        default:
-            typeInsn(Opcodes.ANEWARRAY, type);
-            return;
-        }
-        mv.visitIntInsn(Opcodes.NEWARRAY, typ);
-    }
-
-    // ------------------------------------------------------------------------
-    // Miscelaneous instructions
-    // ------------------------------------------------------------------------
-
-    /**
-     * Generates the instruction to compute the length of an array.
-     */
-    public void arrayLength() {
-        mv.visitInsn(Opcodes.ARRAYLENGTH);
-    }
-
-    /**
-     * Generates the instruction to throw an exception.
-     */
-    public void throwException() {
-        mv.visitInsn(Opcodes.ATHROW);
-    }
-
-    /**
-     * Generates the instructions to create and throw an exception. The
-     * exception class must have a constructor with a single String argument.
-     *
-     * @param type
-     *            the class of the exception to be thrown.
-     * @param msg
-     *            the detailed message of the exception.
-     */
-    public void throwException(final Type type, final String msg) {
-        newInstance(type);
-        dup();
-        push(msg);
-        invokeConstructor(type, Method.getMethod("void <init> (String)"));
-        throwException();
-    }
-
-    /**
-     * Generates the instruction to check that the top stack value is of the
-     * given type.
-     *
-     * @param type
-     *            a class or interface type.
-     */
-    public void checkCast(final Type type) {
-        if (!type.equals(OBJECT_TYPE)) {
-            typeInsn(Opcodes.CHECKCAST, type);
-        }
-    }
-
-    /**
-     * Generates the instruction to test if the top stack value is of the given
-     * type.
-     *
-     * @param type
-     *            a class or interface type.
-     */
-    public void instanceOf(final Type type) {
-        typeInsn(Opcodes.INSTANCEOF, type);
-    }
-
-    /**
-     * Generates the instruction to get the monitor of the top stack value.
-     */
-    public void monitorEnter() {
-        mv.visitInsn(Opcodes.MONITORENTER);
-    }
-
-    /**
-     * Generates the instruction to release the monitor of the top stack value.
-     */
-    public void monitorExit() {
-        mv.visitInsn(Opcodes.MONITOREXIT);
-    }
-
-    // ------------------------------------------------------------------------
-    // Non instructions
-    // ------------------------------------------------------------------------
-
-    /**
-     * Marks the end of the visited method.
-     */
-    public void endMethod() {
-        if ((access & Opcodes.ACC_ABSTRACT) == 0) {
-            mv.visitMaxs(0, 0);
-        }
-        mv.visitEnd();
-    }
-
-    /**
-     * Marks the start of an exception handler.
-     *
-     * @param start
-     *            beginning of the exception handler's scope (inclusive).
-     * @param end
-     *            end of the exception handler's scope (exclusive).
-     * @param exception
-     *            internal name of the type of exceptions handled by the
-     *            handler.
-     */
-    public void catchException(final Label start, final Label end,
-            final Type exception) {
-        if (exception == null) {
-            mv.visitTryCatchBlock(start, end, mark(), null);
-        } else {
-            mv.visitTryCatchBlock(start, end, mark(),
-                    exception.getInternalName());
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/commons/InstructionAdapter.java b/src/jvm/clojure/asm/commons/InstructionAdapter.java
deleted file mode 100644
index e61c109..0000000
--- a/src/jvm/clojure/asm/commons/InstructionAdapter.java
+++ /dev/null
@@ -1,1090 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package clojure.asm.commons;
-
-import clojure.asm.Handle;
-import clojure.asm.Label;
-import clojure.asm.MethodVisitor;
-import clojure.asm.Opcodes;
-import clojure.asm.Type;
-
-/**
- * A {@link MethodVisitor} providing a more detailed API to generate and
- * transform instructions.
- *
- * @author Eric Bruneton
- */
-public class InstructionAdapter extends MethodVisitor {
-
-    public final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
-
-    /**
-     * Creates a new {@link InstructionAdapter}. <i>Subclasses must not use this
-     * constructor</i>. Instead, they must use the
-     * {@link #InstructionAdapter(int, MethodVisitor)} version.
-     *
-     * @param mv
-     *            the method visitor to which this adapter delegates calls.
-     */
-    public InstructionAdapter(final MethodVisitor mv) {
-        this(Opcodes.ASM4, mv);
-    }
-
-    /**
-     * Creates a new {@link InstructionAdapter}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param mv
-     *            the method visitor to which this adapter delegates calls.
-     */
-    protected InstructionAdapter(final int api, final MethodVisitor mv) {
-        super(api, mv);
-    }
-
-    @Override
-    public void visitInsn(final int opcode) {
-        switch (opcode) {
-        case Opcodes.NOP:
-            nop();
-            break;
-        case Opcodes.ACONST_NULL:
-            aconst(null);
-            break;
-        case Opcodes.ICONST_M1:
-        case Opcodes.ICONST_0:
-        case Opcodes.ICONST_1:
-        case Opcodes.ICONST_2:
-        case Opcodes.ICONST_3:
-        case Opcodes.ICONST_4:
-        case Opcodes.ICONST_5:
-            iconst(opcode - Opcodes.ICONST_0);
-            break;
-        case Opcodes.LCONST_0:
-        case Opcodes.LCONST_1:
-            lconst(opcode - Opcodes.LCONST_0);
-            break;
-        case Opcodes.FCONST_0:
-        case Opcodes.FCONST_1:
-        case Opcodes.FCONST_2:
-            fconst(opcode - Opcodes.FCONST_0);
-            break;
-        case Opcodes.DCONST_0:
-        case Opcodes.DCONST_1:
-            dconst(opcode - Opcodes.DCONST_0);
-            break;
-        case Opcodes.IALOAD:
-            aload(Type.INT_TYPE);
-            break;
-        case Opcodes.LALOAD:
-            aload(Type.LONG_TYPE);
-            break;
-        case Opcodes.FALOAD:
-            aload(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DALOAD:
-            aload(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.AALOAD:
-            aload(OBJECT_TYPE);
-            break;
-        case Opcodes.BALOAD:
-            aload(Type.BYTE_TYPE);
-            break;
-        case Opcodes.CALOAD:
-            aload(Type.CHAR_TYPE);
-            break;
-        case Opcodes.SALOAD:
-            aload(Type.SHORT_TYPE);
-            break;
-        case Opcodes.IASTORE:
-            astore(Type.INT_TYPE);
-            break;
-        case Opcodes.LASTORE:
-            astore(Type.LONG_TYPE);
-            break;
-        case Opcodes.FASTORE:
-            astore(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DASTORE:
-            astore(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.AASTORE:
-            astore(OBJECT_TYPE);
-            break;
-        case Opcodes.BASTORE:
-            astore(Type.BYTE_TYPE);
-            break;
-        case Opcodes.CASTORE:
-            astore(Type.CHAR_TYPE);
-            break;
-        case Opcodes.SASTORE:
-            astore(Type.SHORT_TYPE);
-            break;
-        case Opcodes.POP:
-            pop();
-            break;
-        case Opcodes.POP2:
-            pop2();
-            break;
-        case Opcodes.DUP:
-            dup();
-            break;
-        case Opcodes.DUP_X1:
-            dupX1();
-            break;
-        case Opcodes.DUP_X2:
-            dupX2();
-            break;
-        case Opcodes.DUP2:
-            dup2();
-            break;
-        case Opcodes.DUP2_X1:
-            dup2X1();
-            break;
-        case Opcodes.DUP2_X2:
-            dup2X2();
-            break;
-        case Opcodes.SWAP:
-            swap();
-            break;
-        case Opcodes.IADD:
-            add(Type.INT_TYPE);
-            break;
-        case Opcodes.LADD:
-            add(Type.LONG_TYPE);
-            break;
-        case Opcodes.FADD:
-            add(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DADD:
-            add(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.ISUB:
-            sub(Type.INT_TYPE);
-            break;
-        case Opcodes.LSUB:
-            sub(Type.LONG_TYPE);
-            break;
-        case Opcodes.FSUB:
-            sub(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DSUB:
-            sub(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.IMUL:
-            mul(Type.INT_TYPE);
-            break;
-        case Opcodes.LMUL:
-            mul(Type.LONG_TYPE);
-            break;
-        case Opcodes.FMUL:
-            mul(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DMUL:
-            mul(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.IDIV:
-            div(Type.INT_TYPE);
-            break;
-        case Opcodes.LDIV:
-            div(Type.LONG_TYPE);
-            break;
-        case Opcodes.FDIV:
-            div(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DDIV:
-            div(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.IREM:
-            rem(Type.INT_TYPE);
-            break;
-        case Opcodes.LREM:
-            rem(Type.LONG_TYPE);
-            break;
-        case Opcodes.FREM:
-            rem(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DREM:
-            rem(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.INEG:
-            neg(Type.INT_TYPE);
-            break;
-        case Opcodes.LNEG:
-            neg(Type.LONG_TYPE);
-            break;
-        case Opcodes.FNEG:
-            neg(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DNEG:
-            neg(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.ISHL:
-            shl(Type.INT_TYPE);
-            break;
-        case Opcodes.LSHL:
-            shl(Type.LONG_TYPE);
-            break;
-        case Opcodes.ISHR:
-            shr(Type.INT_TYPE);
-            break;
-        case Opcodes.LSHR:
-            shr(Type.LONG_TYPE);
-            break;
-        case Opcodes.IUSHR:
-            ushr(Type.INT_TYPE);
-            break;
-        case Opcodes.LUSHR:
-            ushr(Type.LONG_TYPE);
-            break;
-        case Opcodes.IAND:
-            and(Type.INT_TYPE);
-            break;
-        case Opcodes.LAND:
-            and(Type.LONG_TYPE);
-            break;
-        case Opcodes.IOR:
-            or(Type.INT_TYPE);
-            break;
-        case Opcodes.LOR:
-            or(Type.LONG_TYPE);
-            break;
-        case Opcodes.IXOR:
-            xor(Type.INT_TYPE);
-            break;
-        case Opcodes.LXOR:
-            xor(Type.LONG_TYPE);
-            break;
-        case Opcodes.I2L:
-            cast(Type.INT_TYPE, Type.LONG_TYPE);
-            break;
-        case Opcodes.I2F:
-            cast(Type.INT_TYPE, Type.FLOAT_TYPE);
-            break;
-        case Opcodes.I2D:
-            cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.L2I:
-            cast(Type.LONG_TYPE, Type.INT_TYPE);
-            break;
-        case Opcodes.L2F:
-            cast(Type.LONG_TYPE, Type.FLOAT_TYPE);
-            break;
-        case Opcodes.L2D:
-            cast(Type.LONG_TYPE, Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.F2I:
-            cast(Type.FLOAT_TYPE, Type.INT_TYPE);
-            break;
-        case Opcodes.F2L:
-            cast(Type.FLOAT_TYPE, Type.LONG_TYPE);
-            break;
-        case Opcodes.F2D:
-            cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.D2I:
-            cast(Type.DOUBLE_TYPE, Type.INT_TYPE);
-            break;
-        case Opcodes.D2L:
-            cast(Type.DOUBLE_TYPE, Type.LONG_TYPE);
-            break;
-        case Opcodes.D2F:
-            cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);
-            break;
-        case Opcodes.I2B:
-            cast(Type.INT_TYPE, Type.BYTE_TYPE);
-            break;
-        case Opcodes.I2C:
-            cast(Type.INT_TYPE, Type.CHAR_TYPE);
-            break;
-        case Opcodes.I2S:
-            cast(Type.INT_TYPE, Type.SHORT_TYPE);
-            break;
-        case Opcodes.LCMP:
-            lcmp();
-            break;
-        case Opcodes.FCMPL:
-            cmpl(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.FCMPG:
-            cmpg(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DCMPL:
-            cmpl(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.DCMPG:
-            cmpg(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.IRETURN:
-            areturn(Type.INT_TYPE);
-            break;
-        case Opcodes.LRETURN:
-            areturn(Type.LONG_TYPE);
-            break;
-        case Opcodes.FRETURN:
-            areturn(Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DRETURN:
-            areturn(Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.ARETURN:
-            areturn(OBJECT_TYPE);
-            break;
-        case Opcodes.RETURN:
-            areturn(Type.VOID_TYPE);
-            break;
-        case Opcodes.ARRAYLENGTH:
-            arraylength();
-            break;
-        case Opcodes.ATHROW:
-            athrow();
-            break;
-        case Opcodes.MONITORENTER:
-            monitorenter();
-            break;
-        case Opcodes.MONITOREXIT:
-            monitorexit();
-            break;
-        default:
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public void visitIntInsn(final int opcode, final int operand) {
-        switch (opcode) {
-        case Opcodes.BIPUSH:
-            iconst(operand);
-            break;
-        case Opcodes.SIPUSH:
-            iconst(operand);
-            break;
-        case Opcodes.NEWARRAY:
-            switch (operand) {
-            case Opcodes.T_BOOLEAN:
-                newarray(Type.BOOLEAN_TYPE);
-                break;
-            case Opcodes.T_CHAR:
-                newarray(Type.CHAR_TYPE);
-                break;
-            case Opcodes.T_BYTE:
-                newarray(Type.BYTE_TYPE);
-                break;
-            case Opcodes.T_SHORT:
-                newarray(Type.SHORT_TYPE);
-                break;
-            case Opcodes.T_INT:
-                newarray(Type.INT_TYPE);
-                break;
-            case Opcodes.T_FLOAT:
-                newarray(Type.FLOAT_TYPE);
-                break;
-            case Opcodes.T_LONG:
-                newarray(Type.LONG_TYPE);
-                break;
-            case Opcodes.T_DOUBLE:
-                newarray(Type.DOUBLE_TYPE);
-                break;
-            default:
-                throw new IllegalArgumentException();
-            }
-            break;
-        default:
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public void visitVarInsn(final int opcode, final int var) {
-        switch (opcode) {
-        case Opcodes.ILOAD:
-            load(var, Type.INT_TYPE);
-            break;
-        case Opcodes.LLOAD:
-            load(var, Type.LONG_TYPE);
-            break;
-        case Opcodes.FLOAD:
-            load(var, Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DLOAD:
-            load(var, Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.ALOAD:
-            load(var, OBJECT_TYPE);
-            break;
-        case Opcodes.ISTORE:
-            store(var, Type.INT_TYPE);
-            break;
-        case Opcodes.LSTORE:
-            store(var, Type.LONG_TYPE);
-            break;
-        case Opcodes.FSTORE:
-            store(var, Type.FLOAT_TYPE);
-            break;
-        case Opcodes.DSTORE:
-            store(var, Type.DOUBLE_TYPE);
-            break;
-        case Opcodes.ASTORE:
-            store(var, OBJECT_TYPE);
-            break;
-        case Opcodes.RET:
-            ret(var);
-            break;
-        default:
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public void visitTypeInsn(final int opcode, final String type) {
-        Type t = Type.getObjectType(type);
-        switch (opcode) {
-        case Opcodes.NEW:
-            anew(t);
-            break;
-        case Opcodes.ANEWARRAY:
-            newarray(t);
-            break;
-        case Opcodes.CHECKCAST:
-            checkcast(t);
-            break;
-        case Opcodes.INSTANCEOF:
-            instanceOf(t);
-            break;
-        default:
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public void visitFieldInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        switch (opcode) {
-        case Opcodes.GETSTATIC:
-            getstatic(owner, name, desc);
-            break;
-        case Opcodes.PUTSTATIC:
-            putstatic(owner, name, desc);
-            break;
-        case Opcodes.GETFIELD:
-            getfield(owner, name, desc);
-            break;
-        case Opcodes.PUTFIELD:
-            putfield(owner, name, desc);
-            break;
-        default:
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public void visitMethodInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        switch (opcode) {
-        case Opcodes.INVOKESPECIAL:
-            invokespecial(owner, name, desc);
-            break;
-        case Opcodes.INVOKEVIRTUAL:
-            invokevirtual(owner, name, desc);
-            break;
-        case Opcodes.INVOKESTATIC:
-            invokestatic(owner, name, desc);
-            break;
-        case Opcodes.INVOKEINTERFACE:
-            invokeinterface(owner, name, desc);
-            break;
-        default:
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
-            Object... bsmArgs) {
-        invokedynamic(name, desc, bsm, bsmArgs);
-    }
-
-    @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
-        switch (opcode) {
-        case Opcodes.IFEQ:
-            ifeq(label);
-            break;
-        case Opcodes.IFNE:
-            ifne(label);
-            break;
-        case Opcodes.IFLT:
-            iflt(label);
-            break;
-        case Opcodes.IFGE:
-            ifge(label);
-            break;
-        case Opcodes.IFGT:
-            ifgt(label);
-            break;
-        case Opcodes.IFLE:
-            ifle(label);
-            break;
-        case Opcodes.IF_ICMPEQ:
-            ificmpeq(label);
-            break;
-        case Opcodes.IF_ICMPNE:
-            ificmpne(label);
-            break;
-        case Opcodes.IF_ICMPLT:
-            ificmplt(label);
-            break;
-        case Opcodes.IF_ICMPGE:
-            ificmpge(label);
-            break;
-        case Opcodes.IF_ICMPGT:
-            ificmpgt(label);
-            break;
-        case Opcodes.IF_ICMPLE:
-            ificmple(label);
-            break;
-        case Opcodes.IF_ACMPEQ:
-            ifacmpeq(label);
-            break;
-        case Opcodes.IF_ACMPNE:
-            ifacmpne(label);
-            break;
-        case Opcodes.GOTO:
-            goTo(label);
-            break;
-        case Opcodes.JSR:
-            jsr(label);
-            break;
-        case Opcodes.IFNULL:
-            ifnull(label);
-            break;
-        case Opcodes.IFNONNULL:
-            ifnonnull(label);
-            break;
-        default:
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public void visitLabel(final Label label) {
-        mark(label);
-    }
-
-    @Override
-    public void visitLdcInsn(final Object cst) {
-        if (cst instanceof Integer) {
-            int val = ((Integer) cst).intValue();
-            iconst(val);
-        } else if (cst instanceof Byte) {
-            int val = ((Byte) cst).intValue();
-            iconst(val);
-        } else if (cst instanceof Character) {
-            int val = ((Character) cst).charValue();
-            iconst(val);
-        } else if (cst instanceof Short) {
-            int val = ((Short) cst).intValue();
-            iconst(val);
-        } else if (cst instanceof Boolean) {
-            int val = ((Boolean) cst).booleanValue() ? 1 : 0;
-            iconst(val);
-        } else if (cst instanceof Float) {
-            float val = ((Float) cst).floatValue();
-            fconst(val);
-        } else if (cst instanceof Long) {
-            long val = ((Long) cst).longValue();
-            lconst(val);
-        } else if (cst instanceof Double) {
-            double val = ((Double) cst).doubleValue();
-            dconst(val);
-        } else if (cst instanceof String) {
-            aconst(cst);
-        } else if (cst instanceof Type) {
-            tconst((Type) cst);
-        } else if (cst instanceof Handle) {
-            hconst((Handle) cst);
-        } else {
-            throw new IllegalArgumentException();
-        }
-    }
-
-    @Override
-    public void visitIincInsn(final int var, final int increment) {
-        iinc(var, increment);
-    }
-
-    @Override
-    public void visitTableSwitchInsn(final int min, final int max,
-            final Label dflt, final Label... labels) {
-        tableswitch(min, max, dflt, labels);
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
-            final Label[] labels) {
-        lookupswitch(dflt, keys, labels);
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
-        multianewarray(desc, dims);
-    }
-
-    // -----------------------------------------------------------------------
-
-    public void nop() {
-        mv.visitInsn(Opcodes.NOP);
-    }
-
-    public void aconst(final Object cst) {
-        if (cst == null) {
-            mv.visitInsn(Opcodes.ACONST_NULL);
-        } else {
-            mv.visitLdcInsn(cst);
-        }
-    }
-
-    public void iconst(final int cst) {
-        if (cst >= -1 && cst <= 5) {
-            mv.visitInsn(Opcodes.ICONST_0 + cst);
-        } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
-            mv.visitIntInsn(Opcodes.BIPUSH, cst);
-        } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
-            mv.visitIntInsn(Opcodes.SIPUSH, cst);
-        } else {
-            mv.visitLdcInsn(new Integer(cst));
-        }
-    }
-
-    public void lconst(final long cst) {
-        if (cst == 0L || cst == 1L) {
-            mv.visitInsn(Opcodes.LCONST_0 + (int) cst);
-        } else {
-            mv.visitLdcInsn(new Long(cst));
-        }
-    }
-
-    public void fconst(final float cst) {
-        int bits = Float.floatToIntBits(cst);
-        if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2
-            mv.visitInsn(Opcodes.FCONST_0 + (int) cst);
-        } else {
-            mv.visitLdcInsn(new Float(cst));
-        }
-    }
-
-    public void dconst(final double cst) {
-        long bits = Double.doubleToLongBits(cst);
-        if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d
-            mv.visitInsn(Opcodes.DCONST_0 + (int) cst);
-        } else {
-            mv.visitLdcInsn(new Double(cst));
-        }
-    }
-
-    public void tconst(final Type type) {
-        mv.visitLdcInsn(type);
-    }
-
-    public void hconst(final Handle handle) {
-        mv.visitLdcInsn(handle);
-    }
-
-    public void load(final int var, final Type type) {
-        mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), var);
-    }
-
-    public void aload(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IALOAD));
-    }
-
-    public void store(final int var, final Type type) {
-        mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), var);
-    }
-
-    public void astore(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IASTORE));
-    }
-
-    public void pop() {
-        mv.visitInsn(Opcodes.POP);
-    }
-
-    public void pop2() {
-        mv.visitInsn(Opcodes.POP2);
-    }
-
-    public void dup() {
-        mv.visitInsn(Opcodes.DUP);
-    }
-
-    public void dup2() {
-        mv.visitInsn(Opcodes.DUP2);
-    }
-
-    public void dupX1() {
-        mv.visitInsn(Opcodes.DUP_X1);
-    }
-
-    public void dupX2() {
-        mv.visitInsn(Opcodes.DUP_X2);
-    }
-
-    public void dup2X1() {
-        mv.visitInsn(Opcodes.DUP2_X1);
-    }
-
-    public void dup2X2() {
-        mv.visitInsn(Opcodes.DUP2_X2);
-    }
-
-    public void swap() {
-        mv.visitInsn(Opcodes.SWAP);
-    }
-
-    public void add(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IADD));
-    }
-
-    public void sub(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.ISUB));
-    }
-
-    public void mul(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IMUL));
-    }
-
-    public void div(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IDIV));
-    }
-
-    public void rem(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IREM));
-    }
-
-    public void neg(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.INEG));
-    }
-
-    public void shl(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.ISHL));
-    }
-
-    public void shr(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.ISHR));
-    }
-
-    public void ushr(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IUSHR));
-    }
-
-    public void and(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IAND));
-    }
-
-    public void or(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IOR));
-    }
-
-    public void xor(final Type type) {
-        mv.visitInsn(type.getOpcode(Opcodes.IXOR));
-    }
-
-    public void iinc(final int var, final int increment) {
-        mv.visitIincInsn(var, increment);
-    }
-
-    public void cast(final Type from, final Type to) {
-        if (from != to) {
-            if (from == Type.DOUBLE_TYPE) {
-                if (to == Type.FLOAT_TYPE) {
-                    mv.visitInsn(Opcodes.D2F);
-                } else if (to == Type.LONG_TYPE) {
-                    mv.visitInsn(Opcodes.D2L);
-                } else {
-                    mv.visitInsn(Opcodes.D2I);
-                    cast(Type.INT_TYPE, to);
-                }
-            } else if (from == Type.FLOAT_TYPE) {
-                if (to == Type.DOUBLE_TYPE) {
-                    mv.visitInsn(Opcodes.F2D);
-                } else if (to == Type.LONG_TYPE) {
-                    mv.visitInsn(Opcodes.F2L);
-                } else {
-                    mv.visitInsn(Opcodes.F2I);
-                    cast(Type.INT_TYPE, to);
-                }
-            } else if (from == Type.LONG_TYPE) {
-                if (to == Type.DOUBLE_TYPE) {
-                    mv.visitInsn(Opcodes.L2D);
-                } else if (to == Type.FLOAT_TYPE) {
-                    mv.visitInsn(Opcodes.L2F);
-                } else {
-                    mv.visitInsn(Opcodes.L2I);
-                    cast(Type.INT_TYPE, to);
-                }
-            } else {
-                if (to == Type.BYTE_TYPE) {
-                    mv.visitInsn(Opcodes.I2B);
-                } else if (to == Type.CHAR_TYPE) {
-                    mv.visitInsn(Opcodes.I2C);
-                } else if (to == Type.DOUBLE_TYPE) {
-                    mv.visitInsn(Opcodes.I2D);
-                } else if (to == Type.FLOAT_TYPE) {
-                    mv.visitInsn(Opcodes.I2F);
-                } else if (to == Type.LONG_TYPE) {
-                    mv.visitInsn(Opcodes.I2L);
-                } else if (to == Type.SHORT_TYPE) {
-                    mv.visitInsn(Opcodes.I2S);
-                }
-            }
-        }
-    }
-
-    public void lcmp() {
-        mv.visitInsn(Opcodes.LCMP);
-    }
-
-    public void cmpl(final Type type) {
-        mv.visitInsn(type == Type.FLOAT_TYPE ? Opcodes.FCMPL : Opcodes.DCMPL);
-    }
-
-    public void cmpg(final Type type) {
-        mv.visitInsn(type == Type.FLOAT_TYPE ? Opcodes.FCMPG : Opcodes.DCMPG);
-    }
-
-    public void ifeq(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFEQ, label);
-    }
-
-    public void ifne(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFNE, label);
-    }
-
-    public void iflt(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFLT, label);
-    }
-
-    public void ifge(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFGE, label);
-    }
-
-    public void ifgt(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFGT, label);
-    }
-
-    public void ifle(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFLE, label);
-    }
-
-    public void ificmpeq(final Label label) {
-        mv.visitJumpInsn(Opcodes.IF_ICMPEQ, label);
-    }
-
-    public void ificmpne(final Label label) {
-        mv.visitJumpInsn(Opcodes.IF_ICMPNE, label);
-    }
-
-    public void ificmplt(final Label label) {
-        mv.visitJumpInsn(Opcodes.IF_ICMPLT, label);
-    }
-
-    public void ificmpge(final Label label) {
-        mv.visitJumpInsn(Opcodes.IF_ICMPGE, label);
-    }
-
-    public void ificmpgt(final Label label) {
-        mv.visitJumpInsn(Opcodes.IF_ICMPGT, label);
-    }
-
-    public void ificmple(final Label label) {
-        mv.visitJumpInsn(Opcodes.IF_ICMPLE, label);
-    }
-
-    public void ifacmpeq(final Label label) {
-        mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
-    }
-
-    public void ifacmpne(final Label label) {
-        mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
-    }
-
-    public void goTo(final Label label) {
-        mv.visitJumpInsn(Opcodes.GOTO, label);
-    }
-
-    public void jsr(final Label label) {
-        mv.visitJumpInsn(Opcodes.JSR, label);
-    }
-
-    public void ret(final int var) {
-        mv.visitVarInsn(Opcodes.RET, var);
-    }
-
-    public void tableswitch(final int min, final int max, final Label dflt,
-            final Label... labels) {
-        mv.visitTableSwitchInsn(min, max, dflt, labels);
-    }
-
-    public void lookupswitch(final Label dflt, final int[] keys,
-            final Label[] labels) {
-        mv.visitLookupSwitchInsn(dflt, keys, labels);
-    }
-
-    public void areturn(final Type t) {
-        mv.visitInsn(t.getOpcode(Opcodes.IRETURN));
-    }
-
-    public void getstatic(final String owner, final String name,
-            final String desc) {
-        mv.visitFieldInsn(Opcodes.GETSTATIC, owner, name, desc);
-    }
-
-    public void putstatic(final String owner, final String name,
-            final String desc) {
-        mv.visitFieldInsn(Opcodes.PUTSTATIC, owner, name, desc);
-    }
-
-    public void getfield(final String owner, final String name,
-            final String desc) {
-        mv.visitFieldInsn(Opcodes.GETFIELD, owner, name, desc);
-    }
-
-    public void putfield(final String owner, final String name,
-            final String desc) {
-        mv.visitFieldInsn(Opcodes.PUTFIELD, owner, name, desc);
-    }
-
-    public void invokevirtual(final String owner, final String name,
-            final String desc) {
-        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc);
-    }
-
-    public void invokespecial(final String owner, final String name,
-            final String desc) {
-        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, desc);
-    }
-
-    public void invokestatic(final String owner, final String name,
-            final String desc) {
-        mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc);
-    }
-
-    public void invokeinterface(final String owner, final String name,
-            final String desc) {
-        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, name, desc);
-    }
-
-    public void invokedynamic(String name, String desc, Handle bsm,
-            Object[] bsmArgs) {
-        mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
-    }
-
-    public void anew(final Type type) {
-        mv.visitTypeInsn(Opcodes.NEW, type.getInternalName());
-    }
-
-    public void newarray(final Type type) {
-        int typ;
-        switch (type.getSort()) {
-        case Type.BOOLEAN:
-            typ = Opcodes.T_BOOLEAN;
-            break;
-        case Type.CHAR:
-            typ = Opcodes.T_CHAR;
-            break;
-        case Type.BYTE:
-            typ = Opcodes.T_BYTE;
-            break;
-        case Type.SHORT:
-            typ = Opcodes.T_SHORT;
-            break;
-        case Type.INT:
-            typ = Opcodes.T_INT;
-            break;
-        case Type.FLOAT:
-            typ = Opcodes.T_FLOAT;
-            break;
-        case Type.LONG:
-            typ = Opcodes.T_LONG;
-            break;
-        case Type.DOUBLE:
-            typ = Opcodes.T_DOUBLE;
-            break;
-        default:
-            mv.visitTypeInsn(Opcodes.ANEWARRAY, type.getInternalName());
-            return;
-        }
-        mv.visitIntInsn(Opcodes.NEWARRAY, typ);
-    }
-
-    public void arraylength() {
-        mv.visitInsn(Opcodes.ARRAYLENGTH);
-    }
-
-    public void athrow() {
-        mv.visitInsn(Opcodes.ATHROW);
-    }
-
-    public void checkcast(final Type type) {
-        mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());
-    }
-
-    public void instanceOf(final Type type) {
-        mv.visitTypeInsn(Opcodes.INSTANCEOF, type.getInternalName());
-    }
-
-    public void monitorenter() {
-        mv.visitInsn(Opcodes.MONITORENTER);
-    }
-
-    public void monitorexit() {
-        mv.visitInsn(Opcodes.MONITOREXIT);
-    }
-
-    public void multianewarray(final String desc, final int dims) {
-        mv.visitMultiANewArrayInsn(desc, dims);
-    }
-
-    public void ifnull(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFNULL, label);
-    }
-
-    public void ifnonnull(final Label label) {
-        mv.visitJumpInsn(Opcodes.IFNONNULL, label);
-    }
-
-    public void mark(final Label label) {
-        mv.visitLabel(label);
-    }
-}
diff --git a/src/jvm/clojure/asm/commons/LocalVariablesSorter.java b/src/jvm/clojure/asm/commons/LocalVariablesSorter.java
deleted file mode 100644
index 85f23ba..0000000
--- a/src/jvm/clojure/asm/commons/LocalVariablesSorter.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import clojure.asm.Label;
-import clojure.asm.MethodVisitor;
-import clojure.asm.Opcodes;
-import clojure.asm.Type;
-
-/**
- * A {@link MethodVisitor} that renumbers local variables in their order of
- * appearance. This adapter allows one to easily add new local variables to a
- * method. It may be used by inheriting from this class, but the preferred way
- * of using it is via delegation: the next visitor in the chain can indeed add
- * new locals when needed by calling {@link #newLocal} on this adapter (this
- * requires a reference back to this {@link LocalVariablesSorter}).
- *
- * @author Chris Nokleberg
- * @author Eugene Kuleshov
- * @author Eric Bruneton
- */
-public class LocalVariablesSorter extends MethodVisitor {
-
-    private static final Type OBJECT_TYPE = Type
-            .getObjectType("java/lang/Object");
-
-    /**
-     * Mapping from old to new local variable indexes. A local variable at index
-     * i of size 1 is remapped to 'mapping[2*i]', while a local variable at
-     * index i of size 2 is remapped to 'mapping[2*i+1]'.
-     */
-    private int[] mapping = new int[40];
-
-    /**
-     * Array used to store stack map local variable types after remapping.
-     */
-    private Object[] newLocals = new Object[20];
-
-    /**
-     * Index of the first local variable, after formal parameters.
-     */
-    protected final int firstLocal;
-
-    /**
-     * Index of the next local variable to be created by {@link #newLocal}.
-     */
-    protected int nextLocal;
-
-    /**
-     * Indicates if at least one local variable has moved due to remapping.
-     */
-    private boolean changed;
-
-    /**
-     * Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use
-     * this constructor</i>. Instead, they must use the
-     * {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version.
-     *
-     * @param access
-     *            access flags of the adapted method.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     * @param mv
-     *            the method visitor to which this adapter delegates calls.
-     */
-    public LocalVariablesSorter(final int access, final String desc,
-            final MethodVisitor mv) {
-        this(Opcodes.ASM4, access, desc, mv);
-    }
-
-    /**
-     * Creates a new {@link LocalVariablesSorter}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param access
-     *            access flags of the adapted method.
-     * @param desc
-     *            the method's descriptor (see {@link Type Type}).
-     * @param mv
-     *            the method visitor to which this adapter delegates calls.
-     */
-    protected LocalVariablesSorter(final int api, final int access,
-            final String desc, final MethodVisitor mv) {
-        super(api, mv);
-        Type[] args = Type.getArgumentTypes(desc);
-        nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
-        for (int i = 0; i < args.length; i++) {
-            nextLocal += args[i].getSize();
-        }
-        firstLocal = nextLocal;
-    }
-
-    @Override
-    public void visitVarInsn(final int opcode, final int var) {
-        Type type;
-        switch (opcode) {
-        case Opcodes.LLOAD:
-        case Opcodes.LSTORE:
-            type = Type.LONG_TYPE;
-            break;
-
-        case Opcodes.DLOAD:
-        case Opcodes.DSTORE:
-            type = Type.DOUBLE_TYPE;
-            break;
-
-        case Opcodes.FLOAD:
-        case Opcodes.FSTORE:
-            type = Type.FLOAT_TYPE;
-            break;
-
-        case Opcodes.ILOAD:
-        case Opcodes.ISTORE:
-            type = Type.INT_TYPE;
-            break;
-
-        default:
-            // case Opcodes.ALOAD:
-            // case Opcodes.ASTORE:
-            // case RET:
-            type = OBJECT_TYPE;
-            break;
-        }
-        mv.visitVarInsn(opcode, remap(var, type));
-    }
-
-    @Override
-    public void visitIincInsn(final int var, final int increment) {
-        mv.visitIincInsn(remap(var, Type.INT_TYPE), increment);
-    }
-
-    @Override
-    public void visitMaxs(final int maxStack, final int maxLocals) {
-        mv.visitMaxs(maxStack, nextLocal);
-    }
-
-    @Override
-    public void visitLocalVariable(final String name, final String desc,
-            final String signature, final Label start, final Label end,
-            final int index) {
-        int newIndex = remap(index, Type.getType(desc));
-        mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
-    }
-
-    @Override
-    public void visitFrame(final int type, final int nLocal,
-            final Object[] local, final int nStack, final Object[] stack) {
-        if (type != Opcodes.F_NEW) { // uncompressed frame
-            throw new IllegalStateException(
-                    "ClassReader.accept() should be called with EXPAND_FRAMES flag");
-        }
-
-        if (!changed) { // optimization for the case where mapping = identity
-            mv.visitFrame(type, nLocal, local, nStack, stack);
-            return;
-        }
-
-        // creates a copy of newLocals
-        Object[] oldLocals = new Object[newLocals.length];
-        System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
-
-        updateNewLocals(newLocals);
-
-        // copies types from 'local' to 'newLocals'
-        // 'newLocals' already contains the variables added with 'newLocal'
-
-        int index = 0; // old local variable index
-        int number = 0; // old local variable number
-        for (; number < nLocal; ++number) {
-            Object t = local[number];
-            int size = t == Opcodes.LONG || t == Opcodes.DOUBLE ? 2 : 1;
-            if (t != Opcodes.TOP) {
-                Type typ = OBJECT_TYPE;
-                if (t == Opcodes.INTEGER) {
-                    typ = Type.INT_TYPE;
-                } else if (t == Opcodes.FLOAT) {
-                    typ = Type.FLOAT_TYPE;
-                } else if (t == Opcodes.LONG) {
-                    typ = Type.LONG_TYPE;
-                } else if (t == Opcodes.DOUBLE) {
-                    typ = Type.DOUBLE_TYPE;
-                } else if (t instanceof String) {
-                    typ = Type.getObjectType((String) t);
-                }
-                setFrameLocal(remap(index, typ), t);
-            }
-            index += size;
-        }
-
-        // removes TOP after long and double types as well as trailing TOPs
-
-        index = 0;
-        number = 0;
-        for (int i = 0; index < newLocals.length; ++i) {
-            Object t = newLocals[index++];
-            if (t != null && t != Opcodes.TOP) {
-                newLocals[i] = t;
-                number = i + 1;
-                if (t == Opcodes.LONG || t == Opcodes.DOUBLE) {
-                    index += 1;
-                }
-            } else {
-                newLocals[i] = Opcodes.TOP;
-            }
-        }
-
-        // visits remapped frame
-        mv.visitFrame(type, number, newLocals, nStack, stack);
-
-        // restores original value of 'newLocals'
-        newLocals = oldLocals;
-    }
-
-    // -------------
-
-    /**
-     * Creates a new local variable of the given type.
-     *
-     * @param type
-     *            the type of the local variable to be created.
-     * @return the identifier of the newly created local variable.
-     */
-    public int newLocal(final Type type) {
-        Object t;
-        switch (type.getSort()) {
-        case Type.BOOLEAN:
-        case Type.CHAR:
-        case Type.BYTE:
-        case Type.SHORT:
-        case Type.INT:
-            t = Opcodes.INTEGER;
-            break;
-        case Type.FLOAT:
-            t = Opcodes.FLOAT;
-            break;
-        case Type.LONG:
-            t = Opcodes.LONG;
-            break;
-        case Type.DOUBLE:
-            t = Opcodes.DOUBLE;
-            break;
-        case Type.ARRAY:
-            t = type.getDescriptor();
-            break;
-        // case Type.OBJECT:
-        default:
-            t = type.getInternalName();
-            break;
-        }
-        int local = newLocalMapping(type);
-        setLocalType(local, type);
-        setFrameLocal(local, t);
-        return local;
-    }
-
-    /**
-     * Notifies subclasses that a new stack map frame is being visited. The
-     * array argument contains the stack map frame types corresponding to the
-     * local variables added with {@link #newLocal}. This method can update
-     * these types in place for the stack map frame being visited. The default
-     * implementation of this method does nothing, i.e. a local variable added
-     * with {@link #newLocal} will have the same type in all stack map frames.
-     * But this behavior is not always the desired one, for instance if a local
-     * variable is added in the middle of a try/catch block: the frame for the
-     * exception handler should have a TOP type for this new local.
-     *
-     * @param newLocals
-     *            the stack map frame types corresponding to the local variables
-     *            added with {@link #newLocal} (and null for the others). The
-     *            format of this array is the same as in
-     *            {@link MethodVisitor#visitFrame}, except that long and double
-     *            types use two slots. The types for the current stack map frame
-     *            must be updated in place in this array.
-     */
-    protected void updateNewLocals(Object[] newLocals) {
-    }
-
-    /**
-     * Notifies subclasses that a local variable has been added or remapped. The
-     * default implementation of this method does nothing.
-     *
-     * @param local
-     *            a local variable identifier, as returned by {@link #newLocal
-     *            newLocal()}.
-     * @param type
-     *            the type of the value being stored in the local variable.
-     */
-    protected void setLocalType(final int local, final Type type) {
-    }
-
-    private void setFrameLocal(final int local, final Object type) {
-        int l = newLocals.length;
-        if (local >= l) {
-            Object[] a = new Object[Math.max(2 * l, local + 1)];
-            System.arraycopy(newLocals, 0, a, 0, l);
-            newLocals = a;
-        }
-        newLocals[local] = type;
-    }
-
-    private int remap(final int var, final Type type) {
-        if (var + type.getSize() <= firstLocal) {
-            return var;
-        }
-        int key = 2 * var + type.getSize() - 1;
-        int size = mapping.length;
-        if (key >= size) {
-            int[] newMapping = new int[Math.max(2 * size, key + 1)];
-            System.arraycopy(mapping, 0, newMapping, 0, size);
-            mapping = newMapping;
-        }
-        int value = mapping[key];
-        if (value == 0) {
-            value = newLocalMapping(type);
-            setLocalType(value, type);
-            mapping[key] = value + 1;
-        } else {
-            value--;
-        }
-        if (value != var) {
-            changed = true;
-        }
-        return value;
-    }
-
-    protected int newLocalMapping(final Type type) {
-        int local = nextLocal;
-        nextLocal += type.getSize();
-        return local;
-    }
-}
diff --git a/src/jvm/clojure/asm/commons/Method.java b/src/jvm/clojure/asm/commons/Method.java
deleted file mode 100644
index ee16c93..0000000
--- a/src/jvm/clojure/asm/commons/Method.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import clojure.asm.Type;
-
-/**
- * A named method descriptor.
- *
- * @author Juozas Baliuka
- * @author Chris Nokleberg
- * @author Eric Bruneton
- */
-public class Method {
-
-    /**
-     * The method name.
-     */
-    private final String name;
-
-    /**
-     * The method descriptor.
-     */
-    private final String desc;
-
-    /**
-     * Maps primitive Java type names to their descriptors.
-     */
-    private static final Map<String, String> DESCRIPTORS;
-
-    static {
-        DESCRIPTORS = new HashMap<String, String>();
-        DESCRIPTORS.put("void", "V");
-        DESCRIPTORS.put("byte", "B");
-        DESCRIPTORS.put("char", "C");
-        DESCRIPTORS.put("double", "D");
-        DESCRIPTORS.put("float", "F");
-        DESCRIPTORS.put("int", "I");
-        DESCRIPTORS.put("long", "J");
-        DESCRIPTORS.put("short", "S");
-        DESCRIPTORS.put("boolean", "Z");
-    }
-
-    /**
-     * Creates a new {@link Method}.
-     *
-     * @param name
-     *            the method's name.
-     * @param desc
-     *            the method's descriptor.
-     */
-    public Method(final String name, final String desc) {
-        this.name = name;
-        this.desc = desc;
-    }
-
-    /**
-     * Creates a new {@link Method}.
-     *
-     * @param name
-     *            the method's name.
-     * @param returnType
-     *            the method's return type.
-     * @param argumentTypes
-     *            the method's argument types.
-     */
-    public Method(final String name, final Type returnType,
-            final Type[] argumentTypes) {
-        this(name, Type.getMethodDescriptor(returnType, argumentTypes));
-    }
-
-    /**
-     * Creates a new {@link Method}.
-     *
-     * @param m
-     *            a java.lang.reflect method descriptor
-     * @return a {@link Method} corresponding to the given Java method
-     *         declaration.
-     */
-    public static Method getMethod(java.lang.reflect.Method m) {
-        return new Method(m.getName(), Type.getMethodDescriptor(m));
-    }
-
-    /**
-     * Creates a new {@link Method}.
-     *
-     * @param c
-     *            a java.lang.reflect constructor descriptor
-     * @return a {@link Method} corresponding to the given Java constructor
-     *         declaration.
-     */
-    public static Method getMethod(java.lang.reflect.Constructor<?> c) {
-        return new Method("<init>", Type.getConstructorDescriptor(c));
-    }
-
-    /**
-     * Returns a {@link Method} corresponding to the given Java method
-     * declaration.
-     *
-     * @param method
-     *            a Java method declaration, without argument names, of the form
-     *            "returnType name (argumentType1, ... argumentTypeN)", where
-     *            the types are in plain Java (e.g. "int", "float",
-     *            "java.util.List", ...). Classes of the java.lang package can
-     *            be specified by their unqualified name; all other classes
-     *            names must be fully qualified.
-     * @return a {@link Method} corresponding to the given Java method
-     *         declaration.
-     * @throws IllegalArgumentException
-     *             if <code>method</code> could not get parsed.
-     */
-    public static Method getMethod(final String method)
-            throws IllegalArgumentException {
-        return getMethod(method, false);
-    }
-
-    /**
-     * Returns a {@link Method} corresponding to the given Java method
-     * declaration.
-     *
-     * @param method
-     *            a Java method declaration, without argument names, of the form
-     *            "returnType name (argumentType1, ... argumentTypeN)", where
-     *            the types are in plain Java (e.g. "int", "float",
-     *            "java.util.List", ...). Classes of the java.lang package may
-     *            be specified by their unqualified name, depending on the
-     *            defaultPackage argument; all other classes names must be fully
-     *            qualified.
-     * @param defaultPackage
-     *            true if unqualified class names belong to the default package,
-     *            or false if they correspond to java.lang classes. For instance
-     *            "Object" means "Object" if this option is true, or
-     *            "java.lang.Object" otherwise.
-     * @return a {@link Method} corresponding to the given Java method
-     *         declaration.
-     * @throws IllegalArgumentException
-     *             if <code>method</code> could not get parsed.
-     */
-    public static Method getMethod(final String method,
-            final boolean defaultPackage) throws IllegalArgumentException {
-        int space = method.indexOf(' ');
-        int start = method.indexOf('(', space) + 1;
-        int end = method.indexOf(')', start);
-        if (space == -1 || start == -1 || end == -1) {
-            throw new IllegalArgumentException();
-        }
-        String returnType = method.substring(0, space);
-        String methodName = method.substring(space + 1, start - 1).trim();
-        StringBuffer sb = new StringBuffer();
-        sb.append('(');
-        int p;
-        do {
-            String s;
-            p = method.indexOf(',', start);
-            if (p == -1) {
-                s = map(method.substring(start, end).trim(), defaultPackage);
-            } else {
-                s = map(method.substring(start, p).trim(), defaultPackage);
-                start = p + 1;
-            }
-            sb.append(s);
-        } while (p != -1);
-        sb.append(')');
-        sb.append(map(returnType, defaultPackage));
-        return new Method(methodName, sb.toString());
-    }
-
-    private static String map(final String type, final boolean defaultPackage) {
-        if ("".equals(type)) {
-            return type;
-        }
-
-        StringBuffer sb = new StringBuffer();
-        int index = 0;
-        while ((index = type.indexOf("[]", index) + 1) > 0) {
-            sb.append('[');
-        }
-
-        String t = type.substring(0, type.length() - sb.length() * 2);
-        String desc = DESCRIPTORS.get(t);
-        if (desc != null) {
-            sb.append(desc);
-        } else {
-            sb.append('L');
-            if (t.indexOf('.') < 0) {
-                if (!defaultPackage) {
-                    sb.append("java/lang/");
-                }
-                sb.append(t);
-            } else {
-                sb.append(t.replace('.', '/'));
-            }
-            sb.append(';');
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Returns the name of the method described by this object.
-     *
-     * @return the name of the method described by this object.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Returns the descriptor of the method described by this object.
-     *
-     * @return the descriptor of the method described by this object.
-     */
-    public String getDescriptor() {
-        return desc;
-    }
-
-    /**
-     * Returns the return type of the method described by this object.
-     *
-     * @return the return type of the method described by this object.
-     */
-    public Type getReturnType() {
-        return Type.getReturnType(desc);
-    }
-
-    /**
-     * Returns the argument types of the method described by this object.
-     *
-     * @return the argument types of the method described by this object.
-     */
-    public Type[] getArgumentTypes() {
-        return Type.getArgumentTypes(desc);
-    }
-
-    @Override
-    public String toString() {
-        return name + desc;
-    }
-
-    @Override
-    public boolean equals(final Object o) {
-        if (!(o instanceof Method)) {
-            return false;
-        }
-        Method other = (Method) o;
-        return name.equals(other.name) && desc.equals(other.desc);
-    }
-
-    @Override
-    public int hashCode() {
-        return name.hashCode() ^ desc.hashCode();
-    }
-}
\ No newline at end of file
diff --git a/src/jvm/clojure/asm/commons/SerialVersionUIDAdder.java b/src/jvm/clojure/asm/commons/SerialVersionUIDAdder.java
deleted file mode 100644
index 65dd583..0000000
--- a/src/jvm/clojure/asm/commons/SerialVersionUIDAdder.java
+++ /dev/null
@@ -1,533 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutput;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-
-import clojure.asm.ClassVisitor;
-import clojure.asm.FieldVisitor;
-import clojure.asm.MethodVisitor;
-import clojure.asm.Opcodes;
-
-/**
- * A {@link ClassVisitor} that adds a serial version unique identifier to a
- * class if missing. Here is typical usage of this class:
- *
- * <pre>
- *   ClassWriter cw = new ClassWriter(...);
- *   ClassVisitor sv = new SerialVersionUIDAdder(cw);
- *   ClassVisitor ca = new MyClassAdapter(sv);
- *   new ClassReader(orginalClass).accept(ca, false);
- * </pre>
- *
- * The SVUID algorithm can be found <a href=
- * "http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html"
- * >http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html</a>:
- *
- * <pre>
- * The serialVersionUID is computed using the signature of a stream of bytes
- * that reflect the class definition. The National Institute of Standards and
- * Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a
- * signature for the stream. The first two 32-bit quantities are used to form a
- * 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data
- * types to a sequence of bytes. The values input to the stream are defined by
- * the Java Virtual Machine (VM) specification for classes.
- *
- * The sequence of items in the stream is as follows:
- *
- * 1. The class name written using UTF encoding.
- * 2. The class modifiers written as a 32-bit integer.
- * 3. The name of each interface sorted by name written using UTF encoding.
- * 4. For each field of the class sorted by field name (except private static
- * and private transient fields):
- * 1. The name of the field in UTF encoding.
- * 2. The modifiers of the field written as a 32-bit integer.
- * 3. The descriptor of the field in UTF encoding
- * 5. If a class initializer exists, write out the following:
- * 1. The name of the method, <clinit>, in UTF encoding.
- * 2. The modifier of the method, java.lang.reflect.Modifier.STATIC,
- * written as a 32-bit integer.
- * 3. The descriptor of the method, ()V, in UTF encoding.
- * 6. For each non-private constructor sorted by method name and signature:
- * 1. The name of the method, <init>, in UTF encoding.
- * 2. The modifiers of the method written as a 32-bit integer.
- * 3. The descriptor of the method in UTF encoding.
- * 7. For each non-private method sorted by method name and signature:
- * 1. The name of the method in UTF encoding.
- * 2. The modifiers of the method written as a 32-bit integer.
- * 3. The descriptor of the method in UTF encoding.
- * 8. The SHA-1 algorithm is executed on the stream of bytes produced by
- * DataOutputStream and produces five 32-bit values sha[0..4].
- *
- * 9. The hash value is assembled from the first and second 32-bit values of
- * the SHA-1 message digest. If the result of the message digest, the five
- * 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named
- * sha, the hash value would be computed as follows:
- *
- * long hash = ((sha[0] >>> 24) & 0xFF) |
- * ((sha[0] >>> 16) & 0xFF) << 8 |
- * ((sha[0] >>> 8) & 0xFF) << 16 |
- * ((sha[0] >>> 0) & 0xFF) << 24 |
- * ((sha[1] >>> 24) & 0xFF) << 32 |
- * ((sha[1] >>> 16) & 0xFF) << 40 |
- * ((sha[1] >>> 8) & 0xFF) << 48 |
- * ((sha[1] >>> 0) & 0xFF) << 56;
- * </pre>
- *
- * @author Rajendra Inamdar, Vishal Vishnoi
- */
-public class SerialVersionUIDAdder extends ClassVisitor {
-
-    /**
-     * Flag that indicates if we need to compute SVUID.
-     */
-    private boolean computeSVUID;
-
-    /**
-     * Set to true if the class already has SVUID.
-     */
-    private boolean hasSVUID;
-
-    /**
-     * Classes access flags.
-     */
-    private int access;
-
-    /**
-     * Internal name of the class
-     */
-    private String name;
-
-    /**
-     * Interfaces implemented by the class.
-     */
-    private String[] interfaces;
-
-    /**
-     * Collection of fields. (except private static and private transient
-     * fields)
-     */
-    private Collection<Item> svuidFields;
-
-    /**
-     * Set to true if the class has static initializer.
-     */
-    private boolean hasStaticInitializer;
-
-    /**
-     * Collection of non-private constructors.
-     */
-    private Collection<Item> svuidConstructors;
-
-    /**
-     * Collection of non-private methods.
-     */
-    private Collection<Item> svuidMethods;
-
-    /**
-     * Creates a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use
-     * this constructor</i>. Instead, they must use the
-     * {@link #SerialVersionUIDAdder(int, ClassVisitor)} version.
-     *
-     * @param cv
-     *            a {@link ClassVisitor} to which this visitor will delegate
-     *            calls.
-     */
-    public SerialVersionUIDAdder(final ClassVisitor cv) {
-        this(Opcodes.ASM4, cv);
-    }
-
-    /**
-     * Creates a new {@link SerialVersionUIDAdder}.
-     *
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}.
-     * @param cv
-     *            a {@link ClassVisitor} to which this visitor will delegate
-     *            calls.
-     */
-    protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) {
-        super(api, cv);
-        svuidFields = new ArrayList<Item>();
-        svuidConstructors = new ArrayList<Item>();
-        svuidMethods = new ArrayList<Item>();
-    }
-
-    // ------------------------------------------------------------------------
-    // Overriden methods
-    // ------------------------------------------------------------------------
-
-    /*
-     * Visit class header and get class name, access , and interfaces
-     * information (step 1,2, and 3) for SVUID computation.
-     */
-    @Override
-    public void visit(final int version, final int access, final String name,
-            final String signature, final String superName,
-            final String[] interfaces) {
-        computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;
-
-        if (computeSVUID) {
-            this.name = name;
-            this.access = access;
-            this.interfaces = interfaces;
-        }
-
-        super.visit(version, access, name, signature, superName, interfaces);
-    }
-
-    /*
-     * Visit the methods and get constructor and method information (step 5 and
-     * 7). Also determine if there is a class initializer (step 6).
-     */
-    @Override
-    public MethodVisitor visitMethod(final int access, final String name,
-            final String desc, final String signature, final String[] exceptions) {
-        if (computeSVUID) {
-            if ("<clinit>".equals(name)) {
-                hasStaticInitializer = true;
-            }
-            /*
-             * Remembers non private constructors and methods for SVUID
-             * computation For constructor and method modifiers, only the
-             * ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-             * ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags
-             * are used.
-             */
-            int mods = access
-                    & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
-                            | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
-                            | Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED
-                            | Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT);
-
-            // all non private methods
-            if ((access & Opcodes.ACC_PRIVATE) == 0) {
-                if ("<init>".equals(name)) {
-                    svuidConstructors.add(new Item(name, mods, desc));
-                } else if (!"<clinit>".equals(name)) {
-                    svuidMethods.add(new Item(name, mods, desc));
-                }
-            }
-        }
-
-        return super.visitMethod(access, name, desc, signature, exceptions);
-    }
-
-    /*
-     * Gets class field information for step 4 of the algorithm. Also determines
-     * if the class already has a SVUID.
-     */
-    @Override
-    public FieldVisitor visitField(final int access, final String name,
-            final String desc, final String signature, final Object value) {
-        if (computeSVUID) {
-            if ("serialVersionUID".equals(name)) {
-                // since the class already has SVUID, we won't be computing it.
-                computeSVUID = false;
-                hasSVUID = true;
-            }
-            /*
-             * Remember field for SVUID computation For field modifiers, only
-             * the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC,
-             * ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when
-             * computing serialVersionUID values.
-             */
-            if ((access & Opcodes.ACC_PRIVATE) == 0
-                    || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) {
-                int mods = access
-                        & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
-                                | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
-                                | Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT);
-                svuidFields.add(new Item(name, mods, desc));
-            }
-        }
-
-        return super.visitField(access, name, desc, signature, value);
-    }
-
-    /**
-     * Handle a bizarre special case. Nested classes (static classes declared
-     * inside another class) that are protected have their access bit set to
-     * public in their class files to deal with some odd reflection situation.
-     * Our SVUID computation must do as the JVM does and ignore access bits in
-     * the class file in favor of the access bits InnerClass attribute.
-     */
-    @Override
-    public void visitInnerClass(final String aname, final String outerName,
-            final String innerName, final int attr_access) {
-        if ((name != null) && name.equals(aname)) {
-            this.access = attr_access;
-        }
-        super.visitInnerClass(aname, outerName, innerName, attr_access);
-    }
-
-    /*
-     * Add the SVUID if class doesn't have one
-     */
-    @Override
-    public void visitEnd() {
-        // compute SVUID and add it to the class
-        if (computeSVUID && !hasSVUID) {
-            try {
-                addSVUID(computeSVUID());
-            } catch (Throwable e) {
-                throw new RuntimeException("Error while computing SVUID for "
-                        + name, e);
-            }
-        }
-
-        super.visitEnd();
-    }
-
-    // ------------------------------------------------------------------------
-    // Utility methods
-    // ------------------------------------------------------------------------
-
-    /**
-     * Returns true if the class already has a SVUID field. The result of this
-     * method is only valid when visitEnd is or has been called.
-     *
-     * @return true if the class already has a SVUID field.
-     */
-    public boolean hasSVUID() {
-        return hasSVUID;
-    }
-
-    protected void addSVUID(long svuid) {
-        FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL
-                + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, new Long(
-                svuid));
-        if (fv != null) {
-            fv.visitEnd();
-        }
-    }
-
-    /**
-     * Computes and returns the value of SVUID.
-     *
-     * @return Returns the serial version UID
-     * @throws IOException
-     *             if an I/O error occurs
-     */
-    protected long computeSVUID() throws IOException {
-        ByteArrayOutputStream bos;
-        DataOutputStream dos = null;
-        long svuid = 0;
-
-        try {
-            bos = new ByteArrayOutputStream();
-            dos = new DataOutputStream(bos);
-
-            /*
-             * 1. The class name written using UTF encoding.
-             */
-            dos.writeUTF(name.replace('/', '.'));
-
-            /*
-             * 2. The class modifiers written as a 32-bit integer.
-             */
-            dos.writeInt(access
-                    & (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL
-                            | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT));
-
-            /*
-             * 3. The name of each interface sorted by name written using UTF
-             * encoding.
-             */
-            Arrays.sort(interfaces);
-            for (int i = 0; i < interfaces.length; i++) {
-                dos.writeUTF(interfaces[i].replace('/', '.'));
-            }
-
-            /*
-             * 4. For each field of the class sorted by field name (except
-             * private static and private transient fields):
-             *
-             * 1. The name of the field in UTF encoding. 2. The modifiers of the
-             * field written as a 32-bit integer. 3. The descriptor of the field
-             * in UTF encoding
-             *
-             * Note that field signatures are not dot separated. Method and
-             * constructor signatures are dot separated. Go figure...
-             */
-            writeItems(svuidFields, dos, false);
-
-            /*
-             * 5. If a class initializer exists, write out the following: 1. The
-             * name of the method, <clinit>, in UTF encoding. 2. The modifier of
-             * the method, java.lang.reflect.Modifier.STATIC, written as a
-             * 32-bit integer. 3. The descriptor of the method, ()V, in UTF
-             * encoding.
-             */
-            if (hasStaticInitializer) {
-                dos.writeUTF("<clinit>");
-                dos.writeInt(Opcodes.ACC_STATIC);
-                dos.writeUTF("()V");
-            } // if..
-
-            /*
-             * 6. For each non-private constructor sorted by method name and
-             * signature: 1. The name of the method, <init>, in UTF encoding. 2.
-             * The modifiers of the method written as a 32-bit integer. 3. The
-             * descriptor of the method in UTF encoding.
-             */
-            writeItems(svuidConstructors, dos, true);
-
-            /*
-             * 7. For each non-private method sorted by method name and
-             * signature: 1. The name of the method in UTF encoding. 2. The
-             * modifiers of the method written as a 32-bit integer. 3. The
-             * descriptor of the method in UTF encoding.
-             */
-            writeItems(svuidMethods, dos, true);
-
-            dos.flush();
-
-            /*
-             * 8. The SHA-1 algorithm is executed on the stream of bytes
-             * produced by DataOutputStream and produces five 32-bit values
-             * sha[0..4].
-             */
-            byte[] hashBytes = computeSHAdigest(bos.toByteArray());
-
-            /*
-             * 9. The hash value is assembled from the first and second 32-bit
-             * values of the SHA-1 message digest. If the result of the message
-             * digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of
-             * five int values named sha, the hash value would be computed as
-             * follows:
-             *
-             * long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF)
-             * << 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) <<
-             * 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) & 0xFF) <<
-             * 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & 0xFF) <<
-             * 56;
-             */
-            for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
-                svuid = (svuid << 8) | (hashBytes[i] & 0xFF);
-            }
-        } finally {
-            // close the stream (if open)
-            if (dos != null) {
-                dos.close();
-            }
-        }
-
-        return svuid;
-    }
-
-    /**
-     * Returns the SHA-1 message digest of the given value.
-     *
-     * @param value
-     *            the value whose SHA message digest must be computed.
-     * @return the SHA-1 message digest of the given value.
-     */
-    protected byte[] computeSHAdigest(final byte[] value) {
-        try {
-            return MessageDigest.getInstance("SHA").digest(value);
-        } catch (Exception e) {
-            throw new UnsupportedOperationException(e.toString());
-        }
-    }
-
-    /**
-     * Sorts the items in the collection and writes it to the data output stream
-     *
-     * @param itemCollection
-     *            collection of items
-     * @param dos
-     *            a <code>DataOutputStream</code> value
-     * @param dotted
-     *            a <code>boolean</code> value
-     * @exception IOException
-     *                if an error occurs
-     */
-    private static void writeItems(final Collection<Item> itemCollection,
-            final DataOutput dos, final boolean dotted) throws IOException {
-        int size = itemCollection.size();
-        Item[] items = itemCollection.toArray(new Item[size]);
-        Arrays.sort(items);
-        for (int i = 0; i < size; i++) {
-            dos.writeUTF(items[i].name);
-            dos.writeInt(items[i].access);
-            dos.writeUTF(dotted ? items[i].desc.replace('/', '.')
-                    : items[i].desc);
-        }
-    }
-
-    // ------------------------------------------------------------------------
-    // Inner classes
-    // ------------------------------------------------------------------------
-
-    private static class Item implements Comparable<Item> {
-
-        final String name;
-
-        final int access;
-
-        final String desc;
-
-        Item(final String name, final int access, final String desc) {
-            this.name = name;
-            this.access = access;
-            this.desc = desc;
-        }
-
-        public int compareTo(final Item other) {
-            int retVal = name.compareTo(other.name);
-            if (retVal == 0) {
-                retVal = desc.compareTo(other.desc);
-            }
-            return retVal;
-        }
-
-        @Override
-        public boolean equals(final Object o) {
-            if (o instanceof Item) {
-                return compareTo((Item) o) == 0;
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return (name + desc).hashCode();
-        }
-    }
-}
diff --git a/src/jvm/clojure/asm/commons/StaticInitMerger.java b/src/jvm/clojure/asm/commons/StaticInitMerger.java
deleted file mode 100644
index 1be4dcd..0000000
--- a/src/jvm/clojure/asm/commons/StaticInitMerger.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import clojure.asm.ClassVisitor;
-import clojure.asm.MethodVisitor;
-import clojure.asm.Opcodes;
-
-/**
- * A {@link ClassVisitor} that merges clinit methods into a single one.
- *
- * @author Eric Bruneton
- */
-public class StaticInitMerger extends ClassVisitor {
-
-    private String name;
-
-    private MethodVisitor clinit;
-
-    private final String prefix;
-
-    private int counter;
-
-    public StaticInitMerger(final String prefix, final ClassVisitor cv) {
-        this(Opcodes.ASM4, prefix, cv);
-    }
-
-    protected StaticInitMerger(final int api, final String prefix,
-            final ClassVisitor cv) {
-        super(api, cv);
-        this.prefix = prefix;
-    }
-
-    @Override
-    public void visit(final int version, final int access, final String name,
-            final String signature, final String superName,
-            final String[] interfaces) {
-        cv.visit(version, access, name, signature, superName, interfaces);
-        this.name = name;
-    }
-
-    @Override
-    public MethodVisitor visitMethod(final int access, final String name,
-            final String desc, final String signature, final String[] exceptions) {
-        MethodVisitor mv;
-        if ("<clinit>".equals(name)) {
-            int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;
-            String n = prefix + counter++;
-            mv = cv.visitMethod(a, n, desc, signature, exceptions);
-
-            if (clinit == null) {
-                clinit = cv.visitMethod(a, name, desc, null, null);
-            }
-            clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc);
-        } else {
-            mv = cv.visitMethod(access, name, desc, signature, exceptions);
-        }
-        return mv;
-    }
-
-    @Override
-    public void visitEnd() {
-        if (clinit != null) {
-            clinit.visitInsn(Opcodes.RETURN);
-            clinit.visitMaxs(0, 0);
-        }
-        cv.visitEnd();
-    }
-}
diff --git a/src/jvm/clojure/asm/commons/TableSwitchGenerator.java b/src/jvm/clojure/asm/commons/TableSwitchGenerator.java
deleted file mode 100644
index 7c1cf6e..0000000
--- a/src/jvm/clojure/asm/commons/TableSwitchGenerator.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-package clojure.asm.commons;
-
-import clojure.asm.Label;
-
-/**
- * A code generator for switch statements.
- *
- * @author Juozas Baliuka
- * @author Chris Nokleberg
- * @author Eric Bruneton
- */
-public interface TableSwitchGenerator {
-
-    /**
-     * Generates the code for a switch case.
-     *
-     * @param key
-     *            the switch case key.
-     * @param end
-     *            a label that corresponds to the end of the switch statement.
-     */
-    void generateCase(int key, Label end);
-
-    /**
-     * Generates the code for the default switch case.
-     */
-    void generateDefault();
-}
diff --git a/src/jvm/clojure/asm/commons/package.html b/src/jvm/clojure/asm/commons/package.html
deleted file mode 100644
index 4ce0db8..0000000
--- a/src/jvm/clojure/asm/commons/package.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<html>
-<!--
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
--->
-<body>
-Provides some useful class and method adapters. <i>The preferred way of using
-these adapters is by chaining them together and to custom adapters (instead of
-inheriting from them)</i>. Indeed this approach provides more combination
-possibilities than inheritance. For instance, suppose you want to implement an
-adapter MyAdapter than needs sorted local variables and intermediate stack map
-frame values taking into account the local variables sort. By using inheritance,
-this would require MyAdapter to extend AnalyzerAdapter, itself extending
-LocalVariablesSorter. But AnalyzerAdapter is not a subclass of
-LocalVariablesSorter, so this is not possible. On the contrary, by using
-delegation, you can make LocalVariablesSorter delegate to AnalyzerAdapter,
-itself delegating to MyAdapter. In this case AnalyzerAdapter computes
-intermediate frames based on the output of LocalVariablesSorter, and MyAdapter
-can add new locals by calling the newLocal method on LocalVariablesSorter, and
-can get the stack map frame state before each instruction by reading the locals
-and stack fields in AnalyzerAdapter (this requires references from MyAdapter
-back to LocalVariablesSorter and AnalyzerAdapter).
-</body>
\ No newline at end of file
diff --git a/src/jvm/clojure/asm/package.html b/src/jvm/clojure/asm/package.html
deleted file mode 100644
index 82c1ff9..0000000
--- a/src/jvm/clojure/asm/package.html
+++ /dev/null
@@ -1,87 +0,0 @@
-<html>
-<!--
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2011 INRIA, France Telecom
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the names of its
- *    contributors may be used to endorse or promote products derived from
- *    this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
--->
-<body>
-Provides a small and fast bytecode manipulation framework.
-
-<p>
-The <a href="http://www.objectweb.org/asm">ASM</a> framework is organized
-around the {@link clojure.asm.ClassVisitor ClassVisitor},
-{@link clojure.asm.FieldVisitor FieldVisitor},
-{@link clojure.asm.MethodVisitor MethodVisitor} and
-{@link clojure.asm.AnnotationVisitor AnnotationVisitor} abstract classes,
-which allow one to visit the fields, methods and annotations of a class,
-including the bytecode instructions of each method.
-
-<p>
-In addition to these main abstract classes, ASM provides a {@link
-clojure.asm.ClassReader ClassReader} class, that can parse an
-existing class and make a given visitor visit it. ASM also provides
-a {@link clojure.asm.ClassWriter ClassWriter} class, which is
-a visitor that generates Java class files.
-
-<p>
-In order to generate a class from scratch, only the {@link
-clojure.asm.ClassWriter ClassWriter} class is necessary. Indeed,
-in order to generate a class, one must just call its visit<i>Xxx</i>
-methods with the appropriate arguments to generate the desired fields
-and methods. See the "helloworld" example in the ASM distribution for
-more details about class generation.
-
-<p>
-In order to modify existing classes, one must use a {@link
-clojure.asm.ClassReader ClassReader} class to analyze
-the original class, a class modifier, and a {@link clojure.asm.ClassWriter
-ClassWriter} to construct the modified class. The class modifier
-is just a {@link clojure.asm.ClassVisitor ClassVisitor}
-that delegates most of the work to another {@link clojure.asm.ClassVisitor
-ClassVisitor}, but that sometimes changes some parameter values,
-or call additional methods, in order to implement the desired
-modification process. In order to make it easier to implement such
-class modifiers, the {@link clojure.asm.ClassVisitor
-ClassVisitor} and {@link clojure.asm.MethodVisitor MethodVisitor}
-classes delegate by default all the method calls they receive to an
-optional visitor. See the "adapt" example in the ASM
-distribution for more details about class modification.
-
-<p>
-The size of the core ASM library, <tt>asm.jar</tt>, is only 45KB, which is much
-smaller than the size of the
-<a href="http://jakarta.apache.org/bcel">BCEL</a> library (504KB), and than the
-size of the
-<a href="http://serp.sourceforge.net">SERP</a> library (150KB). ASM is also
-much faster than these tools. Indeed the overhead of a load time class
-transformation process is of the order of 60% with ASM, 700% or more with BCEL,
-and 1100% or more with SERP (see the <tt>test/perf</tt> directory in the ASM
-distribution)!
-
- at since ASM 1.3
-</body>
-</html>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/clojure.git



More information about the pkg-java-commits mailing list