You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by ka...@apache.org on 2014/03/25 19:30:01 UTC

[13/23] FIXED - TAP5-2214: Make tapestry5 java8 compatible - update ASM source to 5.0.1, should be jdk 1.5 compatible, see ASM bug "317132 ASM 5.0 do not supported JDK 1.5?"

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/Remapper.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/Remapper.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/Remapper.java
new file mode 100644
index 0000000..bffd20e
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/Remapper.java
@@ -0,0 +1,223 @@
+/***
+ * 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.commons;
+
+import org.apache.tapestry5.internal.plastic.asm.Handle;
+import org.apache.tapestry5.internal.plastic.asm.Type;
+import org.apache.tapestry5.internal.plastic.asm.signature.SignatureReader;
+import org.apache.tapestry5.internal.plastic.asm.signature.SignatureVisitor;
+import org.apache.tapestry5.internal.plastic.asm.signature.SignatureWriter;
+
+/**
+ * A class responsible for remapping types and names. Subclasses can override
+ * the following methods:
+ * 
+ * <ul>
+ * <li>{@link #map(String)} - map type</li>
+ * <li>{@link #mapFieldName(String, String, String)} - map field name</li>
+ * <li>{@link #mapMethodName(String, String, String)} - map method name</li>
+ * </ul>
+ * 
+ * @author Eugene Kuleshov
+ */
+public abstract class Remapper {
+
+    public String mapDesc(String desc) {
+        Type t = Type.getType(desc);
+        switch (t.getSort()) {
+        case Type.ARRAY:
+            String s = mapDesc(t.getElementType().getDescriptor());
+            for (int i = 0; i < t.getDimensions(); ++i) {
+                s = '[' + s;
+            }
+            return s;
+        case Type.OBJECT:
+            String newType = map(t.getInternalName());
+            if (newType != null) {
+                return 'L' + newType + ';';
+            }
+        }
+        return desc;
+    }
+
+    private Type mapType(Type t) {
+        switch (t.getSort()) {
+        case Type.ARRAY:
+            String s = mapDesc(t.getElementType().getDescriptor());
+            for (int i = 0; i < t.getDimensions(); ++i) {
+                s = '[' + s;
+            }
+            return Type.getType(s);
+        case Type.OBJECT:
+            s = map(t.getInternalName());
+            return s != null ? Type.getObjectType(s) : t;
+        case Type.METHOD:
+            return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
+        }
+        return t;
+    }
+
+    public String mapType(String type) {
+        if (type == null) {
+            return null;
+        }
+        return mapType(Type.getObjectType(type)).getInternalName();
+    }
+
+    public String[] mapTypes(String[] types) {
+        String[] newTypes = null;
+        boolean needMapping = false;
+        for (int i = 0; i < types.length; i++) {
+            String type = types[i];
+            String newType = map(type);
+            if (newType != null && newTypes == null) {
+                newTypes = new String[types.length];
+                if (i > 0) {
+                    System.arraycopy(types, 0, newTypes, 0, i);
+                }
+                needMapping = true;
+            }
+            if (needMapping) {
+                newTypes[i] = newType == null ? type : newType;
+            }
+        }
+        return needMapping ? newTypes : types;
+    }
+
+    public String mapMethodDesc(String desc) {
+        if ("()V".equals(desc)) {
+            return desc;
+        }
+
+        Type[] args = Type.getArgumentTypes(desc);
+        StringBuffer s = new StringBuffer("(");
+        for (int i = 0; i < args.length; i++) {
+            s.append(mapDesc(args[i].getDescriptor()));
+        }
+        Type returnType = Type.getReturnType(desc);
+        if (returnType == Type.VOID_TYPE) {
+            s.append(")V");
+            return s.toString();
+        }
+        s.append(')').append(mapDesc(returnType.getDescriptor()));
+        return s.toString();
+    }
+
+    public Object mapValue(Object value) {
+        if (value instanceof Type) {
+            return mapType((Type) value);
+        }
+        if (value instanceof Handle) {
+            Handle h = (Handle) value;
+            return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(
+                    h.getOwner(), h.getName(), h.getDesc()),
+                    mapMethodDesc(h.getDesc()));
+        }
+        return value;
+    }
+
+    /**
+     * 
+     * @param typeSignature
+     *            true if signature is a FieldTypeSignature, such as the
+     *            signature parameter of the ClassVisitor.visitField or
+     *            MethodVisitor.visitLocalVariable methods
+     */
+    public String mapSignature(String signature, boolean typeSignature) {
+        if (signature == null) {
+            return null;
+        }
+        SignatureReader r = new SignatureReader(signature);
+        SignatureWriter w = new SignatureWriter();
+        SignatureVisitor a = createRemappingSignatureAdapter(w);
+        if (typeSignature) {
+            r.acceptType(a);
+        } else {
+            r.accept(a);
+        }
+        return w.toString();
+    }
+
+    protected SignatureVisitor createRemappingSignatureAdapter(
+            SignatureVisitor v) {
+        return new RemappingSignatureAdapter(v, this);
+    }
+
+    /**
+     * Map method name to the new name. Subclasses can override.
+     * 
+     * @param owner
+     *            owner of the method.
+     * @param name
+     *            name of the method.
+     * @param desc
+     *            descriptor of the method.
+     * @return new name of the method
+     */
+    public String mapMethodName(String owner, String name, String desc) {
+        return name;
+    }
+
+    /**
+     * Map invokedynamic method name to the new name. Subclasses can override.
+     * 
+     * @param name
+     *            name of the invokedynamic.
+     * @param desc
+     *            descriptor of the invokedynamic.
+     * @return new invokdynamic name.
+     */
+    public String mapInvokeDynamicMethodName(String name, String desc) {
+        return name;
+    }
+
+    /**
+     * Map field name to the new name. Subclasses can override.
+     * 
+     * @param owner
+     *            owner of the field.
+     * @param name
+     *            name of the field
+     * @param desc
+     *            descriptor of the field
+     * @return new name of the field.
+     */
+    public String mapFieldName(String owner, String name, String desc) {
+        return name;
+    }
+
+    /**
+     * Map type name to the new name. Subclasses can override.
+     */
+    public String map(String typeName) {
+        return typeName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingAnnotationAdapter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingAnnotationAdapter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingAnnotationAdapter.java
new file mode 100644
index 0000000..2f253dd
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingAnnotationAdapter.java
@@ -0,0 +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.
+ */
+
+package org.apache.tapestry5.internal.plastic.asm.commons;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+
+/**
+ * An {@link AnnotationVisitor} adapter for type remapping.
+ * 
+ * @author Eugene Kuleshov
+ */
+public class RemappingAnnotationAdapter extends AnnotationVisitor {
+
+    protected final Remapper remapper;
+
+    public RemappingAnnotationAdapter(final AnnotationVisitor av,
+            final Remapper remapper) {
+        this(Opcodes.ASM5, av, remapper);
+    }
+
+    protected RemappingAnnotationAdapter(final int api,
+            final AnnotationVisitor av, final Remapper remapper) {
+        super(api, av);
+        this.remapper = remapper;
+    }
+
+    @Override
+    public void visit(String name, Object value) {
+        av.visit(name, remapper.mapValue(value));
+    }
+
+    @Override
+    public void visitEnum(String name, String desc, String value) {
+        av.visitEnum(name, remapper.mapDesc(desc), value);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(String name, String desc) {
+        AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc));
+        return v == null ? null : (v == av ? this
+                : new RemappingAnnotationAdapter(v, remapper));
+    }
+
+    @Override
+    public AnnotationVisitor visitArray(String name) {
+        AnnotationVisitor v = av.visitArray(name);
+        return v == null ? null : (v == av ? this
+                : new RemappingAnnotationAdapter(v, remapper));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingClassAdapter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingClassAdapter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingClassAdapter.java
new file mode 100644
index 0000000..7dbae24
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingClassAdapter.java
@@ -0,0 +1,135 @@
+/***
+ * 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.commons;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
+import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.TypePath;
+
+/**
+ * A {@link ClassVisitor} for type remapping.
+ * 
+ * @author Eugene Kuleshov
+ */
+public class RemappingClassAdapter extends ClassVisitor {
+
+    protected final Remapper remapper;
+
+    protected String className;
+
+    public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper) {
+        this(Opcodes.ASM5, cv, remapper);
+    }
+
+    protected RemappingClassAdapter(final int api, final ClassVisitor cv,
+            final Remapper remapper) {
+        super(api, cv);
+        this.remapper = remapper;
+    }
+
+    @Override
+    public void visit(int version, int access, String name, String signature,
+            String superName, String[] interfaces) {
+        this.className = name;
+        super.visit(version, access, remapper.mapType(name), remapper
+                .mapSignature(signature, false), remapper.mapType(superName),
+                interfaces == null ? null : remapper.mapTypes(interfaces));
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+        AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
+                visible);
+        return av == null ? null : createRemappingAnnotationAdapter(av);
+    }
+
+    @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? null : createRemappingAnnotationAdapter(av);
+    }
+
+    @Override
+    public FieldVisitor visitField(int access, String name, String desc,
+            String signature, Object value) {
+        FieldVisitor fv = super.visitField(access,
+                remapper.mapFieldName(className, name, desc),
+                remapper.mapDesc(desc), remapper.mapSignature(signature, true),
+                remapper.mapValue(value));
+        return fv == null ? null : createRemappingFieldAdapter(fv);
+    }
+
+    @Override
+    public MethodVisitor visitMethod(int access, String name, String desc,
+            String signature, String[] exceptions) {
+        String newDesc = remapper.mapMethodDesc(desc);
+        MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(
+                className, name, desc), newDesc, remapper.mapSignature(
+                signature, false),
+                exceptions == null ? null : remapper.mapTypes(exceptions));
+        return mv == null ? null : createRemappingMethodAdapter(access,
+                newDesc, mv);
+    }
+
+    @Override
+    public void visitInnerClass(String name, String outerName,
+            String innerName, int access) {
+        // TODO should innerName be changed?
+        super.visitInnerClass(remapper.mapType(name), outerName == null ? null
+                : remapper.mapType(outerName), innerName, access);
+    }
+
+    @Override
+    public void visitOuterClass(String owner, String name, String desc) {
+        super.visitOuterClass(remapper.mapType(owner), name == null ? null
+                : remapper.mapMethodName(owner, name, desc),
+                desc == null ? null : remapper.mapMethodDesc(desc));
+    }
+
+    protected FieldVisitor createRemappingFieldAdapter(FieldVisitor fv) {
+        return new RemappingFieldAdapter(fv, remapper);
+    }
+
+    protected MethodVisitor createRemappingMethodAdapter(int access,
+            String newDesc, MethodVisitor mv) {
+        return new RemappingMethodAdapter(access, newDesc, mv, remapper);
+    }
+
+    protected AnnotationVisitor createRemappingAnnotationAdapter(
+            AnnotationVisitor av) {
+        return new RemappingAnnotationAdapter(av, remapper);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingFieldAdapter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingFieldAdapter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingFieldAdapter.java
new file mode 100644
index 0000000..8a8420d
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingFieldAdapter.java
@@ -0,0 +1,71 @@
+/***
+ * 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.commons;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.TypePath;
+
+/**
+ * A {@link FieldVisitor} adapter for type remapping.
+ * 
+ * @author Eugene Kuleshov
+ */
+public class RemappingFieldAdapter extends FieldVisitor {
+
+    private final Remapper remapper;
+
+    public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper) {
+        this(Opcodes.ASM5, fv, remapper);
+    }
+
+    protected RemappingFieldAdapter(final int api, final FieldVisitor fv,
+            final Remapper remapper) {
+        super(api, fv);
+        this.remapper = remapper;
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+        AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc),
+                visible);
+        return av == null ? null : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? null : new RemappingAnnotationAdapter(av, remapper);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingMethodAdapter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingMethodAdapter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingMethodAdapter.java
new file mode 100644
index 0000000..1dec924
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingMethodAdapter.java
@@ -0,0 +1,224 @@
+/***
+ * 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.commons;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Handle;
+import org.apache.tapestry5.internal.plastic.asm.Label;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.TypePath;
+
+/**
+ * A {@link LocalVariablesSorter} for type mapping.
+ * 
+ * @author Eugene Kuleshov
+ */
+public class RemappingMethodAdapter extends LocalVariablesSorter {
+
+    protected final Remapper remapper;
+
+    public RemappingMethodAdapter(final int access, final String desc,
+            final MethodVisitor mv, final Remapper remapper) {
+        this(Opcodes.ASM5, access, desc, mv, remapper);
+    }
+
+    protected RemappingMethodAdapter(final int api, final int access,
+            final String desc, final MethodVisitor mv, final Remapper remapper) {
+        super(api, access, desc, mv);
+        this.remapper = remapper;
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotationDefault() {
+        AnnotationVisitor av = super.visitAnnotationDefault();
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+        AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
+                visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public AnnotationVisitor visitTypeAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public AnnotationVisitor visitParameterAnnotation(int parameter,
+            String desc, boolean visible) {
+        AnnotationVisitor av = super.visitParameterAnnotation(parameter,
+                remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+            Object[] stack) {
+        super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack,
+                remapEntries(nStack, stack));
+    }
+
+    private Object[] remapEntries(int n, Object[] entries) {
+        for (int i = 0; i < n; i++) {
+            if (entries[i] instanceof String) {
+                Object[] newEntries = new Object[n];
+                if (i > 0) {
+                    System.arraycopy(entries, 0, newEntries, 0, i);
+                }
+                do {
+                    Object t = entries[i];
+                    newEntries[i++] = t instanceof String ? remapper
+                            .mapType((String) t) : t;
+                } while (i < n);
+                return newEntries;
+            }
+        }
+        return entries;
+    }
+
+    @Override
+    public void visitFieldInsn(int opcode, String owner, String name,
+            String desc) {
+        super.visitFieldInsn(opcode, remapper.mapType(owner),
+                remapper.mapFieldName(owner, name, desc),
+                remapper.mapDesc(desc));
+    }
+
+    @Deprecated
+    @Override
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc) {
+        if (api >= Opcodes.ASM5) {
+            super.visitMethodInsn(opcode, owner, name, desc);
+            return;
+        }
+        doVisitMethodInsn(opcode, owner, name, desc,
+                opcode == Opcodes.INVOKEINTERFACE);
+    }
+
+    @Override
+    public void visitMethodInsn(final int opcode, final String owner,
+            final String name, final String desc, final boolean itf) {
+        if (api < Opcodes.ASM5) {
+            super.visitMethodInsn(opcode, owner, name, desc, itf);
+            return;
+        }
+        doVisitMethodInsn(opcode, owner, name, desc, itf);
+    }
+
+    private void doVisitMethodInsn(int opcode, String owner, String name,
+            String desc, boolean itf) {
+        // Calling super.visitMethodInsn requires to call the correct version
+        // depending on this.api (otherwise infinite loops can occur). To
+        // simplify and to make it easier to automatically remove the backward
+        // compatibility code, we inline the code of the overridden method here.
+        // IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN
+        // LocalVariableSorter.
+        if (mv != null) {
+            mv.visitMethodInsn(opcode, remapper.mapType(owner),
+                    remapper.mapMethodName(owner, name, desc),
+                    remapper.mapMethodDesc(desc), itf);
+        }
+    }
+
+    @Override
+    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+            Object... bsmArgs) {
+        for (int i = 0; i < bsmArgs.length; i++) {
+            bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
+        }
+        super.visitInvokeDynamicInsn(
+                remapper.mapInvokeDynamicMethodName(name, desc),
+                remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm),
+                bsmArgs);
+    }
+
+    @Override
+    public void visitTypeInsn(int opcode, String type) {
+        super.visitTypeInsn(opcode, remapper.mapType(type));
+    }
+
+    @Override
+    public void visitLdcInsn(Object cst) {
+        super.visitLdcInsn(remapper.mapValue(cst));
+    }
+
+    @Override
+    public void visitMultiANewArrayInsn(String desc, int dims) {
+        super.visitMultiANewArrayInsn(remapper.mapDesc(desc), dims);
+    }
+
+    @Override
+    public AnnotationVisitor visitInsnAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitInsnAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public void visitTryCatchBlock(Label start, Label end, Label handler,
+            String type) {
+        super.visitTryCatchBlock(start, end, handler, type == null ? null
+                : remapper.mapType(type));
+    }
+
+    @Override
+    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+            TypePath typePath, String desc, boolean visible) {
+        AnnotationVisitor av = super.visitTryCatchAnnotation(typeRef, typePath,
+                remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+
+    @Override
+    public void visitLocalVariable(String name, String desc, String signature,
+            Label start, Label end, int index) {
+        super.visitLocalVariable(name, remapper.mapDesc(desc),
+                remapper.mapSignature(signature, true), start, end, index);
+    }
+
+    @Override
+    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+            TypePath typePath, Label[] start, Label[] end, int[] index,
+            String desc, boolean visible) {
+        AnnotationVisitor av = super.visitLocalVariableAnnotation(typeRef,
+                typePath, start, end, index, remapper.mapDesc(desc), visible);
+        return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingSignatureAdapter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingSignatureAdapter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingSignatureAdapter.java
new file mode 100644
index 0000000..ff608a4
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/RemappingSignatureAdapter.java
@@ -0,0 +1,155 @@
+/***
+ * 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.commons;
+
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.signature.SignatureVisitor;
+
+/**
+ * A {@link SignatureVisitor} adapter for type mapping.
+ * 
+ * @author Eugene Kuleshov
+ */
+public class RemappingSignatureAdapter extends SignatureVisitor {
+
+    private final SignatureVisitor v;
+
+    private final Remapper remapper;
+
+    private String className;
+
+    public RemappingSignatureAdapter(final SignatureVisitor v,
+            final Remapper remapper) {
+        this(Opcodes.ASM5, v, remapper);
+    }
+
+    protected RemappingSignatureAdapter(final int api,
+            final SignatureVisitor v, final Remapper remapper) {
+        super(api);
+        this.v = v;
+        this.remapper = remapper;
+    }
+
+    @Override
+    public void visitClassType(String name) {
+        className = name;
+        v.visitClassType(remapper.mapType(name));
+    }
+
+    @Override
+    public void visitInnerClassType(String name) {
+        String remappedOuter = remapper.mapType(className) + '$';
+        className = className + '$' + name;
+        String remappedName = remapper.mapType(className);
+        int index = remappedName.startsWith(remappedOuter) ? remappedOuter
+                .length() : remappedName.lastIndexOf('$') + 1;
+        v.visitInnerClassType(remappedName.substring(index));
+    }
+
+    @Override
+    public void visitFormalTypeParameter(String name) {
+        v.visitFormalTypeParameter(name);
+    }
+
+    @Override
+    public void visitTypeVariable(String name) {
+        v.visitTypeVariable(name);
+    }
+
+    @Override
+    public SignatureVisitor visitArrayType() {
+        v.visitArrayType();
+        return this;
+    }
+
+    @Override
+    public void visitBaseType(char descriptor) {
+        v.visitBaseType(descriptor);
+    }
+
+    @Override
+    public SignatureVisitor visitClassBound() {
+        v.visitClassBound();
+        return this;
+    }
+
+    @Override
+    public SignatureVisitor visitExceptionType() {
+        v.visitExceptionType();
+        return this;
+    }
+
+    @Override
+    public SignatureVisitor visitInterface() {
+        v.visitInterface();
+        return this;
+    }
+
+    @Override
+    public SignatureVisitor visitInterfaceBound() {
+        v.visitInterfaceBound();
+        return this;
+    }
+
+    @Override
+    public SignatureVisitor visitParameterType() {
+        v.visitParameterType();
+        return this;
+    }
+
+    @Override
+    public SignatureVisitor visitReturnType() {
+        v.visitReturnType();
+        return this;
+    }
+
+    @Override
+    public SignatureVisitor visitSuperclass() {
+        v.visitSuperclass();
+        return this;
+    }
+
+    @Override
+    public void visitTypeArgument() {
+        v.visitTypeArgument();
+    }
+
+    @Override
+    public SignatureVisitor visitTypeArgument(char wildcard) {
+        v.visitTypeArgument(wildcard);
+        return this;
+    }
+
+    @Override
+    public void visitEnd() {
+        v.visitEnd();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java
new file mode 100644
index 0000000..04dcc9b
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java
@@ -0,0 +1,540 @@
+/***
+ * 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.commons;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
+import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+
+/**
+ * A {@link ClassVisitor} that adds a serial version unique identifier to a
+ * class if missing. Here is typical usage of this class:
+ * 
+ * <pre>
+ *   ClassWriter cw = new ClassWriter(...);
+ *   ClassVisitor sv = new SerialVersionUIDAdder(cw);
+ *   ClassVisitor ca = new MyClassAdapter(sv);
+ *   new ClassReader(orginalClass).accept(ca, false);
+ * </pre>
+ * 
+ * The SVUID algorithm can be found <a href=
+ * "http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html"
+ * >http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html</a>:
+ * 
+ * <pre>
+ * The serialVersionUID is computed using the signature of a stream of bytes
+ * that reflect the class definition. The National Institute of Standards and
+ * Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a
+ * signature for the stream. The first two 32-bit quantities are used to form a
+ * 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data
+ * types to a sequence of bytes. The values input to the stream are defined by
+ * the Java Virtual Machine (VM) specification for classes.
+ * 
+ * The sequence of items in the stream is as follows:
+ * 
+ * 1. The class name written using UTF encoding.
+ * 2. The class modifiers written as a 32-bit integer.
+ * 3. The name of each interface sorted by name written using UTF encoding.
+ * 4. For each field of the class sorted by field name (except private static
+ * and private transient fields):
+ * 1. The name of the field in UTF encoding.
+ * 2. The modifiers of the field written as a 32-bit integer.
+ * 3. The descriptor of the field in UTF encoding
+ * 5. If a class initializer exists, write out the following:
+ * 1. The name of the method, &lt;clinit&gt;, in UTF encoding.
+ * 2. The modifier of the method, java.lang.reflect.Modifier.STATIC,
+ * written as a 32-bit integer.
+ * 3. The descriptor of the method, ()V, in UTF encoding.
+ * 6. For each non-private constructor sorted by method name and signature:
+ * 1. The name of the method, &lt;init&gt;, in UTF encoding.
+ * 2. The modifiers of the method written as a 32-bit integer.
+ * 3. The descriptor of the method in UTF encoding.
+ * 7. For each non-private method sorted by method name and signature:
+ * 1. The name of the method in UTF encoding.
+ * 2. The modifiers of the method written as a 32-bit integer.
+ * 3. The descriptor of the method in UTF encoding.
+ * 8. The SHA-1 algorithm is executed on the stream of bytes produced by
+ * DataOutputStream and produces five 32-bit values sha[0..4].
+ * 
+ * 9. The hash value is assembled from the first and second 32-bit values of
+ * the SHA-1 message digest. If the result of the message digest, the five
+ * 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named
+ * sha, the hash value would be computed as follows:
+ * 
+ * long hash = ((sha[0] &gt;&gt;&gt; 24) &amp; 0xFF) |
+ * ((sha[0] &gt;&gt;&gt; 16) &amp; 0xFF) &lt;&lt; 8 |
+ * ((sha[0] &gt;&gt;&gt; 8) &amp; 0xFF) &lt;&lt; 16 |
+ * ((sha[0] &gt;&gt;&gt; 0) &amp; 0xFF) &lt;&lt; 24 |
+ * ((sha[1] &gt;&gt;&gt; 24) &amp; 0xFF) &lt;&lt; 32 |
+ * ((sha[1] &gt;&gt;&gt; 16) &amp; 0xFF) &lt;&lt; 40 |
+ * ((sha[1] &gt;&gt;&gt; 8) &amp; 0xFF) &lt;&lt; 48 |
+ * ((sha[1] &gt;&gt;&gt; 0) &amp; 0xFF) &lt;&lt; 56;
+ * </pre>
+ * 
+ * @author Rajendra Inamdar, Vishal Vishnoi
+ */
+public class SerialVersionUIDAdder extends ClassVisitor {
+
+    /**
+     * Flag that indicates if we need to compute SVUID.
+     */
+    private boolean computeSVUID;
+
+    /**
+     * Set to true if the class already has SVUID.
+     */
+    private boolean hasSVUID;
+
+    /**
+     * Classes access flags.
+     */
+    private int access;
+
+    /**
+     * Internal name of the class
+     */
+    private String name;
+
+    /**
+     * Interfaces implemented by the class.
+     */
+    private String[] interfaces;
+
+    /**
+     * Collection of fields. (except private static and private transient
+     * fields)
+     */
+    private Collection<Item> svuidFields;
+
+    /**
+     * Set to true if the class has static initializer.
+     */
+    private boolean hasStaticInitializer;
+
+    /**
+     * Collection of non-private constructors.
+     */
+    private Collection<Item> svuidConstructors;
+
+    /**
+     * Collection of non-private methods.
+     */
+    private Collection<Item> svuidMethods;
+
+    /**
+     * Creates a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use
+     * this constructor</i>. Instead, they must use the
+     * {@link #SerialVersionUIDAdder(int, ClassVisitor)} version.
+     * 
+     * @param cv
+     *            a {@link ClassVisitor} to which this visitor will delegate
+     *            calls.
+     * @throws IllegalStateException
+     *             If a subclass calls this constructor.
+     */
+    public SerialVersionUIDAdder(final ClassVisitor cv) {
+        this(Opcodes.ASM5, cv);
+        if (getClass() != SerialVersionUIDAdder.class) {
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Creates a new {@link SerialVersionUIDAdder}.
+     * 
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be one
+     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * @param cv
+     *            a {@link ClassVisitor} to which this visitor will delegate
+     *            calls.
+     */
+    protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) {
+        super(api, cv);
+        svuidFields = new ArrayList<Item>();
+        svuidConstructors = new ArrayList<Item>();
+        svuidMethods = new ArrayList<Item>();
+    }
+
+    // ------------------------------------------------------------------------
+    // Overridden methods
+    // ------------------------------------------------------------------------
+
+    /*
+     * Visit class header and get class name, access , and interfaces
+     * information (step 1,2, and 3) for SVUID computation.
+     */
+    @Override
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
+        computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;
+
+        if (computeSVUID) {
+            this.name = name;
+            this.access = access;
+            this.interfaces = new String[interfaces.length];
+            System.arraycopy(interfaces, 0, this.interfaces, 0,
+                    interfaces.length);
+        }
+
+        super.visit(version, access, name, signature, superName, interfaces);
+    }
+
+    /*
+     * Visit the methods and get constructor and method information (step 5 and
+     * 7). Also determine if there is a class initializer (step 6).
+     */
+    @Override
+    public MethodVisitor visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
+        if (computeSVUID) {
+            if ("<clinit>".equals(name)) {
+                hasStaticInitializer = true;
+            }
+            /*
+             * Remembers non private constructors and methods for SVUID
+             * computation For constructor and method modifiers, only the
+             * ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
+             * ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags
+             * are used.
+             */
+            int mods = access
+                    & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
+                            | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
+                            | Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED
+                            | Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT);
+
+            // all non private methods
+            if ((access & Opcodes.ACC_PRIVATE) == 0) {
+                if ("<init>".equals(name)) {
+                    svuidConstructors.add(new Item(name, mods, desc));
+                } else if (!"<clinit>".equals(name)) {
+                    svuidMethods.add(new Item(name, mods, desc));
+                }
+            }
+        }
+
+        return super.visitMethod(access, name, desc, signature, exceptions);
+    }
+
+    /*
+     * Gets class field information for step 4 of the algorithm. Also determines
+     * if the class already has a SVUID.
+     */
+    @Override
+    public FieldVisitor visitField(final int access, final String name,
+            final String desc, final String signature, final Object value) {
+        if (computeSVUID) {
+            if ("serialVersionUID".equals(name)) {
+                // since the class already has SVUID, we won't be computing it.
+                computeSVUID = false;
+                hasSVUID = true;
+            }
+            /*
+             * Remember field for SVUID computation For field modifiers, only
+             * the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC,
+             * ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when
+             * computing serialVersionUID values.
+             */
+            if ((access & Opcodes.ACC_PRIVATE) == 0
+                    || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) {
+                int mods = access
+                        & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
+                                | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
+                                | Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT);
+                svuidFields.add(new Item(name, mods, desc));
+            }
+        }
+
+        return super.visitField(access, name, desc, signature, value);
+    }
+
+    /**
+     * Handle a bizarre special case. Nested classes (static classes declared
+     * inside another class) that are protected have their access bit set to
+     * public in their class files to deal with some odd reflection situation.
+     * Our SVUID computation must do as the JVM does and ignore access bits in
+     * the class file in favor of the access bits InnerClass attribute.
+     */
+    @Override
+    public void visitInnerClass(final String aname, final String outerName,
+            final String innerName, final int attr_access) {
+        if ((name != null) && name.equals(aname)) {
+            this.access = attr_access;
+        }
+        super.visitInnerClass(aname, outerName, innerName, attr_access);
+    }
+
+    /*
+     * Add the SVUID if class doesn't have one
+     */
+    @Override
+    public void visitEnd() {
+        // compute SVUID and add it to the class
+        if (computeSVUID && !hasSVUID) {
+            try {
+                addSVUID(computeSVUID());
+            } catch (Throwable e) {
+                throw new RuntimeException("Error while computing SVUID for "
+                        + name, e);
+            }
+        }
+
+        super.visitEnd();
+    }
+
+    // ------------------------------------------------------------------------
+    // Utility methods
+    // ------------------------------------------------------------------------
+
+    /**
+     * Returns true if the class already has a SVUID field. The result of this
+     * method is only valid when visitEnd is or has been called.
+     * 
+     * @return true if the class already has a SVUID field.
+     */
+    public boolean hasSVUID() {
+        return hasSVUID;
+    }
+
+    protected void addSVUID(long svuid) {
+        FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL
+                + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, new Long(
+                svuid));
+        if (fv != null) {
+            fv.visitEnd();
+        }
+    }
+
+    /**
+     * Computes and returns the value of SVUID.
+     * 
+     * @return Returns the serial version UID
+     * @throws IOException
+     *             if an I/O error occurs
+     */
+    protected long computeSVUID() throws IOException {
+        ByteArrayOutputStream bos;
+        DataOutputStream dos = null;
+        long svuid = 0;
+
+        try {
+            bos = new ByteArrayOutputStream();
+            dos = new DataOutputStream(bos);
+
+            /*
+             * 1. The class name written using UTF encoding.
+             */
+            dos.writeUTF(name.replace('/', '.'));
+
+            /*
+             * 2. The class modifiers written as a 32-bit integer.
+             */
+            dos.writeInt(access
+                    & (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL
+                            | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT));
+
+            /*
+             * 3. The name of each interface sorted by name written using UTF
+             * encoding.
+             */
+            Arrays.sort(interfaces);
+            for (int i = 0; i < interfaces.length; i++) {
+                dos.writeUTF(interfaces[i].replace('/', '.'));
+            }
+
+            /*
+             * 4. For each field of the class sorted by field name (except
+             * private static and private transient fields):
+             * 
+             * 1. The name of the field in UTF encoding. 2. The modifiers of the
+             * field written as a 32-bit integer. 3. The descriptor of the field
+             * in UTF encoding
+             * 
+             * Note that field signatures are not dot separated. Method and
+             * constructor signatures are dot separated. Go figure...
+             */
+            writeItems(svuidFields, dos, false);
+
+            /*
+             * 5. If a class initializer exists, write out the following: 1. The
+             * name of the method, <clinit>, in UTF encoding. 2. The modifier of
+             * the method, java.lang.reflect.Modifier.STATIC, written as a
+             * 32-bit integer. 3. The descriptor of the method, ()V, in UTF
+             * encoding.
+             */
+            if (hasStaticInitializer) {
+                dos.writeUTF("<clinit>");
+                dos.writeInt(Opcodes.ACC_STATIC);
+                dos.writeUTF("()V");
+            } // if..
+
+            /*
+             * 6. For each non-private constructor sorted by method name and
+             * signature: 1. The name of the method, <init>, in UTF encoding. 2.
+             * The modifiers of the method written as a 32-bit integer. 3. The
+             * descriptor of the method in UTF encoding.
+             */
+            writeItems(svuidConstructors, dos, true);
+
+            /*
+             * 7. For each non-private method sorted by method name and
+             * signature: 1. The name of the method in UTF encoding. 2. The
+             * modifiers of the method written as a 32-bit integer. 3. The
+             * descriptor of the method in UTF encoding.
+             */
+            writeItems(svuidMethods, dos, true);
+
+            dos.flush();
+
+            /*
+             * 8. The SHA-1 algorithm is executed on the stream of bytes
+             * produced by DataOutputStream and produces five 32-bit values
+             * sha[0..4].
+             */
+            byte[] hashBytes = computeSHAdigest(bos.toByteArray());
+
+            /*
+             * 9. The hash value is assembled from the first and second 32-bit
+             * values of the SHA-1 message digest. If the result of the message
+             * digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of
+             * five int values named sha, the hash value would be computed as
+             * follows:
+             * 
+             * long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF)
+             * << 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) <<
+             * 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) & 0xFF) <<
+             * 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & 0xFF) <<
+             * 56;
+             */
+            for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
+                svuid = (svuid << 8) | (hashBytes[i] & 0xFF);
+            }
+        } finally {
+            // close the stream (if open)
+            if (dos != null) {
+                dos.close();
+            }
+        }
+
+        return svuid;
+    }
+
+    /**
+     * Returns the SHA-1 message digest of the given value.
+     * 
+     * @param value
+     *            the value whose SHA message digest must be computed.
+     * @return the SHA-1 message digest of the given value.
+     */
+    protected byte[] computeSHAdigest(final byte[] value) {
+        try {
+            return MessageDigest.getInstance("SHA").digest(value);
+        } catch (Exception e) {
+            throw new UnsupportedOperationException(e.toString());
+        }
+    }
+
+    /**
+     * Sorts the items in the collection and writes it to the data output stream
+     * 
+     * @param itemCollection
+     *            collection of items
+     * @param dos
+     *            a <code>DataOutputStream</code> value
+     * @param dotted
+     *            a <code>boolean</code> value
+     * @exception IOException
+     *                if an error occurs
+     */
+    private static void writeItems(final Collection<Item> itemCollection,
+            final DataOutput dos, final boolean dotted) throws IOException {
+        int size = itemCollection.size();
+        Item[] items = itemCollection.toArray(new Item[size]);
+        Arrays.sort(items);
+        for (int i = 0; i < size; i++) {
+            dos.writeUTF(items[i].name);
+            dos.writeInt(items[i].access);
+            dos.writeUTF(dotted ? items[i].desc.replace('/', '.')
+                    : items[i].desc);
+        }
+    }
+
+    // ------------------------------------------------------------------------
+    // Inner classes
+    // ------------------------------------------------------------------------
+
+    private static class Item implements Comparable<Item> {
+
+        final String name;
+
+        final int access;
+
+        final String desc;
+
+        Item(final String name, final int access, final String desc) {
+            this.name = name;
+            this.access = access;
+            this.desc = desc;
+        }
+
+        public int compareTo(final Item other) {
+            int retVal = name.compareTo(other.name);
+            if (retVal == 0) {
+                retVal = desc.compareTo(other.desc);
+            }
+            return retVal;
+        }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (o instanceof Item) {
+                return compareTo((Item) o) == 0;
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return (name + desc).hashCode();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java
new file mode 100644
index 0000000..25b594d
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java
@@ -0,0 +1,69 @@
+/***
+ * 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.commons;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * A {@link Remapper} using a {@link Map} to define its mapping.
+ * 
+ * @author Eugene Kuleshov
+ */
+public class SimpleRemapper extends Remapper {
+
+    private final Map<String, String> mapping;
+
+    public SimpleRemapper(Map<String, String> mapping) {
+        this.mapping = mapping;
+    }
+
+    public SimpleRemapper(String oldName, String newName) {
+        this.mapping = Collections.singletonMap(oldName, newName);
+    }
+
+    @Override
+    public String mapMethodName(String owner, String name, String desc) {
+        String s = map(owner + '.' + name + desc);
+        return s == null ? name : s;
+    }
+
+    @Override
+    public String mapFieldName(String owner, String name, String desc) {
+        String s = map(owner + '.' + name);
+        return s == null ? name : s;
+    }
+
+    @Override
+    public String map(String key) {
+        return mapping.get(key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java
new file mode 100644
index 0000000..8291c66
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java
@@ -0,0 +1,97 @@
+/***
+ * 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.commons;
+
+import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+
+/**
+ * A {@link ClassVisitor} that merges clinit methods into a single one.
+ * 
+ * @author Eric Bruneton
+ */
+public class StaticInitMerger extends ClassVisitor {
+
+    private String name;
+
+    private MethodVisitor clinit;
+
+    private final String prefix;
+
+    private int counter;
+
+    public StaticInitMerger(final String prefix, final ClassVisitor cv) {
+        this(Opcodes.ASM5, prefix, cv);
+    }
+
+    protected StaticInitMerger(final int api, final String prefix,
+            final ClassVisitor cv) {
+        super(api, cv);
+        this.prefix = prefix;
+    }
+
+    @Override
+    public void visit(final int version, final int access, final String name,
+            final String signature, final String superName,
+            final String[] interfaces) {
+        cv.visit(version, access, name, signature, superName, interfaces);
+        this.name = name;
+    }
+
+    @Override
+    public MethodVisitor visitMethod(final int access, final String name,
+            final String desc, final String signature, final String[] exceptions) {
+        MethodVisitor mv;
+        if ("<clinit>".equals(name)) {
+            int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;
+            String n = prefix + counter++;
+            mv = cv.visitMethod(a, n, desc, signature, exceptions);
+
+            if (clinit == null) {
+                clinit = cv.visitMethod(a, name, desc, null, null);
+            }
+            clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc,
+                    false);
+        } else {
+            mv = cv.visitMethod(access, name, desc, signature, exceptions);
+        }
+        return mv;
+    }
+
+    @Override
+    public void visitEnd() {
+        if (clinit != null) {
+            clinit.visitInsn(Opcodes.RETURN);
+            clinit.visitMaxs(0, 0);
+        }
+        cv.visitEnd();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java
new file mode 100644
index 0000000..322d7bb
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java
@@ -0,0 +1,57 @@
+/***
+ * 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.commons;
+
+import org.apache.tapestry5.internal.plastic.asm.Label;
+
+/**
+ * A code generator for switch statements.
+ * 
+ * @author Juozas Baliuka
+ * @author Chris Nokleberg
+ * @author Eric Bruneton
+ */
+public interface TableSwitchGenerator {
+
+    /**
+     * Generates the code for a switch case.
+     * 
+     * @param key
+     *            the switch case key.
+     * @param end
+     *            a label that corresponds to the end of the switch statement.
+     */
+    void generateCase(int key, Label end);
+
+    /**
+     * Generates the code for the default switch case.
+     */
+    void generateDefault();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java
new file mode 100644
index 0000000..4b4641a
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java
@@ -0,0 +1,96 @@
+/***
+ * 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.commons;
+
+import java.util.Collections;
+import java.util.Comparator;
+
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.tree.MethodNode;
+import org.apache.tapestry5.internal.plastic.asm.tree.TryCatchBlockNode;
+
+/**
+ * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers
+ * are sorted in a method innermost-to-outermost. This allows the programmer to
+ * add handlers without worrying about ordering them correctly with respect to
+ * existing, in-code handlers.
+ * 
+ * Behavior is only defined for properly-nested handlers. If any "try" blocks
+ * overlap (something that isn't possible in Java code) then this may not do
+ * what you want. In fact, this adapter just sorts by the length of the "try"
+ * block, taking advantage of the fact that a given try block must be larger
+ * than any block it contains).
+ * 
+ * @author Adrian Sampson
+ */
+public class TryCatchBlockSorter extends MethodNode {
+
+    public TryCatchBlockSorter(final MethodVisitor mv, final int access,
+            final String name, final String desc, final String signature,
+            final String[] exceptions) {
+        this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+    }
+
+    protected TryCatchBlockSorter(final int api, final MethodVisitor mv,
+            final int access, final String name, final String desc,
+            final String signature, final String[] exceptions) {
+        super(api, access, name, desc, signature, exceptions);
+        this.mv = mv;
+    }
+
+    @Override
+    public void visitEnd() {
+        // Compares TryCatchBlockNodes by the length of their "try" block.
+        Comparator<TryCatchBlockNode> comp = new Comparator<TryCatchBlockNode>() {
+
+            public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) {
+                int len1 = blockLength(t1);
+                int len2 = blockLength(t2);
+                return len1 - len2;
+            }
+
+            private int blockLength(TryCatchBlockNode block) {
+                int startidx = instructions.indexOf(block.start);
+                int endidx = instructions.indexOf(block.end);
+                return endidx - startidx;
+            }
+        };
+        Collections.sort(tryCatchBlocks, comp);
+        // Updates the 'target' of each try catch block annotation.
+        for (int i = 0; i < tryCatchBlocks.size(); ++i) {
+            tryCatchBlocks.get(i).updateIndex(i);
+        }
+        if (mv != null) {
+            accept(mv);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/package.html
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/package.html b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/package.html
new file mode 100644
index 0000000..4ce0db8
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/package.html
@@ -0,0 +1,48 @@
+<html>
+<!--
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<body>
+Provides some useful class and method adapters. <i>The preferred way of using
+these adapters is by chaining them together and to custom adapters (instead of
+inheriting from them)</i>. Indeed this approach provides more combination
+possibilities than inheritance. For instance, suppose you want to implement an
+adapter MyAdapter than needs sorted local variables and intermediate stack map
+frame values taking into account the local variables sort. By using inheritance,
+this would require MyAdapter to extend AnalyzerAdapter, itself extending
+LocalVariablesSorter. But AnalyzerAdapter is not a subclass of
+LocalVariablesSorter, so this is not possible. On the contrary, by using
+delegation, you can make LocalVariablesSorter delegate to AnalyzerAdapter,
+itself delegating to MyAdapter. In this case AnalyzerAdapter computes
+intermediate frames based on the output of LocalVariablesSorter, and MyAdapter
+can add new locals by calling the newLocal method on LocalVariablesSorter, and
+can get the stack map frame state before each instruction by reading the locals
+and stack fields in AnalyzerAdapter (this requires references from MyAdapter
+back to LocalVariablesSorter and AnalyzerAdapter).
+</body>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/AnnotationConstantsCollector.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/AnnotationConstantsCollector.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/AnnotationConstantsCollector.java
new file mode 100644
index 0000000..84aff49
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/AnnotationConstantsCollector.java
@@ -0,0 +1,147 @@
+/***
+ * 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.optimizer;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.Type;
+
+/**
+ * An {@link AnnotationVisitor} that collects the {@link Constant}s of the
+ * annotations it visits.
+ * 
+ * @author Eric Bruneton
+ */
+public class AnnotationConstantsCollector extends AnnotationVisitor {
+
+    private final ConstantPool cp;
+
+    public AnnotationConstantsCollector(final AnnotationVisitor av,
+            final ConstantPool cp) {
+        super(Opcodes.ASM5, av);
+        this.cp = cp;
+    }
+
+    @Override
+    public void visit(final String name, final Object value) {
+        if (name != null) {
+            cp.newUTF8(name);
+        }
+        if (value instanceof Byte) {
+            cp.newInteger(((Byte) value).byteValue());
+        } else if (value instanceof Boolean) {
+            cp.newInteger(((Boolean) value).booleanValue() ? 1 : 0);
+        } else if (value instanceof Character) {
+            cp.newInteger(((Character) value).charValue());
+        } else if (value instanceof Short) {
+            cp.newInteger(((Short) value).shortValue());
+        } else if (value instanceof Type) {
+            cp.newUTF8(((Type) value).getDescriptor());
+        } else if (value instanceof byte[]) {
+            byte[] v = (byte[]) value;
+            for (int i = 0; i < v.length; i++) {
+                cp.newInteger(v[i]);
+            }
+        } else if (value instanceof boolean[]) {
+            boolean[] v = (boolean[]) value;
+            for (int i = 0; i < v.length; i++) {
+                cp.newInteger(v[i] ? 1 : 0);
+            }
+        } else if (value instanceof short[]) {
+            short[] v = (short[]) value;
+            for (int i = 0; i < v.length; i++) {
+                cp.newInteger(v[i]);
+            }
+        } else if (value instanceof char[]) {
+            char[] v = (char[]) value;
+            for (int i = 0; i < v.length; i++) {
+                cp.newInteger(v[i]);
+            }
+        } else if (value instanceof int[]) {
+            int[] v = (int[]) value;
+            for (int i = 0; i < v.length; i++) {
+                cp.newInteger(v[i]);
+            }
+        } else if (value instanceof long[]) {
+            long[] v = (long[]) value;
+            for (int i = 0; i < v.length; i++) {
+                cp.newLong(v[i]);
+            }
+        } else if (value instanceof float[]) {
+            float[] v = (float[]) value;
+            for (int i = 0; i < v.length; i++) {
+                cp.newFloat(v[i]);
+            }
+        } else if (value instanceof double[]) {
+            double[] v = (double[]) value;
+            for (int i = 0; i < v.length; i++) {
+                cp.newDouble(v[i]);
+            }
+        } else {
+            cp.newConst(value);
+        }
+        av.visit(name, value);
+    }
+
+    @Override
+    public void visitEnum(final String name, final String desc,
+            final String value) {
+        if (name != null) {
+            cp.newUTF8(name);
+        }
+        cp.newUTF8(desc);
+        cp.newUTF8(value);
+        av.visitEnum(name, desc, value);
+    }
+
+    @Override
+    public AnnotationVisitor visitAnnotation(final String name,
+            final String desc) {
+        if (name != null) {
+            cp.newUTF8(name);
+        }
+        cp.newUTF8(desc);
+        return new AnnotationConstantsCollector(av.visitAnnotation(name, desc),
+                cp);
+    }
+
+    @Override
+    public AnnotationVisitor visitArray(final String name) {
+        if (name != null) {
+            cp.newUTF8(name);
+        }
+        return new AnnotationConstantsCollector(av.visitArray(name), cp);
+    }
+
+    @Override
+    public void visitEnd() {
+        av.visitEnd();
+    }
+}