You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2012/05/30 21:20:36 UTC

[2/17] TAP5-1852: Upgrade Plastic to use ASM 4.0 - Remove unused utility classes

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java
index 1186c62..ab7547b 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/ClassWriter.java
@@ -1,6 +1,6 @@
 /***
  * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@ package org.apache.tapestry5.internal.plastic.asm;
  *
  * @author Eric Bruneton
  */
-public class ClassWriter implements ClassVisitor {
+public class ClassWriter extends ClassVisitor {
 
     /**
      * Flag to automatically compute the maximum stack size and the maximum
@@ -70,7 +70,7 @@ public class ClassWriter implements ClassVisitor {
      * the synthetic access flag.
      */
     static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
-    
+
     /**
      * The type of instructions without any argument.
      */
@@ -109,52 +109,57 @@ public class ClassWriter implements ClassVisitor {
     /**
      * The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction.
      */
-    static final int ITFDYNMETH_INSN = 7;
+    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 = 8;
+    static final int LABEL_INSN = 9;
 
     /**
      * The type of instructions with a 4 bytes bytecode offset label.
      */
-    static final int LABELW_INSN = 9;
+    static final int LABELW_INSN = 10;
 
     /**
      * The type of the LDC instruction.
      */
-    static final int LDC_INSN = 10;
+    static final int LDC_INSN = 11;
 
     /**
      * The type of the LDC_W and LDC2_W instructions.
      */
-    static final int LDCW_INSN = 11;
+    static final int LDCW_INSN = 12;
 
     /**
      * The type of the IINC instruction.
      */
-    static final int IINC_INSN = 12;
+    static final int IINC_INSN = 13;
 
     /**
      * The type of the TABLESWITCH instruction.
      */
-    static final int TABL_INSN = 13;
+    static final int TABL_INSN = 14;
 
     /**
      * The type of the LOOKUPSWITCH instruction.
      */
-    static final int LOOK_INSN = 14;
+    static final int LOOK_INSN = 15;
 
     /**
      * The type of the MULTIANEWARRAY instruction.
      */
-    static final int MANA_INSN = 15;
+    static final int MANA_INSN = 16;
 
     /**
      * The type of the WIDE instruction.
      */
-    static final int WIDE_INSN = 16;
+    static final int WIDE_INSN = 17;
 
     /**
      * The instruction types of all JVM opcodes.
@@ -217,11 +222,33 @@ public class ClassWriter implements ClassVisitor {
     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 = 13;
+    static final int TYPE_NORMAL = 30;
 
     /**
      * Uninitialized type Item stored in the ClassWriter
@@ -229,14 +256,21 @@ public class ClassWriter implements ClassVisitor {
      * avoid clashes with normal constant pool items in the ClassWriter constant
      * pool's hash table.
      */
-    static final int TYPE_UNINIT = 14;
+    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 = 15;
+    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.
@@ -284,6 +318,11 @@ public class ClassWriter implements ClassVisitor {
     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
@@ -388,9 +427,19 @@ public class ClassWriter implements ClassVisitor {
     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#next} field. This field stores the first element of
+     * {@link FieldWriter#fv} field. This field stores the first element of
      * this list.
      */
     FieldWriter firstField;
@@ -398,7 +447,7 @@ public class ClassWriter implements ClassVisitor {
     /**
      * 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#next} field. This field stores the last element of
+     * {@link FieldWriter#fv} field. This field stores the last element of
      * this list.
      */
     FieldWriter lastField;
@@ -406,7 +455,7 @@ public class ClassWriter implements ClassVisitor {
     /**
      * 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#next} field. This field stores the first element of
+     * {@link MethodWriter#mv} field. This field stores the first element of
      * this list.
      */
     MethodWriter firstMethod;
@@ -414,7 +463,7 @@ public class ClassWriter implements ClassVisitor {
     /**
      * 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#next} field. This field stores the last element of
+     * {@link MethodWriter#mv} field. This field stores the last element of
      * this list.
      */
     MethodWriter lastMethod;
@@ -450,10 +499,10 @@ public class ClassWriter implements ClassVisitor {
     static {
         int i;
         byte[] b = new byte[220];
-        String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+        String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
                 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
-                + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA"
-                + "AAAAGGGGGGGHHFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII";
+                + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
+                + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
         for (i = 0; i < b.length; ++i) {
             b[i] = (byte) (s.charAt(i) - 'A');
         }
@@ -493,8 +542,8 @@ public class ClassWriter implements ClassVisitor {
         // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
         // b[i] = FIELDORMETH_INSN;
         // }
-        // b[Constants.INVOKEINTERFACE] = ITFDYNMETH_INSN;
-        // b[Constants.INVOKEDYNAMIC] = ITFDYNMETH_INSN;
+        // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
+        // b[Constants.INVOKEDYNAMIC] = INDYMETH_INSN;
         //
         // // LABEL(W)_INSN instructions
         // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
@@ -539,6 +588,7 @@ public class ClassWriter implements ClassVisitor {
      *        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];
@@ -546,6 +596,7 @@ public class ClassWriter implements ClassVisitor {
         key = new Item();
         key2 = new Item();
         key3 = new Item();
+        key4 = new Item();
         this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
         this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
     }
@@ -555,17 +606,16 @@ public class ClassWriter implements ClassVisitor {
      * "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 a custom
-     * {@link ClassAdapter} or any other {@link ClassVisitor} instance).</li>
-     * </ul>
+     * <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
@@ -584,10 +634,11 @@ public class ClassWriter implements ClassVisitor {
     }
 
     // ------------------------------------------------------------------------
-    // Implementation of the ClassVisitor interface
+    // Implementation of the ClassVisitor abstract class
     // ------------------------------------------------------------------------
 
-    public void visit(
+    @Override
+    public final void visit(
         final int version,
         final int access,
         final String name,
@@ -612,7 +663,8 @@ public class ClassWriter implements ClassVisitor {
         }
     }
 
-    public void visitSource(final String file, final String debug) {
+    @Override
+    public final void visitSource(final String file, final String debug) {
         if (file != null) {
             sourceFile = newUTF8(file);
         }
@@ -621,7 +673,8 @@ public class ClassWriter implements ClassVisitor {
         }
     }
 
-    public void visitOuterClass(
+    @Override
+    public final void visitOuterClass(
         final String owner,
         final String name,
         final String desc)
@@ -632,7 +685,8 @@ public class ClassWriter implements ClassVisitor {
         }
     }
 
-    public AnnotationVisitor visitAnnotation(
+    @Override
+    public final AnnotationVisitor visitAnnotation(
         final String desc,
         final boolean visible)
     {
@@ -653,12 +707,14 @@ public class ClassWriter implements ClassVisitor {
         return aw;
     }
 
-    public void visitAttribute(final Attribute attr) {
+    @Override
+    public final void visitAttribute(final Attribute attr) {
         attr.next = attrs;
         attrs = attr;
     }
 
-    public void visitInnerClass(
+    @Override
+    public final void visitInnerClass(
         final String name,
         final String outerName,
         final String innerName,
@@ -674,7 +730,8 @@ public class ClassWriter implements ClassVisitor {
         innerClasses.putShort(access);
     }
 
-    public FieldVisitor visitField(
+    @Override
+    public final FieldVisitor visitField(
         final int access,
         final String name,
         final String desc,
@@ -684,7 +741,8 @@ public class ClassWriter implements ClassVisitor {
         return new FieldWriter(this, access, name, desc, signature, value);
     }
 
-    public MethodVisitor visitMethod(
+    @Override
+    public final MethodVisitor visitMethod(
         final int access,
         final String name,
         final String desc,
@@ -701,7 +759,8 @@ public class ClassWriter implements ClassVisitor {
                 computeFrames);
     }
 
-    public void visitEnd() {
+    @Override
+    public final void visitEnd() {
     }
 
     // ------------------------------------------------------------------------
@@ -714,6 +773,9 @@ public class ClassWriter implements ClassVisitor {
      * @return the bytecode of the class that was build with this class writer.
      */
     public byte[] toByteArray() {
+        if (index > Short.MAX_VALUE) {
+            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;
@@ -721,16 +783,22 @@ public class ClassWriter implements ClassVisitor {
         while (fb != null) {
             ++nbFields;
             size += fb.getSize();
-            fb = fb.next;
+            fb = (FieldWriter) fb.fv;
         }
         int nbMethods = 0;
         MethodWriter mb = firstMethod;
         while (mb != null) {
             ++nbMethods;
             size += mb.getSize();
-            mb = mb.next;
+            mb = (MethodWriter) mb.mv;
         }
         int attributeCount = 0;
+        if (bootstrapMethods != null) {  // we put it as first argument in order
+                                         // to improve a bit ClassReader.copyBootstrapMethods
+            ++attributeCount;
+            size += 8 + bootstrapMethods.length;
+            newUTF8("BootstrapMethods");
+        }
         if (ClassReader.SIGNATURES && signature != 0) {
             ++attributeCount;
             size += 8;
@@ -800,15 +868,20 @@ public class ClassWriter implements ClassVisitor {
         fb = firstField;
         while (fb != null) {
             fb.put(out);
-            fb = fb.next;
+            fb = (FieldWriter) fb.fv;
         }
         out.putShort(nbMethods);
         mb = firstMethod;
         while (mb != null) {
             mb.put(out);
-            mb = mb.next;
+            mb = (MethodWriter) mb.mv;
         }
         out.putShort(attributeCount);
+        if (bootstrapMethods != null) {   // should be the first class attribute ?
+            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);
         }
@@ -899,9 +972,17 @@ public class ClassWriter implements ClassVisitor {
             return newString((String) cst);
         } else if (cst instanceof Type) {
             Type t = (Type) cst;
-            return newClassItem(t.getSort() == Type.OBJECT
-                    ? t.getInternalName()
-                    : t.getDescriptor());
+            int s = t.getSort();
+            if (s == Type.ARRAY) {
+                return newClassItem(t.getDescriptor());
+            } else if (s == Type.OBJECT) {
+                return newClassItem(t.getInternalName());
+            } else { // s == Type.METHOD
+                return newMethodTypeItem(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);
         }
@@ -977,6 +1058,216 @@ public class ClassWriter implements ClassVisitor {
     }
 
     /**
+     * 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.
      *
@@ -1110,8 +1401,8 @@ public class ClassWriter implements ClassVisitor {
         if (result == null) {
             pool.putByte(LONG).putLong(value);
             result = new Item(index, key);
-            put(result);
             index += 2;
+            put(result);
         }
         return result;
     }
@@ -1129,8 +1420,8 @@ public class ClassWriter implements ClassVisitor {
         if (result == null) {
             pool.putByte(DOUBLE).putLong(key.longVal);
             result = new Item(index, key);
-            put(result);
             index += 2;
+            put(result);
         }
         return result;
     }
@@ -1166,7 +1457,7 @@ public class ClassWriter implements ClassVisitor {
     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.
@@ -1288,10 +1579,11 @@ public class ClassWriter implements ClassVisitor {
      */
     protected String getCommonSuperClass(final String type1, final String type2)
     {
-        Class c, d;
+        Class<?> c, d;
+        ClassLoader classLoader = getClass().getClassLoader();
         try {
-            c = Class.forName(type1.replace('/', '.'));
-            d = Class.forName(type2.replace('/', '.'));
+            c = Class.forName(type1.replace('/', '.'), false, classLoader);
+            d = Class.forName(type2.replace('/', '.'), false, classLoader);
         } catch (Exception e) {
             throw new RuntimeException(e.toString());
         }
@@ -1334,7 +1626,7 @@ public class ClassWriter implements ClassVisitor {
      * @param i the item to be added to the constant pool's hash table.
      */
     private void put(final Item i) {
-        if (index > threshold) {
+        if (index + typeCount > threshold) {
             int ll = items.length;
             int nl = ll * 2 + 1;
             Item[] newItems = new Item[nl];
@@ -1366,4 +1658,15 @@ public class ClassWriter implements ClassVisitor {
     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);
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Edge.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Edge.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Edge.java
index d76db79..80222bc 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Edge.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Edge.java
@@ -1,6 +1,6 @@
 /***
  * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@ package org.apache.tapestry5.internal.plastic.asm;
 
 /**
  * An edge in the control flow graph of a method body. See {@link Label Label}.
- * 
+ *
  * @author Eric Bruneton
  */
 class Edge {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java
index 0ae0099..32c23d1 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldVisitor.java
@@ -1,6 +1,6 @@
 /***
  * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -30,35 +30,86 @@
 package org.apache.tapestry5.internal.plastic.asm;
 
 /**
- * A visitor to visit a Java field. The methods of this interface must be called
+ * 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 interface FieldVisitor {
+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.
      */
-    AnnotationVisitor visitAnnotation(String desc, boolean visible);
+    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.
      */
-    void visitAttribute(Attribute attr);
+    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.
      */
-    void visitEnd();
+    public void visitEnd() {
+        if (fv != null) {
+            fv.visitEnd();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java
index f8a5a8c..b61105a 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/FieldWriter.java
@@ -1,6 +1,6 @@
 /***
  * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,15 +31,10 @@ package org.apache.tapestry5.internal.plastic.asm;
 
 /**
  * An {@link FieldVisitor} that generates Java fields in bytecode form.
- * 
+ *
  * @author Eric Bruneton
  */
-final class FieldWriter implements FieldVisitor {
-
-    /**
-     * Next field writer (see {@link ClassWriter#firstField firstField}).
-     */
-    FieldWriter next;
+final class FieldWriter extends FieldVisitor {
 
     /**
      * The class writer to which this field must be added.
@@ -96,7 +91,7 @@ final class FieldWriter implements FieldVisitor {
 
     /**
      * 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.
@@ -112,10 +107,11 @@ final class FieldWriter implements FieldVisitor {
         final String signature,
         final Object value)
     {
+        super(Opcodes.ASM4);
         if (cw.firstField == null) {
             cw.firstField = this;
         } else {
-            cw.lastField.next = this;
+            cw.lastField.fv = this;
         }
         cw.lastField = this;
         this.cw = cw;
@@ -131,9 +127,10 @@ final class FieldWriter implements FieldVisitor {
     }
 
     // ------------------------------------------------------------------------
-    // Implementation of the FieldVisitor interface
+    // Implementation of the FieldVisitor abstract class
     // ------------------------------------------------------------------------
 
+    @Override
     public AnnotationVisitor visitAnnotation(
         final String desc,
         final boolean visible)
@@ -155,11 +152,13 @@ final class FieldWriter implements FieldVisitor {
         return aw;
     }
 
+    @Override
     public void visitAttribute(final Attribute attr) {
         attr.next = attrs;
         attrs = attr;
     }
 
+    @Override
     public void visitEnd() {
     }
 
@@ -169,7 +168,7 @@ final class FieldWriter implements FieldVisitor {
 
     /**
      * Returns the size of this field.
-     * 
+     *
      * @return the size of this field.
      */
     int getSize() {
@@ -208,7 +207,7 @@ final class FieldWriter implements FieldVisitor {
 
     /**
      * 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) {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java
index 65de3c9..fce84e9 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Frame.java
@@ -1,6 +1,6 @@
 /***
  * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@ package org.apache.tapestry5.internal.plastic.asm;
 
 /**
  * Information about the input and output stack map frames of a basic block.
- * 
+ *
  * @author Eric Bruneton
  */
 final class Frame {
@@ -46,14 +46,14 @@ final class 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
@@ -61,7 +61,7 @@ final class Frame {
      * 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
@@ -72,14 +72,14 @@ final class Frame {
      * 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,
@@ -107,7 +107,7 @@ final class Frame {
 
     /**
      * Mask to get the kind of a frame type.
-     * 
+     *
      * @see #BASE
      * @see #LOCAL
      * @see #STACK
@@ -116,9 +116,9 @@ final class Frame {
 
     /**
      * 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), 
+     * 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 
+     * 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;
@@ -437,7 +437,7 @@ final class Frame {
         // NA, //INVOKESPECIAL, // -
         // NA, //INVOKESTATIC, // -
         // NA, //INVOKEINTERFACE, // -
-        // NA, //INVOKEDYNAMIC, // -
+        // NA, //INVOKEDYNAMIC, // visitInvokeDynamicInsn
         // 1, //NEW, // visitTypeInsn
         // 0, //NEWARRAY, // visitIntInsn
         // 0, //ANEWARRAY, // visitTypeInsn
@@ -489,10 +489,10 @@ final class Frame {
     /**
      * 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}.
      */
@@ -500,7 +500,7 @@ final class Frame {
 
     /**
      * Number of types that are initialized in the basic block.
-     * 
+     *
      * @see #initializations
      */
     private int initializationCount;
@@ -522,7 +522,7 @@ final class Frame {
 
     /**
      * 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.
      */
@@ -544,7 +544,7 @@ final class Frame {
 
     /**
      * 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.
      */
@@ -565,7 +565,7 @@ final class Frame {
 
     /**
      * Pushes a new type onto the output frame stack.
-     * 
+     *
      * @param type the type that must be pushed.
      */
     private void push(final int type) {
@@ -590,7 +590,7 @@ final class Frame {
 
     /**
      * 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
@@ -608,7 +608,7 @@ final class Frame {
 
     /**
      * 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.
@@ -680,7 +680,7 @@ final class Frame {
 
     /**
      * 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() {
@@ -694,7 +694,7 @@ final class Frame {
 
     /**
      * 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) {
@@ -711,7 +711,7 @@ final class Frame {
 
     /**
      * 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).
@@ -730,7 +730,7 @@ final class Frame {
     /**
      * 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) {
@@ -751,7 +751,7 @@ final class Frame {
     /**
      * 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
@@ -786,7 +786,7 @@ final class Frame {
     /**
      * 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.
@@ -822,7 +822,7 @@ final class Frame {
 
     /**
      * 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.
@@ -899,9 +899,15 @@ final class Frame {
                     case ClassWriter.CLASS:
                         push(OBJECT | cw.addType("java/lang/Class"));
                         break;
-                    // case ClassWriter.STR:
-                    default:
+                    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:
@@ -1253,7 +1259,7 @@ final class Frame {
      * 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'.
@@ -1356,7 +1362,7 @@ final class Frame {
      * 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.

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java
new file mode 100644
index 0000000..e8906fe
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handle.java
@@ -0,0 +1,159 @@
+/***
+ * 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 org.apache.tapestry5.internal.plastic.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 + ')';
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handler.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handler.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handler.java
index ca5b361..94ac8e5 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handler.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Handler.java
@@ -1,6 +1,6 @@
 /***
  * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@ package org.apache.tapestry5.internal.plastic.asm;
 
 /**
  * Information about an exception handler block.
- * 
+ *
  * @author Eric Bruneton
  */
 class Handler {
@@ -67,4 +67,52 @@ class Handler {
      * 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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java
index 1c5eedd..4fab86a 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Item.java
@@ -1,6 +1,6 @@
 /***
  * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@ package org.apache.tapestry5.internal.plastic.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 {
@@ -50,8 +50,13 @@ final class Item {
      * {@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#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
@@ -109,7 +114,7 @@ final class 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) {
@@ -118,7 +123,7 @@ final class Item {
 
     /**
      * 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.
      */
@@ -135,7 +140,7 @@ final class Item {
 
     /**
      * Sets this item to an integer item.
-     * 
+     *
      * @param intVal the value of this item.
      */
     void set(final int intVal) {
@@ -146,7 +151,7 @@ final class Item {
 
     /**
      * Sets this item to a long item.
-     * 
+     *
      * @param longVal the value of this item.
      */
     void set(final long longVal) {
@@ -157,7 +162,7 @@ final class Item {
 
     /**
      * Sets this item to a float item.
-     * 
+     *
      * @param floatVal the value of this item.
      */
     void set(final float floatVal) {
@@ -168,7 +173,7 @@ final class Item {
 
     /**
      * Sets this item to a double item.
-     * 
+     *
      * @param doubleVal the value of this item.
      */
     void set(final double doubleVal) {
@@ -179,7 +184,7 @@ final class Item {
 
     /**
      * 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.
@@ -199,6 +204,7 @@ final class Item {
             case ClassWriter.UTF8:
             case ClassWriter.STR:
             case ClassWriter.CLASS:
+            case ClassWriter.MTYPE:
             case ClassWriter.TYPE_NORMAL:
                 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
                 return;
@@ -209,6 +215,7 @@ final class Item {
                 // ClassWriter.FIELD:
                 // ClassWriter.METH:
                 // ClassWriter.IMETH:
+                // ClassWriter.HANDLE_BASE + 1..9
             default:
                 hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
                         * strVal2.hashCode() * strVal3.hashCode());
@@ -216,9 +223,39 @@ final class Item {
     }
 
     /**
+     * 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>. 
-     * 
+     * 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,
@@ -229,6 +266,7 @@ final class Item {
             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:
@@ -242,10 +280,15 @@ final class Item {
                 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:
-            default:    
+            // case ClassWriter.HANDLE_BASE + 1..9
+            default:
                 return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
                         && i.strVal3.equals(strVal3);
         }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java
index 3ba9b61..ef338c3 100644
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/Label.java
@@ -1,6 +1,6 @@
 /***
  * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 INRIA, France Telecom
+ * Copyright (c) 2000-2011 INRIA, France Telecom
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,9 +33,9 @@ package org.apache.tapestry5.internal.plastic.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 
+ * 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 {
@@ -96,7 +96,7 @@ public class Label {
     static final int SUBROUTINE = 512;
 
     /**
-     * Indicates if this subroutine basic block has been visited by a 
+     * Indicates if this subroutine basic block has been visited by a
      * visitSubroutine(null, ...) call.
      */
     static final int VISITED = 1024;
@@ -110,14 +110,14 @@ public class Label {
     /**
      * 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 
+     * package you must override the {@link
      * org.apache.tapestry5.internal.plastic.asm.tree.MethodNode#getLabelNode} method.
      */
     public Object info;
 
     /**
      * Flags that indicate the status of this label.
-     * 
+     *
      * @see #DEBUG
      * @see #RESOLVED
      * @see #RESIZED
@@ -170,7 +170,7 @@ public class Label {
      * 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
@@ -182,7 +182,7 @@ public class Label {
      * 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
@@ -192,10 +192,10 @@ public class Label {
     /**
      * 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
@@ -238,9 +238,9 @@ public class Label {
     /**
      * 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 
+     * control flow analysis algorithms. It is also used in
      * {@link #visitSubroutine} to avoid using a recursive method.
-     * 
+     *
      * @see MethodWriter#visitMaxs
      */
     Label next;
@@ -264,7 +264,7 @@ public class Label {
      * 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.
      */
@@ -280,7 +280,7 @@ public class Label {
      * 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
@@ -318,7 +318,7 @@ public class Label {
      * 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.
@@ -350,7 +350,7 @@ public class Label {
      * 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.
@@ -417,7 +417,7 @@ public class Label {
      * 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() {
@@ -430,7 +430,7 @@ public class Label {
 
     /**
      * 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.
      */
@@ -444,7 +444,7 @@ public class Label {
     /**
      * 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.
@@ -463,7 +463,7 @@ public class Label {
 
     /**
      * 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.
      */
@@ -474,13 +474,13 @@ public class Label {
         }
         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.
@@ -497,7 +497,7 @@ public class Label {
             Label l = stack;
             stack = l.next;
             l.next = null;
-            
+
             if (JSR != null) {
                 if ((l.status & VISITED2) != 0) {
                     continue;
@@ -519,13 +519,13 @@ public class Label {
                     continue;
                 }
                 // marks the l block as belonging to subroutine 'id'
-                l.addToSubroutine(id, nbSubroutines);            
+                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 
+                // 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
@@ -545,9 +545,10 @@ public class Label {
 
     /**
      * Returns a string representation of this label.
-     * 
+     *
      * @return a string representation of this label.
      */
+    @Override
     public String toString() {
         return "L" + System.identityHashCode(this);
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/d6e5f413/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodAdapter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodAdapter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodAdapter.java
deleted file mode 100644
index 1c3b05a..0000000
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/MethodAdapter.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/***
- * ASM: a very small and fast Java bytecode manipulation framework
- * Copyright (c) 2000-2007 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 org.apache.tapestry5.internal.plastic.asm;
-
-/**
- * An empty {@link MethodVisitor} that delegates to another
- * {@link MethodVisitor}. This class can be used as a super class to quickly
- * implement usefull method adapter classes, just by overriding the necessary
- * methods.
- * 
- * @author Eric Bruneton
- */
-public class MethodAdapter implements MethodVisitor {
-
-    /**
-     * The {@link MethodVisitor} to which this adapter delegates calls.
-     */
-    protected MethodVisitor mv;
-
-    /**
-     * Constructs a new {@link MethodAdapter} object.
-     * 
-     * @param mv the code visitor to which this adapter must delegate calls.
-     */
-    public MethodAdapter(final MethodVisitor mv) {
-        this.mv = mv;
-    }
-
-    public AnnotationVisitor visitAnnotationDefault() {
-        return mv.visitAnnotationDefault();
-    }
-
-    public AnnotationVisitor visitAnnotation(
-        final String desc,
-        final boolean visible)
-    {
-        return mv.visitAnnotation(desc, visible);
-    }
-
-    public AnnotationVisitor visitParameterAnnotation(
-        final int parameter,
-        final String desc,
-        final boolean visible)
-    {
-        return mv.visitParameterAnnotation(parameter, desc, visible);
-    }
-
-    public void visitAttribute(final Attribute attr) {
-        mv.visitAttribute(attr);
-    }
-
-    public void visitCode() {
-        mv.visitCode();
-    }
-
-    public void visitFrame(
-        final int type,
-        final int nLocal,
-        final Object[] local,
-        final int nStack,
-        final Object[] stack)
-    {
-        mv.visitFrame(type, nLocal, local, nStack, stack);
-    }
-
-    public void visitInsn(final int opcode) {
-        mv.visitInsn(opcode);
-    }
-
-    public void visitIntInsn(final int opcode, final int operand) {
-        mv.visitIntInsn(opcode, operand);
-    }
-
-    public void visitVarInsn(final int opcode, final int var) {
-        mv.visitVarInsn(opcode, var);
-    }
-
-    public void visitTypeInsn(final int opcode, final String type) {
-        mv.visitTypeInsn(opcode, type);
-    }
-
-    public void visitFieldInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
-        mv.visitFieldInsn(opcode, owner, name, desc);
-    }
-
-    public void visitMethodInsn(
-        final int opcode,
-        final String owner,
-        final String name,
-        final String desc)
-    {
-        mv.visitMethodInsn(opcode, owner, name, desc);
-    }
-
-    public void visitJumpInsn(final int opcode, final Label label) {
-        mv.visitJumpInsn(opcode, label);
-    }
-
-    public void visitLabel(final Label label) {
-        mv.visitLabel(label);
-    }
-
-    public void visitLdcInsn(final Object cst) {
-        mv.visitLdcInsn(cst);
-    }
-
-    public void visitIincInsn(final int var, final int increment) {
-        mv.visitIincInsn(var, increment);
-    }
-
-    public void visitTableSwitchInsn(
-        final int min,
-        final int max,
-        final Label dflt,
-        final Label[] labels)
-    {
-        mv.visitTableSwitchInsn(min, max, dflt, labels);
-    }
-
-    public void visitLookupSwitchInsn(
-        final Label dflt,
-        final int[] keys,
-        final Label[] labels)
-    {
-        mv.visitLookupSwitchInsn(dflt, keys, labels);
-    }
-
-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
-        mv.visitMultiANewArrayInsn(desc, dims);
-    }
-
-    public void visitTryCatchBlock(
-        final Label start,
-        final Label end,
-        final Label handler,
-        final String type)
-    {
-        mv.visitTryCatchBlock(start, end, handler, type);
-    }
-
-    public void visitLocalVariable(
-        final String name,
-        final String desc,
-        final String signature,
-        final Label start,
-        final Label end,
-        final int index)
-    {
-        mv.visitLocalVariable(name, desc, signature, start, end, index);
-    }
-
-    public void visitLineNumber(final int line, final Label start) {
-        mv.visitLineNumber(line, start);
-    }
-
-    public void visitMaxs(final int maxStack, final int maxLocals) {
-        mv.visitMaxs(maxStack, maxLocals);
-    }
-
-    public void visitEnd() {
-        mv.visitEnd();
-    }
-}