You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2018/11/29 00:34:06 UTC

[19/46] tapestry-5 git commit: TAP5-2588: upgrading from ASM 6 to 7 for Java 9+ support

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java
old mode 100644
new mode 100755
index 68b4e31..39114ac
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java
@@ -1,41 +1,38 @@
-/***
- * 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.
- */
+// 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.tree;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
-
 import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
 import org.apache.tapestry5.internal.plastic.asm.Attribute;
 import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
+import org.apache.tapestry5.internal.plastic.asm.ConstantDynamic;
 import org.apache.tapestry5.internal.plastic.asm.Handle;
 import org.apache.tapestry5.internal.plastic.asm.Label;
 import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
@@ -45,796 +42,774 @@ import org.apache.tapestry5.internal.plastic.asm.TypePath;
 
 /**
  * A node that represents a method.
- * 
+ *
  * @author Eric Bruneton
  */
 public class MethodNode extends MethodVisitor {
 
-    /**
-     * The method's access flags (see {@link Opcodes}). This field also
-     * indicates if the method is synthetic and/or deprecated.
-     */
-    public int access;
-
-    /**
-     * The method's name.
-     */
-    public String name;
-
-    /**
-     * The method's descriptor (see {@link Type}).
-     */
-    public String desc;
-
-    /**
-     * The method's signature. May be <tt>null</tt>.
-     */
-    public String signature;
-
-    /**
-     * The internal names of the method's exception classes (see
-     * {@link Type#getInternalName() getInternalName}). This list is a list of
-     * {@link String} objects.
-     */
-    public List<String> exceptions;
-
-    /**
-     * The method parameter info (access flags and name)
-     */
-    public List<ParameterNode> parameters;
-
-    /**
-     * The runtime visible annotations of this method. This list is a list of
-     * {@link AnnotationNode} objects. May be <tt>null</tt>.
-     * 
-     * @associates org.objectweb.asm.tree.AnnotationNode
-     * @label visible
-     */
-    public List<AnnotationNode> visibleAnnotations;
-
-    /**
-     * The runtime invisible annotations of this method. This list is a list of
-     * {@link AnnotationNode} objects. May be <tt>null</tt>.
-     * 
-     * @associates org.objectweb.asm.tree.AnnotationNode
-     * @label invisible
-     */
-    public List<AnnotationNode> invisibleAnnotations;
-
-    /**
-     * The runtime visible type annotations of this method. This list is a list
-     * of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
-     * 
-     * @associates org.objectweb.asm.tree.TypeAnnotationNode
-     * @label visible
-     */
-    public List<TypeAnnotationNode> visibleTypeAnnotations;
-
-    /**
-     * The runtime invisible type annotations of this method. This list is a
-     * list of {@link TypeAnnotationNode} objects. May be <tt>null</tt>.
-     * 
-     * @associates org.objectweb.asm.tree.TypeAnnotationNode
-     * @label invisible
-     */
-    public List<TypeAnnotationNode> invisibleTypeAnnotations;
-
-    /**
-     * The non standard attributes of this method. This list is a list of
-     * {@link Attribute} objects. May be <tt>null</tt>.
-     * 
-     * @associates org.objectweb.asm.Attribute
-     */
-    public List<Attribute> attrs;
-
-    /**
-     * The default value of this annotation interface method. This field must be
-     * a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short},
-     * {@link Integer}, {@link Long}, {@link Float}, {@link Double},
-     * {@link String} or {@link Type}, or an two elements String array (for
-     * enumeration values), a {@link AnnotationNode}, or a {@link List} of
-     * values of one of the preceding types. May be <tt>null</tt>.
-     */
-    public Object annotationDefault;
-
-    /**
-     * The runtime visible parameter annotations of this method. These lists are
-     * lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
-     * 
-     * @associates org.objectweb.asm.tree.AnnotationNode
-     * @label invisible parameters
-     */
-    public List<AnnotationNode>[] visibleParameterAnnotations;
-
-    /**
-     * The runtime invisible parameter annotations of this method. These lists
-     * are lists of {@link AnnotationNode} objects. May be <tt>null</tt>.
-     * 
-     * @associates org.objectweb.asm.tree.AnnotationNode
-     * @label visible parameters
-     */
-    public List<AnnotationNode>[] invisibleParameterAnnotations;
-
-    /**
-     * The instructions of this method. This list is a list of
-     * {@link AbstractInsnNode} objects.
-     * 
-     * @associates org.objectweb.asm.tree.AbstractInsnNode
-     * @label instructions
-     */
-    public InsnList instructions;
-
-    /**
-     * The try catch blocks of this method. This list is a list of
-     * {@link TryCatchBlockNode} objects.
-     * 
-     * @associates org.objectweb.asm.tree.TryCatchBlockNode
-     */
-    public List<TryCatchBlockNode> tryCatchBlocks;
-
-    /**
-     * The maximum stack size of this method.
-     */
-    public int maxStack;
-
-    /**
-     * The maximum number of local variables of this method.
-     */
-    public int maxLocals;
-
-    /**
-     * The local variables of this method. This list is a list of
-     * {@link LocalVariableNode} objects. May be <tt>null</tt>
-     * 
-     * @associates org.objectweb.asm.tree.LocalVariableNode
-     */
-    public List<LocalVariableNode> localVariables;
-
-    /**
-     * The visible local variable annotations of this method. This list is a
-     * list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt>
-     * 
-     * @associates org.objectweb.asm.tree.LocalVariableAnnotationNode
-     */
-    public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations;
-
-    /**
-     * The invisible local variable annotations of this method. This list is a
-     * list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt>
-     * 
-     * @associates org.objectweb.asm.tree.LocalVariableAnnotationNode
-     */
-    public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations;
-
-    /**
-     * If the accept method has been called on this object.
-     */
-    private boolean visited;
-
-    /**
-     * Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not
-     * use this constructor</i>. Instead, they must use the
-     * {@link #MethodNode(int)} version.
-     * 
-     * @throws IllegalStateException
-     *             If a subclass calls this constructor.
-     */
-    public MethodNode() {
-        this(Opcodes.ASM6);
-        if (getClass() != MethodNode.class) {
-            throw new IllegalStateException();
-        }
-    }
-
-    /**
-     * Constructs an uninitialized {@link MethodNode}.
-     * 
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
-     */
-    public MethodNode(final int api) {
-        super(api);
-        this.instructions = new InsnList();
-    }
-
-    /**
-     * Constructs a new {@link MethodNode}. <i>Subclasses must not use this
-     * constructor</i>. Instead, they must use the
-     * {@link #MethodNode(int, int, String, String, String, String[])} version.
-     * 
-     * @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}).
-     * @param signature
-     *            the method's signature. May be <tt>null</tt>.
-     * @param exceptions
-     *            the internal names of the method's exception classes (see
-     *            {@link Type#getInternalName() getInternalName}). May be
-     *            <tt>null</tt>.
-     * @throws IllegalStateException
-     *             If a subclass calls this constructor.
-     */
-    public MethodNode(final int access, final String name, final String desc,
-            final String signature, final String[] exceptions) {
-        this(Opcodes.ASM6, access, name, desc, signature, exceptions);
-        if (getClass() != MethodNode.class) {
-            throw new IllegalStateException();
-        }
-    }
-
-    /**
-     * Constructs a new {@link MethodNode}.
-     * 
-     * @param api
-     *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
-     * @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}).
-     * @param signature
-     *            the method's signature. May be <tt>null</tt>.
-     * @param exceptions
-     *            the internal names of the method's exception classes (see
-     *            {@link Type#getInternalName() getInternalName}). May be
-     *            <tt>null</tt>.
-     */
-    public MethodNode(final int api, final int access, final String name,
-            final String desc, final String signature, final String[] exceptions) {
-        super(api);
-        this.access = access;
-        this.name = name;
-        this.desc = desc;
-        this.signature = signature;
-        this.exceptions = new ArrayList<String>(exceptions == null ? 0
-                : exceptions.length);
-        boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
-        if (!isAbstract) {
-            this.localVariables = new ArrayList<LocalVariableNode>(5);
-        }
-        this.tryCatchBlocks = new ArrayList<TryCatchBlockNode>();
-        if (exceptions != null) {
-            this.exceptions.addAll(Arrays.asList(exceptions));
-        }
-        this.instructions = new InsnList();
-    }
-
-    // ------------------------------------------------------------------------
-    // Implementation of the MethodVisitor abstract class
-    // ------------------------------------------------------------------------
-
-    @Override
-    public void visitParameter(String name, int access) {
-        if (parameters == null) {
-            parameters = new ArrayList<ParameterNode>(5);
-        }
-        parameters.add(new ParameterNode(name, access));
-    }
-
-    @Override
-    @SuppressWarnings("serial")
-    public AnnotationVisitor visitAnnotationDefault() {
-        return new AnnotationNode(new ArrayList<Object>(0) {
-            @Override
-            public boolean add(final Object o) {
-                annotationDefault = o;
-                return super.add(o);
-            }
+  /**
+   * The method's access flags (see {@link Opcodes}). This field also indicates if the method is
+   * synthetic and/or deprecated.
+   */
+  public int access;
+
+  /** The method's name. */
+  public String name;
+
+  /** The method's descriptor (see {@link Type}). */
+  public String desc;
+
+  /** The method's signature. May be {@literal null}. */
+  public String signature;
+
+  /** The internal names of the method's exception classes (see {@link Type#getInternalName()}). */
+  public List<String> exceptions;
+
+  /** The method parameter info (access flags and name). */
+  public List<ParameterNode> parameters;
+
+  /** The runtime visible annotations of this method. May be {@literal null}. */
+  public List<AnnotationNode> visibleAnnotations;
+
+  /** The runtime invisible annotations of this method. May be {@literal null}. */
+  public List<AnnotationNode> invisibleAnnotations;
+
+  /** The runtime visible type annotations of this method. May be {@literal null}. */
+  public List<TypeAnnotationNode> visibleTypeAnnotations;
+
+  /** The runtime invisible type annotations of this method. May be {@literal null}. */
+  public List<TypeAnnotationNode> invisibleTypeAnnotations;
+
+  /** The non standard attributes of this method. May be {@literal null}. */
+  public List<Attribute> attrs;
+
+  /**
+   * The default value of this annotation interface method. This field must be a {@link Byte},
+   * {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}, {@link Long}, {@link
+   * Float}, {@link Double}, {@link String} or {@link Type}, or an two elements String array (for
+   * enumeration values), a {@link AnnotationNode}, or a {@link List} of values of one of the
+   * preceding types. May be {@literal null}.
+   */
+  public Object annotationDefault;
+
+  /**
+   * The number of method parameters than can have runtime visible annotations. This number must be
+   * less or equal than the number of parameter types in the method descriptor (the default value 0
+   * indicates that all the parameters described in the method descriptor can have annotations). It
+   * can be strictly less when a method has synthetic parameters and when these parameters are
+   * ignored when computing parameter indices for the purpose of parameter annotations (see
+   * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
+   */
+  public int visibleAnnotableParameterCount;
+
+  /**
+   * The runtime visible parameter annotations of this method. These lists are lists of {@link
+   * AnnotationNode} objects. May be {@literal null}.
+   */
+  public List<AnnotationNode>[] visibleParameterAnnotations;
+
+  /**
+   * The number of method parameters than can have runtime invisible annotations. This number must
+   * be less or equal than the number of parameter types in the method descriptor (the default value
+   * 0 indicates that all the parameters described in the method descriptor can have annotations).
+   * It can be strictly less when a method has synthetic parameters and when these parameters are
+   * ignored when computing parameter indices for the purpose of parameter annotations (see
+   * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
+   */
+  public int invisibleAnnotableParameterCount;
+
+  /**
+   * The runtime invisible parameter annotations of this method. These lists are lists of {@link
+   * AnnotationNode} objects. May be {@literal null}.
+   */
+  public List<AnnotationNode>[] invisibleParameterAnnotations;
+
+  /** The instructions of this method. */
+  public InsnList instructions;
+
+  /** The try catch blocks of this method. */
+  public List<TryCatchBlockNode> tryCatchBlocks;
+
+  /** The maximum stack size of this method. */
+  public int maxStack;
+
+  /** The maximum number of local variables of this method. */
+  public int maxLocals;
+
+  /** The local variables of this method. May be {@literal null} */
+  public List<LocalVariableNode> localVariables;
+
+  /** The visible local variable annotations of this method. May be {@literal null} */
+  public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations;
+
+  /** The invisible local variable annotations of this method. May be {@literal null} */
+  public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations;
+
+  /** Whether the accept method has been called on this object. */
+  private boolean visited;
+
+  /**
+   * Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not use this
+   * constructor</i>. Instead, they must use the {@link #MethodNode(int)} version.
+   *
+   * @throws IllegalStateException If a subclass calls this constructor.
+   */
+  public MethodNode() {
+    this(Opcodes.ASM7);
+    if (getClass() != MethodNode.class) {
+      throw new IllegalStateException();
+    }
+  }
+
+  /**
+   * Constructs an uninitialized {@link MethodNode}.
+   *
+   * @param api the ASM API version implemented by this visitor. Must be one of {@link
+   *     Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+   */
+  public MethodNode(final int api) {
+    super(api);
+    this.instructions = new InsnList();
+  }
+
+  /**
+   * Constructs a new {@link MethodNode}. <i>Subclasses must not use this constructor</i>. Instead,
+   * they must use the {@link #MethodNode(int, int, String, String, String, String[])} version.
+   *
+   * @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 descriptor the method's descriptor (see {@link Type}).
+   * @param signature the method's signature. May be {@literal null}.
+   * @param exceptions the internal names of the method's exception classes (see {@link
+   *     Type#getInternalName()}). May be {@literal null}.
+   * @throws IllegalStateException If a subclass calls this constructor.
+   */
+  public MethodNode(
+      final int access,
+      final String name,
+      final String descriptor,
+      final String signature,
+      final String[] exceptions) {
+    this(Opcodes.ASM7, access, name, descriptor, signature, exceptions);
+    if (getClass() != MethodNode.class) {
+      throw new IllegalStateException();
+    }
+  }
+
+  /**
+   * Constructs a new {@link MethodNode}.
+   *
+   * @param api the ASM API version implemented by this visitor. Must be one of {@link
+   *     Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+   * @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 descriptor the method's descriptor (see {@link Type}).
+   * @param signature the method's signature. May be {@literal null}.
+   * @param exceptions the internal names of the method's exception classes (see {@link
+   *     Type#getInternalName()}). May be {@literal null}.
+   */
+  public MethodNode(
+      final int api,
+      final int access,
+      final String name,
+      final String descriptor,
+      final String signature,
+      final String[] exceptions) {
+    super(api);
+    this.access = access;
+    this.name = name;
+    this.desc = descriptor;
+    this.signature = signature;
+    this.exceptions = Util.asArrayList(exceptions);
+    if ((access & Opcodes.ACC_ABSTRACT) == 0) {
+      this.localVariables = new ArrayList<LocalVariableNode>(5);
+    }
+    this.tryCatchBlocks = new ArrayList<TryCatchBlockNode>();
+    this.instructions = new InsnList();
+  }
+
+  // -----------------------------------------------------------------------------------------------
+  // Implementation of the MethodVisitor abstract class
+  // -----------------------------------------------------------------------------------------------
+
+  @Override
+  public void visitParameter(final String name, final int access) {
+    if (parameters == null) {
+      parameters = new ArrayList<ParameterNode>(5);
+    }
+    parameters.add(new ParameterNode(name, access));
+  }
+
+  @Override
+  @SuppressWarnings("serial")
+  public AnnotationVisitor visitAnnotationDefault() {
+    return new AnnotationNode(
+        new ArrayList<Object>(0) {
+          @Override
+          public boolean add(final Object o) {
+            annotationDefault = o;
+            return super.add(o);
+          }
         });
-    }
-
-    @Override
-    public AnnotationVisitor visitAnnotation(final String desc,
-            final boolean visible) {
-        AnnotationNode an = new AnnotationNode(desc);
-        if (visible) {
-            if (visibleAnnotations == null) {
-                visibleAnnotations = new ArrayList<AnnotationNode>(1);
-            }
-            visibleAnnotations.add(an);
-        } else {
-            if (invisibleAnnotations == null) {
-                invisibleAnnotations = new ArrayList<AnnotationNode>(1);
-            }
-            invisibleAnnotations.add(an);
-        }
-        return an;
-    }
-
-    @Override
-    public AnnotationVisitor visitTypeAnnotation(int typeRef,
-            TypePath typePath, String desc, boolean visible) {
-        TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
-        if (visible) {
-            if (visibleTypeAnnotations == null) {
-                visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
-            }
-            visibleTypeAnnotations.add(an);
-        } else {
-            if (invisibleTypeAnnotations == null) {
-                invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
-            }
-            invisibleTypeAnnotations.add(an);
-        }
-        return an;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public AnnotationVisitor visitParameterAnnotation(final int parameter,
-            final String desc, final boolean visible) {
-        AnnotationNode an = new AnnotationNode(desc);
-        if (visible) {
-            if (visibleParameterAnnotations == null) {
-                int params = Type.getArgumentTypes(this.desc).length;
-                visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
-            }
-            if (visibleParameterAnnotations[parameter] == null) {
-                visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
-                        1);
-            }
-            visibleParameterAnnotations[parameter].add(an);
-        } else {
-            if (invisibleParameterAnnotations == null) {
-                int params = Type.getArgumentTypes(this.desc).length;
-                invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
-            }
-            if (invisibleParameterAnnotations[parameter] == null) {
-                invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(
-                        1);
-            }
-            invisibleParameterAnnotations[parameter].add(an);
-        }
-        return an;
-    }
-
-    @Override
-    public void visitAttribute(final Attribute attr) {
-        if (attrs == null) {
-            attrs = new ArrayList<Attribute>(1);
-        }
-        attrs.add(attr);
-    }
-
-    @Override
-    public void visitCode() {
-    }
-
-    @Override
-    public void visitFrame(final int type, final int nLocal,
-            final Object[] local, final int nStack, final Object[] stack) {
-        instructions.add(new FrameNode(type, nLocal, local == null ? null
-                : getLabelNodes(local), nStack, stack == null ? null
-                : getLabelNodes(stack)));
-    }
-
-    @Override
-    public void visitInsn(final int opcode) {
-        instructions.add(new InsnNode(opcode));
-    }
-
-    @Override
-    public void visitIntInsn(final int opcode, final int operand) {
-        instructions.add(new IntInsnNode(opcode, operand));
-    }
-
-    @Override
-    public void visitVarInsn(final int opcode, final int var) {
-        instructions.add(new VarInsnNode(opcode, var));
-    }
-
-    @Override
-    public void visitTypeInsn(final int opcode, final String type) {
-        instructions.add(new TypeInsnNode(opcode, type));
-    }
-
-    @Override
-    public void visitFieldInsn(final int opcode, final String owner,
-            final String name, final String desc) {
-        instructions.add(new FieldInsnNode(opcode, owner, name, desc));
-    }
-
-    @Deprecated
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name,
-            String desc) {
-        if (api >= Opcodes.ASM5) {
-            super.visitMethodInsn(opcode, owner, name, desc);
-            return;
-        }
-        instructions.add(new MethodInsnNode(opcode, owner, name, desc));
-    }
-
-    @Override
-    public void visitMethodInsn(int opcode, String owner, String name,
-            String desc, boolean itf) {
-        if (api < Opcodes.ASM5) {
-            super.visitMethodInsn(opcode, owner, name, desc, itf);
-            return;
-        }
-        instructions.add(new MethodInsnNode(opcode, owner, name, desc, itf));
-    }
-
-    @Override
-    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
-            Object... bsmArgs) {
-        instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs));
-    }
-
-    @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
-        instructions.add(new JumpInsnNode(opcode, getLabelNode(label)));
-    }
-
-    @Override
-    public void visitLabel(final Label label) {
-        instructions.add(getLabelNode(label));
-    }
-
-    @Override
-    public void visitLdcInsn(final Object cst) {
-        instructions.add(new LdcInsnNode(cst));
-    }
-
-    @Override
-    public void visitIincInsn(final int var, final int increment) {
-        instructions.add(new IincInsnNode(var, increment));
-    }
-
-    @Override
-    public void visitTableSwitchInsn(final int min, final int max,
-            final Label dflt, final Label... labels) {
-        instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt),
-                getLabelNodes(labels)));
-    }
-
-    @Override
-    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
-            final Label[] labels) {
-        instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys,
-                getLabelNodes(labels)));
-    }
-
-    @Override
-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
-        instructions.add(new MultiANewArrayInsnNode(desc, dims));
-    }
-
-    @Override
-    public AnnotationVisitor visitInsnAnnotation(int typeRef,
-            TypePath typePath, String desc, boolean visible) {
-        // Finds the last real instruction, i.e. the instruction targeted by
-        // this annotation.
-        AbstractInsnNode insn = instructions.getLast();
-        while (insn.getOpcode() == -1) {
-            insn = insn.getPrevious();
+  }
+
+  @Override
+  public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
+    AnnotationNode annotation = new AnnotationNode(descriptor);
+    if (visible) {
+      if (visibleAnnotations == null) {
+        visibleAnnotations = new ArrayList<AnnotationNode>(1);
+      }
+      visibleAnnotations.add(annotation);
+    } else {
+      if (invisibleAnnotations == null) {
+        invisibleAnnotations = new ArrayList<AnnotationNode>(1);
+      }
+      invisibleAnnotations.add(annotation);
+    }
+    return annotation;
+  }
+
+  @Override
+  public AnnotationVisitor visitTypeAnnotation(
+      final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+    TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+    if (visible) {
+      if (visibleTypeAnnotations == null) {
+        visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+      }
+      visibleTypeAnnotations.add(typeAnnotation);
+    } else {
+      if (invisibleTypeAnnotations == null) {
+        invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+      }
+      invisibleTypeAnnotations.add(typeAnnotation);
+    }
+    return typeAnnotation;
+  }
+
+  @Override
+  public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
+    if (visible) {
+      visibleAnnotableParameterCount = parameterCount;
+    } else {
+      invisibleAnnotableParameterCount = parameterCount;
+    }
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  public AnnotationVisitor visitParameterAnnotation(
+      final int parameter, final String descriptor, final boolean visible) {
+    AnnotationNode annotation = new AnnotationNode(descriptor);
+    if (visible) {
+      if (visibleParameterAnnotations == null) {
+        int params = Type.getArgumentTypes(desc).length;
+        visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
+      }
+      if (visibleParameterAnnotations[parameter] == null) {
+        visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1);
+      }
+      visibleParameterAnnotations[parameter].add(annotation);
+    } else {
+      if (invisibleParameterAnnotations == null) {
+        int params = Type.getArgumentTypes(desc).length;
+        invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
+      }
+      if (invisibleParameterAnnotations[parameter] == null) {
+        invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1);
+      }
+      invisibleParameterAnnotations[parameter].add(annotation);
+    }
+    return annotation;
+  }
+
+  @Override
+  public void visitAttribute(final Attribute attribute) {
+    if (attrs == null) {
+      attrs = new ArrayList<Attribute>(1);
+    }
+    attrs.add(attribute);
+  }
+
+  @Override
+  public void visitCode() {
+    // Nothing to do.
+  }
+
+  @Override
+  public void visitFrame(
+      final int type,
+      final int numLocal,
+      final Object[] local,
+      final int numStack,
+      final Object[] stack) {
+    instructions.add(
+        new FrameNode(
+            type,
+            numLocal,
+            local == null ? null : getLabelNodes(local),
+            numStack,
+            stack == null ? null : getLabelNodes(stack)));
+  }
+
+  @Override
+  public void visitInsn(final int opcode) {
+    instructions.add(new InsnNode(opcode));
+  }
+
+  @Override
+  public void visitIntInsn(final int opcode, final int operand) {
+    instructions.add(new IntInsnNode(opcode, operand));
+  }
+
+  @Override
+  public void visitVarInsn(final int opcode, final int var) {
+    instructions.add(new VarInsnNode(opcode, var));
+  }
+
+  @Override
+  public void visitTypeInsn(final int opcode, final String type) {
+    instructions.add(new TypeInsnNode(opcode, type));
+  }
+
+  @Override
+  public void visitFieldInsn(
+      final int opcode, final String owner, final String name, final String descriptor) {
+    instructions.add(new FieldInsnNode(opcode, owner, name, descriptor));
+  }
+
+  /**
+   * Deprecated.
+   *
+   * @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead.
+   */
+  @Deprecated
+  @Override
+  public void visitMethodInsn(
+      final int opcode, final String owner, final String name, final String descriptor) {
+    if (api >= Opcodes.ASM5) {
+      super.visitMethodInsn(opcode, owner, name, descriptor);
+      return;
+    }
+    instructions.add(new MethodInsnNode(opcode, owner, name, descriptor));
+  }
+
+  @Override
+  public void visitMethodInsn(
+      final int opcode,
+      final String owner,
+      final String name,
+      final String descriptor,
+      final boolean isInterface) {
+    if (api < Opcodes.ASM5) {
+      super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+      return;
+    }
+    instructions.add(new MethodInsnNode(opcode, owner, name, descriptor, isInterface));
+  }
+
+  @Override
+  public void visitInvokeDynamicInsn(
+      final String name,
+      final String descriptor,
+      final Handle bootstrapMethodHandle,
+      final Object... bootstrapMethodArguments) {
+    instructions.add(
+        new InvokeDynamicInsnNode(
+            name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments));
+  }
+
+  @Override
+  public void visitJumpInsn(final int opcode, final Label label) {
+    instructions.add(new JumpInsnNode(opcode, getLabelNode(label)));
+  }
+
+  @Override
+  public void visitLabel(final Label label) {
+    instructions.add(getLabelNode(label));
+  }
+
+  @Override
+  public void visitLdcInsn(final Object value) {
+    instructions.add(new LdcInsnNode(value));
+  }
+
+  @Override
+  public void visitIincInsn(final int var, final int increment) {
+    instructions.add(new IincInsnNode(var, increment));
+  }
+
+  @Override
+  public void visitTableSwitchInsn(
+      final int min, final int max, final Label dflt, final Label... labels) {
+    instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), getLabelNodes(labels)));
+  }
+
+  @Override
+  public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
+    instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, getLabelNodes(labels)));
+  }
+
+  @Override
+  public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
+    instructions.add(new MultiANewArrayInsnNode(descriptor, numDimensions));
+  }
+
+  @Override
+  public AnnotationVisitor visitInsnAnnotation(
+      final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+    // Find the last real instruction, i.e. the instruction targeted by this annotation.
+    AbstractInsnNode currentInsn = instructions.getLast();
+    while (currentInsn.getOpcode() == -1) {
+      currentInsn = currentInsn.getPrevious();
+    }
+    // Add the annotation to this instruction.
+    TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+    if (visible) {
+      if (currentInsn.visibleTypeAnnotations == null) {
+        currentInsn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+      }
+      currentInsn.visibleTypeAnnotations.add(typeAnnotation);
+    } else {
+      if (currentInsn.invisibleTypeAnnotations == null) {
+        currentInsn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+      }
+      currentInsn.invisibleTypeAnnotations.add(typeAnnotation);
+    }
+    return typeAnnotation;
+  }
+
+  @Override
+  public void visitTryCatchBlock(
+      final Label start, final Label end, final Label handler, final String type) {
+    tryCatchBlocks.add(
+        new TryCatchBlockNode(getLabelNode(start), getLabelNode(end), getLabelNode(handler), type));
+  }
+
+  @Override
+  public AnnotationVisitor visitTryCatchAnnotation(
+      final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
+    TryCatchBlockNode tryCatchBlock = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8);
+    TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor);
+    if (visible) {
+      if (tryCatchBlock.visibleTypeAnnotations == null) {
+        tryCatchBlock.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+      }
+      tryCatchBlock.visibleTypeAnnotations.add(typeAnnotation);
+    } else {
+      if (tryCatchBlock.invisibleTypeAnnotations == null) {
+        tryCatchBlock.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1);
+      }
+      tryCatchBlock.invisibleTypeAnnotations.add(typeAnnotation);
+    }
+    return typeAnnotation;
+  }
+
+  @Override
+  public void visitLocalVariable(
+      final String name,
+      final String descriptor,
+      final String signature,
+      final Label start,
+      final Label end,
+      final int index) {
+    localVariables.add(
+        new LocalVariableNode(
+            name, descriptor, signature, getLabelNode(start), getLabelNode(end), index));
+  }
+
+  @Override
+  public AnnotationVisitor visitLocalVariableAnnotation(
+      final int typeRef,
+      final TypePath typePath,
+      final Label[] start,
+      final Label[] end,
+      final int[] index,
+      final String descriptor,
+      final boolean visible) {
+    LocalVariableAnnotationNode localVariableAnnotation =
+        new LocalVariableAnnotationNode(
+            typeRef, typePath, getLabelNodes(start), getLabelNodes(end), index, descriptor);
+    if (visible) {
+      if (visibleLocalVariableAnnotations == null) {
+        visibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(1);
+      }
+      visibleLocalVariableAnnotations.add(localVariableAnnotation);
+    } else {
+      if (invisibleLocalVariableAnnotations == null) {
+        invisibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(1);
+      }
+      invisibleLocalVariableAnnotations.add(localVariableAnnotation);
+    }
+    return localVariableAnnotation;
+  }
+
+  @Override
+  public void visitLineNumber(final int line, final Label start) {
+    instructions.add(new LineNumberNode(line, getLabelNode(start)));
+  }
+
+  @Override
+  public void visitMaxs(final int maxStack, final int maxLocals) {
+    this.maxStack = maxStack;
+    this.maxLocals = maxLocals;
+  }
+
+  @Override
+  public void visitEnd() {
+    // Nothing to do.
+  }
+
+  /**
+   * Returns the LabelNode corresponding to the given Label. Creates a new LabelNode if necessary.
+   * The default implementation of this method uses the {@link Label#info} field to store
+   * associations between labels and label nodes.
+   *
+   * @param label a Label.
+   * @return the LabelNode corresponding to label.
+   */
+  protected LabelNode getLabelNode(final Label label) {
+    if (!(label.info instanceof LabelNode)) {
+      label.info = new LabelNode();
+    }
+    return (LabelNode) label.info;
+  }
+
+  private LabelNode[] getLabelNodes(final Label[] labels) {
+    LabelNode[] labelNodes = new LabelNode[labels.length];
+    for (int i = 0, n = labels.length; i < n; ++i) {
+      labelNodes[i] = getLabelNode(labels[i]);
+    }
+    return labelNodes;
+  }
+
+  private Object[] getLabelNodes(final Object[] objects) {
+    Object[] labelNodes = new Object[objects.length];
+    for (int i = 0, n = objects.length; i < n; ++i) {
+      Object o = objects[i];
+      if (o instanceof Label) {
+        o = getLabelNode((Label) o);
+      }
+      labelNodes[i] = o;
+    }
+    return labelNodes;
+  }
+
+  // -----------------------------------------------------------------------------------------------
+  // Accept method
+  // -----------------------------------------------------------------------------------------------
+
+  /**
+   * Checks that this method node is compatible with the given ASM API version. This method checks
+   * that this node, and all its children recursively, do not contain elements that were introduced
+   * in more recent versions of the ASM API than the given version.
+   *
+   * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5},
+   *     {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
+   */
+  public void check(final int api) {
+    if (api == Opcodes.ASM4) {
+      if (parameters != null && !parameters.isEmpty()) {
+        throw new UnsupportedClassVersionException();
+      }
+      if (visibleTypeAnnotations != null && !visibleTypeAnnotations.isEmpty()) {
+        throw new UnsupportedClassVersionException();
+      }
+      if (invisibleTypeAnnotations != null && !invisibleTypeAnnotations.isEmpty()) {
+        throw new UnsupportedClassVersionException();
+      }
+      if (tryCatchBlocks != null) {
+        for (int i = tryCatchBlocks.size() - 1; i >= 0; --i) {
+          TryCatchBlockNode tryCatchBlock = tryCatchBlocks.get(i);
+          if (tryCatchBlock.visibleTypeAnnotations != null
+              && !tryCatchBlock.visibleTypeAnnotations.isEmpty()) {
+            throw new UnsupportedClassVersionException();
+          }
+          if (tryCatchBlock.invisibleTypeAnnotations != null
+              && !tryCatchBlock.invisibleTypeAnnotations.isEmpty()) {
+            throw new UnsupportedClassVersionException();
+          }
         }
-        // Adds the annotation to this instruction.
-        TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
-        if (visible) {
-            if (insn.visibleTypeAnnotations == null) {
-                insn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
-                        1);
-            }
-            insn.visibleTypeAnnotations.add(an);
-        } else {
-            if (insn.invisibleTypeAnnotations == null) {
-                insn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
-                        1);
-            }
-            insn.invisibleTypeAnnotations.add(an);
+      }
+      for (int i = instructions.size() - 1; i >= 0; --i) {
+        AbstractInsnNode insn = instructions.get(i);
+        if (insn.visibleTypeAnnotations != null && !insn.visibleTypeAnnotations.isEmpty()) {
+          throw new UnsupportedClassVersionException();
         }
-        return an;
-    }
-
-    @Override
-    public void visitTryCatchBlock(final Label start, final Label end,
-            final Label handler, final String type) {
-        tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start),
-                getLabelNode(end), getLabelNode(handler), type));
-    }
-
-    @Override
-    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
-            TypePath typePath, String desc, boolean visible) {
-        TryCatchBlockNode tcb = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8);
-        TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc);
-        if (visible) {
-            if (tcb.visibleTypeAnnotations == null) {
-                tcb.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
-                        1);
-            }
-            tcb.visibleTypeAnnotations.add(an);
-        } else {
-            if (tcb.invisibleTypeAnnotations == null) {
-                tcb.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(
-                        1);
-            }
-            tcb.invisibleTypeAnnotations.add(an);
+        if (insn.invisibleTypeAnnotations != null && !insn.invisibleTypeAnnotations.isEmpty()) {
+          throw new UnsupportedClassVersionException();
         }
-        return an;
-    }
-
-    @Override
-    public void visitLocalVariable(final String name, final String desc,
-            final String signature, final Label start, final Label end,
-            final int index) {
-        localVariables.add(new LocalVariableNode(name, desc, signature,
-                getLabelNode(start), getLabelNode(end), index));
-    }
-
-    @Override
-    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
-            TypePath typePath, Label[] start, Label[] end, int[] index,
-            String desc, boolean visible) {
-        LocalVariableAnnotationNode an = new LocalVariableAnnotationNode(
-                typeRef, typePath, getLabelNodes(start), getLabelNodes(end),
-                index, desc);
-        if (visible) {
-            if (visibleLocalVariableAnnotations == null) {
-                visibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(
-                        1);
-            }
-            visibleLocalVariableAnnotations.add(an);
-        } else {
-            if (invisibleLocalVariableAnnotations == null) {
-                invisibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(
-                        1);
-            }
-            invisibleLocalVariableAnnotations.add(an);
+        if (insn instanceof MethodInsnNode) {
+          boolean isInterface = ((MethodInsnNode) insn).itf;
+          if (isInterface != (insn.opcode == Opcodes.INVOKEINTERFACE)) {
+            throw new UnsupportedClassVersionException();
+          }
+        } else if (insn instanceof LdcInsnNode) {
+          Object value = ((LdcInsnNode) insn).cst;
+          if (value instanceof Handle
+              || (value instanceof Type && ((Type) value).getSort() == Type.METHOD)) {
+            throw new UnsupportedClassVersionException();
+          }
         }
-        return an;
-    }
-
-    @Override
-    public void visitLineNumber(final int line, final Label start) {
-        instructions.add(new LineNumberNode(line, getLabelNode(start)));
-    }
-
-    @Override
-    public void visitMaxs(final int maxStack, final int maxLocals) {
-        this.maxStack = maxStack;
-        this.maxLocals = maxLocals;
-    }
-
-    @Override
-    public void visitEnd() {
-    }
-
-    /**
-     * Returns the LabelNode corresponding to the given Label. Creates a new
-     * LabelNode if necessary. The default implementation of this method uses
-     * the {@link Label#info} field to store associations between labels and
-     * label nodes.
-     * 
-     * @param l
-     *            a Label.
-     * @return the LabelNode corresponding to l.
-     */
-    protected LabelNode getLabelNode(final Label l) {
-        if (!(l.info instanceof LabelNode)) {
-            l.info = new LabelNode();
+      }
+      if (visibleLocalVariableAnnotations != null && !visibleLocalVariableAnnotations.isEmpty()) {
+        throw new UnsupportedClassVersionException();
+      }
+      if (invisibleLocalVariableAnnotations != null
+          && !invisibleLocalVariableAnnotations.isEmpty()) {
+        throw new UnsupportedClassVersionException();
+      }
+    }
+    if (api != Opcodes.ASM7) {
+      for (int i = instructions.size() - 1; i >= 0; --i) {
+        AbstractInsnNode insn = instructions.get(i);
+        if (insn instanceof LdcInsnNode) {
+          Object value = ((LdcInsnNode) insn).cst;
+          if (value instanceof ConstantDynamic) {
+            throw new UnsupportedClassVersionException();
+          }
         }
-        return (LabelNode) l.info;
-    }
-
-    private LabelNode[] getLabelNodes(final Label[] l) {
-        LabelNode[] nodes = new LabelNode[l.length];
-        for (int i = 0; i < l.length; ++i) {
-            nodes[i] = getLabelNode(l[i]);
+      }
+    }
+  }
+
+  /**
+   * Makes the given class visitor visit this method.
+   *
+   * @param classVisitor a class visitor.
+   */
+  public void accept(final ClassVisitor classVisitor) {
+    String[] exceptionsArray = new String[this.exceptions.size()];
+    this.exceptions.toArray(exceptionsArray);
+    MethodVisitor methodVisitor =
+        classVisitor.visitMethod(access, name, desc, signature, exceptionsArray);
+    if (methodVisitor != null) {
+      accept(methodVisitor);
+    }
+  }
+
+  /**
+   * Makes the given method visitor visit this method.
+   *
+   * @param methodVisitor a method visitor.
+   */
+  public void accept(final MethodVisitor methodVisitor) {
+    // Visit the parameters.
+    if (parameters != null) {
+      for (int i = 0, n = parameters.size(); i < n; i++) {
+        parameters.get(i).accept(methodVisitor);
+      }
+    }
+    // Visit the annotations.
+    if (annotationDefault != null) {
+      AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotationDefault();
+      AnnotationNode.accept(annotationVisitor, null, annotationDefault);
+      if (annotationVisitor != null) {
+        annotationVisitor.visitEnd();
+      }
+    }
+    if (visibleAnnotations != null) {
+      for (int i = 0, n = visibleAnnotations.size(); i < n; ++i) {
+        AnnotationNode annotation = visibleAnnotations.get(i);
+        annotation.accept(methodVisitor.visitAnnotation(annotation.desc, true));
+      }
+    }
+    if (invisibleAnnotations != null) {
+      for (int i = 0, n = invisibleAnnotations.size(); i < n; ++i) {
+        AnnotationNode annotation = invisibleAnnotations.get(i);
+        annotation.accept(methodVisitor.visitAnnotation(annotation.desc, false));
+      }
+    }
+    if (visibleTypeAnnotations != null) {
+      for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) {
+        TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i);
+        typeAnnotation.accept(
+            methodVisitor.visitTypeAnnotation(
+                typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true));
+      }
+    }
+    if (invisibleTypeAnnotations != null) {
+      for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) {
+        TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i);
+        typeAnnotation.accept(
+            methodVisitor.visitTypeAnnotation(
+                typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false));
+      }
+    }
+    if (visibleAnnotableParameterCount > 0) {
+      methodVisitor.visitAnnotableParameterCount(visibleAnnotableParameterCount, true);
+    }
+    if (visibleParameterAnnotations != null) {
+      for (int i = 0, n = visibleParameterAnnotations.length; i < n; ++i) {
+        List<AnnotationNode> parameterAnnotations = visibleParameterAnnotations[i];
+        if (parameterAnnotations == null) {
+          continue;
         }
-        return nodes;
-    }
-
-    private Object[] getLabelNodes(final Object[] objs) {
-        Object[] nodes = new Object[objs.length];
-        for (int i = 0; i < objs.length; ++i) {
-            Object o = objs[i];
-            if (o instanceof Label) {
-                o = getLabelNode((Label) o);
-            }
-            nodes[i] = o;
-        }
-        return nodes;
-    }
-
-    // ------------------------------------------------------------------------
-    // Accept method
-    // ------------------------------------------------------------------------
-
-    /**
-     * Checks that this method node is compatible with the given ASM API
-     * version. This methods checks that this node, and all its nodes
-     * recursively, do not contain elements that were introduced in more recent
-     * versions of the ASM API than the given version.
-     * 
-     * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
-     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
-     */
-    public void check(final int api) {
-        if (api == Opcodes.ASM4) {
-            if (visibleTypeAnnotations != null
-                    && visibleTypeAnnotations.size() > 0) {
-                throw new RuntimeException();
-            }
-            if (invisibleTypeAnnotations != null
-                    && invisibleTypeAnnotations.size() > 0) {
-                throw new RuntimeException();
-            }
-            int n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
-            for (int i = 0; i < n; ++i) {
-                TryCatchBlockNode tcb = tryCatchBlocks.get(i);
-                if (tcb.visibleTypeAnnotations != null
-                        && tcb.visibleTypeAnnotations.size() > 0) {
-                    throw new RuntimeException();
-                }
-                if (tcb.invisibleTypeAnnotations != null
-                        && tcb.invisibleTypeAnnotations.size() > 0) {
-                    throw new RuntimeException();
-                }
-            }
-            for (int i = 0; i < instructions.size(); ++i) {
-                AbstractInsnNode insn = instructions.get(i);
-                if (insn.visibleTypeAnnotations != null
-                        && insn.visibleTypeAnnotations.size() > 0) {
-                    throw new RuntimeException();
-                }
-                if (insn.invisibleTypeAnnotations != null
-                        && insn.invisibleTypeAnnotations.size() > 0) {
-                    throw new RuntimeException();
-                }
-                if (insn instanceof MethodInsnNode) {
-                    boolean itf = ((MethodInsnNode) insn).itf;
-                    if (itf != (insn.opcode == Opcodes.INVOKEINTERFACE)) {
-                        throw new RuntimeException();
-                    }
-                }
-            }
-            if (visibleLocalVariableAnnotations != null
-                    && visibleLocalVariableAnnotations.size() > 0) {
-                throw new RuntimeException();
-            }
-            if (invisibleLocalVariableAnnotations != null
-                    && invisibleLocalVariableAnnotations.size() > 0) {
-                throw new RuntimeException();
-            }
+        for (int j = 0, m = parameterAnnotations.size(); j < m; ++j) {
+          AnnotationNode annotation = parameterAnnotations.get(j);
+          annotation.accept(methodVisitor.visitParameterAnnotation(i, annotation.desc, true));
         }
+      }
     }
-
-    /**
-     * Makes the given class visitor visit this method.
-     * 
-     * @param cv
-     *            a class visitor.
-     */
-    public void accept(final ClassVisitor cv) {
-        String[] exceptions = new String[this.exceptions.size()];
-        this.exceptions.toArray(exceptions);
-        MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
-                exceptions);
-        if (mv != null) {
-            accept(mv);
-        }
+    if (invisibleAnnotableParameterCount > 0) {
+      methodVisitor.visitAnnotableParameterCount(invisibleAnnotableParameterCount, false);
     }
-
-    /**
-     * Makes the given method visitor visit this method.
-     * 
-     * @param mv
-     *            a method visitor.
-     */
-    public void accept(final MethodVisitor mv) {
-        // visits the method parameters
-        int i, j, n;
-        n = parameters == null ? 0 : parameters.size();
-        for (i = 0; i < n; i++) {
-            ParameterNode parameter = parameters.get(i);
-            mv.visitParameter(parameter.name, parameter.access);
-        }
-        // visits the method attributes
-        if (annotationDefault != null) {
-            AnnotationVisitor av = mv.visitAnnotationDefault();
-            AnnotationNode.accept(av, null, annotationDefault);
-            if (av != null) {
-                av.visitEnd();
-            }
-        }
-        n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
-        for (i = 0; i < n; ++i) {
-            AnnotationNode an = visibleAnnotations.get(i);
-            an.accept(mv.visitAnnotation(an.desc, true));
-        }
-        n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
-        for (i = 0; i < n; ++i) {
-            AnnotationNode an = invisibleAnnotations.get(i);
-            an.accept(mv.visitAnnotation(an.desc, false));
-        }
-        n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
-        for (i = 0; i < n; ++i) {
-            TypeAnnotationNode an = visibleTypeAnnotations.get(i);
-            an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
-                    true));
-        }
-        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
-                .size();
-        for (i = 0; i < n; ++i) {
-            TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
-            an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
-                    false));
+    if (invisibleParameterAnnotations != null) {
+      for (int i = 0, n = invisibleParameterAnnotations.length; i < n; ++i) {
+        List<AnnotationNode> parameterAnnotations = invisibleParameterAnnotations[i];
+        if (parameterAnnotations == null) {
+          continue;
         }
-        n = visibleParameterAnnotations == null ? 0
-                : visibleParameterAnnotations.length;
-        for (i = 0; i < n; ++i) {
-            List<?> l = visibleParameterAnnotations[i];
-            if (l == null) {
-                continue;
-            }
-            for (j = 0; j < l.size(); ++j) {
-                AnnotationNode an = (AnnotationNode) l.get(j);
-                an.accept(mv.visitParameterAnnotation(i, an.desc, true));
-            }
+        for (int j = 0, m = parameterAnnotations.size(); j < m; ++j) {
+          AnnotationNode annotation = parameterAnnotations.get(j);
+          annotation.accept(methodVisitor.visitParameterAnnotation(i, annotation.desc, false));
         }
-        n = invisibleParameterAnnotations == null ? 0
-                : invisibleParameterAnnotations.length;
-        for (i = 0; i < n; ++i) {
-            List<?> l = invisibleParameterAnnotations[i];
-            if (l == null) {
-                continue;
-            }
-            for (j = 0; j < l.size(); ++j) {
-                AnnotationNode an = (AnnotationNode) l.get(j);
-                an.accept(mv.visitParameterAnnotation(i, an.desc, false));
-            }
+      }
+    }
+    // Visit the non standard attributes.
+    if (visited) {
+      instructions.resetLabels();
+    }
+    if (attrs != null) {
+      for (int i = 0, n = attrs.size(); i < n; ++i) {
+        methodVisitor.visitAttribute(attrs.get(i));
+      }
+    }
+    // Visit the code.
+    if (instructions.size() > 0) {
+      methodVisitor.visitCode();
+      // Visits the try catch blocks.
+      if (tryCatchBlocks != null) {
+        for (int i = 0, n = tryCatchBlocks.size(); i < n; ++i) {
+          tryCatchBlocks.get(i).updateIndex(i);
+          tryCatchBlocks.get(i).accept(methodVisitor);
         }
-        if (visited) {
-            instructions.resetLabels();
+      }
+      // Visit the instructions.
+      instructions.accept(methodVisitor);
+      // Visits the local variables.
+      if (localVariables != null) {
+        for (int i = 0, n = localVariables.size(); i < n; ++i) {
+          localVariables.get(i).accept(methodVisitor);
         }
-        n = attrs == null ? 0 : attrs.size();
-        for (i = 0; i < n; ++i) {
-            mv.visitAttribute(attrs.get(i));
+      }
+      // Visits the local variable annotations.
+      if (visibleLocalVariableAnnotations != null) {
+        for (int i = 0, n = visibleLocalVariableAnnotations.size(); i < n; ++i) {
+          visibleLocalVariableAnnotations.get(i).accept(methodVisitor, true);
         }
-        // visits the method's code
-        if (instructions.size() > 0) {
-            mv.visitCode();
-            // visits try catch blocks
-            n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
-            for (i = 0; i < n; ++i) {
-                tryCatchBlocks.get(i).updateIndex(i);
-                tryCatchBlocks.get(i).accept(mv);
-            }
-            // visits instructions
-            instructions.accept(mv);
-            // visits local variables
-            n = localVariables == null ? 0 : localVariables.size();
-            for (i = 0; i < n; ++i) {
-                localVariables.get(i).accept(mv);
-            }
-            // visits local variable annotations
-            n = visibleLocalVariableAnnotations == null ? 0
-                    : visibleLocalVariableAnnotations.size();
-            for (i = 0; i < n; ++i) {
-                visibleLocalVariableAnnotations.get(i).accept(mv, true);
-            }
-            n = invisibleLocalVariableAnnotations == null ? 0
-                    : invisibleLocalVariableAnnotations.size();
-            for (i = 0; i < n; ++i) {
-                invisibleLocalVariableAnnotations.get(i).accept(mv, false);
-            }
-            // visits maxs
-            mv.visitMaxs(maxStack, maxLocals);
-            visited = true;
+      }
+      if (invisibleLocalVariableAnnotations != null) {
+        for (int i = 0, n = invisibleLocalVariableAnnotations.size(); i < n; ++i) {
+          invisibleLocalVariableAnnotations.get(i).accept(methodVisitor, false);
         }
-        mv.visitEnd();
+      }
+      methodVisitor.visitMaxs(maxStack, maxLocals);
+      visited = true;
     }
+    methodVisitor.visitEnd();
+  }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java
old mode 100644
new mode 100755
index 946872d..c4f6503
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java
@@ -1,82 +1,79 @@
-/***
- * 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.
- */
+// 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.tree;
 
 import java.util.List;
-
 import org.apache.tapestry5.internal.plastic.asm.ModuleVisitor;
 
 /**
  * A node that represents an exported package with its name and the module that can access to it.
- * 
+ *
  * @author Remi Forax
  */
 public class ModuleExportNode {
-    /**
-     * The package name.
-     */
-    public String packaze;
-    
-    /**
-     * The access flags (see {@link org.objectweb.asm.Opcodes}).
-     * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
-     */
-    public int access;
 
-    /**
-     * A list of modules that can access to this exported package.
-     * May be <tt>null</tt>.
-     */
-    public List<String> modules;
+  /** The internal name of the exported package. */
+  public String packaze;
+
+  /**
+   * The access flags (see {@link org.apache.tapestry5.internal.plastic.asm.Opcodes}). Valid values are {@code
+   * ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+   */
+  public int access;
+
+  /**
+   * The list of modules that can access this exported package, specified with fully qualified names
+   * (using dots). May be {@literal null}.
+   */
+  public List<String> modules;
 
-    /**
-     * Constructs a new {@link ModuleExportNode}.
-     * 
-     * @param packaze
-     *            the parameter's name.
-     * @param modules
-     *            a list of modules that can access to this exported package.
-     */
-    public ModuleExportNode(final String packaze, final int access, final List<String> modules) {
-        this.packaze = packaze;
-        this.access = access;
-        this.modules = modules;
-    }
+  /**
+   * Constructs a new {@link ModuleExportNode}.
+   *
+   * @param packaze the internal name of the exported package.
+   * @param access the package access flags, one or more of {@code ACC_SYNTHETIC} and {@code
+   *     ACC_MANDATED}.
+   * @param modules a list of modules that can access this exported package, specified with fully
+   *     qualified names (using dots).
+   */
+  public ModuleExportNode(final String packaze, final int access, final List<String> modules) {
+    this.packaze = packaze;
+    this.access = access;
+    this.modules = modules;
+  }
 
-    /**
-     * Makes the given module visitor visit this export declaration.
-     * 
-     * @param mv
-     *            a module visitor.
-     */
-    public void accept(final ModuleVisitor mv) {
-        mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
-    }
+  /**
+   * Makes the given module visitor visit this export declaration.
+   *
+   * @param moduleVisitor a module visitor.
+   */
+  public void accept(final ModuleVisitor moduleVisitor) {
+    moduleVisitor.visitExport(
+        packaze, access, modules == null ? null : modules.toArray(new String[0]));
+  }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java
old mode 100644
new mode 100755
index e76dbf1..fe05259
--- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java
@@ -1,115 +1,116 @@
-/***
- * 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.
- */
+// 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.tree;
 
 import java.util.ArrayList;
 import java.util.List;
-
 import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
 import org.apache.tapestry5.internal.plastic.asm.ModuleVisitor;
 import org.apache.tapestry5.internal.plastic.asm.Opcodes;
 
 /**
  * A node that represents a module declaration.
- * 
+ *
  * @author Remi Forax
  */
 public class ModuleNode extends ModuleVisitor {
-    /**
-     * Module name
-     */
-    public String name;
-    
-    /**
-     * Module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
-     *            and {@code ACC_MANDATED}.
-     */
-    public int access;
-    
-    /**
-     * Version of the module.
-     * May be <tt>null</tt>.
-     */
-    public String version;
-    
-    /**
-     * Name of the main class in internal form
-     * May be <tt>null</tt>.
-     */
-    public String mainClass;
-    
-    /**
-     * A list of packages that are declared by the current module.
-     * May be <tt>null</tt>.
-     */
-    public List<String> packages;
-    
-    /**
-     * A list of modules can are required by the current module.
-     * May be <tt>null</tt>.
-     */
-    public List<ModuleRequireNode> requires;
-    
-    /**
-     * A list of packages that are exported by the current module.
-     * May be <tt>null</tt>.
-     */
-    public List<ModuleExportNode> exports;
-    
-    /**
-     * A list of packages that are opened by the current module.
-     * May be <tt>null</tt>.
-     */
-    public List<ModuleOpenNode> opens;
-    
-    /**
-     * A list of classes in their internal forms that are used
-     * as a service by the current module. May be <tt>null</tt>.
-     */
-    public List<String> uses;
-   
-    /**
-     * A list of services along with their implementations provided
-     * by the current module. May be <tt>null</tt>.
-     */
-    public List<ModuleProvideNode> provides;
-
-    public ModuleNode(final String name, final int access,
-            final String version) {
-        super(Opcodes.ASM6);
-        this.name = name;
-        this.access = access;
-        this.version = version;
+
+  /** The fully qualified name (using dots) of this module. */
+  public String name;
+
+  /**
+   * The module's access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
+   * ACC_MANDATED}.
+   */
+  public int access;
+
+  /** The version of this module. May be {@literal null}. */
+  public String version;
+
+  /** The internal name of the main class of this module. May be {@literal null}. */
+  public String mainClass;
+
+  /** The internal name of the packages declared by this module. May be {@literal null}. */
+  public List<String> packages;
+
+  /** The dependencies of this module. May be {@literal null}. */
+  public List<ModuleRequireNode> requires;
+
+  /** The packages exported by this module. May be {@literal null}. */
+  public List<ModuleExportNode> exports;
+
+  /** The packages opened by this module. May be {@literal null}. */
+  public List<ModuleOpenNode> opens;
+
+  /** The internal names of the services used by this module. May be {@literal null}. */
+  public List<String> uses;
+
+  /** The services provided by this module. May be {@literal null}. */
+  public List<ModuleProvideNode> provides;
+
+  /**
+   * Constructs a {@link ModuleNode}. <i>Subclasses must not use this constructor</i>. Instead, they
+   * must use the {@link #ModuleNode(int,String,int,String,List,List,List,List,List)} version.
+   *
+   * @param name the fully qualified name (using dots) of the module.
+   * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
+   *     ACC_MANDATED}.
+   * @param version the module version, or {@literal null}.
+   * @throws IllegalStateException If a subclass calls this constructor.
+   */
+  public ModuleNode(final String name, final int access, final String version) {
+    super(Opcodes.ASM7);
+    if (getClass() != ModuleNode.class) {
+      throw new IllegalStateException();
     }
-    
-    public ModuleNode(final int api,
+    this.name = name;
+    this.access = access;
+    this.version = version;
+  }
+
+  // TODO(forax): why is there no 'mainClass' and 'packages' parameters in this constructor?
+  /**
+   * Constructs a {@link ModuleNode}.
+   *
+   * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6}
+   *     or {@link Opcodes#ASM7}.
+   * @param name the fully qualified name (using dots) of the module.
+   * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code
+   *     ACC_MANDATED}.
+   * @param version the module version, or {@literal null}.
+   * @param requires The dependencies of this module. May be {@literal null}.
+   * @param exports The packages exported by this module. May be {@literal null}.
+   * @param opens The packages opened by this module. May be {@literal null}.
+   * @param uses The internal names of the services used by this module. May be {@literal null}.
+   * @param provides The services provided by this module. May be {@literal null}.
+   */
+  public ModuleNode(
+      final int api,
       final String name,
       final int access,
       final String version,
@@ -118,134 +119,117 @@ public class ModuleNode extends ModuleVisitor {
       final List<ModuleOpenNode> opens,
       final List<String> uses,
       final List<ModuleProvideNode> provides) {
-        super(api);
-        this.name = name;
-        this.access = access;
-        this.version = version;
-        this.requires = requires;
-        this.exports = exports;
-        this.opens = opens;
-        this.uses = uses;
-        this.provides = provides;
-        if (getClass() != ModuleNode.class) {
-            throw new IllegalStateException();
-        }
+    super(api);
+    this.name = name;
+    this.access = access;
+    this.version = version;
+    this.requires = requires;
+    this.exports = exports;
+    this.opens = opens;
+    this.uses = uses;
+    this.provides = provides;
+  }
+
+  @Override
+  public void visitMainClass(final String mainClass) {
+    this.mainClass = mainClass;
+  }
+
+  @Override
+  public void visitPackage(final String packaze) {
+    if (packages == null) {
+      packages = new ArrayList<String>(5);
     }
-    
-    @Override
-    public void visitMainClass(String mainClass) {
-        this.mainClass = mainClass;
+    packages.add(packaze);
+  }
+
+  @Override
+  public void visitRequire(final String module, final int access, final String version) {
+    if (requires == null) {
+      requires = new ArrayList<ModuleRequireNode>(5);
+    }
+    requires.add(new ModuleRequireNode(module, access, version));
+  }
+
+  @Override
+  public void visitExport(final String packaze, final int access, final String... modules) {
+    if (exports == null) {
+      exports = new ArrayList<ModuleExportNode>(5);
     }
-    
-    @Override
-    public void visitPackage(String packaze) {
-        if (packages == null) {
-            packages = new ArrayList<String>(5);
-        }
-        packages.add(packaze);
+    exports.add(new ModuleExportNode(packaze, access, Util.asArrayList(modules)));
+  }
+
+  @Override
+  public void visitOpen(final String packaze, final int access, final String... modules) {
+    if (opens == null) {
+      opens = new ArrayList<ModuleOpenNode>(5);
+    }
+    opens.add(new ModuleOpenNode(packaze, access, Util.asArrayList(modules)));
+  }
+
+  @Override
+  public void visitUse(final String service) {
+    if (uses == null) {
+      uses = new ArrayList<String>(5);
+    }
+    uses.add(service);
+  }
+
+  @Override
+  public void visitProvide(final String service, final String... providers) {
+    if (provides == null) {
+      provides = new ArrayList<ModuleProvideNode>(5);
+    }
+    provides.add(new ModuleProvideNode(service, Util.asArrayList(providers)));
+  }
+
+  @Override
+  public void visitEnd() {
+    // Nothing to do.
+  }
+
+  /**
+   * Makes the given class visitor visit this module.
+   *
+   * @param classVisitor a class visitor.
+   */
+  public void accept(final ClassVisitor classVisitor) {
+    ModuleVisitor moduleVisitor = classVisitor.visitModule(name, access, version);
+    if (moduleVisitor == null) {
+      return;
     }
-    
-    @Override
-    public void visitRequire(String module, int access, String version) {
-        if (requires == null) {
-            requires = new ArrayList<ModuleRequireNode>(5);
-        }
-        requires.add(new ModuleRequireNode(module, access, version));
+    if (mainClass != null) {
+      moduleVisitor.visitMainClass(mainClass);
     }
-    
-    @Override
-    public void visitExport(String packaze, int access, String... modules) {
-        if (exports == null) {
-            exports = new ArrayList<ModuleExportNode>(5);
-        }
-        List<String> moduleList = null;
-        if (modules != null) {
-            moduleList = new ArrayList<String>(modules.length);
-            for (int i = 0; i < modules.length; i++) {
-                moduleList.add(modules[i]);
-            }
-        }
-        exports.add(new ModuleExportNode(packaze, access, moduleList));
+    if (packages != null) {
+      for (int i = 0, n = packages.size(); i < n; i++) {
+        moduleVisitor.visitPackage(packages.get(i));
+      }
     }
-    
-    @Override
-    public void visitOpen(String packaze, int access, String... modules) {
-        if (opens == null) {
-            opens = new ArrayList<ModuleOpenNode>(5);
-        }
-        List<String> moduleList = null;
-        if (modules != null) {
-            moduleList = new ArrayList<String>(modules.length);
-            for (int i = 0; i < modules.length; i++) {
-                moduleList.add(modules[i]);
-            }
-        }
-        opens.add(new ModuleOpenNode(packaze, access, moduleList));
+    if (requires != null) {
+      for (int i = 0, n = requires.size(); i < n; i++) {
+        requires.get(i).accept(moduleVisitor);
+      }
     }
-    
-    @Override
-    public void visitUse(String service) {
-        if (uses == null) {
-            uses = new ArrayList<String>(5);
-        }
-        uses.add(service);
+    if (exports != null) {
+      for (int i = 0, n = exports.size(); i < n; i++) {
+        exports.get(i).accept(moduleVisitor);
+      }
     }
-    
-    @Override
-    public void visitProvide(String service, String... providers) {
-        if (provides == null) {
-            provides = new ArrayList<ModuleProvideNode>(5);
-        }
-        ArrayList<String> providerList =
-                new ArrayList<String>(providers.length);
-        for (int i = 0; i < providers.length; i++) {
-                providerList.add(providers[i]);
-        }
-        provides.add(new ModuleProvideNode(service, providerList));
+    if (opens != null) {
+      for (int i = 0, n = opens.size(); i < n; i++) {
+        opens.get(i).accept(moduleVisitor);
+      }
     }
-    
-    @Override
-    public void visitEnd() {
+    if (uses != null) {
+      for (int i = 0, n = uses.size(); i < n; i++) {
+        moduleVisitor.visitUse(uses.get(i));
+      }
     }
-    
-    public void accept(final ClassVisitor cv) {
-        ModuleVisitor mv = cv.visitModule(name, access, version);
-        if (mv == null) {
-            return;
-        }
-        if (mainClass != null) {
-            mv.visitMainClass(mainClass);
-        }
-        if (packages != null) {
-            for (int i = 0; i < packages.size(); i++) {
-                mv.visitPackage(packages.get(i));
-            }
-        }
-        
-        if (requires != null) {
-            for (int i = 0; i < requires.size(); i++) {
-                requires.get(i).accept(mv);
-            }
-        }
-        if (exports != null) {
-            for (int i = 0; i < exports.size(); i++) {
-                exports.get(i).accept(mv);
-            }
-        }
-        if (opens != null) {
-            for (int i = 0; i < opens.size(); i++) {
-                opens.get(i).accept(mv);
-            }
-        }
-        if (uses != null) {
-            for (int i = 0; i < uses.size(); i++) {
-                mv.visitUse(uses.get(i));
-            }
-        }
-        if (provides != null) {
-            for (int i = 0; i < provides.size(); i++) {
-                provides.get(i).accept(mv);
-            }
-        }
+    if (provides != null) {
+      for (int i = 0, n = provides.size(); i < n; i++) {
+        provides.get(i).accept(moduleVisitor);
+      }
     }
+  }
 }