diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a197e7f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+/mvel-2.0.19.tar.xz
+/mvel2-2.0.19.tar.gz
+/mvel2-2.1.6.Final.tar.gz
+/mvel2-2.2.2.Final.tar.gz
+/mvel2-2.2.6.Final.tar.gz
+/mvel2-2.2.7.Final.tar.gz
+/mvel2-2.2.8.Final.tar.gz
diff --git a/dead.package b/dead.package
deleted file mode 100644
index 5204a84..0000000
--- a/dead.package
+++ /dev/null
@@ -1 +0,0 @@
-Orphaned for 6+ weeks
diff --git a/mvel-2.2.7.Final-use-system-asm.patch b/mvel-2.2.7.Final-use-system-asm.patch
new file mode 100644
index 0000000..70868d5
--- /dev/null
+++ b/mvel-2.2.7.Final-use-system-asm.patch
@@ -0,0 +1,44472 @@
+diff -Nru mvel-mvel2-2.2.7.Final/pom.xml mvel-mvel2-2.2.7.Final.asm/pom.xml
+--- mvel-mvel2-2.2.7.Final/pom.xml 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/pom.xml 2016-02-11 17:13:55.485582031 +0100
+@@ -267,6 +267,17 @@
+ test
+
+
++
++ org.ow2.asm
++ asm
++ 5.0.4
++
++
++ org.ow2.asm
++ asm-util
++ 5.0.4
++
++
+
+
+
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/AnnotationVisitor.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/AnnotationVisitor.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/AnnotationVisitor.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/AnnotationVisitor.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,169 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A visitor to visit a Java annotation. The methods of this class must be
+- * called in the following order: ( visit | visitEnum |
+- * visitAnnotation | visitArray )* visitEnd .
+- *
+- * @author Eric Bruneton
+- * @author Eugene Kuleshov
+- */
+-public abstract class AnnotationVisitor {
+-
+- /**
+- * The ASM API version implemented by this visitor. The value of this field
+- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- protected final int api;
+-
+- /**
+- * The annotation visitor to which this visitor must delegate method calls.
+- * May be null.
+- */
+- protected AnnotationVisitor av;
+-
+- /**
+- * Constructs a new {@link AnnotationVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- public AnnotationVisitor(final int api) {
+- this(api, null);
+- }
+-
+- /**
+- * Constructs a new {@link AnnotationVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param av
+- * the annotation visitor to which this visitor must delegate
+- * method calls. May be null.
+- */
+- public AnnotationVisitor(final int api, final AnnotationVisitor av) {
+- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+- throw new IllegalArgumentException();
+- }
+- this.api = api;
+- this.av = av;
+- }
+-
+- /**
+- * Visits a primitive value of the annotation.
+- *
+- * @param name
+- * the value name.
+- * @param value
+- * the actual value, whose type must be {@link Byte},
+- * {@link Boolean}, {@link Character}, {@link Short},
+- * {@link Integer} , {@link Long}, {@link Float}, {@link Double},
+- * {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+- * value can also be an array of byte, boolean, short, char, int,
+- * long, float or double values (this is equivalent to using
+- * {@link #visitArray visitArray} and visiting each array element
+- * in turn, but is more convenient).
+- */
+- public void visit(String name, Object value) {
+- if (av != null) {
+- av.visit(name, value);
+- }
+- }
+-
+- /**
+- * Visits an enumeration value of the annotation.
+- *
+- * @param name
+- * the value name.
+- * @param desc
+- * the class descriptor of the enumeration class.
+- * @param value
+- * the actual enumeration value.
+- */
+- public void visitEnum(String name, String desc, String value) {
+- if (av != null) {
+- av.visitEnum(name, desc, value);
+- }
+- }
+-
+- /**
+- * Visits a nested annotation value of the annotation.
+- *
+- * @param name
+- * the value name.
+- * @param desc
+- * the class descriptor of the nested annotation class.
+- * @return a visitor to visit the actual nested annotation value, or
+- * null if this visitor is not interested in visiting this
+- * nested annotation. The nested annotation value must be fully
+- * visited before calling other methods on this annotation
+- * visitor .
+- */
+- public AnnotationVisitor visitAnnotation(String name, String desc) {
+- if (av != null) {
+- return av.visitAnnotation(name, desc);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits an array value of the annotation. Note that arrays of primitive
+- * types (such as byte, boolean, short, char, int, long, float or double)
+- * can be passed as value to {@link #visit visit}. This is what
+- * {@link ClassReader} does.
+- *
+- * @param name
+- * the value name.
+- * @return a visitor to visit the actual array value elements, or
+- * null if this visitor is not interested in visiting these
+- * values. The 'name' parameters passed to the methods of this
+- * visitor are ignored. All the array values must be visited
+- * before calling other methods on this annotation visitor .
+- */
+- public AnnotationVisitor visitArray(String name) {
+- if (av != null) {
+- return av.visitArray(name);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits the end of the annotation.
+- */
+- public void visitEnd() {
+- if (av != null) {
+- av.visitEnd();
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/AnnotationWriter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/AnnotationWriter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/AnnotationWriter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/AnnotationWriter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,371 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * An {@link AnnotationVisitor} that generates annotations in bytecode form.
+- *
+- * @author Eric Bruneton
+- * @author Eugene Kuleshov
+- */
+-final class AnnotationWriter extends AnnotationVisitor {
+-
+- /**
+- * The class writer to which this annotation must be added.
+- */
+- private final ClassWriter cw;
+-
+- /**
+- * The number of values in this annotation.
+- */
+- private int size;
+-
+- /**
+- * true if values are named, false otherwise. Annotation
+- * writers used for annotation default and annotation arrays use unnamed
+- * values.
+- */
+- private final boolean named;
+-
+- /**
+- * The annotation values in bytecode form. This byte vector only contains
+- * the values themselves, i.e. the number of values must be stored as a
+- * unsigned short just before these bytes.
+- */
+- private final ByteVector bv;
+-
+- /**
+- * The byte vector to be used to store the number of values of this
+- * annotation. See {@link #bv}.
+- */
+- private final ByteVector parent;
+-
+- /**
+- * Where the number of values of this annotation must be stored in
+- * {@link #parent}.
+- */
+- private final int offset;
+-
+- /**
+- * Next annotation writer. This field is used to store annotation lists.
+- */
+- AnnotationWriter next;
+-
+- /**
+- * Previous annotation writer. This field is used to store annotation lists.
+- */
+- AnnotationWriter prev;
+-
+- // ------------------------------------------------------------------------
+- // Constructor
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Constructs a new {@link AnnotationWriter}.
+- *
+- * @param cw
+- * the class writer to which this annotation must be added.
+- * @param named
+- * true if values are named, false otherwise.
+- * @param bv
+- * where the annotation values must be stored.
+- * @param parent
+- * where the number of annotation values must be stored.
+- * @param offset
+- * where in parent the number of annotation values must
+- * be stored.
+- */
+- AnnotationWriter(final ClassWriter cw, final boolean named,
+- final ByteVector bv, final ByteVector parent, final int offset) {
+- super(Opcodes.ASM5);
+- this.cw = cw;
+- this.named = named;
+- this.bv = bv;
+- this.parent = parent;
+- this.offset = offset;
+- }
+-
+- // ------------------------------------------------------------------------
+- // Implementation of the AnnotationVisitor abstract class
+- // ------------------------------------------------------------------------
+-
+- @Override
+- public void visit(final String name, final Object value) {
+- ++size;
+- if (named) {
+- bv.putShort(cw.newUTF8(name));
+- }
+- if (value instanceof String) {
+- bv.put12('s', cw.newUTF8((String) value));
+- } else if (value instanceof Byte) {
+- bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
+- } else if (value instanceof Boolean) {
+- int v = ((Boolean) value).booleanValue() ? 1 : 0;
+- bv.put12('Z', cw.newInteger(v).index);
+- } else if (value instanceof Character) {
+- bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
+- } else if (value instanceof Short) {
+- bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
+- } else if (value instanceof Type) {
+- bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
+- } else if (value instanceof byte[]) {
+- byte[] v = (byte[]) value;
+- bv.put12('[', v.length);
+- for (int i = 0; i < v.length; i++) {
+- bv.put12('B', cw.newInteger(v[i]).index);
+- }
+- } else if (value instanceof boolean[]) {
+- boolean[] v = (boolean[]) value;
+- bv.put12('[', v.length);
+- for (int i = 0; i < v.length; i++) {
+- bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
+- }
+- } else if (value instanceof short[]) {
+- short[] v = (short[]) value;
+- bv.put12('[', v.length);
+- for (int i = 0; i < v.length; i++) {
+- bv.put12('S', cw.newInteger(v[i]).index);
+- }
+- } else if (value instanceof char[]) {
+- char[] v = (char[]) value;
+- bv.put12('[', v.length);
+- for (int i = 0; i < v.length; i++) {
+- bv.put12('C', cw.newInteger(v[i]).index);
+- }
+- } else if (value instanceof int[]) {
+- int[] v = (int[]) value;
+- bv.put12('[', v.length);
+- for (int i = 0; i < v.length; i++) {
+- bv.put12('I', cw.newInteger(v[i]).index);
+- }
+- } else if (value instanceof long[]) {
+- long[] v = (long[]) value;
+- bv.put12('[', v.length);
+- for (int i = 0; i < v.length; i++) {
+- bv.put12('J', cw.newLong(v[i]).index);
+- }
+- } else if (value instanceof float[]) {
+- float[] v = (float[]) value;
+- bv.put12('[', v.length);
+- for (int i = 0; i < v.length; i++) {
+- bv.put12('F', cw.newFloat(v[i]).index);
+- }
+- } else if (value instanceof double[]) {
+- double[] v = (double[]) value;
+- bv.put12('[', v.length);
+- for (int i = 0; i < v.length; i++) {
+- bv.put12('D', cw.newDouble(v[i]).index);
+- }
+- } else {
+- Item i = cw.newConstItem(value);
+- bv.put12(".s.IFJDCS".charAt(i.type), i.index);
+- }
+- }
+-
+- @Override
+- public void visitEnum(final String name, final String desc,
+- final String value) {
+- ++size;
+- if (named) {
+- bv.putShort(cw.newUTF8(name));
+- }
+- bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
+- }
+-
+- @Override
+- public AnnotationVisitor visitAnnotation(final String name,
+- final String desc) {
+- ++size;
+- if (named) {
+- bv.putShort(cw.newUTF8(name));
+- }
+- // write tag and type, and reserve space for values count
+- bv.put12('@', cw.newUTF8(desc)).putShort(0);
+- return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
+- }
+-
+- @Override
+- public AnnotationVisitor visitArray(final String name) {
+- ++size;
+- if (named) {
+- bv.putShort(cw.newUTF8(name));
+- }
+- // write tag, and reserve space for array size
+- bv.put12('[', 0);
+- return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
+- }
+-
+- @Override
+- public void visitEnd() {
+- if (parent != null) {
+- byte[] data = parent.data;
+- data[offset] = (byte) (size >>> 8);
+- data[offset + 1] = (byte) size;
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns the size of this annotation writer list.
+- *
+- * @return the size of this annotation writer list.
+- */
+- int getSize() {
+- int size = 0;
+- AnnotationWriter aw = this;
+- while (aw != null) {
+- size += aw.bv.length;
+- aw = aw.next;
+- }
+- return size;
+- }
+-
+- /**
+- * Puts the annotations of this annotation writer list into the given byte
+- * vector.
+- *
+- * @param out
+- * where the annotations must be put.
+- */
+- void put(final ByteVector out) {
+- int n = 0;
+- int size = 2;
+- AnnotationWriter aw = this;
+- AnnotationWriter last = null;
+- while (aw != null) {
+- ++n;
+- size += aw.bv.length;
+- aw.visitEnd(); // in case user forgot to call visitEnd
+- aw.prev = last;
+- last = aw;
+- aw = aw.next;
+- }
+- out.putInt(size);
+- out.putShort(n);
+- aw = last;
+- while (aw != null) {
+- out.putByteArray(aw.bv.data, 0, aw.bv.length);
+- aw = aw.prev;
+- }
+- }
+-
+- /**
+- * Puts the given annotation lists into the given byte vector.
+- *
+- * @param panns
+- * an array of annotation writer lists.
+- * @param off
+- * index of the first annotation to be written.
+- * @param out
+- * where the annotations must be put.
+- */
+- static void put(final AnnotationWriter[] panns, final int off,
+- final ByteVector out) {
+- int size = 1 + 2 * (panns.length - off);
+- for (int i = off; i < panns.length; ++i) {
+- size += panns[i] == null ? 0 : panns[i].getSize();
+- }
+- out.putInt(size).putByte(panns.length - off);
+- for (int i = off; i < panns.length; ++i) {
+- AnnotationWriter aw = panns[i];
+- AnnotationWriter last = null;
+- int n = 0;
+- while (aw != null) {
+- ++n;
+- aw.visitEnd(); // in case user forgot to call visitEnd
+- aw.prev = last;
+- last = aw;
+- aw = aw.next;
+- }
+- out.putShort(n);
+- aw = last;
+- while (aw != null) {
+- out.putByteArray(aw.bv.data, 0, aw.bv.length);
+- aw = aw.prev;
+- }
+- }
+- }
+-
+- /**
+- * Puts the given type reference and type path into the given bytevector.
+- * LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported.
+- *
+- * @param typeRef
+- * a reference to the annotated type. See {@link TypeReference}.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param out
+- * where the type reference and type path must be put.
+- */
+- static void putTarget(int typeRef, TypePath typePath, ByteVector out) {
+- switch (typeRef >>> 24) {
+- case 0x00: // CLASS_TYPE_PARAMETER
+- case 0x01: // METHOD_TYPE_PARAMETER
+- case 0x16: // METHOD_FORMAL_PARAMETER
+- out.putShort(typeRef >>> 16);
+- break;
+- case 0x13: // FIELD
+- case 0x14: // METHOD_RETURN
+- case 0x15: // METHOD_RECEIVER
+- out.putByte(typeRef >>> 24);
+- break;
+- case 0x47: // CAST
+- case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+- case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+- case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+- case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+- out.putInt(typeRef);
+- break;
+- // case 0x10: // CLASS_EXTENDS
+- // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+- // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+- // case 0x17: // THROWS
+- // case 0x42: // EXCEPTION_PARAMETER
+- // case 0x43: // INSTANCEOF
+- // case 0x44: // NEW
+- // case 0x45: // CONSTRUCTOR_REFERENCE
+- // case 0x46: // METHOD_REFERENCE
+- default:
+- out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8);
+- break;
+- }
+- if (typePath == null) {
+- out.putByte(0);
+- } else {
+- int length = typePath.b[typePath.offset] * 2 + 1;
+- out.putByteArray(typePath.b, typePath.offset, length);
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Attribute.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Attribute.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Attribute.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Attribute.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,255 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A non standard class, field, method or code attribute.
+- *
+- * @author Eric Bruneton
+- * @author Eugene Kuleshov
+- */
+-public class Attribute {
+-
+- /**
+- * The type of this attribute.
+- */
+- public final String type;
+-
+- /**
+- * The raw value of this attribute, used only for unknown attributes.
+- */
+- byte[] value;
+-
+- /**
+- * The next attribute in this attribute list. May be null .
+- */
+- Attribute next;
+-
+- /**
+- * Constructs a new empty attribute.
+- *
+- * @param type
+- * the type of the attribute.
+- */
+- protected Attribute(final String type) {
+- this.type = type;
+- }
+-
+- /**
+- * Returns true if this type of attribute is unknown. The default
+- * implementation of this method always returns true .
+- *
+- * @return true if this type of attribute is unknown.
+- */
+- public boolean isUnknown() {
+- return true;
+- }
+-
+- /**
+- * Returns true if this type of attribute is a code attribute.
+- *
+- * @return true if this type of attribute is a code attribute.
+- */
+- public boolean isCodeAttribute() {
+- return false;
+- }
+-
+- /**
+- * Returns the labels corresponding to this attribute.
+- *
+- * @return the labels corresponding to this attribute, or null if
+- * this attribute is not a code attribute that contains labels.
+- */
+- protected Label[] getLabels() {
+- return null;
+- }
+-
+- /**
+- * Reads a {@link #type type} attribute. This method must return a
+- * new {@link Attribute} object, of type {@link #type type},
+- * corresponding to the len bytes starting at the given offset, in
+- * the given class reader.
+- *
+- * @param cr
+- * the class that contains the attribute to be read.
+- * @param off
+- * index of the first byte of the attribute's content in
+- * {@link ClassReader#b cr.b}. The 6 attribute header bytes,
+- * containing the type and the length of the attribute, are not
+- * taken into account here.
+- * @param len
+- * the length of the attribute's content.
+- * @param buf
+- * buffer to be used to call {@link ClassReader#readUTF8
+- * readUTF8}, {@link ClassReader#readClass(int,char[]) readClass}
+- * or {@link ClassReader#readConst readConst}.
+- * @param codeOff
+- * index of the first byte of code's attribute content in
+- * {@link ClassReader#b cr.b}, or -1 if the attribute to be read
+- * is not a code attribute. The 6 attribute header bytes,
+- * containing the type and the length of the attribute, are not
+- * taken into account here.
+- * @param labels
+- * the labels of the method's code, or null if the
+- * attribute to be read is not a code attribute.
+- * @return a new {@link Attribute} object corresponding to the given
+- * bytes.
+- */
+- protected Attribute read(final ClassReader cr, final int off,
+- final int len, final char[] buf, final int codeOff,
+- final Label[] labels) {
+- Attribute attr = new Attribute(type);
+- attr.value = new byte[len];
+- System.arraycopy(cr.b, off, attr.value, 0, len);
+- return attr;
+- }
+-
+- /**
+- * Returns the byte array form of this attribute.
+- *
+- * @param cw
+- * the class to which this attribute must be added. This
+- * parameter can be used to add to the constant pool of this
+- * class the items that corresponds to this attribute.
+- * @param code
+- * the bytecode of the method corresponding to this code
+- * attribute, or null if this attribute is not a code
+- * attributes.
+- * @param len
+- * the length of the bytecode of the method corresponding to this
+- * code attribute, or null if this attribute is not a
+- * code attribute.
+- * @param maxStack
+- * the maximum stack size of the method corresponding to this
+- * code attribute, or -1 if this attribute is not a code
+- * attribute.
+- * @param maxLocals
+- * the maximum number of local variables of the method
+- * corresponding to this code attribute, or -1 if this attribute
+- * is not a code attribute.
+- * @return the byte array form of this attribute.
+- */
+- protected ByteVector write(final ClassWriter cw, final byte[] code,
+- final int len, final int maxStack, final int maxLocals) {
+- ByteVector v = new ByteVector();
+- v.data = value;
+- v.length = value.length;
+- return v;
+- }
+-
+- /**
+- * Returns the length of the attribute list that begins with this attribute.
+- *
+- * @return the length of the attribute list that begins with this attribute.
+- */
+- final int getCount() {
+- int count = 0;
+- Attribute attr = this;
+- while (attr != null) {
+- count += 1;
+- attr = attr.next;
+- }
+- return count;
+- }
+-
+- /**
+- * Returns the size of all the attributes in this attribute list.
+- *
+- * @param cw
+- * the class writer to be used to convert the attributes into
+- * byte arrays, with the {@link #write write} method.
+- * @param code
+- * the bytecode of the method corresponding to these code
+- * attributes, or null if these attributes are not code
+- * attributes.
+- * @param len
+- * the length of the bytecode of the method corresponding to
+- * these code attributes, or null if these attributes
+- * are not code attributes.
+- * @param maxStack
+- * the maximum stack size of the method corresponding to these
+- * code attributes, or -1 if these attributes are not code
+- * attributes.
+- * @param maxLocals
+- * the maximum number of local variables of the method
+- * corresponding to these code attributes, or -1 if these
+- * attributes are not code attributes.
+- * @return the size of all the attributes in this attribute list. This size
+- * includes the size of the attribute headers.
+- */
+- final int getSize(final ClassWriter cw, final byte[] code, final int len,
+- final int maxStack, final int maxLocals) {
+- Attribute attr = this;
+- int size = 0;
+- while (attr != null) {
+- cw.newUTF8(attr.type);
+- size += attr.write(cw, code, len, maxStack, maxLocals).length + 6;
+- attr = attr.next;
+- }
+- return size;
+- }
+-
+- /**
+- * Writes all the attributes of this attribute list in the given byte
+- * vector.
+- *
+- * @param cw
+- * the class writer to be used to convert the attributes into
+- * byte arrays, with the {@link #write write} method.
+- * @param code
+- * the bytecode of the method corresponding to these code
+- * attributes, or null if these attributes are not code
+- * attributes.
+- * @param len
+- * the length of the bytecode of the method corresponding to
+- * these code attributes, or null if these attributes
+- * are not code attributes.
+- * @param maxStack
+- * the maximum stack size of the method corresponding to these
+- * code attributes, or -1 if these attributes are not code
+- * attributes.
+- * @param maxLocals
+- * the maximum number of local variables of the method
+- * corresponding to these code attributes, or -1 if these
+- * attributes are not code attributes.
+- * @param out
+- * where the attributes must be written.
+- */
+- final void put(final ClassWriter cw, final byte[] code, final int len,
+- final int maxStack, final int maxLocals, final ByteVector out) {
+- Attribute attr = this;
+- while (attr != null) {
+- ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
+- out.putShort(cw.newUTF8(attr.type)).putInt(b.length);
+- out.putByteArray(b.data, 0, b.length);
+- attr = attr.next;
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/attrs/package.html mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/attrs/package.html
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/attrs/package.html 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/attrs/package.html 1970-01-01 01:00:00.000000000 +0100
+@@ -1,49 +0,0 @@
+-
+-
+-
+-Provides an implementation for optional class, field and method attributes.
+-
+-
+-
+- By default ASM strips optional attributes, in order to keep them in
+- the bytecode that is being readed you should pass an array of required attribute
+- instances to {@link org.mvel2.asm.ClassReader#accept(org.mvel2.asm.ClassVisitor,
+- org.mvel2.asm.Attribute[], boolean) ClassReader.accept()} method.
+- In order to add custom attributes to the manually constructed bytecode concrete
+- subclasses of the {@link org.mvel2.asm.Attribute Attribute} can be passed to
+- the visitAttribute methods of the
+- {@link org.mvel2.asm.ClassVisitor ClassVisitor},
+- {@link org.mvel2.asm.FieldVisitor FieldVisitor} and
+- {@link org.mvel2.asm.MethodVisitor MethodVisitor} interfaces.
+-
+- @since ASM 1.4.1
+-
+-
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/ByteVector.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/ByteVector.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/ByteVector.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/ByteVector.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,339 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A dynamically extensible vector of bytes. This class is roughly equivalent to
+- * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient.
+- *
+- * @author Eric Bruneton
+- */
+-public class ByteVector {
+-
+- /**
+- * The content of this vector.
+- */
+- byte[] data;
+-
+- /**
+- * Actual number of bytes in this vector.
+- */
+- int length;
+-
+- /**
+- * Constructs a new {@link ByteVector ByteVector} with a default initial
+- * size.
+- */
+- public ByteVector() {
+- data = new byte[64];
+- }
+-
+- /**
+- * Constructs a new {@link ByteVector ByteVector} with the given initial
+- * size.
+- *
+- * @param initialSize
+- * the initial size of the byte vector to be constructed.
+- */
+- public ByteVector(final int initialSize) {
+- data = new byte[initialSize];
+- }
+-
+- /**
+- * Puts a byte into this byte vector. The byte vector is automatically
+- * enlarged if necessary.
+- *
+- * @param b
+- * a byte.
+- * @return this byte vector.
+- */
+- public ByteVector putByte(final int b) {
+- int length = this.length;
+- if (length + 1 > data.length) {
+- enlarge(1);
+- }
+- data[length++] = (byte) b;
+- this.length = length;
+- return this;
+- }
+-
+- /**
+- * Puts two bytes into this byte vector. The byte vector is automatically
+- * enlarged if necessary.
+- *
+- * @param b1
+- * a byte.
+- * @param b2
+- * another byte.
+- * @return this byte vector.
+- */
+- ByteVector put11(final int b1, final int b2) {
+- int length = this.length;
+- if (length + 2 > data.length) {
+- enlarge(2);
+- }
+- byte[] data = this.data;
+- data[length++] = (byte) b1;
+- data[length++] = (byte) b2;
+- this.length = length;
+- return this;
+- }
+-
+- /**
+- * Puts a short into this byte vector. The byte vector is automatically
+- * enlarged if necessary.
+- *
+- * @param s
+- * a short.
+- * @return this byte vector.
+- */
+- public ByteVector putShort(final int s) {
+- int length = this.length;
+- if (length + 2 > data.length) {
+- enlarge(2);
+- }
+- byte[] data = this.data;
+- data[length++] = (byte) (s >>> 8);
+- data[length++] = (byte) s;
+- this.length = length;
+- return this;
+- }
+-
+- /**
+- * Puts a byte and a short into this byte vector. The byte vector is
+- * automatically enlarged if necessary.
+- *
+- * @param b
+- * a byte.
+- * @param s
+- * a short.
+- * @return this byte vector.
+- */
+- ByteVector put12(final int b, final int s) {
+- int length = this.length;
+- if (length + 3 > data.length) {
+- enlarge(3);
+- }
+- byte[] data = this.data;
+- data[length++] = (byte) b;
+- data[length++] = (byte) (s >>> 8);
+- data[length++] = (byte) s;
+- this.length = length;
+- return this;
+- }
+-
+- /**
+- * Puts an int into this byte vector. The byte vector is automatically
+- * enlarged if necessary.
+- *
+- * @param i
+- * an int.
+- * @return this byte vector.
+- */
+- public ByteVector putInt(final int i) {
+- int length = this.length;
+- if (length + 4 > data.length) {
+- enlarge(4);
+- }
+- byte[] data = this.data;
+- data[length++] = (byte) (i >>> 24);
+- data[length++] = (byte) (i >>> 16);
+- data[length++] = (byte) (i >>> 8);
+- data[length++] = (byte) i;
+- this.length = length;
+- return this;
+- }
+-
+- /**
+- * Puts a long into this byte vector. The byte vector is automatically
+- * enlarged if necessary.
+- *
+- * @param l
+- * a long.
+- * @return this byte vector.
+- */
+- public ByteVector putLong(final long l) {
+- int length = this.length;
+- if (length + 8 > data.length) {
+- enlarge(8);
+- }
+- byte[] data = this.data;
+- int i = (int) (l >>> 32);
+- data[length++] = (byte) (i >>> 24);
+- data[length++] = (byte) (i >>> 16);
+- data[length++] = (byte) (i >>> 8);
+- data[length++] = (byte) i;
+- i = (int) l;
+- data[length++] = (byte) (i >>> 24);
+- data[length++] = (byte) (i >>> 16);
+- data[length++] = (byte) (i >>> 8);
+- data[length++] = (byte) i;
+- this.length = length;
+- return this;
+- }
+-
+- /**
+- * Puts an UTF8 string into this byte vector. The byte vector is
+- * automatically enlarged if necessary.
+- *
+- * @param s
+- * a String whose UTF8 encoded length must be less than 65536.
+- * @return this byte vector.
+- */
+- public ByteVector putUTF8(final String s) {
+- int charLength = s.length();
+- if (charLength > 65535) {
+- throw new IllegalArgumentException();
+- }
+- int len = length;
+- if (len + 2 + charLength > data.length) {
+- enlarge(2 + charLength);
+- }
+- byte[] data = this.data;
+- // optimistic algorithm: instead of computing the byte length and then
+- // serializing the string (which requires two loops), we assume the byte
+- // length is equal to char length (which is the most frequent case), and
+- // we start serializing the string right away. During the serialization,
+- // if we find that this assumption is wrong, we continue with the
+- // general method.
+- data[len++] = (byte) (charLength >>> 8);
+- data[len++] = (byte) charLength;
+- for (int i = 0; i < charLength; ++i) {
+- char c = s.charAt(i);
+- if (c >= '\001' && c <= '\177') {
+- data[len++] = (byte) c;
+- } else {
+- length = len;
+- return encodeUTF8(s, i, 65535);
+- }
+- }
+- length = len;
+- return this;
+- }
+-
+- /**
+- * Puts an UTF8 string into this byte vector. The byte vector is
+- * automatically enlarged if necessary. The string length is encoded in two
+- * bytes before the encoded characters, if there is space for that (i.e. if
+- * this.length - i - 2 >= 0).
+- *
+- * @param s
+- * the String to encode.
+- * @param i
+- * the index of the first character to encode. The previous
+- * characters are supposed to have already been encoded, using
+- * only one byte per character.
+- * @param maxByteLength
+- * the maximum byte length of the encoded string, including the
+- * already encoded characters.
+- * @return this byte vector.
+- */
+- ByteVector encodeUTF8(final String s, int i, int maxByteLength) {
+- int charLength = s.length();
+- int byteLength = i;
+- char c;
+- for (int j = i; j < charLength; ++j) {
+- c = s.charAt(j);
+- if (c >= '\001' && c <= '\177') {
+- byteLength++;
+- } else if (c > '\u07FF') {
+- byteLength += 3;
+- } else {
+- byteLength += 2;
+- }
+- }
+- if (byteLength > maxByteLength) {
+- throw new IllegalArgumentException();
+- }
+- int start = length - i - 2;
+- if (start >= 0) {
+- data[start] = (byte) (byteLength >>> 8);
+- data[start + 1] = (byte) byteLength;
+- }
+- if (length + byteLength - i > data.length) {
+- enlarge(byteLength - i);
+- }
+- int len = length;
+- for (int j = i; j < charLength; ++j) {
+- c = s.charAt(j);
+- if (c >= '\001' && c <= '\177') {
+- data[len++] = (byte) c;
+- } else if (c > '\u07FF') {
+- data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
+- data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
+- data[len++] = (byte) (0x80 | c & 0x3F);
+- } else {
+- data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
+- data[len++] = (byte) (0x80 | c & 0x3F);
+- }
+- }
+- length = len;
+- return this;
+- }
+-
+- /**
+- * Puts an array of bytes into this byte vector. The byte vector is
+- * automatically enlarged if necessary.
+- *
+- * @param b
+- * an array of bytes. May be null to put len
+- * null bytes into this byte vector.
+- * @param off
+- * index of the fist byte of b that must be copied.
+- * @param len
+- * number of bytes of b that must be copied.
+- * @return this byte vector.
+- */
+- public ByteVector putByteArray(final byte[] b, final int off, final int len) {
+- if (length + len > data.length) {
+- enlarge(len);
+- }
+- if (b != null) {
+- System.arraycopy(b, off, data, length, len);
+- }
+- length += len;
+- return this;
+- }
+-
+- /**
+- * Enlarge this byte vector so that it can receive n more bytes.
+- *
+- * @param size
+- * number of additional bytes that this byte vector should be
+- * able to receive.
+- */
+- private void enlarge(final int size) {
+- int length1 = 2 * data.length;
+- int length2 = length + size;
+- byte[] newData = new byte[length1 > length2 ? length1 : length2];
+- System.arraycopy(data, 0, newData, 0, length);
+- data = newData;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/ClassReader.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/ClassReader.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/ClassReader.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/ClassReader.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2496 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-import java.io.IOException;
+-import java.io.InputStream;
+-
+-/**
+- * A Java class parser to make a {@link ClassVisitor} visit an existing class.
+- * This class parses a byte array conforming to the Java class file format and
+- * calls the appropriate visit methods of a given class visitor for each field,
+- * method and bytecode instruction encountered.
+- *
+- * @author Eric Bruneton
+- * @author Eugene Kuleshov
+- */
+-public class ClassReader {
+-
+- /**
+- * True to enable signatures support.
+- */
+- static final boolean SIGNATURES = true;
+-
+- /**
+- * True to enable annotations support.
+- */
+- static final boolean ANNOTATIONS = true;
+-
+- /**
+- * True to enable stack map frames support.
+- */
+- static final boolean FRAMES = true;
+-
+- /**
+- * True to enable bytecode writing support.
+- */
+- static final boolean WRITER = true;
+-
+- /**
+- * True to enable JSR_W and GOTO_W support.
+- */
+- static final boolean RESIZE = true;
+-
+- /**
+- * Flag to skip method code. If this class is set CODE
+- * attribute won't be visited. This can be used, for example, to retrieve
+- * annotations for methods and method parameters.
+- */
+- public static final int SKIP_CODE = 1;
+-
+- /**
+- * Flag to skip the debug information in the class. If this flag is set the
+- * debug information of the class is not visited, i.e. the
+- * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and
+- * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be
+- * called.
+- */
+- public static final int SKIP_DEBUG = 2;
+-
+- /**
+- * Flag to skip the stack map frames in the class. If this flag is set the
+- * stack map frames of the class is not visited, i.e. the
+- * {@link MethodVisitor#visitFrame visitFrame} method will not be called.
+- * This flag is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is
+- * used: it avoids visiting frames that will be ignored and recomputed from
+- * scratch in the class writer.
+- */
+- public static final int SKIP_FRAMES = 4;
+-
+- /**
+- * Flag to expand the stack map frames. By default stack map frames are
+- * visited in their original format (i.e. "expanded" for classes whose
+- * version is less than V1_6, and "compressed" for the other classes). If
+- * this flag is set, stack map frames are always visited in expanded format
+- * (this option adds a decompression/recompression step in ClassReader and
+- * ClassWriter which degrades performances quite a lot).
+- */
+- public static final int EXPAND_FRAMES = 8;
+-
+- /**
+- * The class to be parsed. The content of this array must not be
+- * modified. This field is intended for {@link Attribute} sub classes, and
+- * is normally not needed by class generators or adapters.
+- */
+- public final byte[] b;
+-
+- /**
+- * The start index of each constant pool item in {@link #b b}, plus one. The
+- * one byte offset skips the constant pool item tag that indicates its type.
+- */
+- private final int[] items;
+-
+- /**
+- * The String objects corresponding to the CONSTANT_Utf8 items. This cache
+- * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
+- * which GREATLY improves performances (by a factor 2 to 3). This caching
+- * strategy could be extended to all constant pool items, but its benefit
+- * would not be so great for these items (because they are much less
+- * expensive to parse than CONSTANT_Utf8 items).
+- */
+- private final String[] strings;
+-
+- /**
+- * Maximum length of the strings contained in the constant pool of the
+- * class.
+- */
+- private final int maxStringLength;
+-
+- /**
+- * Start index of the class header information (access, name...) in
+- * {@link #b b}.
+- */
+- public final int header;
+-
+- // ------------------------------------------------------------------------
+- // Constructors
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Constructs a new {@link ClassReader} object.
+- *
+- * @param b
+- * the bytecode of the class to be read.
+- */
+- public ClassReader(final byte[] b) {
+- this(b, 0, b.length);
+- }
+-
+- /**
+- * Constructs a new {@link ClassReader} object.
+- *
+- * @param b
+- * the bytecode of the class to be read.
+- * @param off
+- * the start offset of the class data.
+- * @param len
+- * the length of the class data.
+- */
+- public ClassReader(final byte[] b, final int off, final int len) {
+- this.b = b;
+- // checks the class version
+- if (readShort(off + 6) > Opcodes.V1_8) {
+- throw new IllegalArgumentException();
+- }
+- // parses the constant pool
+- items = new int[readUnsignedShort(off + 8)];
+- int n = items.length;
+- strings = new String[n];
+- int max = 0;
+- int index = off + 10;
+- for (int i = 1; i < n; ++i) {
+- items[i] = index + 1;
+- int size;
+- switch (b[index]) {
+- case ClassWriter.FIELD:
+- case ClassWriter.METH:
+- case ClassWriter.IMETH:
+- case ClassWriter.INT:
+- case ClassWriter.FLOAT:
+- case ClassWriter.NAME_TYPE:
+- case ClassWriter.INDY:
+- size = 5;
+- break;
+- case ClassWriter.LONG:
+- case ClassWriter.DOUBLE:
+- size = 9;
+- ++i;
+- break;
+- case ClassWriter.UTF8:
+- size = 3 + readUnsignedShort(index + 1);
+- if (size > max) {
+- max = size;
+- }
+- break;
+- case ClassWriter.HANDLE:
+- size = 4;
+- break;
+- // case ClassWriter.CLASS:
+- // case ClassWriter.STR:
+- // case ClassWriter.MTYPE
+- default:
+- size = 3;
+- break;
+- }
+- index += size;
+- }
+- maxStringLength = max;
+- // the class header information starts just after the constant pool
+- header = index;
+- }
+-
+- /**
+- * Returns the class's access flags (see {@link Opcodes}). This value may
+- * not reflect Deprecated and Synthetic flags when bytecode is before 1.5
+- * and those flags are represented by attributes.
+- *
+- * @return the class access flags
+- *
+- * @see ClassVisitor#visit(int, int, String, String, String, String[])
+- */
+- public int getAccess() {
+- return readUnsignedShort(header);
+- }
+-
+- /**
+- * Returns the internal name of the class (see
+- * {@link Type#getInternalName() getInternalName}).
+- *
+- * @return the internal class name
+- *
+- * @see ClassVisitor#visit(int, int, String, String, String, String[])
+- */
+- public String getClassName() {
+- return readClass(header + 2, new char[maxStringLength]);
+- }
+-
+- /**
+- * Returns the internal of name of the super class (see
+- * {@link Type#getInternalName() getInternalName}). For interfaces, the
+- * super class is {@link Object}.
+- *
+- * @return the internal name of super class, or null for
+- * {@link Object} class.
+- *
+- * @see ClassVisitor#visit(int, int, String, String, String, String[])
+- */
+- public String getSuperName() {
+- return readClass(header + 4, new char[maxStringLength]);
+- }
+-
+- /**
+- * Returns the internal names of the class's interfaces (see
+- * {@link Type#getInternalName() getInternalName}).
+- *
+- * @return the array of internal names for all implemented interfaces or
+- * null .
+- *
+- * @see ClassVisitor#visit(int, int, String, String, String, String[])
+- */
+- public String[] getInterfaces() {
+- int index = header + 6;
+- int n = readUnsignedShort(index);
+- String[] interfaces = new String[n];
+- if (n > 0) {
+- char[] buf = new char[maxStringLength];
+- for (int i = 0; i < n; ++i) {
+- index += 2;
+- interfaces[i] = readClass(index, buf);
+- }
+- }
+- return interfaces;
+- }
+-
+- /**
+- * Copies the constant pool data into the given {@link ClassWriter}. Should
+- * be called before the {@link #accept(ClassVisitor,int)} method.
+- *
+- * @param classWriter
+- * the {@link ClassWriter} to copy constant pool into.
+- */
+- void copyPool(final ClassWriter classWriter) {
+- char[] buf = new char[maxStringLength];
+- int ll = items.length;
+- Item[] items2 = new Item[ll];
+- for (int i = 1; i < ll; i++) {
+- int index = items[i];
+- int tag = b[index - 1];
+- Item item = new Item(i);
+- int nameType;
+- switch (tag) {
+- case ClassWriter.FIELD:
+- case ClassWriter.METH:
+- case ClassWriter.IMETH:
+- nameType = items[readUnsignedShort(index + 2)];
+- item.set(tag, readClass(index, buf), readUTF8(nameType, buf),
+- readUTF8(nameType + 2, buf));
+- break;
+- case ClassWriter.INT:
+- item.set(readInt(index));
+- break;
+- case ClassWriter.FLOAT:
+- item.set(Float.intBitsToFloat(readInt(index)));
+- break;
+- case ClassWriter.NAME_TYPE:
+- item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf),
+- null);
+- break;
+- case ClassWriter.LONG:
+- item.set(readLong(index));
+- ++i;
+- break;
+- case ClassWriter.DOUBLE:
+- item.set(Double.longBitsToDouble(readLong(index)));
+- ++i;
+- break;
+- case ClassWriter.UTF8: {
+- String s = strings[i];
+- if (s == null) {
+- index = items[i];
+- s = strings[i] = readUTF(index + 2,
+- readUnsignedShort(index), buf);
+- }
+- item.set(tag, s, null, null);
+- break;
+- }
+- case ClassWriter.HANDLE: {
+- int fieldOrMethodRef = items[readUnsignedShort(index + 1)];
+- nameType = items[readUnsignedShort(fieldOrMethodRef + 2)];
+- item.set(ClassWriter.HANDLE_BASE + readByte(index),
+- readClass(fieldOrMethodRef, buf),
+- readUTF8(nameType, buf), readUTF8(nameType + 2, buf));
+- break;
+- }
+- case ClassWriter.INDY:
+- if (classWriter.bootstrapMethods == null) {
+- copyBootstrapMethods(classWriter, items2, buf);
+- }
+- nameType = items[readUnsignedShort(index + 2)];
+- item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf),
+- readUnsignedShort(index));
+- break;
+- // case ClassWriter.STR:
+- // case ClassWriter.CLASS:
+- // case ClassWriter.MTYPE
+- default:
+- item.set(tag, readUTF8(index, buf), null, null);
+- break;
+- }
+-
+- int index2 = item.hashCode % items2.length;
+- item.next = items2[index2];
+- items2[index2] = item;
+- }
+-
+- int off = items[1] - 1;
+- classWriter.pool.putByteArray(b, off, header - off);
+- classWriter.items = items2;
+- classWriter.threshold = (int) (0.75d * ll);
+- classWriter.index = ll;
+- }
+-
+- /**
+- * Copies the bootstrap method data into the given {@link ClassWriter}.
+- * Should be called before the {@link #accept(ClassVisitor,int)} method.
+- *
+- * @param classWriter
+- * the {@link ClassWriter} to copy bootstrap methods into.
+- */
+- private void copyBootstrapMethods(final ClassWriter classWriter,
+- final Item[] items, final char[] c) {
+- // finds the "BootstrapMethods" attribute
+- int u = getAttributes();
+- boolean found = false;
+- for (int i = readUnsignedShort(u); i > 0; --i) {
+- String attrName = readUTF8(u + 2, c);
+- if ("BootstrapMethods".equals(attrName)) {
+- found = true;
+- break;
+- }
+- u += 6 + readInt(u + 4);
+- }
+- if (!found) {
+- return;
+- }
+- // copies the bootstrap methods in the class writer
+- int boostrapMethodCount = readUnsignedShort(u + 8);
+- for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) {
+- int position = v - u - 10;
+- int hashCode = readConst(readUnsignedShort(v), c).hashCode();
+- for (int k = readUnsignedShort(v + 2); k > 0; --k) {
+- hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode();
+- v += 2;
+- }
+- v += 4;
+- Item item = new Item(j);
+- item.set(position, hashCode & 0x7FFFFFFF);
+- int index = item.hashCode % items.length;
+- item.next = items[index];
+- items[index] = item;
+- }
+- int attrSize = readInt(u + 4);
+- ByteVector bootstrapMethods = new ByteVector(attrSize + 62);
+- bootstrapMethods.putByteArray(b, u + 10, attrSize - 2);
+- classWriter.bootstrapMethodsCount = boostrapMethodCount;
+- classWriter.bootstrapMethods = bootstrapMethods;
+- }
+-
+- /**
+- * Constructs a new {@link ClassReader} object.
+- *
+- * @param is
+- * an input stream from which to read the class.
+- * @throws IOException
+- * if a problem occurs during reading.
+- */
+- public ClassReader(final InputStream is) throws IOException {
+- this(readClass(is, false));
+- }
+-
+- /**
+- * Constructs a new {@link ClassReader} object.
+- *
+- * @param name
+- * the binary qualified name of the class to be read.
+- * @throws IOException
+- * if an exception occurs during reading.
+- */
+- public ClassReader(final String name) throws IOException {
+- this(readClass(
+- ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
+- + ".class"), true));
+- }
+-
+- /**
+- * Reads the bytecode of a class.
+- *
+- * @param is
+- * an input stream from which to read the class.
+- * @param close
+- * true to close the input stream after reading.
+- * @return the bytecode read from the given input stream.
+- * @throws IOException
+- * if a problem occurs during reading.
+- */
+- private static byte[] readClass(final InputStream is, boolean close)
+- throws IOException {
+- if (is == null) {
+- throw new IOException("Class not found");
+- }
+- try {
+- byte[] b = new byte[is.available()];
+- int len = 0;
+- while (true) {
+- int n = is.read(b, len, b.length - len);
+- if (n == -1) {
+- if (len < b.length) {
+- byte[] c = new byte[len];
+- System.arraycopy(b, 0, c, 0, len);
+- b = c;
+- }
+- return b;
+- }
+- len += n;
+- if (len == b.length) {
+- int last = is.read();
+- if (last < 0) {
+- return b;
+- }
+- byte[] c = new byte[b.length + 1000];
+- System.arraycopy(b, 0, c, 0, len);
+- c[len++] = (byte) last;
+- b = c;
+- }
+- }
+- } finally {
+- if (close) {
+- is.close();
+- }
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Public methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Makes the given visitor visit the Java class of this {@link ClassReader}
+- * . This class is the one specified in the constructor (see
+- * {@link #ClassReader(byte[]) ClassReader}).
+- *
+- * @param classVisitor
+- * the visitor that must visit this class.
+- * @param flags
+- * option flags that can be used to modify the default behavior
+- * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
+- * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
+- */
+- public void accept(final ClassVisitor classVisitor, final int flags) {
+- accept(classVisitor, new Attribute[0], flags);
+- }
+-
+- /**
+- * Makes the given visitor visit the Java class of this {@link ClassReader}.
+- * This class is the one specified in the constructor (see
+- * {@link #ClassReader(byte[]) ClassReader}).
+- *
+- * @param classVisitor
+- * the visitor that must visit this class.
+- * @param attrs
+- * prototypes of the attributes that must be parsed during the
+- * visit of the class. Any attribute whose type is not equal to
+- * the type of one the prototypes will not be parsed: its byte
+- * array value will be passed unchanged to the ClassWriter.
+- * This may corrupt it if this value contains references to
+- * the constant pool, or has syntactic or semantic links with a
+- * class element that has been transformed by a class adapter
+- * between the reader and the writer .
+- * @param flags
+- * option flags that can be used to modify the default behavior
+- * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}
+- * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}.
+- */
+- public void accept(final ClassVisitor classVisitor,
+- final Attribute[] attrs, final int flags) {
+- int u = header; // current offset in the class file
+- char[] c = new char[maxStringLength]; // buffer used to read strings
+-
+- Context context = new Context();
+- context.attrs = attrs;
+- context.flags = flags;
+- context.buffer = c;
+-
+- // reads the class declaration
+- int access = readUnsignedShort(u);
+- String name = readClass(u + 2, c);
+- String superClass = readClass(u + 4, c);
+- String[] interfaces = new String[readUnsignedShort(u + 6)];
+- u += 8;
+- for (int i = 0; i < interfaces.length; ++i) {
+- interfaces[i] = readClass(u, c);
+- u += 2;
+- }
+-
+- // reads the class attributes
+- String signature = null;
+- String sourceFile = null;
+- String sourceDebug = null;
+- String enclosingOwner = null;
+- String enclosingName = null;
+- String enclosingDesc = null;
+- int anns = 0;
+- int ianns = 0;
+- int tanns = 0;
+- int itanns = 0;
+- int innerClasses = 0;
+- Attribute attributes = null;
+-
+- u = getAttributes();
+- for (int i = readUnsignedShort(u); i > 0; --i) {
+- String attrName = readUTF8(u + 2, c);
+- // tests are sorted in decreasing frequency order
+- // (based on frequencies observed on typical classes)
+- if ("SourceFile".equals(attrName)) {
+- sourceFile = readUTF8(u + 8, c);
+- } else if ("InnerClasses".equals(attrName)) {
+- innerClasses = u + 8;
+- } else if ("EnclosingMethod".equals(attrName)) {
+- enclosingOwner = readClass(u + 8, c);
+- int item = readUnsignedShort(u + 10);
+- if (item != 0) {
+- enclosingName = readUTF8(items[item], c);
+- enclosingDesc = readUTF8(items[item] + 2, c);
+- }
+- } else if (SIGNATURES && "Signature".equals(attrName)) {
+- signature = readUTF8(u + 8, c);
+- } else if (ANNOTATIONS
+- && "RuntimeVisibleAnnotations".equals(attrName)) {
+- anns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+- tanns = u + 8;
+- } else if ("Deprecated".equals(attrName)) {
+- access |= Opcodes.ACC_DEPRECATED;
+- } else if ("Synthetic".equals(attrName)) {
+- access |= Opcodes.ACC_SYNTHETIC
+- | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+- } else if ("SourceDebugExtension".equals(attrName)) {
+- int len = readInt(u + 4);
+- sourceDebug = readUTF(u + 8, len, new char[len]);
+- } else if (ANNOTATIONS
+- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+- ianns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+- itanns = u + 8;
+- } else if ("BootstrapMethods".equals(attrName)) {
+- int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
+- for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
+- bootstrapMethods[j] = v;
+- v += 2 + readUnsignedShort(v + 2) << 1;
+- }
+- context.bootstrapMethods = bootstrapMethods;
+- } else {
+- Attribute attr = readAttribute(attrs, attrName, u + 8,
+- readInt(u + 4), c, -1, null);
+- if (attr != null) {
+- attr.next = attributes;
+- attributes = attr;
+- }
+- }
+- u += 6 + readInt(u + 4);
+- }
+-
+- // visits the class declaration
+- classVisitor.visit(readInt(items[1] - 7), access, name, signature,
+- superClass, interfaces);
+-
+- // visits the source and debug info
+- if ((flags & SKIP_DEBUG) == 0
+- && (sourceFile != null || sourceDebug != null)) {
+- classVisitor.visitSource(sourceFile, sourceDebug);
+- }
+-
+- // visits the outer class
+- if (enclosingOwner != null) {
+- classVisitor.visitOuterClass(enclosingOwner, enclosingName,
+- enclosingDesc);
+- }
+-
+- // visits the class annotations and type annotations
+- if (ANNOTATIONS && anns != 0) {
+- for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+- v = readAnnotationValues(v + 2, c, true,
+- classVisitor.visitAnnotation(readUTF8(v, c), true));
+- }
+- }
+- if (ANNOTATIONS && ianns != 0) {
+- for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+- v = readAnnotationValues(v + 2, c, true,
+- classVisitor.visitAnnotation(readUTF8(v, c), false));
+- }
+- }
+- if (ANNOTATIONS && tanns != 0) {
+- for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+- v = readAnnotationTarget(context, v);
+- v = readAnnotationValues(v + 2, c, true,
+- classVisitor.visitTypeAnnotation(context.typeRef,
+- context.typePath, readUTF8(v, c), true));
+- }
+- }
+- if (ANNOTATIONS && itanns != 0) {
+- for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+- v = readAnnotationTarget(context, v);
+- v = readAnnotationValues(v + 2, c, true,
+- classVisitor.visitTypeAnnotation(context.typeRef,
+- context.typePath, readUTF8(v, c), false));
+- }
+- }
+-
+- // visits the attributes
+- while (attributes != null) {
+- Attribute attr = attributes.next;
+- attributes.next = null;
+- classVisitor.visitAttribute(attributes);
+- attributes = attr;
+- }
+-
+- // visits the inner classes
+- if (innerClasses != 0) {
+- int v = innerClasses + 2;
+- for (int i = readUnsignedShort(innerClasses); i > 0; --i) {
+- classVisitor.visitInnerClass(readClass(v, c),
+- readClass(v + 2, c), readUTF8(v + 4, c),
+- readUnsignedShort(v + 6));
+- v += 8;
+- }
+- }
+-
+- // visits the fields and methods
+- u = header + 10 + 2 * interfaces.length;
+- for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+- u = readField(classVisitor, context, u);
+- }
+- u += 2;
+- for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+- u = readMethod(classVisitor, context, u);
+- }
+-
+- // visits the end of the class
+- classVisitor.visitEnd();
+- }
+-
+- /**
+- * Reads a field and makes the given visitor visit it.
+- *
+- * @param classVisitor
+- * the visitor that must visit the field.
+- * @param context
+- * information about the class being parsed.
+- * @param u
+- * the start offset of the field in the class file.
+- * @return the offset of the first byte following the field in the class.
+- */
+- private int readField(final ClassVisitor classVisitor,
+- final Context context, int u) {
+- // reads the field declaration
+- char[] c = context.buffer;
+- int access = readUnsignedShort(u);
+- String name = readUTF8(u + 2, c);
+- String desc = readUTF8(u + 4, c);
+- u += 6;
+-
+- // reads the field attributes
+- String signature = null;
+- int anns = 0;
+- int ianns = 0;
+- int tanns = 0;
+- int itanns = 0;
+- Object value = null;
+- Attribute attributes = null;
+-
+- for (int i = readUnsignedShort(u); i > 0; --i) {
+- String attrName = readUTF8(u + 2, c);
+- // tests are sorted in decreasing frequency order
+- // (based on frequencies observed on typical classes)
+- if ("ConstantValue".equals(attrName)) {
+- int item = readUnsignedShort(u + 8);
+- value = item == 0 ? null : readConst(item, c);
+- } else if (SIGNATURES && "Signature".equals(attrName)) {
+- signature = readUTF8(u + 8, c);
+- } else if ("Deprecated".equals(attrName)) {
+- access |= Opcodes.ACC_DEPRECATED;
+- } else if ("Synthetic".equals(attrName)) {
+- access |= Opcodes.ACC_SYNTHETIC
+- | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+- } else if (ANNOTATIONS
+- && "RuntimeVisibleAnnotations".equals(attrName)) {
+- anns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+- tanns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+- ianns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+- itanns = u + 8;
+- } else {
+- Attribute attr = readAttribute(context.attrs, attrName, u + 8,
+- readInt(u + 4), c, -1, null);
+- if (attr != null) {
+- attr.next = attributes;
+- attributes = attr;
+- }
+- }
+- u += 6 + readInt(u + 4);
+- }
+- u += 2;
+-
+- // visits the field declaration
+- FieldVisitor fv = classVisitor.visitField(access, name, desc,
+- signature, value);
+- if (fv == null) {
+- return u;
+- }
+-
+- // visits the field annotations and type annotations
+- if (ANNOTATIONS && anns != 0) {
+- for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+- v = readAnnotationValues(v + 2, c, true,
+- fv.visitAnnotation(readUTF8(v, c), true));
+- }
+- }
+- if (ANNOTATIONS && ianns != 0) {
+- for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+- v = readAnnotationValues(v + 2, c, true,
+- fv.visitAnnotation(readUTF8(v, c), false));
+- }
+- }
+- if (ANNOTATIONS && tanns != 0) {
+- for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+- v = readAnnotationTarget(context, v);
+- v = readAnnotationValues(v + 2, c, true,
+- fv.visitTypeAnnotation(context.typeRef,
+- context.typePath, readUTF8(v, c), true));
+- }
+- }
+- if (ANNOTATIONS && itanns != 0) {
+- for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+- v = readAnnotationTarget(context, v);
+- v = readAnnotationValues(v + 2, c, true,
+- fv.visitTypeAnnotation(context.typeRef,
+- context.typePath, readUTF8(v, c), false));
+- }
+- }
+-
+- // visits the field attributes
+- while (attributes != null) {
+- Attribute attr = attributes.next;
+- attributes.next = null;
+- fv.visitAttribute(attributes);
+- attributes = attr;
+- }
+-
+- // visits the end of the field
+- fv.visitEnd();
+-
+- return u;
+- }
+-
+- /**
+- * Reads a method and makes the given visitor visit it.
+- *
+- * @param classVisitor
+- * the visitor that must visit the method.
+- * @param context
+- * information about the class being parsed.
+- * @param u
+- * the start offset of the method in the class file.
+- * @return the offset of the first byte following the method in the class.
+- */
+- private int readMethod(final ClassVisitor classVisitor,
+- final Context context, int u) {
+- // reads the method declaration
+- char[] c = context.buffer;
+- context.access = readUnsignedShort(u);
+- context.name = readUTF8(u + 2, c);
+- context.desc = readUTF8(u + 4, c);
+- u += 6;
+-
+- // reads the method attributes
+- int code = 0;
+- int exception = 0;
+- String[] exceptions = null;
+- String signature = null;
+- int methodParameters = 0;
+- int anns = 0;
+- int ianns = 0;
+- int tanns = 0;
+- int itanns = 0;
+- int dann = 0;
+- int mpanns = 0;
+- int impanns = 0;
+- int firstAttribute = u;
+- Attribute attributes = null;
+-
+- for (int i = readUnsignedShort(u); i > 0; --i) {
+- String attrName = readUTF8(u + 2, c);
+- // tests are sorted in decreasing frequency order
+- // (based on frequencies observed on typical classes)
+- if ("Code".equals(attrName)) {
+- if ((context.flags & SKIP_CODE) == 0) {
+- code = u + 8;
+- }
+- } else if ("Exceptions".equals(attrName)) {
+- exceptions = new String[readUnsignedShort(u + 8)];
+- exception = u + 10;
+- for (int j = 0; j < exceptions.length; ++j) {
+- exceptions[j] = readClass(exception, c);
+- exception += 2;
+- }
+- } else if (SIGNATURES && "Signature".equals(attrName)) {
+- signature = readUTF8(u + 8, c);
+- } else if ("Deprecated".equals(attrName)) {
+- context.access |= Opcodes.ACC_DEPRECATED;
+- } else if (ANNOTATIONS
+- && "RuntimeVisibleAnnotations".equals(attrName)) {
+- anns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+- tanns = u + 8;
+- } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+- dann = u + 8;
+- } else if ("Synthetic".equals(attrName)) {
+- context.access |= Opcodes.ACC_SYNTHETIC
+- | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
+- } else if (ANNOTATIONS
+- && "RuntimeInvisibleAnnotations".equals(attrName)) {
+- ianns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+- itanns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+- mpanns = u + 8;
+- } else if (ANNOTATIONS
+- && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+- impanns = u + 8;
+- } else if ("MethodParameters".equals(attrName)) {
+- methodParameters = u + 8;
+- } else {
+- Attribute attr = readAttribute(context.attrs, attrName, u + 8,
+- readInt(u + 4), c, -1, null);
+- if (attr != null) {
+- attr.next = attributes;
+- attributes = attr;
+- }
+- }
+- u += 6 + readInt(u + 4);
+- }
+- u += 2;
+-
+- // visits the method declaration
+- MethodVisitor mv = classVisitor.visitMethod(context.access,
+- context.name, context.desc, signature, exceptions);
+- if (mv == null) {
+- return u;
+- }
+-
+- /*
+- * if the returned MethodVisitor is in fact a MethodWriter, it means
+- * there is no method adapter between the reader and the writer. If, in
+- * addition, the writer's constant pool was copied from this reader
+- * (mw.cw.cr == this), and the signature and exceptions of the method
+- * have not been changed, then it is possible to skip all visit events
+- * and just copy the original code of the method to the writer (the
+- * access, name and descriptor can have been changed, this is not
+- * important since they are not copied as is from the reader).
+- */
+- if (WRITER && mv instanceof MethodWriter) {
+- MethodWriter mw = (MethodWriter) mv;
+- if (mw.cw.cr == this && signature == mw.signature) {
+- boolean sameExceptions = false;
+- if (exceptions == null) {
+- sameExceptions = mw.exceptionCount == 0;
+- } else if (exceptions.length == mw.exceptionCount) {
+- sameExceptions = true;
+- for (int j = exceptions.length - 1; j >= 0; --j) {
+- exception -= 2;
+- if (mw.exceptions[j] != readUnsignedShort(exception)) {
+- sameExceptions = false;
+- break;
+- }
+- }
+- }
+- if (sameExceptions) {
+- /*
+- * we do not copy directly the code into MethodWriter to
+- * save a byte array copy operation. The real copy will be
+- * done in ClassWriter.toByteArray().
+- */
+- mw.classReaderOffset = firstAttribute;
+- mw.classReaderLength = u - firstAttribute;
+- return u;
+- }
+- }
+- }
+-
+- // visit the method parameters
+- if (methodParameters != 0) {
+- for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) {
+- mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2));
+- }
+- }
+-
+- // visits the method annotations
+- if (ANNOTATIONS && dann != 0) {
+- AnnotationVisitor dv = mv.visitAnnotationDefault();
+- readAnnotationValue(dann, c, null, dv);
+- if (dv != null) {
+- dv.visitEnd();
+- }
+- }
+- if (ANNOTATIONS && anns != 0) {
+- for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
+- v = readAnnotationValues(v + 2, c, true,
+- mv.visitAnnotation(readUTF8(v, c), true));
+- }
+- }
+- if (ANNOTATIONS && ianns != 0) {
+- for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
+- v = readAnnotationValues(v + 2, c, true,
+- mv.visitAnnotation(readUTF8(v, c), false));
+- }
+- }
+- if (ANNOTATIONS && tanns != 0) {
+- for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
+- v = readAnnotationTarget(context, v);
+- v = readAnnotationValues(v + 2, c, true,
+- mv.visitTypeAnnotation(context.typeRef,
+- context.typePath, readUTF8(v, c), true));
+- }
+- }
+- if (ANNOTATIONS && itanns != 0) {
+- for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
+- v = readAnnotationTarget(context, v);
+- v = readAnnotationValues(v + 2, c, true,
+- mv.visitTypeAnnotation(context.typeRef,
+- context.typePath, readUTF8(v, c), false));
+- }
+- }
+- if (ANNOTATIONS && mpanns != 0) {
+- readParameterAnnotations(mv, context, mpanns, true);
+- }
+- if (ANNOTATIONS && impanns != 0) {
+- readParameterAnnotations(mv, context, impanns, false);
+- }
+-
+- // visits the method attributes
+- while (attributes != null) {
+- Attribute attr = attributes.next;
+- attributes.next = null;
+- mv.visitAttribute(attributes);
+- attributes = attr;
+- }
+-
+- // visits the method code
+- if (code != 0) {
+- mv.visitCode();
+- readCode(mv, context, code);
+- }
+-
+- // visits the end of the method
+- mv.visitEnd();
+-
+- return u;
+- }
+-
+- /**
+- * Reads the bytecode of a method and makes the given visitor visit it.
+- *
+- * @param mv
+- * the visitor that must visit the method's code.
+- * @param context
+- * information about the class being parsed.
+- * @param u
+- * the start offset of the code attribute in the class file.
+- */
+- private void readCode(final MethodVisitor mv, final Context context, int u) {
+- // reads the header
+- byte[] b = this.b;
+- char[] c = context.buffer;
+- int maxStack = readUnsignedShort(u);
+- int maxLocals = readUnsignedShort(u + 2);
+- int codeLength = readInt(u + 4);
+- u += 8;
+-
+- // reads the bytecode to find the labels
+- int codeStart = u;
+- int codeEnd = u + codeLength;
+- Label[] labels = context.labels = new Label[codeLength + 2];
+- readLabel(codeLength + 1, labels);
+- while (u < codeEnd) {
+- int offset = u - codeStart;
+- int opcode = b[u] & 0xFF;
+- switch (ClassWriter.TYPE[opcode]) {
+- case ClassWriter.NOARG_INSN:
+- case ClassWriter.IMPLVAR_INSN:
+- u += 1;
+- break;
+- case ClassWriter.LABEL_INSN:
+- readLabel(offset + readShort(u + 1), labels);
+- u += 3;
+- break;
+- case ClassWriter.LABELW_INSN:
+- readLabel(offset + readInt(u + 1), labels);
+- u += 5;
+- break;
+- case ClassWriter.WIDE_INSN:
+- opcode = b[u + 1] & 0xFF;
+- if (opcode == Opcodes.IINC) {
+- u += 6;
+- } else {
+- u += 4;
+- }
+- break;
+- case ClassWriter.TABL_INSN:
+- // skips 0 to 3 padding bytes
+- u = u + 4 - (offset & 3);
+- // reads instruction
+- readLabel(offset + readInt(u), labels);
+- for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
+- readLabel(offset + readInt(u + 12), labels);
+- u += 4;
+- }
+- u += 12;
+- break;
+- case ClassWriter.LOOK_INSN:
+- // skips 0 to 3 padding bytes
+- u = u + 4 - (offset & 3);
+- // reads instruction
+- readLabel(offset + readInt(u), labels);
+- for (int i = readInt(u + 4); i > 0; --i) {
+- readLabel(offset + readInt(u + 12), labels);
+- u += 8;
+- }
+- u += 8;
+- break;
+- case ClassWriter.VAR_INSN:
+- case ClassWriter.SBYTE_INSN:
+- case ClassWriter.LDC_INSN:
+- u += 2;
+- break;
+- case ClassWriter.SHORT_INSN:
+- case ClassWriter.LDCW_INSN:
+- case ClassWriter.FIELDORMETH_INSN:
+- case ClassWriter.TYPE_INSN:
+- case ClassWriter.IINC_INSN:
+- u += 3;
+- break;
+- case ClassWriter.ITFMETH_INSN:
+- case ClassWriter.INDYMETH_INSN:
+- u += 5;
+- break;
+- // case MANA_INSN:
+- default:
+- u += 4;
+- break;
+- }
+- }
+-
+- // reads the try catch entries to find the labels, and also visits them
+- for (int i = readUnsignedShort(u); i > 0; --i) {
+- Label start = readLabel(readUnsignedShort(u + 2), labels);
+- Label end = readLabel(readUnsignedShort(u + 4), labels);
+- Label handler = readLabel(readUnsignedShort(u + 6), labels);
+- String type = readUTF8(items[readUnsignedShort(u + 8)], c);
+- mv.visitTryCatchBlock(start, end, handler, type);
+- u += 8;
+- }
+- u += 2;
+-
+- // reads the code attributes
+- int[] tanns = null; // start index of each visible type annotation
+- int[] itanns = null; // start index of each invisible type annotation
+- int tann = 0; // current index in tanns array
+- int itann = 0; // current index in itanns array
+- int ntoff = -1; // next visible type annotation code offset
+- int nitoff = -1; // next invisible type annotation code offset
+- int varTable = 0;
+- int varTypeTable = 0;
+- boolean zip = true;
+- boolean unzip = (context.flags & EXPAND_FRAMES) != 0;
+- int stackMap = 0;
+- int stackMapSize = 0;
+- int frameCount = 0;
+- Context frame = null;
+- Attribute attributes = null;
+-
+- for (int i = readUnsignedShort(u); i > 0; --i) {
+- String attrName = readUTF8(u + 2, c);
+- if ("LocalVariableTable".equals(attrName)) {
+- if ((context.flags & SKIP_DEBUG) == 0) {
+- varTable = u + 8;
+- for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
+- int label = readUnsignedShort(v + 10);
+- if (labels[label] == null) {
+- readLabel(label, labels).status |= Label.DEBUG;
+- }
+- label += readUnsignedShort(v + 12);
+- if (labels[label] == null) {
+- readLabel(label, labels).status |= Label.DEBUG;
+- }
+- v += 10;
+- }
+- }
+- } else if ("LocalVariableTypeTable".equals(attrName)) {
+- varTypeTable = u + 8;
+- } else if ("LineNumberTable".equals(attrName)) {
+- if ((context.flags & SKIP_DEBUG) == 0) {
+- for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
+- int label = readUnsignedShort(v + 10);
+- if (labels[label] == null) {
+- readLabel(label, labels).status |= Label.DEBUG;
+- }
+- labels[label].line = readUnsignedShort(v + 12);
+- v += 4;
+- }
+- }
+- } else if (ANNOTATIONS
+- && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+- tanns = readTypeAnnotations(mv, context, u + 8, true);
+- ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
+- : readUnsignedShort(tanns[0] + 1);
+- } else if (ANNOTATIONS
+- && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+- itanns = readTypeAnnotations(mv, context, u + 8, false);
+- nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
+- : readUnsignedShort(itanns[0] + 1);
+- } else if (FRAMES && "StackMapTable".equals(attrName)) {
+- if ((context.flags & SKIP_FRAMES) == 0) {
+- stackMap = u + 10;
+- stackMapSize = readInt(u + 4);
+- frameCount = readUnsignedShort(u + 8);
+- }
+- /*
+- * here we do not extract the labels corresponding to the
+- * attribute content. This would require a full parsing of the
+- * attribute, which would need to be repeated in the second
+- * phase (see below). Instead the content of the attribute is
+- * read one frame at a time (i.e. after a frame has been
+- * visited, the next frame is read), and the labels it contains
+- * are also extracted one frame at a time. Thanks to the
+- * ordering of frames, having only a "one frame lookahead" is
+- * not a problem, i.e. it is not possible to see an offset
+- * smaller than the offset of the current insn and for which no
+- * Label exist.
+- */
+- /*
+- * This is not true for UNINITIALIZED type offsets. We solve
+- * this by parsing the stack map table without a full decoding
+- * (see below).
+- */
+- } else if (FRAMES && "StackMap".equals(attrName)) {
+- if ((context.flags & SKIP_FRAMES) == 0) {
+- zip = false;
+- stackMap = u + 10;
+- stackMapSize = readInt(u + 4);
+- frameCount = readUnsignedShort(u + 8);
+- }
+- /*
+- * IMPORTANT! here we assume that the frames are ordered, as in
+- * the StackMapTable attribute, although this is not guaranteed
+- * by the attribute format.
+- */
+- } else {
+- for (int j = 0; j < context.attrs.length; ++j) {
+- if (context.attrs[j].type.equals(attrName)) {
+- Attribute attr = context.attrs[j].read(this, u + 8,
+- readInt(u + 4), c, codeStart - 8, labels);
+- if (attr != null) {
+- attr.next = attributes;
+- attributes = attr;
+- }
+- }
+- }
+- }
+- u += 6 + readInt(u + 4);
+- }
+- u += 2;
+-
+- // generates the first (implicit) stack map frame
+- if (FRAMES && stackMap != 0) {
+- /*
+- * for the first explicit frame the offset is not offset_delta + 1
+- * but only offset_delta; setting the implicit frame offset to -1
+- * allow the use of the "offset_delta + 1" rule in all cases
+- */
+- frame = context;
+- frame.offset = -1;
+- frame.mode = 0;
+- frame.localCount = 0;
+- frame.localDiff = 0;
+- frame.stackCount = 0;
+- frame.local = new Object[maxLocals];
+- frame.stack = new Object[maxStack];
+- if (unzip) {
+- getImplicitFrame(context);
+- }
+- /*
+- * Finds labels for UNINITIALIZED frame types. Instead of decoding
+- * each element of the stack map table, we look for 3 consecutive
+- * bytes that "look like" an UNINITIALIZED type (tag 8, offset
+- * within code bounds, NEW instruction at this offset). We may find
+- * false positives (i.e. not real UNINITIALIZED types), but this
+- * should be rare, and the only consequence will be the creation of
+- * an unneeded label. This is better than creating a label for each
+- * NEW instruction, and faster than fully decoding the whole stack
+- * map table.
+- */
+- for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) {
+- if (b[i] == 8) { // UNINITIALIZED FRAME TYPE
+- int v = readUnsignedShort(i + 1);
+- if (v >= 0 && v < codeLength) {
+- if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
+- readLabel(v, labels);
+- }
+- }
+- }
+- }
+- }
+-
+- // visits the instructions
+- u = codeStart;
+- while (u < codeEnd) {
+- int offset = u - codeStart;
+-
+- // visits the label and line number for this offset, if any
+- Label l = labels[offset];
+- if (l != null) {
+- mv.visitLabel(l);
+- if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) {
+- mv.visitLineNumber(l.line, l);
+- }
+- }
+-
+- // visits the frame for this offset, if any
+- while (FRAMES && frame != null
+- && (frame.offset == offset || frame.offset == -1)) {
+- // if there is a frame for this offset, makes the visitor visit
+- // it, and reads the next frame if there is one.
+- if (frame.offset != -1) {
+- if (!zip || unzip) {
+- mv.visitFrame(Opcodes.F_NEW, frame.localCount,
+- frame.local, frame.stackCount, frame.stack);
+- } else {
+- mv.visitFrame(frame.mode, frame.localDiff, frame.local,
+- frame.stackCount, frame.stack);
+- }
+- }
+- if (frameCount > 0) {
+- stackMap = readFrame(stackMap, zip, unzip, frame);
+- --frameCount;
+- } else {
+- frame = null;
+- }
+- }
+-
+- // visits the instruction at this offset
+- int opcode = b[u] & 0xFF;
+- switch (ClassWriter.TYPE[opcode]) {
+- case ClassWriter.NOARG_INSN:
+- mv.visitInsn(opcode);
+- u += 1;
+- break;
+- case ClassWriter.IMPLVAR_INSN:
+- if (opcode > Opcodes.ISTORE) {
+- opcode -= 59; // ISTORE_0
+- mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2),
+- opcode & 0x3);
+- } else {
+- opcode -= 26; // ILOAD_0
+- mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3);
+- }
+- u += 1;
+- break;
+- case ClassWriter.LABEL_INSN:
+- mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]);
+- u += 3;
+- break;
+- case ClassWriter.LABELW_INSN:
+- mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+- u += 5;
+- break;
+- case ClassWriter.WIDE_INSN:
+- opcode = b[u + 1] & 0xFF;
+- if (opcode == Opcodes.IINC) {
+- mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4));
+- u += 6;
+- } else {
+- mv.visitVarInsn(opcode, readUnsignedShort(u + 2));
+- u += 4;
+- }
+- break;
+- case ClassWriter.TABL_INSN: {
+- // skips 0 to 3 padding bytes
+- u = u + 4 - (offset & 3);
+- // reads instruction
+- int label = offset + readInt(u);
+- int min = readInt(u + 4);
+- int max = readInt(u + 8);
+- Label[] table = new Label[max - min + 1];
+- u += 12;
+- for (int i = 0; i < table.length; ++i) {
+- table[i] = labels[offset + readInt(u)];
+- u += 4;
+- }
+- mv.visitTableSwitchInsn(min, max, labels[label], table);
+- break;
+- }
+- case ClassWriter.LOOK_INSN: {
+- // skips 0 to 3 padding bytes
+- u = u + 4 - (offset & 3);
+- // reads instruction
+- int label = offset + readInt(u);
+- int len = readInt(u + 4);
+- int[] keys = new int[len];
+- Label[] values = new Label[len];
+- u += 8;
+- for (int i = 0; i < len; ++i) {
+- keys[i] = readInt(u);
+- values[i] = labels[offset + readInt(u + 4)];
+- u += 8;
+- }
+- mv.visitLookupSwitchInsn(labels[label], keys, values);
+- break;
+- }
+- case ClassWriter.VAR_INSN:
+- mv.visitVarInsn(opcode, b[u + 1] & 0xFF);
+- u += 2;
+- break;
+- case ClassWriter.SBYTE_INSN:
+- mv.visitIntInsn(opcode, b[u + 1]);
+- u += 2;
+- break;
+- case ClassWriter.SHORT_INSN:
+- mv.visitIntInsn(opcode, readShort(u + 1));
+- u += 3;
+- break;
+- case ClassWriter.LDC_INSN:
+- mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c));
+- u += 2;
+- break;
+- case ClassWriter.LDCW_INSN:
+- mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c));
+- u += 3;
+- break;
+- case ClassWriter.FIELDORMETH_INSN:
+- case ClassWriter.ITFMETH_INSN: {
+- int cpIndex = items[readUnsignedShort(u + 1)];
+- boolean itf = b[cpIndex - 1] == ClassWriter.IMETH;
+- String iowner = readClass(cpIndex, c);
+- cpIndex = items[readUnsignedShort(cpIndex + 2)];
+- String iname = readUTF8(cpIndex, c);
+- String idesc = readUTF8(cpIndex + 2, c);
+- if (opcode < Opcodes.INVOKEVIRTUAL) {
+- mv.visitFieldInsn(opcode, iowner, iname, idesc);
+- } else {
+- mv.visitMethodInsn(opcode, iowner, iname, idesc, itf);
+- }
+- if (opcode == Opcodes.INVOKEINTERFACE) {
+- u += 5;
+- } else {
+- u += 3;
+- }
+- break;
+- }
+- case ClassWriter.INDYMETH_INSN: {
+- int cpIndex = items[readUnsignedShort(u + 1)];
+- int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)];
+- Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c);
+- int bsmArgCount = readUnsignedShort(bsmIndex + 2);
+- Object[] bsmArgs = new Object[bsmArgCount];
+- bsmIndex += 4;
+- for (int i = 0; i < bsmArgCount; i++) {
+- bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c);
+- bsmIndex += 2;
+- }
+- cpIndex = items[readUnsignedShort(cpIndex + 2)];
+- String iname = readUTF8(cpIndex, c);
+- String idesc = readUTF8(cpIndex + 2, c);
+- mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs);
+- u += 5;
+- break;
+- }
+- case ClassWriter.TYPE_INSN:
+- mv.visitTypeInsn(opcode, readClass(u + 1, c));
+- u += 3;
+- break;
+- case ClassWriter.IINC_INSN:
+- mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]);
+- u += 3;
+- break;
+- // case MANA_INSN:
+- default:
+- mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF);
+- u += 4;
+- break;
+- }
+-
+- // visit the instruction annotations, if any
+- while (tanns != null && tann < tanns.length && ntoff <= offset) {
+- if (ntoff == offset) {
+- int v = readAnnotationTarget(context, tanns[tann]);
+- readAnnotationValues(v + 2, c, true,
+- mv.visitInsnAnnotation(context.typeRef,
+- context.typePath, readUTF8(v, c), true));
+- }
+- ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1
+- : readUnsignedShort(tanns[tann] + 1);
+- }
+- while (itanns != null && itann < itanns.length && nitoff <= offset) {
+- if (nitoff == offset) {
+- int v = readAnnotationTarget(context, itanns[itann]);
+- readAnnotationValues(v + 2, c, true,
+- mv.visitInsnAnnotation(context.typeRef,
+- context.typePath, readUTF8(v, c), false));
+- }
+- nitoff = ++itann >= itanns.length
+- || readByte(itanns[itann]) < 0x43 ? -1
+- : readUnsignedShort(itanns[itann] + 1);
+- }
+- }
+- if (labels[codeLength] != null) {
+- mv.visitLabel(labels[codeLength]);
+- }
+-
+- // visits the local variable tables
+- if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) {
+- int[] typeTable = null;
+- if (varTypeTable != 0) {
+- u = varTypeTable + 2;
+- typeTable = new int[readUnsignedShort(varTypeTable) * 3];
+- for (int i = typeTable.length; i > 0;) {
+- typeTable[--i] = u + 6; // signature
+- typeTable[--i] = readUnsignedShort(u + 8); // index
+- typeTable[--i] = readUnsignedShort(u); // start
+- u += 10;
+- }
+- }
+- u = varTable + 2;
+- for (int i = readUnsignedShort(varTable); i > 0; --i) {
+- int start = readUnsignedShort(u);
+- int length = readUnsignedShort(u + 2);
+- int index = readUnsignedShort(u + 8);
+- String vsignature = null;
+- if (typeTable != null) {
+- for (int j = 0; j < typeTable.length; j += 3) {
+- if (typeTable[j] == start && typeTable[j + 1] == index) {
+- vsignature = readUTF8(typeTable[j + 2], c);
+- break;
+- }
+- }
+- }
+- mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c),
+- vsignature, labels[start], labels[start + length],
+- index);
+- u += 10;
+- }
+- }
+-
+- // visits the local variables type annotations
+- if (tanns != null) {
+- for (int i = 0; i < tanns.length; ++i) {
+- if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) {
+- int v = readAnnotationTarget(context, tanns[i]);
+- v = readAnnotationValues(v + 2, c, true,
+- mv.visitLocalVariableAnnotation(context.typeRef,
+- context.typePath, context.start,
+- context.end, context.index, readUTF8(v, c),
+- true));
+- }
+- }
+- }
+- if (itanns != null) {
+- for (int i = 0; i < itanns.length; ++i) {
+- if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) {
+- int v = readAnnotationTarget(context, itanns[i]);
+- v = readAnnotationValues(v + 2, c, true,
+- mv.visitLocalVariableAnnotation(context.typeRef,
+- context.typePath, context.start,
+- context.end, context.index, readUTF8(v, c),
+- false));
+- }
+- }
+- }
+-
+- // visits the code attributes
+- while (attributes != null) {
+- Attribute attr = attributes.next;
+- attributes.next = null;
+- mv.visitAttribute(attributes);
+- attributes = attr;
+- }
+-
+- // visits the max stack and max locals values
+- mv.visitMaxs(maxStack, maxLocals);
+- }
+-
+- /**
+- * Parses a type annotation table to find the labels, and to visit the try
+- * catch block annotations.
+- *
+- * @param u
+- * the start offset of a type annotation table.
+- * @param mv
+- * the method visitor to be used to visit the try catch block
+- * annotations.
+- * @param context
+- * information about the class being parsed.
+- * @param visible
+- * if the type annotation table to parse contains runtime visible
+- * annotations.
+- * @return the start offset of each type annotation in the parsed table.
+- */
+- private int[] readTypeAnnotations(final MethodVisitor mv,
+- final Context context, int u, boolean visible) {
+- char[] c = context.buffer;
+- int[] offsets = new int[readUnsignedShort(u)];
+- u += 2;
+- for (int i = 0; i < offsets.length; ++i) {
+- offsets[i] = u;
+- int target = readInt(u);
+- switch (target >>> 24) {
+- case 0x00: // CLASS_TYPE_PARAMETER
+- case 0x01: // METHOD_TYPE_PARAMETER
+- case 0x16: // METHOD_FORMAL_PARAMETER
+- u += 2;
+- break;
+- case 0x13: // FIELD
+- case 0x14: // METHOD_RETURN
+- case 0x15: // METHOD_RECEIVER
+- u += 1;
+- break;
+- case 0x40: // LOCAL_VARIABLE
+- case 0x41: // RESOURCE_VARIABLE
+- for (int j = readUnsignedShort(u + 1); j > 0; --j) {
+- int start = readUnsignedShort(u + 3);
+- int length = readUnsignedShort(u + 5);
+- readLabel(start, context.labels);
+- readLabel(start + length, context.labels);
+- u += 6;
+- }
+- u += 3;
+- break;
+- case 0x47: // CAST
+- case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+- case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+- case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+- case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+- u += 4;
+- break;
+- // case 0x10: // CLASS_EXTENDS
+- // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+- // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+- // case 0x17: // THROWS
+- // case 0x42: // EXCEPTION_PARAMETER
+- // case 0x43: // INSTANCEOF
+- // case 0x44: // NEW
+- // case 0x45: // CONSTRUCTOR_REFERENCE
+- // case 0x46: // METHOD_REFERENCE
+- default:
+- u += 3;
+- break;
+- }
+- int pathLength = readByte(u);
+- if ((target >>> 24) == 0x42) {
+- TypePath path = pathLength == 0 ? null : new TypePath(b, u);
+- u += 1 + 2 * pathLength;
+- u = readAnnotationValues(u + 2, c, true,
+- mv.visitTryCatchAnnotation(target, path,
+- readUTF8(u, c), visible));
+- } else {
+- u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null);
+- }
+- }
+- return offsets;
+- }
+-
+- /**
+- * Parses the header of a type annotation to extract its target_type and
+- * target_path (the result is stored in the given context), and returns the
+- * start offset of the rest of the type_annotation structure (i.e. the
+- * offset to the type_index field, which is followed by
+- * num_element_value_pairs and then the name,value pairs).
+- *
+- * @param context
+- * information about the class being parsed. This is where the
+- * extracted target_type and target_path must be stored.
+- * @param u
+- * the start offset of a type_annotation structure.
+- * @return the start offset of the rest of the type_annotation structure.
+- */
+- private int readAnnotationTarget(final Context context, int u) {
+- int target = readInt(u);
+- switch (target >>> 24) {
+- case 0x00: // CLASS_TYPE_PARAMETER
+- case 0x01: // METHOD_TYPE_PARAMETER
+- case 0x16: // METHOD_FORMAL_PARAMETER
+- target &= 0xFFFF0000;
+- u += 2;
+- break;
+- case 0x13: // FIELD
+- case 0x14: // METHOD_RETURN
+- case 0x15: // METHOD_RECEIVER
+- target &= 0xFF000000;
+- u += 1;
+- break;
+- case 0x40: // LOCAL_VARIABLE
+- case 0x41: { // RESOURCE_VARIABLE
+- target &= 0xFF000000;
+- int n = readUnsignedShort(u + 1);
+- context.start = new Label[n];
+- context.end = new Label[n];
+- context.index = new int[n];
+- u += 3;
+- for (int i = 0; i < n; ++i) {
+- int start = readUnsignedShort(u);
+- int length = readUnsignedShort(u + 2);
+- context.start[i] = readLabel(start, context.labels);
+- context.end[i] = readLabel(start + length, context.labels);
+- context.index[i] = readUnsignedShort(u + 4);
+- u += 6;
+- }
+- break;
+- }
+- case 0x47: // CAST
+- case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+- case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT
+- case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+- case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT
+- target &= 0xFF0000FF;
+- u += 4;
+- break;
+- // case 0x10: // CLASS_EXTENDS
+- // case 0x11: // CLASS_TYPE_PARAMETER_BOUND
+- // case 0x12: // METHOD_TYPE_PARAMETER_BOUND
+- // case 0x17: // THROWS
+- // case 0x42: // EXCEPTION_PARAMETER
+- // case 0x43: // INSTANCEOF
+- // case 0x44: // NEW
+- // case 0x45: // CONSTRUCTOR_REFERENCE
+- // case 0x46: // METHOD_REFERENCE
+- default:
+- target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000;
+- u += 3;
+- break;
+- }
+- int pathLength = readByte(u);
+- context.typeRef = target;
+- context.typePath = pathLength == 0 ? null : new TypePath(b, u);
+- return u + 1 + 2 * pathLength;
+- }
+-
+- /**
+- * Reads parameter annotations and makes the given visitor visit them.
+- *
+- * @param mv
+- * the visitor that must visit the annotations.
+- * @param context
+- * information about the class being parsed.
+- * @param v
+- * start offset in {@link #b b} of the annotations to be read.
+- * @param visible
+- * true if the annotations to be read are visible at
+- * runtime.
+- */
+- private void readParameterAnnotations(final MethodVisitor mv,
+- final Context context, int v, final boolean visible) {
+- int i;
+- int n = b[v++] & 0xFF;
+- // workaround for a bug in javac (javac compiler generates a parameter
+- // annotation array whose size is equal to the number of parameters in
+- // the Java source file, while it should generate an array whose size is
+- // equal to the number of parameters in the method descriptor - which
+- // includes the synthetic parameters added by the compiler). This work-
+- // around supposes that the synthetic parameters are the first ones.
+- int synthetics = Type.getArgumentTypes(context.desc).length - n;
+- AnnotationVisitor av;
+- for (i = 0; i < synthetics; ++i) {
+- // virtual annotation to detect synthetic parameters in MethodWriter
+- av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false);
+- if (av != null) {
+- av.visitEnd();
+- }
+- }
+- char[] c = context.buffer;
+- for (; i < n + synthetics; ++i) {
+- int j = readUnsignedShort(v);
+- v += 2;
+- for (; j > 0; --j) {
+- av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible);
+- v = readAnnotationValues(v + 2, c, true, av);
+- }
+- }
+- }
+-
+- /**
+- * Reads the values of an annotation and makes the given visitor visit them.
+- *
+- * @param v
+- * the start offset in {@link #b b} of the values to be read
+- * (including the unsigned short that gives the number of
+- * values).
+- * @param buf
+- * buffer to be used to call {@link #readUTF8 readUTF8},
+- * {@link #readClass(int,char[]) readClass} or {@link #readConst
+- * readConst}.
+- * @param named
+- * if the annotation values are named or not.
+- * @param av
+- * the visitor that must visit the values.
+- * @return the end offset of the annotation values.
+- */
+- private int readAnnotationValues(int v, final char[] buf,
+- final boolean named, final AnnotationVisitor av) {
+- int i = readUnsignedShort(v);
+- v += 2;
+- if (named) {
+- for (; i > 0; --i) {
+- v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
+- }
+- } else {
+- for (; i > 0; --i) {
+- v = readAnnotationValue(v, buf, null, av);
+- }
+- }
+- if (av != null) {
+- av.visitEnd();
+- }
+- return v;
+- }
+-
+- /**
+- * Reads a value of an annotation and makes the given visitor visit it.
+- *
+- * @param v
+- * the start offset in {@link #b b} of the value to be read
+- * (not including the value name constant pool index ).
+- * @param buf
+- * buffer to be used to call {@link #readUTF8 readUTF8},
+- * {@link #readClass(int,char[]) readClass} or {@link #readConst
+- * readConst}.
+- * @param name
+- * the name of the value to be read.
+- * @param av
+- * the visitor that must visit the value.
+- * @return the end offset of the annotation value.
+- */
+- private int readAnnotationValue(int v, final char[] buf, final String name,
+- final AnnotationVisitor av) {
+- int i;
+- if (av == null) {
+- switch (b[v] & 0xFF) {
+- case 'e': // enum_const_value
+- return v + 5;
+- case '@': // annotation_value
+- return readAnnotationValues(v + 3, buf, true, null);
+- case '[': // array_value
+- return readAnnotationValues(v + 1, buf, false, null);
+- default:
+- return v + 3;
+- }
+- }
+- switch (b[v++] & 0xFF) {
+- case 'I': // pointer to CONSTANT_Integer
+- case 'J': // pointer to CONSTANT_Long
+- case 'F': // pointer to CONSTANT_Float
+- case 'D': // pointer to CONSTANT_Double
+- av.visit(name, readConst(readUnsignedShort(v), buf));
+- v += 2;
+- break;
+- case 'B': // pointer to CONSTANT_Byte
+- av.visit(name,
+- new Byte((byte) readInt(items[readUnsignedShort(v)])));
+- v += 2;
+- break;
+- case 'Z': // pointer to CONSTANT_Boolean
+- av.visit(name,
+- readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE
+- : Boolean.TRUE);
+- v += 2;
+- break;
+- case 'S': // pointer to CONSTANT_Short
+- av.visit(name, new Short(
+- (short) readInt(items[readUnsignedShort(v)])));
+- v += 2;
+- break;
+- case 'C': // pointer to CONSTANT_Char
+- av.visit(name, new Character(
+- (char) readInt(items[readUnsignedShort(v)])));
+- v += 2;
+- break;
+- case 's': // pointer to CONSTANT_Utf8
+- av.visit(name, readUTF8(v, buf));
+- v += 2;
+- break;
+- case 'e': // enum_const_value
+- av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
+- v += 4;
+- break;
+- case 'c': // class_info
+- av.visit(name, Type.getType(readUTF8(v, buf)));
+- v += 2;
+- break;
+- case '@': // annotation_value
+- v = readAnnotationValues(v + 2, buf, true,
+- av.visitAnnotation(name, readUTF8(v, buf)));
+- break;
+- case '[': // array_value
+- int size = readUnsignedShort(v);
+- v += 2;
+- if (size == 0) {
+- return readAnnotationValues(v - 2, buf, false,
+- av.visitArray(name));
+- }
+- switch (this.b[v++] & 0xFF) {
+- case 'B':
+- byte[] bv = new byte[size];
+- for (i = 0; i < size; i++) {
+- bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
+- v += 3;
+- }
+- av.visit(name, bv);
+- --v;
+- break;
+- case 'Z':
+- boolean[] zv = new boolean[size];
+- for (i = 0; i < size; i++) {
+- zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
+- v += 3;
+- }
+- av.visit(name, zv);
+- --v;
+- break;
+- case 'S':
+- short[] sv = new short[size];
+- for (i = 0; i < size; i++) {
+- sv[i] = (short) readInt(items[readUnsignedShort(v)]);
+- v += 3;
+- }
+- av.visit(name, sv);
+- --v;
+- break;
+- case 'C':
+- char[] cv = new char[size];
+- for (i = 0; i < size; i++) {
+- cv[i] = (char) readInt(items[readUnsignedShort(v)]);
+- v += 3;
+- }
+- av.visit(name, cv);
+- --v;
+- break;
+- case 'I':
+- int[] iv = new int[size];
+- for (i = 0; i < size; i++) {
+- iv[i] = readInt(items[readUnsignedShort(v)]);
+- v += 3;
+- }
+- av.visit(name, iv);
+- --v;
+- break;
+- case 'J':
+- long[] lv = new long[size];
+- for (i = 0; i < size; i++) {
+- lv[i] = readLong(items[readUnsignedShort(v)]);
+- v += 3;
+- }
+- av.visit(name, lv);
+- --v;
+- break;
+- case 'F':
+- float[] fv = new float[size];
+- for (i = 0; i < size; i++) {
+- fv[i] = Float
+- .intBitsToFloat(readInt(items[readUnsignedShort(v)]));
+- v += 3;
+- }
+- av.visit(name, fv);
+- --v;
+- break;
+- case 'D':
+- double[] dv = new double[size];
+- for (i = 0; i < size; i++) {
+- dv[i] = Double
+- .longBitsToDouble(readLong(items[readUnsignedShort(v)]));
+- v += 3;
+- }
+- av.visit(name, dv);
+- --v;
+- break;
+- default:
+- v = readAnnotationValues(v - 3, buf, false, av.visitArray(name));
+- }
+- }
+- return v;
+- }
+-
+- /**
+- * Computes the implicit frame of the method currently being parsed (as
+- * defined in the given {@link Context}) and stores it in the given context.
+- *
+- * @param frame
+- * information about the class being parsed.
+- */
+- private void getImplicitFrame(final Context frame) {
+- String desc = frame.desc;
+- Object[] locals = frame.local;
+- int local = 0;
+- if ((frame.access & Opcodes.ACC_STATIC) == 0) {
+- if ("".equals(frame.name)) {
+- locals[local++] = Opcodes.UNINITIALIZED_THIS;
+- } else {
+- locals[local++] = readClass(header + 2, frame.buffer);
+- }
+- }
+- int i = 1;
+- loop: while (true) {
+- int j = i;
+- switch (desc.charAt(i++)) {
+- case 'Z':
+- case 'C':
+- case 'B':
+- case 'S':
+- case 'I':
+- locals[local++] = Opcodes.INTEGER;
+- break;
+- case 'F':
+- locals[local++] = Opcodes.FLOAT;
+- break;
+- case 'J':
+- locals[local++] = Opcodes.LONG;
+- break;
+- case 'D':
+- locals[local++] = Opcodes.DOUBLE;
+- break;
+- case '[':
+- while (desc.charAt(i) == '[') {
+- ++i;
+- }
+- if (desc.charAt(i) == 'L') {
+- ++i;
+- while (desc.charAt(i) != ';') {
+- ++i;
+- }
+- }
+- locals[local++] = desc.substring(j, ++i);
+- break;
+- case 'L':
+- while (desc.charAt(i) != ';') {
+- ++i;
+- }
+- locals[local++] = desc.substring(j + 1, i++);
+- break;
+- default:
+- break loop;
+- }
+- }
+- frame.localCount = local;
+- }
+-
+- /**
+- * Reads a stack map frame and stores the result in the given
+- * {@link Context} object.
+- *
+- * @param stackMap
+- * the start offset of a stack map frame in the class file.
+- * @param zip
+- * if the stack map frame at stackMap is compressed or not.
+- * @param unzip
+- * if the stack map frame must be uncompressed.
+- * @param frame
+- * where the parsed stack map frame must be stored.
+- * @return the offset of the first byte following the parsed frame.
+- */
+- private int readFrame(int stackMap, boolean zip, boolean unzip,
+- Context frame) {
+- char[] c = frame.buffer;
+- Label[] labels = frame.labels;
+- int tag;
+- int delta;
+- if (zip) {
+- tag = b[stackMap++] & 0xFF;
+- } else {
+- tag = MethodWriter.FULL_FRAME;
+- frame.offset = -1;
+- }
+- frame.localDiff = 0;
+- if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
+- delta = tag;
+- frame.mode = Opcodes.F_SAME;
+- frame.stackCount = 0;
+- } else if (tag < MethodWriter.RESERVED) {
+- delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
+- stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
+- frame.mode = Opcodes.F_SAME1;
+- frame.stackCount = 1;
+- } else {
+- delta = readUnsignedShort(stackMap);
+- stackMap += 2;
+- if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+- stackMap = readFrameType(frame.stack, 0, stackMap, c, labels);
+- frame.mode = Opcodes.F_SAME1;
+- frame.stackCount = 1;
+- } else if (tag >= MethodWriter.CHOP_FRAME
+- && tag < MethodWriter.SAME_FRAME_EXTENDED) {
+- frame.mode = Opcodes.F_CHOP;
+- frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag;
+- frame.localCount -= frame.localDiff;
+- frame.stackCount = 0;
+- } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
+- frame.mode = Opcodes.F_SAME;
+- frame.stackCount = 0;
+- } else if (tag < MethodWriter.FULL_FRAME) {
+- int local = unzip ? frame.localCount : 0;
+- for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) {
+- stackMap = readFrameType(frame.local, local++, stackMap, c,
+- labels);
+- }
+- frame.mode = Opcodes.F_APPEND;
+- frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED;
+- frame.localCount += frame.localDiff;
+- frame.stackCount = 0;
+- } else { // if (tag == FULL_FRAME) {
+- frame.mode = Opcodes.F_FULL;
+- int n = readUnsignedShort(stackMap);
+- stackMap += 2;
+- frame.localDiff = n;
+- frame.localCount = n;
+- for (int local = 0; n > 0; n--) {
+- stackMap = readFrameType(frame.local, local++, stackMap, c,
+- labels);
+- }
+- n = readUnsignedShort(stackMap);
+- stackMap += 2;
+- frame.stackCount = n;
+- for (int stack = 0; n > 0; n--) {
+- stackMap = readFrameType(frame.stack, stack++, stackMap, c,
+- labels);
+- }
+- }
+- }
+- frame.offset += delta + 1;
+- readLabel(frame.offset, labels);
+- return stackMap;
+- }
+-
+- /**
+- * Reads a stack map frame type and stores it at the given index in the
+- * given array.
+- *
+- * @param frame
+- * the array where the parsed type must be stored.
+- * @param index
+- * the index in 'frame' where the parsed type must be stored.
+- * @param v
+- * the start offset of the stack map frame type to read.
+- * @param buf
+- * a buffer to read strings.
+- * @param labels
+- * the labels of the method currently being parsed, indexed by
+- * their offset. If the parsed type is an Uninitialized type, a
+- * new label for the corresponding NEW instruction is stored in
+- * this array if it does not already exist.
+- * @return the offset of the first byte after the parsed type.
+- */
+- private int readFrameType(final Object[] frame, final int index, int v,
+- final char[] buf, final Label[] labels) {
+- int type = b[v++] & 0xFF;
+- switch (type) {
+- case 0:
+- frame[index] = Opcodes.TOP;
+- break;
+- case 1:
+- frame[index] = Opcodes.INTEGER;
+- break;
+- case 2:
+- frame[index] = Opcodes.FLOAT;
+- break;
+- case 3:
+- frame[index] = Opcodes.DOUBLE;
+- break;
+- case 4:
+- frame[index] = Opcodes.LONG;
+- break;
+- case 5:
+- frame[index] = Opcodes.NULL;
+- break;
+- case 6:
+- frame[index] = Opcodes.UNINITIALIZED_THIS;
+- break;
+- case 7: // Object
+- frame[index] = readClass(v, buf);
+- v += 2;
+- break;
+- default: // Uninitialized
+- frame[index] = readLabel(readUnsignedShort(v), labels);
+- v += 2;
+- }
+- return v;
+- }
+-
+- /**
+- * Returns the label corresponding to the given offset. The default
+- * implementation of this method creates a label for the given offset if it
+- * has not been already created.
+- *
+- * @param offset
+- * a bytecode offset in a method.
+- * @param labels
+- * the already created labels, indexed by their offset. If a
+- * label already exists for offset this method must not create a
+- * new one. Otherwise it must store the new label in this array.
+- * @return a non null Label, which must be equal to labels[offset].
+- */
+- protected Label readLabel(int offset, Label[] labels) {
+- if (labels[offset] == null) {
+- labels[offset] = new Label();
+- }
+- return labels[offset];
+- }
+-
+- /**
+- * Returns the start index of the attribute_info structure of this class.
+- *
+- * @return the start index of the attribute_info structure of this class.
+- */
+- private int getAttributes() {
+- // skips the header
+- int u = header + 8 + readUnsignedShort(header + 6) * 2;
+- // skips fields and methods
+- for (int i = readUnsignedShort(u); i > 0; --i) {
+- for (int j = readUnsignedShort(u + 8); j > 0; --j) {
+- u += 6 + readInt(u + 12);
+- }
+- u += 8;
+- }
+- u += 2;
+- for (int i = readUnsignedShort(u); i > 0; --i) {
+- for (int j = readUnsignedShort(u + 8); j > 0; --j) {
+- u += 6 + readInt(u + 12);
+- }
+- u += 8;
+- }
+- // the attribute_info structure starts just after the methods
+- return u + 2;
+- }
+-
+- /**
+- * Reads an attribute in {@link #b b}.
+- *
+- * @param attrs
+- * prototypes of the attributes that must be parsed during the
+- * visit of the class. Any attribute whose type is not equal to
+- * the type of one the prototypes is ignored (i.e. an empty
+- * {@link Attribute} instance is returned).
+- * @param type
+- * the type of the attribute.
+- * @param off
+- * index of the first byte of the attribute's content in
+- * {@link #b b}. The 6 attribute header bytes, containing the
+- * type and the length of the attribute, are not taken into
+- * account here (they have already been read).
+- * @param len
+- * the length of the attribute's content.
+- * @param buf
+- * buffer to be used to call {@link #readUTF8 readUTF8},
+- * {@link #readClass(int,char[]) readClass} or {@link #readConst
+- * readConst}.
+- * @param codeOff
+- * index of the first byte of code's attribute content in
+- * {@link #b b}, or -1 if the attribute to be read is not a code
+- * attribute. The 6 attribute header bytes, containing the type
+- * and the length of the attribute, are not taken into account
+- * here.
+- * @param labels
+- * the labels of the method's code, or null if the
+- * attribute to be read is not a code attribute.
+- * @return the attribute that has been read, or null to skip this
+- * attribute.
+- */
+- private Attribute readAttribute(final Attribute[] attrs, final String type,
+- final int off, final int len, final char[] buf, final int codeOff,
+- final Label[] labels) {
+- for (int i = 0; i < attrs.length; ++i) {
+- if (attrs[i].type.equals(type)) {
+- return attrs[i].read(this, off, len, buf, codeOff, labels);
+- }
+- }
+- return new Attribute(type).read(this, off, len, null, -1, null);
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods: low level parsing
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns the number of constant pool items in {@link #b b}.
+- *
+- * @return the number of constant pool items in {@link #b b}.
+- */
+- public int getItemCount() {
+- return items.length;
+- }
+-
+- /**
+- * Returns the start index of the constant pool item in {@link #b b}, plus
+- * one. This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param item
+- * the index a constant pool item.
+- * @return the start index of the constant pool item in {@link #b b}, plus
+- * one.
+- */
+- public int getItem(final int item) {
+- return items[item];
+- }
+-
+- /**
+- * Returns the maximum length of the strings contained in the constant pool
+- * of the class.
+- *
+- * @return the maximum length of the strings contained in the constant pool
+- * of the class.
+- */
+- public int getMaxStringLength() {
+- return maxStringLength;
+- }
+-
+- /**
+- * Reads a byte value in {@link #b b}. This method is intended for
+- * {@link Attribute} sub classes, and is normally not needed by class
+- * generators or adapters.
+- *
+- * @param index
+- * the start index of the value to be read in {@link #b b}.
+- * @return the read value.
+- */
+- public int readByte(final int index) {
+- return b[index] & 0xFF;
+- }
+-
+- /**
+- * Reads an unsigned short value in {@link #b b}. This method is intended
+- * for {@link Attribute} sub classes, and is normally not needed by class
+- * generators or adapters.
+- *
+- * @param index
+- * the start index of the value to be read in {@link #b b}.
+- * @return the read value.
+- */
+- public int readUnsignedShort(final int index) {
+- byte[] b = this.b;
+- return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
+- }
+-
+- /**
+- * Reads a signed short value in {@link #b b}. This method is intended
+- * for {@link Attribute} sub classes, and is normally not needed by class
+- * generators or adapters.
+- *
+- * @param index
+- * the start index of the value to be read in {@link #b b}.
+- * @return the read value.
+- */
+- public short readShort(final int index) {
+- byte[] b = this.b;
+- return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
+- }
+-
+- /**
+- * Reads a signed int value in {@link #b b}. This method is intended for
+- * {@link Attribute} sub classes, and is normally not needed by class
+- * generators or adapters.
+- *
+- * @param index
+- * the start index of the value to be read in {@link #b b}.
+- * @return the read value.
+- */
+- public int readInt(final int index) {
+- byte[] b = this.b;
+- return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
+- | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
+- }
+-
+- /**
+- * Reads a signed long value in {@link #b b}. This method is intended for
+- * {@link Attribute} sub classes, and is normally not needed by class
+- * generators or adapters.
+- *
+- * @param index
+- * the start index of the value to be read in {@link #b b}.
+- * @return the read value.
+- */
+- public long readLong(final int index) {
+- long l1 = readInt(index);
+- long l0 = readInt(index + 4) & 0xFFFFFFFFL;
+- return (l1 << 32) | l0;
+- }
+-
+- /**
+- * Reads an UTF8 string constant pool item in {@link #b b}. This method
+- * is intended for {@link Attribute} sub classes, and is normally not needed
+- * by class generators or adapters.
+- *
+- * @param index
+- * the start index of an unsigned short value in {@link #b b},
+- * whose value is the index of an UTF8 constant pool item.
+- * @param buf
+- * buffer to be used to read the item. This buffer must be
+- * sufficiently large. It is not automatically resized.
+- * @return the String corresponding to the specified UTF8 item.
+- */
+- public String readUTF8(int index, final char[] buf) {
+- int item = readUnsignedShort(index);
+- if (index == 0 || item == 0) {
+- return null;
+- }
+- String s = strings[item];
+- if (s != null) {
+- return s;
+- }
+- index = items[item];
+- return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf);
+- }
+-
+- /**
+- * Reads UTF8 string in {@link #b b}.
+- *
+- * @param index
+- * start offset of the UTF8 string to be read.
+- * @param utfLen
+- * length of the UTF8 string to be read.
+- * @param buf
+- * buffer to be used to read the string. This buffer must be
+- * sufficiently large. It is not automatically resized.
+- * @return the String corresponding to the specified UTF8 string.
+- */
+- private String readUTF(int index, final int utfLen, final char[] buf) {
+- int endIndex = index + utfLen;
+- byte[] b = this.b;
+- int strLen = 0;
+- int c;
+- int st = 0;
+- char cc = 0;
+- while (index < endIndex) {
+- c = b[index++];
+- switch (st) {
+- case 0:
+- c = c & 0xFF;
+- if (c < 0x80) { // 0xxxxxxx
+- buf[strLen++] = (char) c;
+- } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx
+- cc = (char) (c & 0x1F);
+- st = 1;
+- } else { // 1110 xxxx 10xx xxxx 10xx xxxx
+- cc = (char) (c & 0x0F);
+- st = 2;
+- }
+- break;
+-
+- case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char
+- buf[strLen++] = (char) ((cc << 6) | (c & 0x3F));
+- st = 0;
+- break;
+-
+- case 2: // byte 2 of 3-byte char
+- cc = (char) ((cc << 6) | (c & 0x3F));
+- st = 1;
+- break;
+- }
+- }
+- return new String(buf, 0, strLen);
+- }
+-
+- /**
+- * Reads a class constant pool item in {@link #b b}. This method is
+- * intended for {@link Attribute} sub classes, and is normally not needed by
+- * class generators or adapters.
+- *
+- * @param index
+- * the start index of an unsigned short value in {@link #b b},
+- * whose value is the index of a class constant pool item.
+- * @param buf
+- * buffer to be used to read the item. This buffer must be
+- * sufficiently large. It is not automatically resized.
+- * @return the String corresponding to the specified class item.
+- */
+- public String readClass(final int index, final char[] buf) {
+- // computes the start index of the CONSTANT_Class item in b
+- // and reads the CONSTANT_Utf8 item designated by
+- // the first two bytes of this CONSTANT_Class item
+- return readUTF8(items[readUnsignedShort(index)], buf);
+- }
+-
+- /**
+- * Reads a numeric or string constant pool item in {@link #b b}. This
+- * method is intended for {@link Attribute} sub classes, and is normally not
+- * needed by class generators or adapters.
+- *
+- * @param item
+- * the index of a constant pool item.
+- * @param buf
+- * buffer to be used to read the item. This buffer must be
+- * sufficiently large. It is not automatically resized.
+- * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double},
+- * {@link String}, {@link Type} or {@link Handle} corresponding to
+- * the given constant pool item.
+- */
+- public Object readConst(final int item, final char[] buf) {
+- int index = items[item];
+- switch (b[index - 1]) {
+- case ClassWriter.INT:
+- return new Integer(readInt(index));
+- case ClassWriter.FLOAT:
+- return new Float(Float.intBitsToFloat(readInt(index)));
+- case ClassWriter.LONG:
+- return new Long(readLong(index));
+- case ClassWriter.DOUBLE:
+- return new Double(Double.longBitsToDouble(readLong(index)));
+- case ClassWriter.CLASS:
+- return Type.getObjectType(readUTF8(index, buf));
+- case ClassWriter.STR:
+- return readUTF8(index, buf);
+- case ClassWriter.MTYPE:
+- return Type.getMethodType(readUTF8(index, buf));
+- default: // case ClassWriter.HANDLE_BASE + [1..9]:
+- int tag = readByte(index);
+- int[] items = this.items;
+- int cpIndex = items[readUnsignedShort(index + 1)];
+- String owner = readClass(cpIndex, buf);
+- cpIndex = items[readUnsignedShort(cpIndex + 2)];
+- String name = readUTF8(cpIndex, buf);
+- String desc = readUTF8(cpIndex + 2, buf);
+- return new Handle(tag, owner, name, desc);
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/ClassVisitor.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/ClassVisitor.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/ClassVisitor.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/ClassVisitor.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,320 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A visitor to visit a Java class. The methods of this class must be called in
+- * the following order: visit [ visitSource ] [
+- * visitOuterClass ] ( visitAnnotation |
+- * visitTypeAnnotation | visitAttribute )* (
+- * visitInnerClass | visitField | visitMethod )*
+- * visitEnd .
+- *
+- * @author Eric Bruneton
+- */
+-public abstract class ClassVisitor {
+-
+- /**
+- * The ASM API version implemented by this visitor. The value of this field
+- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- protected final int api;
+-
+- /**
+- * The class visitor to which this visitor must delegate method calls. May
+- * be null.
+- */
+- protected ClassVisitor cv;
+-
+- /**
+- * Constructs a new {@link ClassVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- public ClassVisitor(final int api) {
+- this(api, null);
+- }
+-
+- /**
+- * Constructs a new {@link ClassVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param cv
+- * the class visitor to which this visitor must delegate method
+- * calls. May be null.
+- */
+- public ClassVisitor(final int api, final ClassVisitor cv) {
+- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+- throw new IllegalArgumentException();
+- }
+- this.api = api;
+- this.cv = cv;
+- }
+-
+- /**
+- * Visits the header of the class.
+- *
+- * @param version
+- * the class version.
+- * @param access
+- * the class's access flags (see {@link Opcodes}). This parameter
+- * also indicates if the class is deprecated.
+- * @param name
+- * the internal name of the class (see
+- * {@link Type#getInternalName() getInternalName}).
+- * @param signature
+- * the signature of this class. May be null if the class
+- * is not a generic one, and does not extend or implement generic
+- * classes or interfaces.
+- * @param superName
+- * the internal of name of the super class (see
+- * {@link Type#getInternalName() getInternalName}). For
+- * interfaces, the super class is {@link Object}. May be
+- * null , but only for the {@link Object} class.
+- * @param interfaces
+- * the internal names of the class's interfaces (see
+- * {@link Type#getInternalName() getInternalName}). May be
+- * null .
+- */
+- public void visit(int version, int access, String name, String signature,
+- String superName, String[] interfaces) {
+- if (cv != null) {
+- cv.visit(version, access, name, signature, superName, interfaces);
+- }
+- }
+-
+- /**
+- * Visits the source of the class.
+- *
+- * @param source
+- * the name of the source file from which the class was compiled.
+- * May be null .
+- * @param debug
+- * additional debug information to compute the correspondance
+- * between source and compiled elements of the class. May be
+- * null .
+- */
+- public void visitSource(String source, String debug) {
+- if (cv != null) {
+- cv.visitSource(source, debug);
+- }
+- }
+-
+- /**
+- * Visits the enclosing class of the class. This method must be called only
+- * if the class has an enclosing class.
+- *
+- * @param owner
+- * internal name of the enclosing class of the class.
+- * @param name
+- * the name of the method that contains the class, or
+- * null if the class is not enclosed in a method of its
+- * enclosing class.
+- * @param desc
+- * the descriptor of the method that contains the class, or
+- * null if the class is not enclosed in a method of its
+- * enclosing class.
+- */
+- public void visitOuterClass(String owner, String name, String desc) {
+- if (cv != null) {
+- cv.visitOuterClass(owner, name, desc);
+- }
+- }
+-
+- /**
+- * Visits an annotation of the class.
+- *
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+- if (cv != null) {
+- return cv.visitAnnotation(desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits an annotation on a type in the class signature.
+- *
+- * @param typeRef
+- * a reference to the annotated type. The sort of this type
+- * reference must be {@link TypeReference#CLASS_TYPE_PARAMETER
+- * CLASS_TYPE_PARAMETER},
+- * {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND
+- * CLASS_TYPE_PARAMETER_BOUND} or
+- * {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See
+- * {@link TypeReference}.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitTypeAnnotation(int typeRef,
+- TypePath typePath, String desc, boolean visible) {
+- if (api < Opcodes.ASM5) {
+- throw new RuntimeException();
+- }
+- if (cv != null) {
+- return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits a non standard attribute of the class.
+- *
+- * @param attr
+- * an attribute.
+- */
+- public void visitAttribute(Attribute attr) {
+- if (cv != null) {
+- cv.visitAttribute(attr);
+- }
+- }
+-
+- /**
+- * Visits information about an inner class. This inner class is not
+- * necessarily a member of the class being visited.
+- *
+- * @param name
+- * the internal name of an inner class (see
+- * {@link Type#getInternalName() getInternalName}).
+- * @param outerName
+- * the internal name of the class to which the inner class
+- * belongs (see {@link Type#getInternalName() getInternalName}).
+- * May be null for not member classes.
+- * @param innerName
+- * the (simple) name of the inner class inside its enclosing
+- * class. May be null for anonymous inner classes.
+- * @param access
+- * the access flags of the inner class as originally declared in
+- * the enclosing class.
+- */
+- public void visitInnerClass(String name, String outerName,
+- String innerName, int access) {
+- if (cv != null) {
+- cv.visitInnerClass(name, outerName, innerName, access);
+- }
+- }
+-
+- /**
+- * Visits a field of the class.
+- *
+- * @param access
+- * the field's access flags (see {@link Opcodes}). This parameter
+- * also indicates if the field is synthetic and/or deprecated.
+- * @param name
+- * the field's name.
+- * @param desc
+- * the field's descriptor (see {@link Type Type}).
+- * @param signature
+- * the field's signature. May be null if the field's
+- * type does not use generic types.
+- * @param value
+- * the field's initial value. This parameter, which may be
+- * null if the field does not have an initial value,
+- * must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+- * {@link Double} or a {@link String} (for int ,
+- * float , long or String fields
+- * respectively). This parameter is only used for static
+- * fields . Its value is ignored for non static fields, which
+- * must be initialized through bytecode instructions in
+- * constructors or methods.
+- * @return a visitor to visit field annotations and attributes, or
+- * null if this class visitor is not interested in visiting
+- * these annotations and attributes.
+- */
+- public FieldVisitor visitField(int access, String name, String desc,
+- String signature, Object value) {
+- if (cv != null) {
+- return cv.visitField(access, name, desc, signature, value);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits a method of the class. This method must return a new
+- * {@link MethodVisitor} instance (or null ) each time it is called,
+- * i.e., it should not return a previously returned visitor.
+- *
+- * @param access
+- * the method's access flags (see {@link Opcodes}). This
+- * parameter also indicates if the method is synthetic and/or
+- * deprecated.
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @param signature
+- * the method's signature. May be null if the method
+- * parameters, return type and exceptions do not use generic
+- * types.
+- * @param exceptions
+- * the internal names of the method's exception classes (see
+- * {@link Type#getInternalName() getInternalName}). May be
+- * null .
+- * @return an object to visit the byte code of the method, or null
+- * if this class visitor is not interested in visiting the code of
+- * this method.
+- */
+- public MethodVisitor visitMethod(int access, String name, String desc,
+- String signature, String[] exceptions) {
+- if (cv != null) {
+- return cv.visitMethod(access, name, desc, signature, exceptions);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits the end of the class. This method, which is the last one to be
+- * called, is used to inform the visitor that all the fields and methods of
+- * the class have been visited.
+- */
+- public void visitEnd() {
+- if (cv != null) {
+- cv.visitEnd();
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/ClassWriter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/ClassWriter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/ClassWriter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/ClassWriter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,1776 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A {@link ClassVisitor} that generates classes in bytecode form. More
+- * precisely this visitor generates a byte array conforming to the Java class
+- * file format. It can be used alone, to generate a Java class "from scratch",
+- * or with one or more {@link ClassReader ClassReader} and adapter class visitor
+- * to generate a modified class from one or more existing Java classes.
+- *
+- * @author Eric Bruneton
+- */
+-public class ClassWriter extends ClassVisitor {
+-
+- /**
+- * Flag to automatically compute the maximum stack size and the maximum
+- * number of local variables of methods. If this flag is set, then the
+- * arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the
+- * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod}
+- * method will be ignored, and computed automatically from the signature and
+- * the bytecode of each method.
+- *
+- * @see #ClassWriter(int)
+- */
+- public static final int COMPUTE_MAXS = 1;
+-
+- /**
+- * Flag to automatically compute the stack map frames of methods from
+- * scratch. If this flag is set, then the calls to the
+- * {@link MethodVisitor#visitFrame} method are ignored, and the stack map
+- * frames are recomputed from the methods bytecode. The arguments of the
+- * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
+- * recomputed from the bytecode. In other words, computeFrames implies
+- * computeMaxs.
+- *
+- * @see #ClassWriter(int)
+- */
+- public static final int COMPUTE_FRAMES = 2;
+-
+- /**
+- * Pseudo access flag to distinguish between the synthetic attribute and the
+- * synthetic access flag.
+- */
+- static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000;
+-
+- /**
+- * Factor to convert from ACC_SYNTHETIC_ATTRIBUTE to Opcode.ACC_SYNTHETIC.
+- */
+- static final int TO_ACC_SYNTHETIC = ACC_SYNTHETIC_ATTRIBUTE
+- / Opcodes.ACC_SYNTHETIC;
+-
+- /**
+- * The type of instructions without any argument.
+- */
+- static final int NOARG_INSN = 0;
+-
+- /**
+- * The type of instructions with an signed byte argument.
+- */
+- static final int SBYTE_INSN = 1;
+-
+- /**
+- * The type of instructions with an signed short argument.
+- */
+- static final int SHORT_INSN = 2;
+-
+- /**
+- * The type of instructions with a local variable index argument.
+- */
+- static final int VAR_INSN = 3;
+-
+- /**
+- * The type of instructions with an implicit local variable index argument.
+- */
+- static final int IMPLVAR_INSN = 4;
+-
+- /**
+- * The type of instructions with a type descriptor argument.
+- */
+- static final int TYPE_INSN = 5;
+-
+- /**
+- * The type of field and method invocations instructions.
+- */
+- static final int FIELDORMETH_INSN = 6;
+-
+- /**
+- * The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction.
+- */
+- static final int ITFMETH_INSN = 7;
+-
+- /**
+- * The type of the INVOKEDYNAMIC instruction.
+- */
+- static final int INDYMETH_INSN = 8;
+-
+- /**
+- * The type of instructions with a 2 bytes bytecode offset label.
+- */
+- static final int LABEL_INSN = 9;
+-
+- /**
+- * The type of instructions with a 4 bytes bytecode offset label.
+- */
+- static final int LABELW_INSN = 10;
+-
+- /**
+- * The type of the LDC instruction.
+- */
+- static final int LDC_INSN = 11;
+-
+- /**
+- * The type of the LDC_W and LDC2_W instructions.
+- */
+- static final int LDCW_INSN = 12;
+-
+- /**
+- * The type of the IINC instruction.
+- */
+- static final int IINC_INSN = 13;
+-
+- /**
+- * The type of the TABLESWITCH instruction.
+- */
+- static final int TABL_INSN = 14;
+-
+- /**
+- * The type of the LOOKUPSWITCH instruction.
+- */
+- static final int LOOK_INSN = 15;
+-
+- /**
+- * The type of the MULTIANEWARRAY instruction.
+- */
+- static final int MANA_INSN = 16;
+-
+- /**
+- * The type of the WIDE instruction.
+- */
+- static final int WIDE_INSN = 17;
+-
+- /**
+- * The instruction types of all JVM opcodes.
+- */
+- static final byte[] TYPE;
+-
+- /**
+- * The type of CONSTANT_Class constant pool items.
+- */
+- static final int CLASS = 7;
+-
+- /**
+- * The type of CONSTANT_Fieldref constant pool items.
+- */
+- static final int FIELD = 9;
+-
+- /**
+- * The type of CONSTANT_Methodref constant pool items.
+- */
+- static final int METH = 10;
+-
+- /**
+- * The type of CONSTANT_InterfaceMethodref constant pool items.
+- */
+- static final int IMETH = 11;
+-
+- /**
+- * The type of CONSTANT_String constant pool items.
+- */
+- static final int STR = 8;
+-
+- /**
+- * The type of CONSTANT_Integer constant pool items.
+- */
+- static final int INT = 3;
+-
+- /**
+- * The type of CONSTANT_Float constant pool items.
+- */
+- static final int FLOAT = 4;
+-
+- /**
+- * The type of CONSTANT_Long constant pool items.
+- */
+- static final int LONG = 5;
+-
+- /**
+- * The type of CONSTANT_Double constant pool items.
+- */
+- static final int DOUBLE = 6;
+-
+- /**
+- * The type of CONSTANT_NameAndType constant pool items.
+- */
+- static final int NAME_TYPE = 12;
+-
+- /**
+- * The type of CONSTANT_Utf8 constant pool items.
+- */
+- static final int UTF8 = 1;
+-
+- /**
+- * The type of CONSTANT_MethodType constant pool items.
+- */
+- static final int MTYPE = 16;
+-
+- /**
+- * The type of CONSTANT_MethodHandle constant pool items.
+- */
+- static final int HANDLE = 15;
+-
+- /**
+- * The type of CONSTANT_InvokeDynamic constant pool items.
+- */
+- static final int INDY = 18;
+-
+- /**
+- * The base value for all CONSTANT_MethodHandle constant pool items.
+- * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
+- * different items.
+- */
+- static final int HANDLE_BASE = 20;
+-
+- /**
+- * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable},
+- * instead of the constant pool, in order to avoid clashes with normal
+- * constant pool items in the ClassWriter constant pool's hash table.
+- */
+- static final int TYPE_NORMAL = 30;
+-
+- /**
+- * Uninitialized type Item stored in the ClassWriter
+- * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
+- * avoid clashes with normal constant pool items in the ClassWriter constant
+- * pool's hash table.
+- */
+- static final int TYPE_UNINIT = 31;
+-
+- /**
+- * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable},
+- * instead of the constant pool, in order to avoid clashes with normal
+- * constant pool items in the ClassWriter constant pool's hash table.
+- */
+- static final int TYPE_MERGED = 32;
+-
+- /**
+- * The type of BootstrapMethods items. These items are stored in a special
+- * class attribute named BootstrapMethods and not in the constant pool.
+- */
+- static final int BSM = 33;
+-
+- /**
+- * The class reader from which this class writer was constructed, if any.
+- */
+- ClassReader cr;
+-
+- /**
+- * Minor and major version numbers of the class to be generated.
+- */
+- int version;
+-
+- /**
+- * Index of the next item to be added in the constant pool.
+- */
+- int index;
+-
+- /**
+- * The constant pool of this class.
+- */
+- final ByteVector pool;
+-
+- /**
+- * The constant pool's hash table data.
+- */
+- Item[] items;
+-
+- /**
+- * The threshold of the constant pool's hash table.
+- */
+- int threshold;
+-
+- /**
+- * A reusable key used to look for items in the {@link #items} hash table.
+- */
+- final Item key;
+-
+- /**
+- * A reusable key used to look for items in the {@link #items} hash table.
+- */
+- final Item key2;
+-
+- /**
+- * A reusable key used to look for items in the {@link #items} hash table.
+- */
+- final Item key3;
+-
+- /**
+- * A reusable key used to look for items in the {@link #items} hash table.
+- */
+- final Item key4;
+-
+- /**
+- * A type table used to temporarily store internal names that will not
+- * necessarily be stored in the constant pool. This type table is used by
+- * the control flow and data flow analysis algorithm used to compute stack
+- * map frames from scratch. This array associates to each index i
+- * the Item whose index is i . All Item objects stored in this array
+- * are also stored in the {@link #items} hash table. These two arrays allow
+- * to retrieve an Item from its index or, conversely, to get the index of an
+- * Item from its value. Each Item stores an internal name in its
+- * {@link Item#strVal1} field.
+- */
+- Item[] typeTable;
+-
+- /**
+- * Number of elements in the {@link #typeTable} array.
+- */
+- private short typeCount;
+-
+- /**
+- * The access flags of this class.
+- */
+- private int access;
+-
+- /**
+- * The constant pool item that contains the internal name of this class.
+- */
+- private int name;
+-
+- /**
+- * The internal name of this class.
+- */
+- String thisName;
+-
+- /**
+- * The constant pool item that contains the signature of this class.
+- */
+- private int signature;
+-
+- /**
+- * The constant pool item that contains the internal name of the super class
+- * of this class.
+- */
+- private int superName;
+-
+- /**
+- * Number of interfaces implemented or extended by this class or interface.
+- */
+- private int interfaceCount;
+-
+- /**
+- * The interfaces implemented or extended by this class or interface. More
+- * precisely, this array contains the indexes of the constant pool items
+- * that contain the internal names of these interfaces.
+- */
+- private int[] interfaces;
+-
+- /**
+- * The index of the constant pool item that contains the name of the source
+- * file from which this class was compiled.
+- */
+- private int sourceFile;
+-
+- /**
+- * The SourceDebug attribute of this class.
+- */
+- private ByteVector sourceDebug;
+-
+- /**
+- * The constant pool item that contains the name of the enclosing class of
+- * this class.
+- */
+- private int enclosingMethodOwner;
+-
+- /**
+- * The constant pool item that contains the name and descriptor of the
+- * enclosing method of this class.
+- */
+- private int enclosingMethod;
+-
+- /**
+- * The runtime visible annotations of this class.
+- */
+- private AnnotationWriter anns;
+-
+- /**
+- * The runtime invisible annotations of this class.
+- */
+- private AnnotationWriter ianns;
+-
+- /**
+- * The runtime visible type annotations of this class.
+- */
+- private AnnotationWriter tanns;
+-
+- /**
+- * The runtime invisible type annotations of this class.
+- */
+- private AnnotationWriter itanns;
+-
+- /**
+- * The non standard attributes of this class.
+- */
+- private Attribute attrs;
+-
+- /**
+- * The number of entries in the InnerClasses attribute.
+- */
+- private int innerClassesCount;
+-
+- /**
+- * The InnerClasses attribute.
+- */
+- private ByteVector innerClasses;
+-
+- /**
+- * The number of entries in the BootstrapMethods attribute.
+- */
+- int bootstrapMethodsCount;
+-
+- /**
+- * The BootstrapMethods attribute.
+- */
+- ByteVector bootstrapMethods;
+-
+- /**
+- * The fields of this class. These fields are stored in a linked list of
+- * {@link FieldWriter} objects, linked to each other by their
+- * {@link FieldWriter#fv} field. This field stores the first element of this
+- * list.
+- */
+- FieldWriter firstField;
+-
+- /**
+- * The fields of this class. These fields are stored in a linked list of
+- * {@link FieldWriter} objects, linked to each other by their
+- * {@link FieldWriter#fv} field. This field stores the last element of this
+- * list.
+- */
+- FieldWriter lastField;
+-
+- /**
+- * The methods of this class. These methods are stored in a linked list of
+- * {@link MethodWriter} objects, linked to each other by their
+- * {@link MethodWriter#mv} field. This field stores the first element of
+- * this list.
+- */
+- MethodWriter firstMethod;
+-
+- /**
+- * The methods of this class. These methods are stored in a linked list of
+- * {@link MethodWriter} objects, linked to each other by their
+- * {@link MethodWriter#mv} field. This field stores the last element of this
+- * list.
+- */
+- MethodWriter lastMethod;
+-
+- /**
+- * true if the maximum stack size and number of local variables
+- * must be automatically computed.
+- */
+- private boolean computeMaxs;
+-
+- /**
+- * true if the stack map frames must be recomputed from scratch.
+- */
+- private boolean computeFrames;
+-
+- /**
+- * true if the stack map tables of this class are invalid. The
+- * {@link MethodWriter#resizeInstructions} method cannot transform existing
+- * stack map tables, and so produces potentially invalid classes when it is
+- * executed. In this case the class is reread and rewritten with the
+- * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
+- * stack map tables when this option is used).
+- */
+- boolean invalidFrames;
+-
+- // ------------------------------------------------------------------------
+- // Static initializer
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Computes the instruction types of JVM opcodes.
+- */
+- static {
+- int i;
+- byte[] b = new byte[220];
+- String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+- + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+- + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
+- + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
+- for (i = 0; i < b.length; ++i) {
+- b[i] = (byte) (s.charAt(i) - 'A');
+- }
+- TYPE = b;
+-
+- // code to generate the above string
+- //
+- // // SBYTE_INSN instructions
+- // b[Constants.NEWARRAY] = SBYTE_INSN;
+- // b[Constants.BIPUSH] = SBYTE_INSN;
+- //
+- // // SHORT_INSN instructions
+- // b[Constants.SIPUSH] = SHORT_INSN;
+- //
+- // // (IMPL)VAR_INSN instructions
+- // b[Constants.RET] = VAR_INSN;
+- // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) {
+- // b[i] = VAR_INSN;
+- // }
+- // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) {
+- // b[i] = VAR_INSN;
+- // }
+- // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3
+- // b[i] = IMPLVAR_INSN;
+- // }
+- // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3
+- // b[i] = IMPLVAR_INSN;
+- // }
+- //
+- // // TYPE_INSN instructions
+- // b[Constants.NEW] = TYPE_INSN;
+- // b[Constants.ANEWARRAY] = TYPE_INSN;
+- // b[Constants.CHECKCAST] = TYPE_INSN;
+- // b[Constants.INSTANCEOF] = TYPE_INSN;
+- //
+- // // (Set)FIELDORMETH_INSN instructions
+- // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) {
+- // b[i] = FIELDORMETH_INSN;
+- // }
+- // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN;
+- // b[Constants.INVOKEDYNAMIC] = INDYMETH_INSN;
+- //
+- // // LABEL(W)_INSN instructions
+- // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) {
+- // b[i] = LABEL_INSN;
+- // }
+- // b[Constants.IFNULL] = LABEL_INSN;
+- // b[Constants.IFNONNULL] = LABEL_INSN;
+- // b[200] = LABELW_INSN; // GOTO_W
+- // b[201] = LABELW_INSN; // JSR_W
+- // // temporary opcodes used internally by ASM - see Label and
+- // MethodWriter
+- // for (i = 202; i < 220; ++i) {
+- // b[i] = LABEL_INSN;
+- // }
+- //
+- // // LDC(_W) instructions
+- // b[Constants.LDC] = LDC_INSN;
+- // b[19] = LDCW_INSN; // LDC_W
+- // b[20] = LDCW_INSN; // LDC2_W
+- //
+- // // special instructions
+- // b[Constants.IINC] = IINC_INSN;
+- // b[Constants.TABLESWITCH] = TABL_INSN;
+- // b[Constants.LOOKUPSWITCH] = LOOK_INSN;
+- // b[Constants.MULTIANEWARRAY] = MANA_INSN;
+- // b[196] = WIDE_INSN; // WIDE
+- //
+- // for (i = 0; i < b.length; ++i) {
+- // System.err.print((char)('A' + b[i]));
+- // }
+- // System.err.println();
+- }
+-
+- // ------------------------------------------------------------------------
+- // Constructor
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Constructs a new {@link ClassWriter} object.
+- *
+- * @param flags
+- * option flags that can be used to modify the default behavior
+- * of this class. See {@link #COMPUTE_MAXS},
+- * {@link #COMPUTE_FRAMES}.
+- */
+- public ClassWriter(final int flags) {
+- super(Opcodes.ASM5);
+- index = 1;
+- pool = new ByteVector();
+- items = new Item[256];
+- threshold = (int) (0.75d * items.length);
+- key = new Item();
+- key2 = new Item();
+- key3 = new Item();
+- key4 = new Item();
+- this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
+- this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
+- }
+-
+- /**
+- * Constructs a new {@link ClassWriter} object and enables optimizations for
+- * "mostly add" bytecode transformations. These optimizations are the
+- * following:
+- *
+- *
+- * The constant pool from the original class is copied as is in the new
+- * class, which saves time. New constant pool entries will be added at the
+- * end if necessary, but unused constant pool entries won't be
+- * removed .
+- * Methods that are not transformed are copied as is in the new class,
+- * directly from the original class bytecode (i.e. without emitting visit
+- * events for all the method instructions), which saves a lot of
+- * time. Untransformed methods are detected by the fact that the
+- * {@link ClassReader} receives {@link MethodVisitor} objects that come from
+- * a {@link ClassWriter} (and not from any other {@link ClassVisitor}
+- * instance).
+- *
+- *
+- * @param classReader
+- * the {@link ClassReader} used to read the original class. It
+- * will be used to copy the entire constant pool from the
+- * original class and also to copy other fragments of original
+- * bytecode where applicable.
+- * @param flags
+- * option flags that can be used to modify the default behavior
+- * of this class. These option flags do not affect methods
+- * that are copied as is in the new class. This means that the
+- * maximum stack size nor the stack frames will be computed for
+- * these methods . See {@link #COMPUTE_MAXS},
+- * {@link #COMPUTE_FRAMES}.
+- */
+- public ClassWriter(final ClassReader classReader, final int flags) {
+- this(flags);
+- classReader.copyPool(this);
+- this.cr = classReader;
+- }
+-
+- // ------------------------------------------------------------------------
+- // Implementation of the ClassVisitor abstract class
+- // ------------------------------------------------------------------------
+-
+- @Override
+- public final void visit(final int version, final int access,
+- final String name, final String signature, final String superName,
+- final String[] interfaces) {
+- this.version = version;
+- this.access = access;
+- this.name = newClass(name);
+- thisName = name;
+- if (ClassReader.SIGNATURES && signature != null) {
+- this.signature = newUTF8(signature);
+- }
+- this.superName = superName == null ? 0 : newClass(superName);
+- if (interfaces != null && interfaces.length > 0) {
+- interfaceCount = interfaces.length;
+- this.interfaces = new int[interfaceCount];
+- for (int i = 0; i < interfaceCount; ++i) {
+- this.interfaces[i] = newClass(interfaces[i]);
+- }
+- }
+- }
+-
+- @Override
+- public final void visitSource(final String file, final String debug) {
+- if (file != null) {
+- sourceFile = newUTF8(file);
+- }
+- if (debug != null) {
+- sourceDebug = new ByteVector().encodeUTF8(debug, 0,
+- Integer.MAX_VALUE);
+- }
+- }
+-
+- @Override
+- public final void visitOuterClass(final String owner, final String name,
+- final String desc) {
+- enclosingMethodOwner = newClass(owner);
+- if (name != null && desc != null) {
+- enclosingMethod = newNameType(name, desc);
+- }
+- }
+-
+- @Override
+- public final AnnotationVisitor visitAnnotation(final String desc,
+- final boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write type, and reserve space for values count
+- bv.putShort(newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2);
+- if (visible) {
+- aw.next = anns;
+- anns = aw;
+- } else {
+- aw.next = ianns;
+- ianns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public final AnnotationVisitor visitTypeAnnotation(int typeRef,
+- TypePath typePath, final String desc, final boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write target_type and target_info
+- AnnotationWriter.putTarget(typeRef, typePath, bv);
+- // write type, and reserve space for values count
+- bv.putShort(newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv,
+- bv.length - 2);
+- if (visible) {
+- aw.next = tanns;
+- tanns = aw;
+- } else {
+- aw.next = itanns;
+- itanns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public final void visitAttribute(final Attribute attr) {
+- attr.next = attrs;
+- attrs = attr;
+- }
+-
+- @Override
+- public final void visitInnerClass(final String name,
+- final String outerName, final String innerName, final int access) {
+- if (innerClasses == null) {
+- innerClasses = new ByteVector();
+- }
+- // �4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the
+- // constant_pool table which represents a class or interface C that is
+- // not a package member must have exactly one corresponding entry in the
+- // classes array". To avoid duplicates we keep track in the intVal field
+- // of the Item of each CONSTANT_Class_info entry C whether an inner
+- // class entry has already been added for C (this field is unused for
+- // class entries, and changing its value does not change the hashcode
+- // and equality tests). If so we store the index of this inner class
+- // entry (plus one) in intVal. This hack allows duplicate detection in
+- // O(1) time.
+- Item nameItem = newClassItem(name);
+- if (nameItem.intVal == 0) {
+- ++innerClassesCount;
+- innerClasses.putShort(nameItem.index);
+- innerClasses.putShort(outerName == null ? 0 : newClass(outerName));
+- innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName));
+- innerClasses.putShort(access);
+- nameItem.intVal = innerClassesCount;
+- } else {
+- // Compare the inner classes entry nameItem.intVal - 1 with the
+- // arguments of this method and throw an exception if there is a
+- // difference?
+- }
+- }
+-
+- @Override
+- public final FieldVisitor visitField(final int access, final String name,
+- final String desc, final String signature, final Object value) {
+- return new FieldWriter(this, access, name, desc, signature, value);
+- }
+-
+- @Override
+- public final MethodVisitor visitMethod(final int access, final String name,
+- final String desc, final String signature, final String[] exceptions) {
+- return new MethodWriter(this, access, name, desc, signature,
+- exceptions, computeMaxs, computeFrames);
+- }
+-
+- @Override
+- public final void visitEnd() {
+- }
+-
+- // ------------------------------------------------------------------------
+- // Other public methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns the bytecode of the class that was build with this class writer.
+- *
+- * @return the bytecode of the class that was build with this class writer.
+- */
+- public byte[] toByteArray() {
+- if (index > 0xFFFF) {
+- throw new RuntimeException("Class file too large!");
+- }
+- // computes the real size of the bytecode of this class
+- int size = 24 + 2 * interfaceCount;
+- int nbFields = 0;
+- FieldWriter fb = firstField;
+- while (fb != null) {
+- ++nbFields;
+- size += fb.getSize();
+- fb = (FieldWriter) fb.fv;
+- }
+- int nbMethods = 0;
+- MethodWriter mb = firstMethod;
+- while (mb != null) {
+- ++nbMethods;
+- size += mb.getSize();
+- mb = (MethodWriter) mb.mv;
+- }
+- int attributeCount = 0;
+- if (bootstrapMethods != null) {
+- // we put it as first attribute in order to improve a bit
+- // ClassReader.copyBootstrapMethods
+- ++attributeCount;
+- size += 8 + bootstrapMethods.length;
+- newUTF8("BootstrapMethods");
+- }
+- if (ClassReader.SIGNATURES && signature != 0) {
+- ++attributeCount;
+- size += 8;
+- newUTF8("Signature");
+- }
+- if (sourceFile != 0) {
+- ++attributeCount;
+- size += 8;
+- newUTF8("SourceFile");
+- }
+- if (sourceDebug != null) {
+- ++attributeCount;
+- size += sourceDebug.length + 6;
+- newUTF8("SourceDebugExtension");
+- }
+- if (enclosingMethodOwner != 0) {
+- ++attributeCount;
+- size += 10;
+- newUTF8("EnclosingMethod");
+- }
+- if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+- ++attributeCount;
+- size += 6;
+- newUTF8("Deprecated");
+- }
+- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+- if ((version & 0xFFFF) < Opcodes.V1_5
+- || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+- ++attributeCount;
+- size += 6;
+- newUTF8("Synthetic");
+- }
+- }
+- if (innerClasses != null) {
+- ++attributeCount;
+- size += 8 + innerClasses.length;
+- newUTF8("InnerClasses");
+- }
+- if (ClassReader.ANNOTATIONS && anns != null) {
+- ++attributeCount;
+- size += 8 + anns.getSize();
+- newUTF8("RuntimeVisibleAnnotations");
+- }
+- if (ClassReader.ANNOTATIONS && ianns != null) {
+- ++attributeCount;
+- size += 8 + ianns.getSize();
+- newUTF8("RuntimeInvisibleAnnotations");
+- }
+- if (ClassReader.ANNOTATIONS && tanns != null) {
+- ++attributeCount;
+- size += 8 + tanns.getSize();
+- newUTF8("RuntimeVisibleTypeAnnotations");
+- }
+- if (ClassReader.ANNOTATIONS && itanns != null) {
+- ++attributeCount;
+- size += 8 + itanns.getSize();
+- newUTF8("RuntimeInvisibleTypeAnnotations");
+- }
+- if (attrs != null) {
+- attributeCount += attrs.getCount();
+- size += attrs.getSize(this, null, 0, -1, -1);
+- }
+- size += pool.length;
+- // allocates a byte vector of this size, in order to avoid unnecessary
+- // arraycopy operations in the ByteVector.enlarge() method
+- ByteVector out = new ByteVector(size);
+- out.putInt(0xCAFEBABE).putInt(version);
+- out.putShort(index).putByteArray(pool.data, 0, pool.length);
+- int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE
+- | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC);
+- out.putShort(access & ~mask).putShort(name).putShort(superName);
+- out.putShort(interfaceCount);
+- for (int i = 0; i < interfaceCount; ++i) {
+- out.putShort(interfaces[i]);
+- }
+- out.putShort(nbFields);
+- fb = firstField;
+- while (fb != null) {
+- fb.put(out);
+- fb = (FieldWriter) fb.fv;
+- }
+- out.putShort(nbMethods);
+- mb = firstMethod;
+- while (mb != null) {
+- mb.put(out);
+- mb = (MethodWriter) mb.mv;
+- }
+- out.putShort(attributeCount);
+- if (bootstrapMethods != null) {
+- out.putShort(newUTF8("BootstrapMethods"));
+- out.putInt(bootstrapMethods.length + 2).putShort(
+- bootstrapMethodsCount);
+- out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
+- }
+- if (ClassReader.SIGNATURES && signature != 0) {
+- out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
+- }
+- if (sourceFile != 0) {
+- out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
+- }
+- if (sourceDebug != null) {
+- int len = sourceDebug.length;
+- out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
+- out.putByteArray(sourceDebug.data, 0, len);
+- }
+- if (enclosingMethodOwner != 0) {
+- out.putShort(newUTF8("EnclosingMethod")).putInt(4);
+- out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
+- }
+- if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+- out.putShort(newUTF8("Deprecated")).putInt(0);
+- }
+- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+- if ((version & 0xFFFF) < Opcodes.V1_5
+- || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+- out.putShort(newUTF8("Synthetic")).putInt(0);
+- }
+- }
+- if (innerClasses != null) {
+- out.putShort(newUTF8("InnerClasses"));
+- out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
+- out.putByteArray(innerClasses.data, 0, innerClasses.length);
+- }
+- if (ClassReader.ANNOTATIONS && anns != null) {
+- out.putShort(newUTF8("RuntimeVisibleAnnotations"));
+- anns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && ianns != null) {
+- out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
+- ianns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && tanns != null) {
+- out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
+- tanns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && itanns != null) {
+- out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
+- itanns.put(out);
+- }
+- if (attrs != null) {
+- attrs.put(this, null, 0, -1, -1, out);
+- }
+- if (invalidFrames) {
+- anns = null;
+- ianns = null;
+- attrs = null;
+- innerClassesCount = 0;
+- innerClasses = null;
+- bootstrapMethodsCount = 0;
+- bootstrapMethods = null;
+- firstField = null;
+- lastField = null;
+- firstMethod = null;
+- lastMethod = null;
+- computeMaxs = false;
+- computeFrames = true;
+- invalidFrames = false;
+- new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
+- return toByteArray();
+- }
+- return out.data;
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods: constant pool management
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Adds a number or string constant to the constant pool of the class being
+- * build. Does nothing if the constant pool already contains a similar item.
+- *
+- * @param cst
+- * the value of the constant to be added to the constant pool.
+- * This parameter must be an {@link Integer}, a {@link Float}, a
+- * {@link Long}, a {@link Double}, a {@link String} or a
+- * {@link Type}.
+- * @return a new or already existing constant item with the given value.
+- */
+- Item newConstItem(final Object cst) {
+- if (cst instanceof Integer) {
+- int val = ((Integer) cst).intValue();
+- return newInteger(val);
+- } else if (cst instanceof Byte) {
+- int val = ((Byte) cst).intValue();
+- return newInteger(val);
+- } else if (cst instanceof Character) {
+- int val = ((Character) cst).charValue();
+- return newInteger(val);
+- } else if (cst instanceof Short) {
+- int val = ((Short) cst).intValue();
+- return newInteger(val);
+- } else if (cst instanceof Boolean) {
+- int val = ((Boolean) cst).booleanValue() ? 1 : 0;
+- return newInteger(val);
+- } else if (cst instanceof Float) {
+- float val = ((Float) cst).floatValue();
+- return newFloat(val);
+- } else if (cst instanceof Long) {
+- long val = ((Long) cst).longValue();
+- return newLong(val);
+- } else if (cst instanceof Double) {
+- double val = ((Double) cst).doubleValue();
+- return newDouble(val);
+- } else if (cst instanceof String) {
+- return newString((String) cst);
+- } else if (cst instanceof Type) {
+- Type t = (Type) cst;
+- int s = t.getSort();
+- if (s == Type.OBJECT) {
+- return newClassItem(t.getInternalName());
+- } else if (s == Type.METHOD) {
+- return newMethodTypeItem(t.getDescriptor());
+- } else { // s == primitive type or array
+- return newClassItem(t.getDescriptor());
+- }
+- } else if (cst instanceof Handle) {
+- Handle h = (Handle) cst;
+- return newHandleItem(h.tag, h.owner, h.name, h.desc);
+- } else {
+- throw new IllegalArgumentException("value " + cst);
+- }
+- }
+-
+- /**
+- * Adds a number or string constant to the constant pool of the class being
+- * build. Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param cst
+- * the value of the constant to be added to the constant pool.
+- * This parameter must be an {@link Integer}, a {@link Float}, a
+- * {@link Long}, a {@link Double} or a {@link String}.
+- * @return the index of a new or already existing constant item with the
+- * given value.
+- */
+- public int newConst(final Object cst) {
+- return newConstItem(cst).index;
+- }
+-
+- /**
+- * Adds an UTF8 string to the constant pool of the class being build. Does
+- * nothing if the constant pool already contains a similar item. This
+- * method is intended for {@link Attribute} sub classes, and is normally not
+- * needed by class generators or adapters.
+- *
+- * @param value
+- * the String value.
+- * @return the index of a new or already existing UTF8 item.
+- */
+- public int newUTF8(final String value) {
+- key.set(UTF8, value, null, null);
+- Item result = get(key);
+- if (result == null) {
+- pool.putByte(UTF8).putUTF8(value);
+- result = new Item(index++, key);
+- put(result);
+- }
+- return result.index;
+- }
+-
+- /**
+- * Adds a class reference to the constant pool of the class being build.
+- * Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param value
+- * the internal name of the class.
+- * @return a new or already existing class reference item.
+- */
+- Item newClassItem(final String value) {
+- key2.set(CLASS, value, null, null);
+- Item result = get(key2);
+- if (result == null) {
+- pool.put12(CLASS, newUTF8(value));
+- result = new Item(index++, key2);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a class reference to the constant pool of the class being build.
+- * Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param value
+- * the internal name of the class.
+- * @return the index of a new or already existing class reference item.
+- */
+- public int newClass(final String value) {
+- return newClassItem(value).index;
+- }
+-
+- /**
+- * Adds a method type reference to the constant pool of the class being
+- * build. Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param methodDesc
+- * method descriptor of the method type.
+- * @return a new or already existing method type reference item.
+- */
+- Item newMethodTypeItem(final String methodDesc) {
+- key2.set(MTYPE, methodDesc, null, null);
+- Item result = get(key2);
+- if (result == null) {
+- pool.put12(MTYPE, newUTF8(methodDesc));
+- result = new Item(index++, key2);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a method type reference to the constant pool of the class being
+- * build. Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param methodDesc
+- * method descriptor of the method type.
+- * @return the index of a new or already existing method type reference
+- * item.
+- */
+- public int newMethodType(final String methodDesc) {
+- return newMethodTypeItem(methodDesc).index;
+- }
+-
+- /**
+- * Adds a handle to the constant pool of the class being build. Does nothing
+- * if the constant pool already contains a similar item. This method is
+- * intended for {@link Attribute} sub classes, and is normally not needed by
+- * class generators or adapters.
+- *
+- * @param tag
+- * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+- * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+- * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+- * {@link Opcodes#H_INVOKESTATIC},
+- * {@link Opcodes#H_INVOKESPECIAL},
+- * {@link Opcodes#H_NEWINVOKESPECIAL} or
+- * {@link Opcodes#H_INVOKEINTERFACE}.
+- * @param owner
+- * the internal name of the field or method owner class.
+- * @param name
+- * the name of the field or method.
+- * @param desc
+- * the descriptor of the field or method.
+- * @return a new or an already existing method type reference item.
+- */
+- Item newHandleItem(final int tag, final String owner, final String name,
+- final String desc) {
+- key4.set(HANDLE_BASE + tag, owner, name, desc);
+- Item result = get(key4);
+- if (result == null) {
+- if (tag <= Opcodes.H_PUTSTATIC) {
+- put112(HANDLE, tag, newField(owner, name, desc));
+- } else {
+- put112(HANDLE,
+- tag,
+- newMethod(owner, name, desc,
+- tag == Opcodes.H_INVOKEINTERFACE));
+- }
+- result = new Item(index++, key4);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a handle to the constant pool of the class being build. Does nothing
+- * if the constant pool already contains a similar item. This method is
+- * intended for {@link Attribute} sub classes, and is normally not needed by
+- * class generators or adapters.
+- *
+- * @param tag
+- * the kind of this handle. Must be {@link Opcodes#H_GETFIELD},
+- * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
+- * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
+- * {@link Opcodes#H_INVOKESTATIC},
+- * {@link Opcodes#H_INVOKESPECIAL},
+- * {@link Opcodes#H_NEWINVOKESPECIAL} or
+- * {@link Opcodes#H_INVOKEINTERFACE}.
+- * @param owner
+- * the internal name of the field or method owner class.
+- * @param name
+- * the name of the field or method.
+- * @param desc
+- * the descriptor of the field or method.
+- * @return the index of a new or already existing method type reference
+- * item.
+- */
+- public int newHandle(final int tag, final String owner, final String name,
+- final String desc) {
+- return newHandleItem(tag, owner, name, desc).index;
+- }
+-
+- /**
+- * Adds an invokedynamic reference to the constant pool of the class being
+- * build. Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param name
+- * name of the invoked method.
+- * @param desc
+- * descriptor of the invoke method.
+- * @param bsm
+- * the bootstrap method.
+- * @param bsmArgs
+- * the bootstrap method constant arguments.
+- *
+- * @return a new or an already existing invokedynamic type reference item.
+- */
+- Item newInvokeDynamicItem(final String name, final String desc,
+- final Handle bsm, final Object... bsmArgs) {
+- // cache for performance
+- ByteVector bootstrapMethods = this.bootstrapMethods;
+- if (bootstrapMethods == null) {
+- bootstrapMethods = this.bootstrapMethods = new ByteVector();
+- }
+-
+- int position = bootstrapMethods.length; // record current position
+-
+- int hashCode = bsm.hashCode();
+- bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name,
+- bsm.desc));
+-
+- int argsLength = bsmArgs.length;
+- bootstrapMethods.putShort(argsLength);
+-
+- for (int i = 0; i < argsLength; i++) {
+- Object bsmArg = bsmArgs[i];
+- hashCode ^= bsmArg.hashCode();
+- bootstrapMethods.putShort(newConst(bsmArg));
+- }
+-
+- byte[] data = bootstrapMethods.data;
+- int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments)
+- hashCode &= 0x7FFFFFFF;
+- Item result = items[hashCode % items.length];
+- loop: while (result != null) {
+- if (result.type != BSM || result.hashCode != hashCode) {
+- result = result.next;
+- continue;
+- }
+-
+- // because the data encode the size of the argument
+- // we don't need to test if these size are equals
+- int resultPosition = result.intVal;
+- for (int p = 0; p < length; p++) {
+- if (data[position + p] != data[resultPosition + p]) {
+- result = result.next;
+- continue loop;
+- }
+- }
+- break;
+- }
+-
+- int bootstrapMethodIndex;
+- if (result != null) {
+- bootstrapMethodIndex = result.index;
+- bootstrapMethods.length = position; // revert to old position
+- } else {
+- bootstrapMethodIndex = bootstrapMethodsCount++;
+- result = new Item(bootstrapMethodIndex);
+- result.set(position, hashCode);
+- put(result);
+- }
+-
+- // now, create the InvokeDynamic constant
+- key3.set(name, desc, bootstrapMethodIndex);
+- result = get(key3);
+- if (result == null) {
+- put122(INDY, bootstrapMethodIndex, newNameType(name, desc));
+- result = new Item(index++, key3);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds an invokedynamic reference to the constant pool of the class being
+- * build. Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param name
+- * name of the invoked method.
+- * @param desc
+- * descriptor of the invoke method.
+- * @param bsm
+- * the bootstrap method.
+- * @param bsmArgs
+- * the bootstrap method constant arguments.
+- *
+- * @return the index of a new or already existing invokedynamic reference
+- * item.
+- */
+- public int newInvokeDynamic(final String name, final String desc,
+- final Handle bsm, final Object... bsmArgs) {
+- return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index;
+- }
+-
+- /**
+- * Adds a field reference to the constant pool of the class being build.
+- * Does nothing if the constant pool already contains a similar item.
+- *
+- * @param owner
+- * the internal name of the field's owner class.
+- * @param name
+- * the field's name.
+- * @param desc
+- * the field's descriptor.
+- * @return a new or already existing field reference item.
+- */
+- Item newFieldItem(final String owner, final String name, final String desc) {
+- key3.set(FIELD, owner, name, desc);
+- Item result = get(key3);
+- if (result == null) {
+- put122(FIELD, newClass(owner), newNameType(name, desc));
+- result = new Item(index++, key3);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a field reference to the constant pool of the class being build.
+- * Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param owner
+- * the internal name of the field's owner class.
+- * @param name
+- * the field's name.
+- * @param desc
+- * the field's descriptor.
+- * @return the index of a new or already existing field reference item.
+- */
+- public int newField(final String owner, final String name, final String desc) {
+- return newFieldItem(owner, name, desc).index;
+- }
+-
+- /**
+- * Adds a method reference to the constant pool of the class being build.
+- * Does nothing if the constant pool already contains a similar item.
+- *
+- * @param owner
+- * the internal name of the method's owner class.
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor.
+- * @param itf
+- * true if owner is an interface.
+- * @return a new or already existing method reference item.
+- */
+- Item newMethodItem(final String owner, final String name,
+- final String desc, final boolean itf) {
+- int type = itf ? IMETH : METH;
+- key3.set(type, owner, name, desc);
+- Item result = get(key3);
+- if (result == null) {
+- put122(type, newClass(owner), newNameType(name, desc));
+- result = new Item(index++, key3);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a method reference to the constant pool of the class being build.
+- * Does nothing if the constant pool already contains a similar item.
+- * This method is intended for {@link Attribute} sub classes, and is
+- * normally not needed by class generators or adapters.
+- *
+- * @param owner
+- * the internal name of the method's owner class.
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor.
+- * @param itf
+- * true if owner is an interface.
+- * @return the index of a new or already existing method reference item.
+- */
+- public int newMethod(final String owner, final String name,
+- final String desc, final boolean itf) {
+- return newMethodItem(owner, name, desc, itf).index;
+- }
+-
+- /**
+- * Adds an integer to the constant pool of the class being build. Does
+- * nothing if the constant pool already contains a similar item.
+- *
+- * @param value
+- * the int value.
+- * @return a new or already existing int item.
+- */
+- Item newInteger(final int value) {
+- key.set(value);
+- Item result = get(key);
+- if (result == null) {
+- pool.putByte(INT).putInt(value);
+- result = new Item(index++, key);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a float to the constant pool of the class being build. Does nothing
+- * if the constant pool already contains a similar item.
+- *
+- * @param value
+- * the float value.
+- * @return a new or already existing float item.
+- */
+- Item newFloat(final float value) {
+- key.set(value);
+- Item result = get(key);
+- if (result == null) {
+- pool.putByte(FLOAT).putInt(key.intVal);
+- result = new Item(index++, key);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a long to the constant pool of the class being build. Does nothing
+- * if the constant pool already contains a similar item.
+- *
+- * @param value
+- * the long value.
+- * @return a new or already existing long item.
+- */
+- Item newLong(final long value) {
+- key.set(value);
+- Item result = get(key);
+- if (result == null) {
+- pool.putByte(LONG).putLong(value);
+- result = new Item(index, key);
+- index += 2;
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a double to the constant pool of the class being build. Does nothing
+- * if the constant pool already contains a similar item.
+- *
+- * @param value
+- * the double value.
+- * @return a new or already existing double item.
+- */
+- Item newDouble(final double value) {
+- key.set(value);
+- Item result = get(key);
+- if (result == null) {
+- pool.putByte(DOUBLE).putLong(key.longVal);
+- result = new Item(index, key);
+- index += 2;
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a string to the constant pool of the class being build. Does nothing
+- * if the constant pool already contains a similar item.
+- *
+- * @param value
+- * the String value.
+- * @return a new or already existing string item.
+- */
+- private Item newString(final String value) {
+- key2.set(STR, value, null, null);
+- Item result = get(key2);
+- if (result == null) {
+- pool.put12(STR, newUTF8(value));
+- result = new Item(index++, key2);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds a name and type to the constant pool of the class being build. Does
+- * nothing if the constant pool already contains a similar item. This
+- * method is intended for {@link Attribute} sub classes, and is normally not
+- * needed by class generators or adapters.
+- *
+- * @param name
+- * a name.
+- * @param desc
+- * a type descriptor.
+- * @return the index of a new or already existing name and type item.
+- */
+- public int newNameType(final String name, final String desc) {
+- return newNameTypeItem(name, desc).index;
+- }
+-
+- /**
+- * Adds a name and type to the constant pool of the class being build. Does
+- * nothing if the constant pool already contains a similar item.
+- *
+- * @param name
+- * a name.
+- * @param desc
+- * a type descriptor.
+- * @return a new or already existing name and type item.
+- */
+- Item newNameTypeItem(final String name, final String desc) {
+- key2.set(NAME_TYPE, name, desc, null);
+- Item result = get(key2);
+- if (result == null) {
+- put122(NAME_TYPE, newUTF8(name), newUTF8(desc));
+- result = new Item(index++, key2);
+- put(result);
+- }
+- return result;
+- }
+-
+- /**
+- * Adds the given internal name to {@link #typeTable} and returns its index.
+- * Does nothing if the type table already contains this internal name.
+- *
+- * @param type
+- * the internal name to be added to the type table.
+- * @return the index of this internal name in the type table.
+- */
+- int addType(final String type) {
+- key.set(TYPE_NORMAL, type, null, null);
+- Item result = get(key);
+- if (result == null) {
+- result = addType(key);
+- }
+- return result.index;
+- }
+-
+- /**
+- * Adds the given "uninitialized" type to {@link #typeTable} and returns its
+- * index. This method is used for UNINITIALIZED types, made of an internal
+- * name and a bytecode offset.
+- *
+- * @param type
+- * the internal name to be added to the type table.
+- * @param offset
+- * the bytecode offset of the NEW instruction that created this
+- * UNINITIALIZED type value.
+- * @return the index of this internal name in the type table.
+- */
+- int addUninitializedType(final String type, final int offset) {
+- key.type = TYPE_UNINIT;
+- key.intVal = offset;
+- key.strVal1 = type;
+- key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset);
+- Item result = get(key);
+- if (result == null) {
+- result = addType(key);
+- }
+- return result.index;
+- }
+-
+- /**
+- * Adds the given Item to {@link #typeTable}.
+- *
+- * @param item
+- * the value to be added to the type table.
+- * @return the added Item, which a new Item instance with the same value as
+- * the given Item.
+- */
+- private Item addType(final Item item) {
+- ++typeCount;
+- Item result = new Item(typeCount, key);
+- put(result);
+- if (typeTable == null) {
+- typeTable = new Item[16];
+- }
+- if (typeCount == typeTable.length) {
+- Item[] newTable = new Item[2 * typeTable.length];
+- System.arraycopy(typeTable, 0, newTable, 0, typeTable.length);
+- typeTable = newTable;
+- }
+- typeTable[typeCount] = result;
+- return result;
+- }
+-
+- /**
+- * Returns the index of the common super type of the two given types. This
+- * method calls {@link #getCommonSuperClass} and caches the result in the
+- * {@link #items} hash table to speedup future calls with the same
+- * parameters.
+- *
+- * @param type1
+- * index of an internal name in {@link #typeTable}.
+- * @param type2
+- * index of an internal name in {@link #typeTable}.
+- * @return the index of the common super type of the two given types.
+- */
+- int getMergedType(final int type1, final int type2) {
+- key2.type = TYPE_MERGED;
+- key2.longVal = type1 | (((long) type2) << 32);
+- key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2);
+- Item result = get(key2);
+- if (result == null) {
+- String t = typeTable[type1].strVal1;
+- String u = typeTable[type2].strVal1;
+- key2.intVal = addType(getCommonSuperClass(t, u));
+- result = new Item((short) 0, key2);
+- put(result);
+- }
+- return result.intVal;
+- }
+-
+- /**
+- * Returns the common super type of the two given types. The default
+- * implementation of this method loads the two given classes and uses
+- * the java.lang.Class methods to find the common super class. It can be
+- * overridden to compute this common super type in other ways, in particular
+- * without actually loading any class, or to take into account the class
+- * that is currently being generated by this ClassWriter, which can of
+- * course not be loaded since it is under construction.
+- *
+- * @param type1
+- * the internal name of a class.
+- * @param type2
+- * the internal name of another class.
+- * @return the internal name of the common super class of the two given
+- * classes.
+- */
+- protected String getCommonSuperClass(final String type1, final String type2) {
+- Class> c, d;
+- ClassLoader classLoader = getClass().getClassLoader();
+- try {
+- c = Class.forName(type1.replace('/', '.'), false, classLoader);
+- d = Class.forName(type2.replace('/', '.'), false, classLoader);
+- } catch (Exception e) {
+- throw new RuntimeException(e.toString());
+- }
+- if (c.isAssignableFrom(d)) {
+- return type1;
+- }
+- if (d.isAssignableFrom(c)) {
+- return type2;
+- }
+- if (c.isInterface() || d.isInterface()) {
+- return "java/lang/Object";
+- } else {
+- do {
+- c = c.getSuperclass();
+- } while (!c.isAssignableFrom(d));
+- return c.getName().replace('.', '/');
+- }
+- }
+-
+- /**
+- * Returns the constant pool's hash table item which is equal to the given
+- * item.
+- *
+- * @param key
+- * a constant pool item.
+- * @return the constant pool's hash table item which is equal to the given
+- * item, or null if there is no such item.
+- */
+- private Item get(final Item key) {
+- Item i = items[key.hashCode % items.length];
+- while (i != null && (i.type != key.type || !key.isEqualTo(i))) {
+- i = i.next;
+- }
+- return i;
+- }
+-
+- /**
+- * Puts the given item in the constant pool's hash table. The hash table
+- * must not already contains this item.
+- *
+- * @param i
+- * the item to be added to the constant pool's hash table.
+- */
+- private void put(final Item i) {
+- if (index + typeCount > threshold) {
+- int ll = items.length;
+- int nl = ll * 2 + 1;
+- Item[] newItems = new Item[nl];
+- for (int l = ll - 1; l >= 0; --l) {
+- Item j = items[l];
+- while (j != null) {
+- int index = j.hashCode % newItems.length;
+- Item k = j.next;
+- j.next = newItems[index];
+- newItems[index] = j;
+- j = k;
+- }
+- }
+- items = newItems;
+- threshold = (int) (nl * 0.75);
+- }
+- int index = i.hashCode % items.length;
+- i.next = items[index];
+- items[index] = i;
+- }
+-
+- /**
+- * Puts one byte and two shorts into the constant pool.
+- *
+- * @param b
+- * a byte.
+- * @param s1
+- * a short.
+- * @param s2
+- * another short.
+- */
+- private void put122(final int b, final int s1, final int s2) {
+- pool.put12(b, s1).putShort(s2);
+- }
+-
+- /**
+- * Puts two bytes and one short into the constant pool.
+- *
+- * @param b1
+- * a byte.
+- * @param b2
+- * another byte.
+- * @param s
+- * a short.
+- */
+- private void put112(final int b1, final int b2, final int s) {
+- pool.put11(b1, b2).putShort(s);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/AdviceAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/AdviceAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/AdviceAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/AdviceAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,646 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import java.util.ArrayList;
+-import java.util.HashMap;
+-import java.util.List;
+-import java.util.Map;
+-
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-
+-/**
+- * A {@link org.mvel2.asm.MethodVisitor} to insert before, after and around
+- * advices in methods and constructors.
+- *
+- * The behavior for constructors is like this:
+- *
+- *
+- * as long as the INVOKESPECIAL for the object initialization has not been
+- * reached, every bytecode instruction is dispatched in the ctor code visitor
+- *
+- * when this one is reached, it is only added in the ctor code visitor and a
+- * JP invoke is added
+- *
+- * after that, only the other code visitor receives the instructions
+- *
+- *
+- *
+- * @author Eugene Kuleshov
+- * @author Eric Bruneton
+- */
+-public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes {
+-
+- private static final Object THIS = new Object();
+-
+- private static final Object OTHER = new Object();
+-
+- protected int methodAccess;
+-
+- protected String methodDesc;
+-
+- private boolean constructor;
+-
+- private boolean superInitialized;
+-
+- private List stackFrame;
+-
+- private Map> branches;
+-
+- /**
+- * Creates a new {@link AdviceAdapter}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param mv
+- * the method visitor to which this adapter delegates calls.
+- * @param access
+- * the method's access flags (see {@link Opcodes}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- */
+- protected AdviceAdapter(final int api, final MethodVisitor mv,
+- final int access, final String name, final String desc) {
+- super(api, mv, access, name, desc);
+- methodAccess = access;
+- methodDesc = desc;
+- constructor = "".equals(name);
+- }
+-
+- @Override
+- public void visitCode() {
+- mv.visitCode();
+- if (constructor) {
+- stackFrame = new ArrayList();
+- branches = new HashMap>();
+- } else {
+- superInitialized = true;
+- onMethodEnter();
+- }
+- }
+-
+- @Override
+- public void visitLabel(final Label label) {
+- mv.visitLabel(label);
+- if (constructor && branches != null) {
+- List frame = branches.get(label);
+- if (frame != null) {
+- stackFrame = frame;
+- branches.remove(label);
+- }
+- }
+- }
+-
+- @Override
+- public void visitInsn(final int opcode) {
+- if (constructor) {
+- int s;
+- switch (opcode) {
+- case RETURN: // empty stack
+- onMethodExit(opcode);
+- break;
+- case IRETURN: // 1 before n/a after
+- case FRETURN: // 1 before n/a after
+- case ARETURN: // 1 before n/a after
+- case ATHROW: // 1 before n/a after
+- popValue();
+- onMethodExit(opcode);
+- break;
+- case LRETURN: // 2 before n/a after
+- case DRETURN: // 2 before n/a after
+- popValue();
+- popValue();
+- onMethodExit(opcode);
+- break;
+- case NOP:
+- case LALOAD: // remove 2 add 2
+- case DALOAD: // remove 2 add 2
+- case LNEG:
+- case DNEG:
+- case FNEG:
+- case INEG:
+- case L2D:
+- case D2L:
+- case F2I:
+- case I2B:
+- case I2C:
+- case I2S:
+- case I2F:
+- case ARRAYLENGTH:
+- break;
+- case ACONST_NULL:
+- case ICONST_M1:
+- case ICONST_0:
+- case ICONST_1:
+- case ICONST_2:
+- case ICONST_3:
+- case ICONST_4:
+- case ICONST_5:
+- case FCONST_0:
+- case FCONST_1:
+- case FCONST_2:
+- case F2L: // 1 before 2 after
+- case F2D:
+- case I2L:
+- case I2D:
+- pushValue(OTHER);
+- break;
+- case LCONST_0:
+- case LCONST_1:
+- case DCONST_0:
+- case DCONST_1:
+- pushValue(OTHER);
+- pushValue(OTHER);
+- break;
+- case IALOAD: // remove 2 add 1
+- case FALOAD: // remove 2 add 1
+- case AALOAD: // remove 2 add 1
+- case BALOAD: // remove 2 add 1
+- case CALOAD: // remove 2 add 1
+- case SALOAD: // remove 2 add 1
+- case POP:
+- case IADD:
+- case FADD:
+- case ISUB:
+- case LSHL: // 3 before 2 after
+- case LSHR: // 3 before 2 after
+- case LUSHR: // 3 before 2 after
+- case L2I: // 2 before 1 after
+- case L2F: // 2 before 1 after
+- case D2I: // 2 before 1 after
+- case D2F: // 2 before 1 after
+- case FSUB:
+- case FMUL:
+- case FDIV:
+- case FREM:
+- case FCMPL: // 2 before 1 after
+- case FCMPG: // 2 before 1 after
+- case IMUL:
+- case IDIV:
+- case IREM:
+- case ISHL:
+- case ISHR:
+- case IUSHR:
+- case IAND:
+- case IOR:
+- case IXOR:
+- case MONITORENTER:
+- case MONITOREXIT:
+- popValue();
+- break;
+- case POP2:
+- case LSUB:
+- case LMUL:
+- case LDIV:
+- case LREM:
+- case LADD:
+- case LAND:
+- case LOR:
+- case LXOR:
+- case DADD:
+- case DMUL:
+- case DSUB:
+- case DDIV:
+- case DREM:
+- popValue();
+- popValue();
+- break;
+- case IASTORE:
+- case FASTORE:
+- case AASTORE:
+- case BASTORE:
+- case CASTORE:
+- case SASTORE:
+- case LCMP: // 4 before 1 after
+- case DCMPL:
+- case DCMPG:
+- popValue();
+- popValue();
+- popValue();
+- break;
+- case LASTORE:
+- case DASTORE:
+- popValue();
+- popValue();
+- popValue();
+- popValue();
+- break;
+- case DUP:
+- pushValue(peekValue());
+- break;
+- case DUP_X1:
+- s = stackFrame.size();
+- stackFrame.add(s - 2, stackFrame.get(s - 1));
+- break;
+- case DUP_X2:
+- s = stackFrame.size();
+- stackFrame.add(s - 3, stackFrame.get(s - 1));
+- break;
+- case DUP2:
+- s = stackFrame.size();
+- stackFrame.add(s - 2, stackFrame.get(s - 1));
+- stackFrame.add(s - 2, stackFrame.get(s - 1));
+- break;
+- case DUP2_X1:
+- s = stackFrame.size();
+- stackFrame.add(s - 3, stackFrame.get(s - 1));
+- stackFrame.add(s - 3, stackFrame.get(s - 1));
+- break;
+- case DUP2_X2:
+- s = stackFrame.size();
+- stackFrame.add(s - 4, stackFrame.get(s - 1));
+- stackFrame.add(s - 4, stackFrame.get(s - 1));
+- break;
+- case SWAP:
+- s = stackFrame.size();
+- stackFrame.add(s - 2, stackFrame.get(s - 1));
+- stackFrame.remove(s);
+- break;
+- }
+- } else {
+- switch (opcode) {
+- case RETURN:
+- case IRETURN:
+- case FRETURN:
+- case ARETURN:
+- case LRETURN:
+- case DRETURN:
+- case ATHROW:
+- onMethodExit(opcode);
+- break;
+- }
+- }
+- mv.visitInsn(opcode);
+- }
+-
+- @Override
+- public void visitVarInsn(final int opcode, final int var) {
+- super.visitVarInsn(opcode, var);
+- if (constructor) {
+- switch (opcode) {
+- case ILOAD:
+- case FLOAD:
+- pushValue(OTHER);
+- break;
+- case LLOAD:
+- case DLOAD:
+- pushValue(OTHER);
+- pushValue(OTHER);
+- break;
+- case ALOAD:
+- pushValue(var == 0 ? THIS : OTHER);
+- break;
+- case ASTORE:
+- case ISTORE:
+- case FSTORE:
+- popValue();
+- break;
+- case LSTORE:
+- case DSTORE:
+- popValue();
+- popValue();
+- break;
+- }
+- }
+- }
+-
+- @Override
+- public void visitFieldInsn(final int opcode, final String owner,
+- final String name, final String desc) {
+- mv.visitFieldInsn(opcode, owner, name, desc);
+- if (constructor) {
+- char c = desc.charAt(0);
+- boolean longOrDouble = c == 'J' || c == 'D';
+- switch (opcode) {
+- case GETSTATIC:
+- pushValue(OTHER);
+- if (longOrDouble) {
+- pushValue(OTHER);
+- }
+- break;
+- case PUTSTATIC:
+- popValue();
+- if (longOrDouble) {
+- popValue();
+- }
+- break;
+- case PUTFIELD:
+- popValue();
+- if (longOrDouble) {
+- popValue();
+- popValue();
+- }
+- break;
+- // case GETFIELD:
+- default:
+- if (longOrDouble) {
+- pushValue(OTHER);
+- }
+- }
+- }
+- }
+-
+- @Override
+- public void visitIntInsn(final int opcode, final int operand) {
+- mv.visitIntInsn(opcode, operand);
+- if (constructor && opcode != NEWARRAY) {
+- pushValue(OTHER);
+- }
+- }
+-
+- @Override
+- public void visitLdcInsn(final Object cst) {
+- mv.visitLdcInsn(cst);
+- if (constructor) {
+- pushValue(OTHER);
+- if (cst instanceof Double || cst instanceof Long) {
+- pushValue(OTHER);
+- }
+- }
+- }
+-
+- @Override
+- public void visitMultiANewArrayInsn(final String desc, final int dims) {
+- mv.visitMultiANewArrayInsn(desc, dims);
+- if (constructor) {
+- for (int i = 0; i < dims; i++) {
+- popValue();
+- }
+- pushValue(OTHER);
+- }
+- }
+-
+- @Override
+- public void visitTypeInsn(final int opcode, final String type) {
+- mv.visitTypeInsn(opcode, type);
+- // ANEWARRAY, CHECKCAST or INSTANCEOF don't change stack
+- if (constructor && opcode == NEW) {
+- pushValue(OTHER);
+- }
+- }
+-
+- @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, final String owner,
+- final String name, final String desc, final boolean itf) {
+- mv.visitMethodInsn(opcode, owner, name, desc, itf);
+- if (constructor) {
+- Type[] types = Type.getArgumentTypes(desc);
+- for (int i = 0; i < types.length; i++) {
+- popValue();
+- if (types[i].getSize() == 2) {
+- popValue();
+- }
+- }
+- switch (opcode) {
+- // case INVOKESTATIC:
+- // break;
+- case INVOKEINTERFACE:
+- case INVOKEVIRTUAL:
+- popValue(); // objectref
+- break;
+- case INVOKESPECIAL:
+- Object type = popValue(); // objectref
+- if (type == THIS && !superInitialized) {
+- onMethodEnter();
+- superInitialized = true;
+- // once super has been initialized it is no longer
+- // necessary to keep track of stack state
+- constructor = false;
+- }
+- break;
+- }
+-
+- Type returnType = Type.getReturnType(desc);
+- if (returnType != Type.VOID_TYPE) {
+- pushValue(OTHER);
+- if (returnType.getSize() == 2) {
+- pushValue(OTHER);
+- }
+- }
+- }
+- }
+-
+- @Override
+- public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+- Object... bsmArgs) {
+- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+- if (constructor) {
+- Type[] types = Type.getArgumentTypes(desc);
+- for (int i = 0; i < types.length; i++) {
+- popValue();
+- if (types[i].getSize() == 2) {
+- popValue();
+- }
+- }
+-
+- Type returnType = Type.getReturnType(desc);
+- if (returnType != Type.VOID_TYPE) {
+- pushValue(OTHER);
+- if (returnType.getSize() == 2) {
+- pushValue(OTHER);
+- }
+- }
+- }
+- }
+-
+- @Override
+- public void visitJumpInsn(final int opcode, final Label label) {
+- mv.visitJumpInsn(opcode, label);
+- if (constructor) {
+- switch (opcode) {
+- case IFEQ:
+- case IFNE:
+- case IFLT:
+- case IFGE:
+- case IFGT:
+- case IFLE:
+- case IFNULL:
+- case IFNONNULL:
+- popValue();
+- break;
+- case IF_ICMPEQ:
+- case IF_ICMPNE:
+- case IF_ICMPLT:
+- case IF_ICMPGE:
+- case IF_ICMPGT:
+- case IF_ICMPLE:
+- case IF_ACMPEQ:
+- case IF_ACMPNE:
+- popValue();
+- popValue();
+- break;
+- case JSR:
+- pushValue(OTHER);
+- break;
+- }
+- addBranch(label);
+- }
+- }
+-
+- @Override
+- public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+- final Label[] labels) {
+- mv.visitLookupSwitchInsn(dflt, keys, labels);
+- if (constructor) {
+- popValue();
+- addBranches(dflt, labels);
+- }
+- }
+-
+- @Override
+- public void visitTableSwitchInsn(final int min, final int max,
+- final Label dflt, final Label... labels) {
+- mv.visitTableSwitchInsn(min, max, dflt, labels);
+- if (constructor) {
+- popValue();
+- addBranches(dflt, labels);
+- }
+- }
+-
+- @Override
+- public void visitTryCatchBlock(Label start, Label end, Label handler,
+- String type) {
+- super.visitTryCatchBlock(start, end, handler, type);
+- if (constructor && !branches.containsKey(handler)) {
+- List stackFrame = new ArrayList();
+- stackFrame.add(OTHER);
+- branches.put(handler, stackFrame);
+- }
+- }
+-
+- private void addBranches(final Label dflt, final Label[] labels) {
+- addBranch(dflt);
+- for (int i = 0; i < labels.length; i++) {
+- addBranch(labels[i]);
+- }
+- }
+-
+- private void addBranch(final Label label) {
+- if (branches.containsKey(label)) {
+- return;
+- }
+- branches.put(label, new ArrayList(stackFrame));
+- }
+-
+- private Object popValue() {
+- return stackFrame.remove(stackFrame.size() - 1);
+- }
+-
+- private Object peekValue() {
+- return stackFrame.get(stackFrame.size() - 1);
+- }
+-
+- private void pushValue(final Object o) {
+- stackFrame.add(o);
+- }
+-
+- /**
+- * Called at the beginning of the method or after super class class call in
+- * the constructor.
+- *
+- *
+- * Custom code can use or change all the local variables, but should not
+- * change state of the stack.
+- */
+- protected void onMethodEnter() {
+- }
+-
+- /**
+- * Called before explicit exit from the method using either return or throw.
+- * Top element on the stack contains the return value or exception instance.
+- * For example:
+- *
+- *
+- * public void onMethodExit(int opcode) {
+- * if(opcode==RETURN) {
+- * visitInsn(ACONST_NULL);
+- * } else if(opcode==ARETURN || opcode==ATHROW) {
+- * dup();
+- * } else {
+- * if(opcode==LRETURN || opcode==DRETURN) {
+- * dup2();
+- * } else {
+- * dup();
+- * }
+- * box(Type.getReturnType(this.methodDesc));
+- * }
+- * visitIntInsn(SIPUSH, opcode);
+- * visitMethodInsn(INVOKESTATIC, owner, "onExit", "(Ljava/lang/Object;I)V");
+- * }
+- *
+- * // an actual call back method
+- * public static void onExit(Object param, int opcode) {
+- * ...
+- *
+- *
+- *
+- *
+- *
+- * Custom code can use or change all the local variables, but should not
+- * change state of the stack.
+- *
+- * @param opcode
+- * one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN, DRETURN
+- * or ATHROW
+- *
+- */
+- protected void onMethodExit(int opcode) {
+- }
+-
+- // TODO onException, onMethodCall
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/AnalyzerAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/AnalyzerAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/AnalyzerAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/AnalyzerAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,947 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import java.util.ArrayList;
+-import java.util.HashMap;
+-import java.util.List;
+-import java.util.Map;
+-
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-
+-/**
+- * A {@link MethodVisitor} that keeps track of stack map frame changes between
+- * {@link #visitFrame(int, int, Object[], int, Object[]) visitFrame} calls. This
+- * adapter must be used with the
+- * {@link org.mvel2.asm.ClassReader#EXPAND_FRAMES} option. Each
+- * visitX instruction delegates to the next visitor in the chain, if any,
+- * and then simulates the effect of this instruction on the stack map frame,
+- * represented by {@link #locals} and {@link #stack}. The next visitor in the
+- * chain can get the state of the stack map frame before each instruction
+- * by reading the value of these fields in its visitX methods (this
+- * requires a reference to the AnalyzerAdapter that is before it in the chain).
+- * If this adapter is used with a class that does not contain stack map table
+- * attributes (i.e., pre Java 6 classes) then this adapter may not be able to
+- * compute the stack map frame for each instruction. In this case no exception
+- * is thrown but the {@link #locals} and {@link #stack} fields will be null for
+- * these instructions.
+- *
+- * @author Eric Bruneton
+- */
+-public class AnalyzerAdapter extends MethodVisitor {
+-
+- /**
+- * List
of the local variable slots for current execution
+- * frame. Primitive types are represented by {@link Opcodes#TOP},
+- * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+- * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+- * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by
+- * two elements, the second one being TOP). Reference types are represented
+- * by String objects (representing internal names), and uninitialized types
+- * by Label objects (this label designates the NEW instruction that created
+- * this uninitialized value). This field is null for unreachable
+- * instructions.
+- */
+- public List locals;
+-
+- /**
+- * List
of the operand stack slots for current execution frame.
+- * Primitive types are represented by {@link Opcodes#TOP},
+- * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+- * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+- * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by
+- * two elements, the second one being TOP). Reference types are represented
+- * by String objects (representing internal names), and uninitialized types
+- * by Label objects (this label designates the NEW instruction that created
+- * this uninitialized value). This field is null for unreachable
+- * instructions.
+- */
+- public List stack;
+-
+- /**
+- * The labels that designate the next instruction to be visited. May be
+- * null .
+- */
+- private List labels;
+-
+- /**
+- * Information about uninitialized types in the current execution frame.
+- * This map associates internal names to Label objects. Each label
+- * designates a NEW instruction that created the currently uninitialized
+- * types, and the associated internal name represents the NEW operand, i.e.
+- * the final, initialized type value.
+- */
+- public Map uninitializedTypes;
+-
+- /**
+- * The maximum stack size of this method.
+- */
+- private int maxStack;
+-
+- /**
+- * The maximum number of local variables of this method.
+- */
+- private int maxLocals;
+-
+- /**
+- * The owner's class name.
+- */
+- private String owner;
+-
+- /**
+- * Creates a new {@link AnalyzerAdapter}. Subclasses must not use this
+- * constructor . Instead, they must use the
+- * {@link #AnalyzerAdapter(int, String, int, String, String, MethodVisitor)}
+- * version.
+- *
+- * @param owner
+- * the owner's class name.
+- * @param access
+- * the method's access flags (see {@link Opcodes}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @param mv
+- * the method visitor to which this adapter delegates calls. May
+- * be null .
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public AnalyzerAdapter(final String owner, final int access,
+- final String name, final String desc, final MethodVisitor mv) {
+- this(Opcodes.ASM5, owner, access, name, desc, mv);
+- if (getClass() != AnalyzerAdapter.class) {
+- throw new IllegalStateException();
+- }
+- }
+-
+- /**
+- * Creates a new {@link AnalyzerAdapter}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param owner
+- * the owner's class name.
+- * @param access
+- * the method's access flags (see {@link Opcodes}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @param mv
+- * the method visitor to which this adapter delegates calls. May
+- * be null .
+- */
+- protected AnalyzerAdapter(final int api, final String owner,
+- final int access, final String name, final String desc,
+- final MethodVisitor mv) {
+- super(api, mv);
+- this.owner = owner;
+- locals = new ArrayList();
+- stack = new ArrayList();
+- uninitializedTypes = new HashMap();
+-
+- if ((access & Opcodes.ACC_STATIC) == 0) {
+- if ("".equals(name)) {
+- locals.add(Opcodes.UNINITIALIZED_THIS);
+- } else {
+- locals.add(owner);
+- }
+- }
+- Type[] types = Type.getArgumentTypes(desc);
+- for (int i = 0; i < types.length; ++i) {
+- Type type = types[i];
+- switch (type.getSort()) {
+- case Type.BOOLEAN:
+- case Type.CHAR:
+- case Type.BYTE:
+- case Type.SHORT:
+- case Type.INT:
+- locals.add(Opcodes.INTEGER);
+- break;
+- case Type.FLOAT:
+- locals.add(Opcodes.FLOAT);
+- break;
+- case Type.LONG:
+- locals.add(Opcodes.LONG);
+- locals.add(Opcodes.TOP);
+- break;
+- case Type.DOUBLE:
+- locals.add(Opcodes.DOUBLE);
+- locals.add(Opcodes.TOP);
+- break;
+- case Type.ARRAY:
+- locals.add(types[i].getDescriptor());
+- break;
+- // case Type.OBJECT:
+- default:
+- locals.add(types[i].getInternalName());
+- }
+- }
+- maxLocals = locals.size();
+- }
+-
+- @Override
+- public void visitFrame(final int type, final int nLocal,
+- final Object[] local, final int nStack, final Object[] stack) {
+- if (type != Opcodes.F_NEW) { // uncompressed frame
+- throw new IllegalStateException(
+- "ClassReader.accept() should be called with EXPAND_FRAMES flag");
+- }
+-
+- if (mv != null) {
+- mv.visitFrame(type, nLocal, local, nStack, stack);
+- }
+-
+- if (this.locals != null) {
+- this.locals.clear();
+- this.stack.clear();
+- } else {
+- this.locals = new ArrayList();
+- this.stack = new ArrayList();
+- }
+- visitFrameTypes(nLocal, local, this.locals);
+- visitFrameTypes(nStack, stack, this.stack);
+- maxStack = Math.max(maxStack, this.stack.size());
+- }
+-
+- private static void visitFrameTypes(final int n, final Object[] types,
+- final List result) {
+- for (int i = 0; i < n; ++i) {
+- Object type = types[i];
+- result.add(type);
+- if (type == Opcodes.LONG || type == Opcodes.DOUBLE) {
+- result.add(Opcodes.TOP);
+- }
+- }
+- }
+-
+- @Override
+- public void visitInsn(final int opcode) {
+- if (mv != null) {
+- mv.visitInsn(opcode);
+- }
+- execute(opcode, 0, null);
+- if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
+- || opcode == Opcodes.ATHROW) {
+- this.locals = null;
+- this.stack = null;
+- }
+- }
+-
+- @Override
+- public void visitIntInsn(final int opcode, final int operand) {
+- if (mv != null) {
+- mv.visitIntInsn(opcode, operand);
+- }
+- execute(opcode, operand, null);
+- }
+-
+- @Override
+- public void visitVarInsn(final int opcode, final int var) {
+- if (mv != null) {
+- mv.visitVarInsn(opcode, var);
+- }
+- execute(opcode, var, null);
+- }
+-
+- @Override
+- public void visitTypeInsn(final int opcode, final String type) {
+- if (opcode == Opcodes.NEW) {
+- if (labels == null) {
+- Label l = new Label();
+- labels = new ArrayList(3);
+- labels.add(l);
+- if (mv != null) {
+- mv.visitLabel(l);
+- }
+- }
+- for (int i = 0; i < labels.size(); ++i) {
+- uninitializedTypes.put(labels.get(i), type);
+- }
+- }
+- if (mv != null) {
+- mv.visitTypeInsn(opcode, type);
+- }
+- execute(opcode, 0, type);
+- }
+-
+- @Override
+- public void visitFieldInsn(final int opcode, final String owner,
+- final String name, final String desc) {
+- if (mv != null) {
+- mv.visitFieldInsn(opcode, owner, name, desc);
+- }
+- execute(opcode, 0, desc);
+- }
+-
+- @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, final String owner,
+- final String name, final String desc, final boolean itf) {
+- if (mv != null) {
+- mv.visitMethodInsn(opcode, owner, name, desc, itf);
+- }
+- if (this.locals == null) {
+- labels = null;
+- return;
+- }
+- pop(desc);
+- if (opcode != Opcodes.INVOKESTATIC) {
+- Object t = pop();
+- if (opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') {
+- Object u;
+- if (t == Opcodes.UNINITIALIZED_THIS) {
+- u = this.owner;
+- } else {
+- u = uninitializedTypes.get(t);
+- }
+- for (int i = 0; i < locals.size(); ++i) {
+- if (locals.get(i) == t) {
+- locals.set(i, u);
+- }
+- }
+- for (int i = 0; i < stack.size(); ++i) {
+- if (stack.get(i) == t) {
+- stack.set(i, u);
+- }
+- }
+- }
+- }
+- pushDesc(desc);
+- labels = null;
+- }
+-
+- @Override
+- public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+- Object... bsmArgs) {
+- if (mv != null) {
+- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+- }
+- if (this.locals == null) {
+- labels = null;
+- return;
+- }
+- pop(desc);
+- pushDesc(desc);
+- labels = null;
+- }
+-
+- @Override
+- public void visitJumpInsn(final int opcode, final Label label) {
+- if (mv != null) {
+- mv.visitJumpInsn(opcode, label);
+- }
+- execute(opcode, 0, null);
+- if (opcode == Opcodes.GOTO) {
+- this.locals = null;
+- this.stack = null;
+- }
+- }
+-
+- @Override
+- public void visitLabel(final Label label) {
+- if (mv != null) {
+- mv.visitLabel(label);
+- }
+- if (labels == null) {
+- labels = new ArrayList(3);
+- }
+- labels.add(label);
+- }
+-
+- @Override
+- public void visitLdcInsn(final Object cst) {
+- if (mv != null) {
+- mv.visitLdcInsn(cst);
+- }
+- if (this.locals == null) {
+- labels = null;
+- return;
+- }
+- if (cst instanceof Integer) {
+- push(Opcodes.INTEGER);
+- } else if (cst instanceof Long) {
+- push(Opcodes.LONG);
+- push(Opcodes.TOP);
+- } else if (cst instanceof Float) {
+- push(Opcodes.FLOAT);
+- } else if (cst instanceof Double) {
+- push(Opcodes.DOUBLE);
+- push(Opcodes.TOP);
+- } else if (cst instanceof String) {
+- push("java/lang/String");
+- } else if (cst instanceof Type) {
+- int sort = ((Type) cst).getSort();
+- if (sort == Type.OBJECT || sort == Type.ARRAY) {
+- push("java/lang/Class");
+- } else if (sort == Type.METHOD) {
+- push("java/lang/invoke/MethodType");
+- } else {
+- throw new IllegalArgumentException();
+- }
+- } else if (cst instanceof Handle) {
+- push("java/lang/invoke/MethodHandle");
+- } else {
+- throw new IllegalArgumentException();
+- }
+- labels = null;
+- }
+-
+- @Override
+- public void visitIincInsn(final int var, final int increment) {
+- if (mv != null) {
+- mv.visitIincInsn(var, increment);
+- }
+- execute(Opcodes.IINC, var, null);
+- }
+-
+- @Override
+- public void visitTableSwitchInsn(final int min, final int max,
+- final Label dflt, final Label... labels) {
+- if (mv != null) {
+- mv.visitTableSwitchInsn(min, max, dflt, labels);
+- }
+- execute(Opcodes.TABLESWITCH, 0, null);
+- this.locals = null;
+- this.stack = null;
+- }
+-
+- @Override
+- public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+- final Label[] labels) {
+- if (mv != null) {
+- mv.visitLookupSwitchInsn(dflt, keys, labels);
+- }
+- execute(Opcodes.LOOKUPSWITCH, 0, null);
+- this.locals = null;
+- this.stack = null;
+- }
+-
+- @Override
+- public void visitMultiANewArrayInsn(final String desc, final int dims) {
+- if (mv != null) {
+- mv.visitMultiANewArrayInsn(desc, dims);
+- }
+- execute(Opcodes.MULTIANEWARRAY, dims, desc);
+- }
+-
+- @Override
+- public void visitMaxs(final int maxStack, final int maxLocals) {
+- if (mv != null) {
+- this.maxStack = Math.max(this.maxStack, maxStack);
+- this.maxLocals = Math.max(this.maxLocals, maxLocals);
+- mv.visitMaxs(this.maxStack, this.maxLocals);
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+-
+- private Object get(final int local) {
+- maxLocals = Math.max(maxLocals, local + 1);
+- return local < locals.size() ? locals.get(local) : Opcodes.TOP;
+- }
+-
+- private void set(final int local, final Object type) {
+- maxLocals = Math.max(maxLocals, local + 1);
+- while (local >= locals.size()) {
+- locals.add(Opcodes.TOP);
+- }
+- locals.set(local, type);
+- }
+-
+- private void push(final Object type) {
+- stack.add(type);
+- maxStack = Math.max(maxStack, stack.size());
+- }
+-
+- private void pushDesc(final String desc) {
+- int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
+- switch (desc.charAt(index)) {
+- case 'V':
+- return;
+- case 'Z':
+- case 'C':
+- case 'B':
+- case 'S':
+- case 'I':
+- push(Opcodes.INTEGER);
+- return;
+- case 'F':
+- push(Opcodes.FLOAT);
+- return;
+- case 'J':
+- push(Opcodes.LONG);
+- push(Opcodes.TOP);
+- return;
+- case 'D':
+- push(Opcodes.DOUBLE);
+- push(Opcodes.TOP);
+- return;
+- case '[':
+- if (index == 0) {
+- push(desc);
+- } else {
+- push(desc.substring(index, desc.length()));
+- }
+- break;
+- // case 'L':
+- default:
+- if (index == 0) {
+- push(desc.substring(1, desc.length() - 1));
+- } else {
+- push(desc.substring(index + 1, desc.length() - 1));
+- }
+- }
+- }
+-
+- private Object pop() {
+- return stack.remove(stack.size() - 1);
+- }
+-
+- private void pop(final int n) {
+- int size = stack.size();
+- int end = size - n;
+- for (int i = size - 1; i >= end; --i) {
+- stack.remove(i);
+- }
+- }
+-
+- private void pop(final String desc) {
+- char c = desc.charAt(0);
+- if (c == '(') {
+- int n = 0;
+- Type[] types = Type.getArgumentTypes(desc);
+- for (int i = 0; i < types.length; ++i) {
+- n += types[i].getSize();
+- }
+- pop(n);
+- } else if (c == 'J' || c == 'D') {
+- pop(2);
+- } else {
+- pop(1);
+- }
+- }
+-
+- private void execute(final int opcode, final int iarg, final String sarg) {
+- if (this.locals == null) {
+- labels = null;
+- return;
+- }
+- Object t1, t2, t3, t4;
+- switch (opcode) {
+- case Opcodes.NOP:
+- case Opcodes.INEG:
+- case Opcodes.LNEG:
+- case Opcodes.FNEG:
+- case Opcodes.DNEG:
+- case Opcodes.I2B:
+- case Opcodes.I2C:
+- case Opcodes.I2S:
+- case Opcodes.GOTO:
+- case Opcodes.RETURN:
+- break;
+- case Opcodes.ACONST_NULL:
+- push(Opcodes.NULL);
+- break;
+- case Opcodes.ICONST_M1:
+- case Opcodes.ICONST_0:
+- case Opcodes.ICONST_1:
+- case Opcodes.ICONST_2:
+- case Opcodes.ICONST_3:
+- case Opcodes.ICONST_4:
+- case Opcodes.ICONST_5:
+- case Opcodes.BIPUSH:
+- case Opcodes.SIPUSH:
+- push(Opcodes.INTEGER);
+- break;
+- case Opcodes.LCONST_0:
+- case Opcodes.LCONST_1:
+- push(Opcodes.LONG);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.FCONST_0:
+- case Opcodes.FCONST_1:
+- case Opcodes.FCONST_2:
+- push(Opcodes.FLOAT);
+- break;
+- case Opcodes.DCONST_0:
+- case Opcodes.DCONST_1:
+- push(Opcodes.DOUBLE);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.ILOAD:
+- case Opcodes.FLOAD:
+- case Opcodes.ALOAD:
+- push(get(iarg));
+- break;
+- case Opcodes.LLOAD:
+- case Opcodes.DLOAD:
+- push(get(iarg));
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.IALOAD:
+- case Opcodes.BALOAD:
+- case Opcodes.CALOAD:
+- case Opcodes.SALOAD:
+- pop(2);
+- push(Opcodes.INTEGER);
+- break;
+- case Opcodes.LALOAD:
+- case Opcodes.D2L:
+- pop(2);
+- push(Opcodes.LONG);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.FALOAD:
+- pop(2);
+- push(Opcodes.FLOAT);
+- break;
+- case Opcodes.DALOAD:
+- case Opcodes.L2D:
+- pop(2);
+- push(Opcodes.DOUBLE);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.AALOAD:
+- pop(1);
+- t1 = pop();
+- if (t1 instanceof String) {
+- pushDesc(((String) t1).substring(1));
+- } else {
+- push("java/lang/Object");
+- }
+- break;
+- case Opcodes.ISTORE:
+- case Opcodes.FSTORE:
+- case Opcodes.ASTORE:
+- t1 = pop();
+- set(iarg, t1);
+- if (iarg > 0) {
+- t2 = get(iarg - 1);
+- if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
+- set(iarg - 1, Opcodes.TOP);
+- }
+- }
+- break;
+- case Opcodes.LSTORE:
+- case Opcodes.DSTORE:
+- pop(1);
+- t1 = pop();
+- set(iarg, t1);
+- set(iarg + 1, Opcodes.TOP);
+- if (iarg > 0) {
+- t2 = get(iarg - 1);
+- if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
+- set(iarg - 1, Opcodes.TOP);
+- }
+- }
+- break;
+- case Opcodes.IASTORE:
+- case Opcodes.BASTORE:
+- case Opcodes.CASTORE:
+- case Opcodes.SASTORE:
+- case Opcodes.FASTORE:
+- case Opcodes.AASTORE:
+- pop(3);
+- break;
+- case Opcodes.LASTORE:
+- case Opcodes.DASTORE:
+- pop(4);
+- break;
+- case Opcodes.POP:
+- case Opcodes.IFEQ:
+- case Opcodes.IFNE:
+- case Opcodes.IFLT:
+- case Opcodes.IFGE:
+- case Opcodes.IFGT:
+- case Opcodes.IFLE:
+- case Opcodes.IRETURN:
+- case Opcodes.FRETURN:
+- case Opcodes.ARETURN:
+- case Opcodes.TABLESWITCH:
+- case Opcodes.LOOKUPSWITCH:
+- case Opcodes.ATHROW:
+- case Opcodes.MONITORENTER:
+- case Opcodes.MONITOREXIT:
+- case Opcodes.IFNULL:
+- case Opcodes.IFNONNULL:
+- pop(1);
+- break;
+- case Opcodes.POP2:
+- case Opcodes.IF_ICMPEQ:
+- case Opcodes.IF_ICMPNE:
+- case Opcodes.IF_ICMPLT:
+- case Opcodes.IF_ICMPGE:
+- case Opcodes.IF_ICMPGT:
+- case Opcodes.IF_ICMPLE:
+- case Opcodes.IF_ACMPEQ:
+- case Opcodes.IF_ACMPNE:
+- case Opcodes.LRETURN:
+- case Opcodes.DRETURN:
+- pop(2);
+- break;
+- case Opcodes.DUP:
+- t1 = pop();
+- push(t1);
+- push(t1);
+- break;
+- case Opcodes.DUP_X1:
+- t1 = pop();
+- t2 = pop();
+- push(t1);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.DUP_X2:
+- t1 = pop();
+- t2 = pop();
+- t3 = pop();
+- push(t1);
+- push(t3);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.DUP2:
+- t1 = pop();
+- t2 = pop();
+- push(t2);
+- push(t1);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.DUP2_X1:
+- t1 = pop();
+- t2 = pop();
+- t3 = pop();
+- push(t2);
+- push(t1);
+- push(t3);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.DUP2_X2:
+- t1 = pop();
+- t2 = pop();
+- t3 = pop();
+- t4 = pop();
+- push(t2);
+- push(t1);
+- push(t4);
+- push(t3);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.SWAP:
+- t1 = pop();
+- t2 = pop();
+- push(t1);
+- push(t2);
+- break;
+- case Opcodes.IADD:
+- case Opcodes.ISUB:
+- case Opcodes.IMUL:
+- case Opcodes.IDIV:
+- case Opcodes.IREM:
+- case Opcodes.IAND:
+- case Opcodes.IOR:
+- case Opcodes.IXOR:
+- case Opcodes.ISHL:
+- case Opcodes.ISHR:
+- case Opcodes.IUSHR:
+- case Opcodes.L2I:
+- case Opcodes.D2I:
+- case Opcodes.FCMPL:
+- case Opcodes.FCMPG:
+- pop(2);
+- push(Opcodes.INTEGER);
+- break;
+- case Opcodes.LADD:
+- case Opcodes.LSUB:
+- case Opcodes.LMUL:
+- case Opcodes.LDIV:
+- case Opcodes.LREM:
+- case Opcodes.LAND:
+- case Opcodes.LOR:
+- case Opcodes.LXOR:
+- pop(4);
+- push(Opcodes.LONG);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.FADD:
+- case Opcodes.FSUB:
+- case Opcodes.FMUL:
+- case Opcodes.FDIV:
+- case Opcodes.FREM:
+- case Opcodes.L2F:
+- case Opcodes.D2F:
+- pop(2);
+- push(Opcodes.FLOAT);
+- break;
+- case Opcodes.DADD:
+- case Opcodes.DSUB:
+- case Opcodes.DMUL:
+- case Opcodes.DDIV:
+- case Opcodes.DREM:
+- pop(4);
+- push(Opcodes.DOUBLE);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.LSHL:
+- case Opcodes.LSHR:
+- case Opcodes.LUSHR:
+- pop(3);
+- push(Opcodes.LONG);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.IINC:
+- set(iarg, Opcodes.INTEGER);
+- break;
+- case Opcodes.I2L:
+- case Opcodes.F2L:
+- pop(1);
+- push(Opcodes.LONG);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.I2F:
+- pop(1);
+- push(Opcodes.FLOAT);
+- break;
+- case Opcodes.I2D:
+- case Opcodes.F2D:
+- pop(1);
+- push(Opcodes.DOUBLE);
+- push(Opcodes.TOP);
+- break;
+- case Opcodes.F2I:
+- case Opcodes.ARRAYLENGTH:
+- case Opcodes.INSTANCEOF:
+- pop(1);
+- push(Opcodes.INTEGER);
+- break;
+- case Opcodes.LCMP:
+- case Opcodes.DCMPL:
+- case Opcodes.DCMPG:
+- pop(4);
+- push(Opcodes.INTEGER);
+- break;
+- case Opcodes.JSR:
+- case Opcodes.RET:
+- throw new RuntimeException("JSR/RET are not supported");
+- case Opcodes.GETSTATIC:
+- pushDesc(sarg);
+- break;
+- case Opcodes.PUTSTATIC:
+- pop(sarg);
+- break;
+- case Opcodes.GETFIELD:
+- pop(1);
+- pushDesc(sarg);
+- break;
+- case Opcodes.PUTFIELD:
+- pop(sarg);
+- pop();
+- break;
+- case Opcodes.NEW:
+- push(labels.get(0));
+- break;
+- case Opcodes.NEWARRAY:
+- pop();
+- switch (iarg) {
+- case Opcodes.T_BOOLEAN:
+- pushDesc("[Z");
+- break;
+- case Opcodes.T_CHAR:
+- pushDesc("[C");
+- break;
+- case Opcodes.T_BYTE:
+- pushDesc("[B");
+- break;
+- case Opcodes.T_SHORT:
+- pushDesc("[S");
+- break;
+- case Opcodes.T_INT:
+- pushDesc("[I");
+- break;
+- case Opcodes.T_FLOAT:
+- pushDesc("[F");
+- break;
+- case Opcodes.T_DOUBLE:
+- pushDesc("[D");
+- break;
+- // case Opcodes.T_LONG:
+- default:
+- pushDesc("[J");
+- break;
+- }
+- break;
+- case Opcodes.ANEWARRAY:
+- pop();
+- pushDesc("[" + Type.getObjectType(sarg));
+- break;
+- case Opcodes.CHECKCAST:
+- pop();
+- pushDesc(Type.getObjectType(sarg).getDescriptor());
+- break;
+- // case Opcodes.MULTIANEWARRAY:
+- default:
+- pop(iarg);
+- pushDesc(sarg);
+- break;
+- }
+- labels = null;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/CodeSizeEvaluator.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/CodeSizeEvaluator.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/CodeSizeEvaluator.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/CodeSizeEvaluator.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,238 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A {@link MethodVisitor} that can be used to approximate method size.
+- *
+- * @author Eugene Kuleshov
+- */
+-public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
+-
+- private int minSize;
+-
+- private int maxSize;
+-
+- public CodeSizeEvaluator(final MethodVisitor mv) {
+- this(Opcodes.ASM5, mv);
+- }
+-
+- protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
+- super(api, mv);
+- }
+-
+- public int getMinSize() {
+- return this.minSize;
+- }
+-
+- public int getMaxSize() {
+- return this.maxSize;
+- }
+-
+- @Override
+- public void visitInsn(final int opcode) {
+- minSize += 1;
+- maxSize += 1;
+- if (mv != null) {
+- mv.visitInsn(opcode);
+- }
+- }
+-
+- @Override
+- public void visitIntInsn(final int opcode, final int operand) {
+- if (opcode == SIPUSH) {
+- minSize += 3;
+- maxSize += 3;
+- } else {
+- minSize += 2;
+- maxSize += 2;
+- }
+- if (mv != null) {
+- mv.visitIntInsn(opcode, operand);
+- }
+- }
+-
+- @Override
+- public void visitVarInsn(final int opcode, final int var) {
+- if (var < 4 && opcode != RET) {
+- minSize += 1;
+- maxSize += 1;
+- } else if (var >= 256) {
+- minSize += 4;
+- maxSize += 4;
+- } else {
+- minSize += 2;
+- maxSize += 2;
+- }
+- if (mv != null) {
+- mv.visitVarInsn(opcode, var);
+- }
+- }
+-
+- @Override
+- public void visitTypeInsn(final int opcode, final String type) {
+- minSize += 3;
+- maxSize += 3;
+- if (mv != null) {
+- mv.visitTypeInsn(opcode, type);
+- }
+- }
+-
+- @Override
+- public void visitFieldInsn(final int opcode, final String owner,
+- final String name, final String desc) {
+- minSize += 3;
+- maxSize += 3;
+- if (mv != null) {
+- mv.visitFieldInsn(opcode, owner, name, desc);
+- }
+- }
+-
+- @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, final String owner,
+- final String name, final String desc, final boolean itf) {
+- if (opcode == INVOKEINTERFACE) {
+- minSize += 5;
+- maxSize += 5;
+- } else {
+- minSize += 3;
+- maxSize += 3;
+- }
+- if (mv != null) {
+- mv.visitMethodInsn(opcode, owner, name, desc, itf);
+- }
+- }
+-
+- @Override
+- public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+- Object... bsmArgs) {
+- minSize += 5;
+- maxSize += 5;
+- if (mv != null) {
+- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+- }
+- }
+-
+- @Override
+- public void visitJumpInsn(final int opcode, final Label label) {
+- minSize += 3;
+- if (opcode == GOTO || opcode == JSR) {
+- maxSize += 5;
+- } else {
+- maxSize += 8;
+- }
+- if (mv != null) {
+- mv.visitJumpInsn(opcode, label);
+- }
+- }
+-
+- @Override
+- public void visitLdcInsn(final Object cst) {
+- if (cst instanceof Long || cst instanceof Double) {
+- minSize += 3;
+- maxSize += 3;
+- } else {
+- minSize += 2;
+- maxSize += 3;
+- }
+- if (mv != null) {
+- mv.visitLdcInsn(cst);
+- }
+- }
+-
+- @Override
+- public void visitIincInsn(final int var, final int increment) {
+- if (var > 255 || increment > 127 || increment < -128) {
+- minSize += 6;
+- maxSize += 6;
+- } else {
+- minSize += 3;
+- maxSize += 3;
+- }
+- if (mv != null) {
+- mv.visitIincInsn(var, increment);
+- }
+- }
+-
+- @Override
+- public void visitTableSwitchInsn(final int min, final int max,
+- final Label dflt, final Label... labels) {
+- minSize += 13 + labels.length * 4;
+- maxSize += 16 + labels.length * 4;
+- if (mv != null) {
+- mv.visitTableSwitchInsn(min, max, dflt, labels);
+- }
+- }
+-
+- @Override
+- public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+- final Label[] labels) {
+- minSize += 9 + keys.length * 8;
+- maxSize += 12 + keys.length * 8;
+- if (mv != null) {
+- mv.visitLookupSwitchInsn(dflt, keys, labels);
+- }
+- }
+-
+- @Override
+- public void visitMultiANewArrayInsn(final String desc, final int dims) {
+- minSize += 4;
+- maxSize += 4;
+- if (mv != null) {
+- mv.visitMultiANewArrayInsn(desc, dims);
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/GeneratorAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/GeneratorAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/GeneratorAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/GeneratorAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,1628 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import java.util.ArrayList;
+-import java.util.Arrays;
+-import java.util.List;
+-
+-import org.mvel2.asm.ClassVisitor;
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-
+-/**
+- * A {@link org.mvel2.asm.MethodVisitor} with convenient methods to generate
+- * code. For example, using this adapter, the class below
+- *
+- *
+- * public class Example {
+- * public static void main(String[] args) {
+- * System.out.println("Hello world!");
+- * }
+- * }
+- *
+- *
+- * can be generated as follows:
+- *
+- *
+- * ClassWriter cw = new ClassWriter(true);
+- * cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
+- *
+- * Method m = Method.getMethod("void <init> ()");
+- * GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);
+- * mg.loadThis();
+- * mg.invokeConstructor(Type.getType(Object.class), m);
+- * mg.returnValue();
+- * mg.endMethod();
+- *
+- * m = Method.getMethod("void main (String[])");
+- * mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
+- * mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
+- * mg.push("Hello world!");
+- * mg.invokeVirtual(Type.getType(PrintStream.class),
+- * Method.getMethod("void println (String)"));
+- * mg.returnValue();
+- * mg.endMethod();
+- *
+- * cw.visitEnd();
+- *
+- *
+- * @author Juozas Baliuka
+- * @author Chris Nokleberg
+- * @author Eric Bruneton
+- * @author Prashant Deva
+- */
+-public class GeneratorAdapter extends LocalVariablesSorter {
+-
+- private static final String CLDESC = "Ljava/lang/Class;";
+-
+- private static final Type BYTE_TYPE = Type.getObjectType("java/lang/Byte");
+-
+- private static final Type BOOLEAN_TYPE = Type
+- .getObjectType("java/lang/Boolean");
+-
+- private static final Type SHORT_TYPE = Type
+- .getObjectType("java/lang/Short");
+-
+- private static final Type CHARACTER_TYPE = Type
+- .getObjectType("java/lang/Character");
+-
+- private static final Type INTEGER_TYPE = Type
+- .getObjectType("java/lang/Integer");
+-
+- private static final Type FLOAT_TYPE = Type
+- .getObjectType("java/lang/Float");
+-
+- private static final Type LONG_TYPE = Type.getObjectType("java/lang/Long");
+-
+- private static final Type DOUBLE_TYPE = Type
+- .getObjectType("java/lang/Double");
+-
+- private static final Type NUMBER_TYPE = Type
+- .getObjectType("java/lang/Number");
+-
+- private static final Type OBJECT_TYPE = Type
+- .getObjectType("java/lang/Object");
+-
+- private static final Method BOOLEAN_VALUE = Method
+- .getMethod("boolean booleanValue()");
+-
+- private static final Method CHAR_VALUE = Method
+- .getMethod("char charValue()");
+-
+- private static final Method INT_VALUE = Method.getMethod("int intValue()");
+-
+- private static final Method FLOAT_VALUE = Method
+- .getMethod("float floatValue()");
+-
+- private static final Method LONG_VALUE = Method
+- .getMethod("long longValue()");
+-
+- private static final Method DOUBLE_VALUE = Method
+- .getMethod("double doubleValue()");
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int ADD = Opcodes.IADD;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int SUB = Opcodes.ISUB;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int MUL = Opcodes.IMUL;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int DIV = Opcodes.IDIV;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int REM = Opcodes.IREM;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int NEG = Opcodes.INEG;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int SHL = Opcodes.ISHL;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int SHR = Opcodes.ISHR;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int USHR = Opcodes.IUSHR;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int AND = Opcodes.IAND;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int OR = Opcodes.IOR;
+-
+- /**
+- * Constant for the {@link #math math} method.
+- */
+- public static final int XOR = Opcodes.IXOR;
+-
+- /**
+- * Constant for the {@link #ifCmp ifCmp} method.
+- */
+- public static final int EQ = Opcodes.IFEQ;
+-
+- /**
+- * Constant for the {@link #ifCmp ifCmp} method.
+- */
+- public static final int NE = Opcodes.IFNE;
+-
+- /**
+- * Constant for the {@link #ifCmp ifCmp} method.
+- */
+- public static final int LT = Opcodes.IFLT;
+-
+- /**
+- * Constant for the {@link #ifCmp ifCmp} method.
+- */
+- public static final int GE = Opcodes.IFGE;
+-
+- /**
+- * Constant for the {@link #ifCmp ifCmp} method.
+- */
+- public static final int GT = Opcodes.IFGT;
+-
+- /**
+- * Constant for the {@link #ifCmp ifCmp} method.
+- */
+- public static final int LE = Opcodes.IFLE;
+-
+- /**
+- * Access flags of the method visited by this adapter.
+- */
+- private final int access;
+-
+- /**
+- * Return type of the method visited by this adapter.
+- */
+- private final Type returnType;
+-
+- /**
+- * Argument types of the method visited by this adapter.
+- */
+- private final Type[] argumentTypes;
+-
+- /**
+- * Types of the local variables of the method visited by this adapter.
+- */
+- private final List localTypes = new ArrayList();
+-
+- /**
+- * Creates a new {@link GeneratorAdapter}. Subclasses must not use this
+- * constructor . Instead, they must use the
+- * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
+- * version.
+- *
+- * @param mv
+- * the method visitor to which this adapter delegates calls.
+- * @param access
+- * the method's access flags (see {@link Opcodes}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public GeneratorAdapter(final MethodVisitor mv, final int access,
+- final String name, final String desc) {
+- this(Opcodes.ASM5, mv, access, name, desc);
+- if (getClass() != GeneratorAdapter.class) {
+- throw new IllegalStateException();
+- }
+- }
+-
+- /**
+- * Creates a new {@link GeneratorAdapter}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param mv
+- * the method visitor to which this adapter delegates calls.
+- * @param access
+- * the method's access flags (see {@link Opcodes}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- */
+- protected GeneratorAdapter(final int api, final MethodVisitor mv,
+- final int access, final String name, final String desc) {
+- super(api, access, desc, mv);
+- this.access = access;
+- this.returnType = Type.getReturnType(desc);
+- this.argumentTypes = Type.getArgumentTypes(desc);
+- }
+-
+- /**
+- * Creates a new {@link GeneratorAdapter}. Subclasses must not use this
+- * constructor . Instead, they must use the
+- * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
+- * version.
+- *
+- * @param access
+- * access flags of the adapted method.
+- * @param method
+- * the adapted method.
+- * @param mv
+- * the method visitor to which this adapter delegates calls.
+- */
+- public GeneratorAdapter(final int access, final Method method,
+- final MethodVisitor mv) {
+- this(mv, access, null, method.getDescriptor());
+- }
+-
+- /**
+- * Creates a new {@link GeneratorAdapter}. Subclasses must not use this
+- * constructor . Instead, they must use the
+- * {@link #GeneratorAdapter(int, MethodVisitor, int, String, String)}
+- * version.
+- *
+- * @param access
+- * access flags of the adapted method.
+- * @param method
+- * the adapted method.
+- * @param signature
+- * the signature of the adapted method (may be null ).
+- * @param exceptions
+- * the exceptions thrown by the adapted method (may be
+- * null ).
+- * @param cv
+- * the class visitor to which this adapter delegates calls.
+- */
+- public GeneratorAdapter(final int access, final Method method,
+- final String signature, final Type[] exceptions,
+- final ClassVisitor cv) {
+- this(access, method, cv
+- .visitMethod(access, method.getName(), method.getDescriptor(),
+- signature, getInternalNames(exceptions)));
+- }
+-
+- /**
+- * Returns the internal names of the given types.
+- *
+- * @param types
+- * a set of types.
+- * @return the internal names of the given types.
+- */
+- private static String[] getInternalNames(final Type[] types) {
+- if (types == null) {
+- return null;
+- }
+- String[] names = new String[types.length];
+- for (int i = 0; i < names.length; ++i) {
+- names[i] = types[i].getInternalName();
+- }
+- return names;
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to push constants on the stack
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Generates the instruction to push the given value on the stack.
+- *
+- * @param value
+- * the value to be pushed on the stack.
+- */
+- public void push(final boolean value) {
+- push(value ? 1 : 0);
+- }
+-
+- /**
+- * Generates the instruction to push the given value on the stack.
+- *
+- * @param value
+- * the value to be pushed on the stack.
+- */
+- public void push(final int value) {
+- if (value >= -1 && value <= 5) {
+- mv.visitInsn(Opcodes.ICONST_0 + value);
+- } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
+- mv.visitIntInsn(Opcodes.BIPUSH, value);
+- } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+- mv.visitIntInsn(Opcodes.SIPUSH, value);
+- } else {
+- mv.visitLdcInsn(new Integer(value));
+- }
+- }
+-
+- /**
+- * Generates the instruction to push the given value on the stack.
+- *
+- * @param value
+- * the value to be pushed on the stack.
+- */
+- public void push(final long value) {
+- if (value == 0L || value == 1L) {
+- mv.visitInsn(Opcodes.LCONST_0 + (int) value);
+- } else {
+- mv.visitLdcInsn(new Long(value));
+- }
+- }
+-
+- /**
+- * Generates the instruction to push the given value on the stack.
+- *
+- * @param value
+- * the value to be pushed on the stack.
+- */
+- public void push(final float value) {
+- int bits = Float.floatToIntBits(value);
+- if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2
+- mv.visitInsn(Opcodes.FCONST_0 + (int) value);
+- } else {
+- mv.visitLdcInsn(new Float(value));
+- }
+- }
+-
+- /**
+- * Generates the instruction to push the given value on the stack.
+- *
+- * @param value
+- * the value to be pushed on the stack.
+- */
+- public void push(final double value) {
+- long bits = Double.doubleToLongBits(value);
+- if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d
+- mv.visitInsn(Opcodes.DCONST_0 + (int) value);
+- } else {
+- mv.visitLdcInsn(new Double(value));
+- }
+- }
+-
+- /**
+- * Generates the instruction to push the given value on the stack.
+- *
+- * @param value
+- * the value to be pushed on the stack. May be null .
+- */
+- public void push(final String value) {
+- if (value == null) {
+- mv.visitInsn(Opcodes.ACONST_NULL);
+- } else {
+- mv.visitLdcInsn(value);
+- }
+- }
+-
+- /**
+- * Generates the instruction to push the given value on the stack.
+- *
+- * @param value
+- * the value to be pushed on the stack.
+- */
+- public void push(final Type value) {
+- if (value == null) {
+- mv.visitInsn(Opcodes.ACONST_NULL);
+- } else {
+- switch (value.getSort()) {
+- case Type.BOOLEAN:
+- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean",
+- "TYPE", CLDESC);
+- break;
+- case Type.CHAR:
+- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Character",
+- "TYPE", CLDESC);
+- break;
+- case Type.BYTE:
+- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE",
+- CLDESC);
+- break;
+- case Type.SHORT:
+- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Short", "TYPE",
+- CLDESC);
+- break;
+- case Type.INT:
+- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Integer",
+- "TYPE", CLDESC);
+- break;
+- case Type.FLOAT:
+- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Float", "TYPE",
+- CLDESC);
+- break;
+- case Type.LONG:
+- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "TYPE",
+- CLDESC);
+- break;
+- case Type.DOUBLE:
+- mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Double",
+- "TYPE", CLDESC);
+- break;
+- default:
+- mv.visitLdcInsn(value);
+- }
+- }
+- }
+-
+- /**
+- * Generates the instruction to push a handle on the stack.
+- *
+- * @param handle
+- * the handle to be pushed on the stack.
+- */
+- public void push(final Handle handle) {
+- mv.visitLdcInsn(handle);
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to load and store method arguments
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns the index of the given method argument in the frame's local
+- * variables array.
+- *
+- * @param arg
+- * the index of a method argument.
+- * @return the index of the given method argument in the frame's local
+- * variables array.
+- */
+- private int getArgIndex(final int arg) {
+- int index = (access & Opcodes.ACC_STATIC) == 0 ? 1 : 0;
+- for (int i = 0; i < arg; i++) {
+- index += argumentTypes[i].getSize();
+- }
+- return index;
+- }
+-
+- /**
+- * Generates the instruction to push a local variable on the stack.
+- *
+- * @param type
+- * the type of the local variable to be loaded.
+- * @param index
+- * an index in the frame's local variables array.
+- */
+- private void loadInsn(final Type type, final int index) {
+- mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), index);
+- }
+-
+- /**
+- * Generates the instruction to store the top stack value in a local
+- * variable.
+- *
+- * @param type
+- * the type of the local variable to be stored.
+- * @param index
+- * an index in the frame's local variables array.
+- */
+- private void storeInsn(final Type type, final int index) {
+- mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), index);
+- }
+-
+- /**
+- * Generates the instruction to load 'this' on the stack.
+- */
+- public void loadThis() {
+- if ((access & Opcodes.ACC_STATIC) != 0) {
+- throw new IllegalStateException(
+- "no 'this' pointer within static method");
+- }
+- mv.visitVarInsn(Opcodes.ALOAD, 0);
+- }
+-
+- /**
+- * Generates the instruction to load the given method argument on the stack.
+- *
+- * @param arg
+- * the index of a method argument.
+- */
+- public void loadArg(final int arg) {
+- loadInsn(argumentTypes[arg], getArgIndex(arg));
+- }
+-
+- /**
+- * Generates the instructions to load the given method arguments on the
+- * stack.
+- *
+- * @param arg
+- * the index of the first method argument to be loaded.
+- * @param count
+- * the number of method arguments to be loaded.
+- */
+- public void loadArgs(final int arg, final int count) {
+- int index = getArgIndex(arg);
+- for (int i = 0; i < count; ++i) {
+- Type t = argumentTypes[arg + i];
+- loadInsn(t, index);
+- index += t.getSize();
+- }
+- }
+-
+- /**
+- * Generates the instructions to load all the method arguments on the stack.
+- */
+- public void loadArgs() {
+- loadArgs(0, argumentTypes.length);
+- }
+-
+- /**
+- * Generates the instructions to load all the method arguments on the stack,
+- * as a single object array.
+- */
+- public void loadArgArray() {
+- push(argumentTypes.length);
+- newArray(OBJECT_TYPE);
+- for (int i = 0; i < argumentTypes.length; i++) {
+- dup();
+- push(i);
+- loadArg(i);
+- box(argumentTypes[i]);
+- arrayStore(OBJECT_TYPE);
+- }
+- }
+-
+- /**
+- * Generates the instruction to store the top stack value in the given
+- * method argument.
+- *
+- * @param arg
+- * the index of a method argument.
+- */
+- public void storeArg(final int arg) {
+- storeInsn(argumentTypes[arg], getArgIndex(arg));
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to load and store local variables
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns the type of the given local variable.
+- *
+- * @param local
+- * a local variable identifier, as returned by
+- * {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+- * @return the type of the given local variable.
+- */
+- public Type getLocalType(final int local) {
+- return localTypes.get(local - firstLocal);
+- }
+-
+- @Override
+- protected void setLocalType(final int local, final Type type) {
+- int index = local - firstLocal;
+- while (localTypes.size() < index + 1) {
+- localTypes.add(null);
+- }
+- localTypes.set(index, type);
+- }
+-
+- /**
+- * Generates the instruction to load the given local variable on the stack.
+- *
+- * @param local
+- * a local variable identifier, as returned by
+- * {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+- */
+- public void loadLocal(final int local) {
+- loadInsn(getLocalType(local), local);
+- }
+-
+- /**
+- * Generates the instruction to load the given local variable on the stack.
+- *
+- * @param local
+- * a local variable identifier, as returned by
+- * {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+- * @param type
+- * the type of this local variable.
+- */
+- public void loadLocal(final int local, final Type type) {
+- setLocalType(local, type);
+- loadInsn(type, local);
+- }
+-
+- /**
+- * Generates the instruction to store the top stack value in the given local
+- * variable.
+- *
+- * @param local
+- * a local variable identifier, as returned by
+- * {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+- */
+- public void storeLocal(final int local) {
+- storeInsn(getLocalType(local), local);
+- }
+-
+- /**
+- * Generates the instruction to store the top stack value in the given local
+- * variable.
+- *
+- * @param local
+- * a local variable identifier, as returned by
+- * {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+- * @param type
+- * the type of this local variable.
+- */
+- public void storeLocal(final int local, final Type type) {
+- setLocalType(local, type);
+- storeInsn(type, local);
+- }
+-
+- /**
+- * Generates the instruction to load an element from an array.
+- *
+- * @param type
+- * the type of the array element to be loaded.
+- */
+- public void arrayLoad(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IALOAD));
+- }
+-
+- /**
+- * Generates the instruction to store an element in an array.
+- *
+- * @param type
+- * the type of the array element to be stored.
+- */
+- public void arrayStore(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IASTORE));
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to manage the stack
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Generates a POP instruction.
+- */
+- public void pop() {
+- mv.visitInsn(Opcodes.POP);
+- }
+-
+- /**
+- * Generates a POP2 instruction.
+- */
+- public void pop2() {
+- mv.visitInsn(Opcodes.POP2);
+- }
+-
+- /**
+- * Generates a DUP instruction.
+- */
+- public void dup() {
+- mv.visitInsn(Opcodes.DUP);
+- }
+-
+- /**
+- * Generates a DUP2 instruction.
+- */
+- public void dup2() {
+- mv.visitInsn(Opcodes.DUP2);
+- }
+-
+- /**
+- * Generates a DUP_X1 instruction.
+- */
+- public void dupX1() {
+- mv.visitInsn(Opcodes.DUP_X1);
+- }
+-
+- /**
+- * Generates a DUP_X2 instruction.
+- */
+- public void dupX2() {
+- mv.visitInsn(Opcodes.DUP_X2);
+- }
+-
+- /**
+- * Generates a DUP2_X1 instruction.
+- */
+- public void dup2X1() {
+- mv.visitInsn(Opcodes.DUP2_X1);
+- }
+-
+- /**
+- * Generates a DUP2_X2 instruction.
+- */
+- public void dup2X2() {
+- mv.visitInsn(Opcodes.DUP2_X2);
+- }
+-
+- /**
+- * Generates a SWAP instruction.
+- */
+- public void swap() {
+- mv.visitInsn(Opcodes.SWAP);
+- }
+-
+- /**
+- * Generates the instructions to swap the top two stack values.
+- *
+- * @param prev
+- * type of the top - 1 stack value.
+- * @param type
+- * type of the top stack value.
+- */
+- public void swap(final Type prev, final Type type) {
+- if (type.getSize() == 1) {
+- if (prev.getSize() == 1) {
+- swap(); // same as dupX1(), pop();
+- } else {
+- dupX2();
+- pop();
+- }
+- } else {
+- if (prev.getSize() == 1) {
+- dup2X1();
+- pop2();
+- } else {
+- dup2X2();
+- pop2();
+- }
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to do mathematical and logical operations
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Generates the instruction to do the specified mathematical or logical
+- * operation.
+- *
+- * @param op
+- * a mathematical or logical operation. Must be one of ADD, SUB,
+- * MUL, DIV, REM, NEG, SHL, SHR, USHR, AND, OR, XOR.
+- * @param type
+- * the type of the operand(s) for this operation.
+- */
+- public void math(final int op, final Type type) {
+- mv.visitInsn(type.getOpcode(op));
+- }
+-
+- /**
+- * Generates the instructions to compute the bitwise negation of the top
+- * stack value.
+- */
+- public void not() {
+- mv.visitInsn(Opcodes.ICONST_1);
+- mv.visitInsn(Opcodes.IXOR);
+- }
+-
+- /**
+- * Generates the instruction to increment the given local variable.
+- *
+- * @param local
+- * the local variable to be incremented.
+- * @param amount
+- * the amount by which the local variable must be incremented.
+- */
+- public void iinc(final int local, final int amount) {
+- mv.visitIincInsn(local, amount);
+- }
+-
+- /**
+- * Generates the instructions to cast a numerical value from one type to
+- * another.
+- *
+- * @param from
+- * the type of the top stack value
+- * @param to
+- * the type into which this value must be cast.
+- */
+- public void cast(final Type from, final Type to) {
+- if (from != to) {
+- if (from == Type.DOUBLE_TYPE) {
+- if (to == Type.FLOAT_TYPE) {
+- mv.visitInsn(Opcodes.D2F);
+- } else if (to == Type.LONG_TYPE) {
+- mv.visitInsn(Opcodes.D2L);
+- } else {
+- mv.visitInsn(Opcodes.D2I);
+- cast(Type.INT_TYPE, to);
+- }
+- } else if (from == Type.FLOAT_TYPE) {
+- if (to == Type.DOUBLE_TYPE) {
+- mv.visitInsn(Opcodes.F2D);
+- } else if (to == Type.LONG_TYPE) {
+- mv.visitInsn(Opcodes.F2L);
+- } else {
+- mv.visitInsn(Opcodes.F2I);
+- cast(Type.INT_TYPE, to);
+- }
+- } else if (from == Type.LONG_TYPE) {
+- if (to == Type.DOUBLE_TYPE) {
+- mv.visitInsn(Opcodes.L2D);
+- } else if (to == Type.FLOAT_TYPE) {
+- mv.visitInsn(Opcodes.L2F);
+- } else {
+- mv.visitInsn(Opcodes.L2I);
+- cast(Type.INT_TYPE, to);
+- }
+- } else {
+- if (to == Type.BYTE_TYPE) {
+- mv.visitInsn(Opcodes.I2B);
+- } else if (to == Type.CHAR_TYPE) {
+- mv.visitInsn(Opcodes.I2C);
+- } else if (to == Type.DOUBLE_TYPE) {
+- mv.visitInsn(Opcodes.I2D);
+- } else if (to == Type.FLOAT_TYPE) {
+- mv.visitInsn(Opcodes.I2F);
+- } else if (to == Type.LONG_TYPE) {
+- mv.visitInsn(Opcodes.I2L);
+- } else if (to == Type.SHORT_TYPE) {
+- mv.visitInsn(Opcodes.I2S);
+- }
+- }
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to do boxing and unboxing operations
+- // ------------------------------------------------------------------------
+-
+- private static Type getBoxedType(final Type type) {
+- switch (type.getSort()) {
+- case Type.BYTE:
+- return BYTE_TYPE;
+- case Type.BOOLEAN:
+- return BOOLEAN_TYPE;
+- case Type.SHORT:
+- return SHORT_TYPE;
+- case Type.CHAR:
+- return CHARACTER_TYPE;
+- case Type.INT:
+- return INTEGER_TYPE;
+- case Type.FLOAT:
+- return FLOAT_TYPE;
+- case Type.LONG:
+- return LONG_TYPE;
+- case Type.DOUBLE:
+- return DOUBLE_TYPE;
+- }
+- return type;
+- }
+-
+- /**
+- * Generates the instructions to box the top stack value. This value is
+- * replaced by its boxed equivalent on top of the stack.
+- *
+- * @param type
+- * the type of the top stack value.
+- */
+- public void box(final Type type) {
+- if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
+- return;
+- }
+- if (type == Type.VOID_TYPE) {
+- push((String) null);
+- } else {
+- Type boxed = getBoxedType(type);
+- newInstance(boxed);
+- if (type.getSize() == 2) {
+- // Pp -> Ppo -> oPpo -> ooPpo -> ooPp -> o
+- dupX2();
+- dupX2();
+- pop();
+- } else {
+- // p -> po -> opo -> oop -> o
+- dupX1();
+- swap();
+- }
+- invokeConstructor(boxed, new Method("", Type.VOID_TYPE,
+- new Type[] { type }));
+- }
+- }
+-
+- /**
+- * Generates the instructions to box the top stack value using Java 5's
+- * valueOf() method. This value is replaced by its boxed equivalent on top
+- * of the stack.
+- *
+- * @param type
+- * the type of the top stack value.
+- */
+- public void valueOf(final Type type) {
+- if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
+- return;
+- }
+- if (type == Type.VOID_TYPE) {
+- push((String) null);
+- } else {
+- Type boxed = getBoxedType(type);
+- invokeStatic(boxed, new Method("valueOf", boxed,
+- new Type[] { type }));
+- }
+- }
+-
+- /**
+- * Generates the instructions to unbox the top stack value. This value is
+- * replaced by its unboxed equivalent on top of the stack.
+- *
+- * @param type
+- * the type of the top stack value.
+- */
+- public void unbox(final Type type) {
+- Type t = NUMBER_TYPE;
+- Method sig = null;
+- switch (type.getSort()) {
+- case Type.VOID:
+- return;
+- case Type.CHAR:
+- t = CHARACTER_TYPE;
+- sig = CHAR_VALUE;
+- break;
+- case Type.BOOLEAN:
+- t = BOOLEAN_TYPE;
+- sig = BOOLEAN_VALUE;
+- break;
+- case Type.DOUBLE:
+- sig = DOUBLE_VALUE;
+- break;
+- case Type.FLOAT:
+- sig = FLOAT_VALUE;
+- break;
+- case Type.LONG:
+- sig = LONG_VALUE;
+- break;
+- case Type.INT:
+- case Type.SHORT:
+- case Type.BYTE:
+- sig = INT_VALUE;
+- }
+- if (sig == null) {
+- checkCast(type);
+- } else {
+- checkCast(t);
+- invokeVirtual(t, sig);
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to jump to other instructions
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Creates a new {@link Label}.
+- *
+- * @return a new {@link Label}.
+- */
+- public Label newLabel() {
+- return new Label();
+- }
+-
+- /**
+- * Marks the current code position with the given label.
+- *
+- * @param label
+- * a label.
+- */
+- public void mark(final Label label) {
+- mv.visitLabel(label);
+- }
+-
+- /**
+- * Marks the current code position with a new label.
+- *
+- * @return the label that was created to mark the current code position.
+- */
+- public Label mark() {
+- Label label = new Label();
+- mv.visitLabel(label);
+- return label;
+- }
+-
+- /**
+- * Generates the instructions to jump to a label based on the comparison of
+- * the top two stack values.
+- *
+- * @param type
+- * the type of the top two stack values.
+- * @param mode
+- * how these values must be compared. One of EQ, NE, LT, GE, GT,
+- * LE.
+- * @param label
+- * where to jump if the comparison result is true .
+- */
+- public void ifCmp(final Type type, final int mode, final Label label) {
+- switch (type.getSort()) {
+- case Type.LONG:
+- mv.visitInsn(Opcodes.LCMP);
+- break;
+- case Type.DOUBLE:
+- mv.visitInsn(mode == GE || mode == GT ? Opcodes.DCMPL
+- : Opcodes.DCMPG);
+- break;
+- case Type.FLOAT:
+- mv.visitInsn(mode == GE || mode == GT ? Opcodes.FCMPL
+- : Opcodes.FCMPG);
+- break;
+- case Type.ARRAY:
+- case Type.OBJECT:
+- switch (mode) {
+- case EQ:
+- mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
+- return;
+- case NE:
+- mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
+- return;
+- }
+- throw new IllegalArgumentException("Bad comparison for type "
+- + type);
+- default:
+- int intOp = -1;
+- switch (mode) {
+- case EQ:
+- intOp = Opcodes.IF_ICMPEQ;
+- break;
+- case NE:
+- intOp = Opcodes.IF_ICMPNE;
+- break;
+- case GE:
+- intOp = Opcodes.IF_ICMPGE;
+- break;
+- case LT:
+- intOp = Opcodes.IF_ICMPLT;
+- break;
+- case LE:
+- intOp = Opcodes.IF_ICMPLE;
+- break;
+- case GT:
+- intOp = Opcodes.IF_ICMPGT;
+- break;
+- }
+- mv.visitJumpInsn(intOp, label);
+- return;
+- }
+- mv.visitJumpInsn(mode, label);
+- }
+-
+- /**
+- * Generates the instructions to jump to a label based on the comparison of
+- * the top two integer stack values.
+- *
+- * @param mode
+- * how these values must be compared. One of EQ, NE, LT, GE, GT,
+- * LE.
+- * @param label
+- * where to jump if the comparison result is true .
+- */
+- public void ifICmp(final int mode, final Label label) {
+- ifCmp(Type.INT_TYPE, mode, label);
+- }
+-
+- /**
+- * Generates the instructions to jump to a label based on the comparison of
+- * the top integer stack value with zero.
+- *
+- * @param mode
+- * how these values must be compared. One of EQ, NE, LT, GE, GT,
+- * LE.
+- * @param label
+- * where to jump if the comparison result is true .
+- */
+- public void ifZCmp(final int mode, final Label label) {
+- mv.visitJumpInsn(mode, label);
+- }
+-
+- /**
+- * Generates the instruction to jump to the given label if the top stack
+- * value is null.
+- *
+- * @param label
+- * where to jump if the condition is true .
+- */
+- public void ifNull(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFNULL, label);
+- }
+-
+- /**
+- * Generates the instruction to jump to the given label if the top stack
+- * value is not null.
+- *
+- * @param label
+- * where to jump if the condition is true .
+- */
+- public void ifNonNull(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFNONNULL, label);
+- }
+-
+- /**
+- * Generates the instruction to jump to the given label.
+- *
+- * @param label
+- * where to jump if the condition is true .
+- */
+- public void goTo(final Label label) {
+- mv.visitJumpInsn(Opcodes.GOTO, label);
+- }
+-
+- /**
+- * Generates a RET instruction.
+- *
+- * @param local
+- * a local variable identifier, as returned by
+- * {@link LocalVariablesSorter#newLocal(Type) newLocal()}.
+- */
+- public void ret(final int local) {
+- mv.visitVarInsn(Opcodes.RET, local);
+- }
+-
+- /**
+- * Generates the instructions for a switch statement.
+- *
+- * @param keys
+- * the switch case keys.
+- * @param generator
+- * a generator to generate the code for the switch cases.
+- */
+- public void tableSwitch(final int[] keys,
+- final TableSwitchGenerator generator) {
+- float density;
+- if (keys.length == 0) {
+- density = 0;
+- } else {
+- density = (float) keys.length
+- / (keys[keys.length - 1] - keys[0] + 1);
+- }
+- tableSwitch(keys, generator, density >= 0.5f);
+- }
+-
+- /**
+- * Generates the instructions for a switch statement.
+- *
+- * @param keys
+- * the switch case keys.
+- * @param generator
+- * a generator to generate the code for the switch cases.
+- * @param useTable
+- * true to use a TABLESWITCH instruction, or
+- * false to use a LOOKUPSWITCH instruction.
+- */
+- public void tableSwitch(final int[] keys,
+- final TableSwitchGenerator generator, final boolean useTable) {
+- for (int i = 1; i < keys.length; ++i) {
+- if (keys[i] < keys[i - 1]) {
+- throw new IllegalArgumentException(
+- "keys must be sorted ascending");
+- }
+- }
+- Label def = newLabel();
+- Label end = newLabel();
+- if (keys.length > 0) {
+- int len = keys.length;
+- int min = keys[0];
+- int max = keys[len - 1];
+- int range = max - min + 1;
+- if (useTable) {
+- Label[] labels = new Label[range];
+- Arrays.fill(labels, def);
+- for (int i = 0; i < len; ++i) {
+- labels[keys[i] - min] = newLabel();
+- }
+- mv.visitTableSwitchInsn(min, max, def, labels);
+- for (int i = 0; i < range; ++i) {
+- Label label = labels[i];
+- if (label != def) {
+- mark(label);
+- generator.generateCase(i + min, end);
+- }
+- }
+- } else {
+- Label[] labels = new Label[len];
+- for (int i = 0; i < len; ++i) {
+- labels[i] = newLabel();
+- }
+- mv.visitLookupSwitchInsn(def, keys, labels);
+- for (int i = 0; i < len; ++i) {
+- mark(labels[i]);
+- generator.generateCase(keys[i], end);
+- }
+- }
+- }
+- mark(def);
+- generator.generateDefault();
+- mark(end);
+- }
+-
+- /**
+- * Generates the instruction to return the top stack value to the caller.
+- */
+- public void returnValue() {
+- mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to load and store fields
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Generates a get field or set field instruction.
+- *
+- * @param opcode
+- * the instruction's opcode.
+- * @param ownerType
+- * the class in which the field is defined.
+- * @param name
+- * the name of the field.
+- * @param fieldType
+- * the type of the field.
+- */
+- private void fieldInsn(final int opcode, final Type ownerType,
+- final String name, final Type fieldType) {
+- mv.visitFieldInsn(opcode, ownerType.getInternalName(), name,
+- fieldType.getDescriptor());
+- }
+-
+- /**
+- * Generates the instruction to push the value of a static field on the
+- * stack.
+- *
+- * @param owner
+- * the class in which the field is defined.
+- * @param name
+- * the name of the field.
+- * @param type
+- * the type of the field.
+- */
+- public void getStatic(final Type owner, final String name, final Type type) {
+- fieldInsn(Opcodes.GETSTATIC, owner, name, type);
+- }
+-
+- /**
+- * Generates the instruction to store the top stack value in a static field.
+- *
+- * @param owner
+- * the class in which the field is defined.
+- * @param name
+- * the name of the field.
+- * @param type
+- * the type of the field.
+- */
+- public void putStatic(final Type owner, final String name, final Type type) {
+- fieldInsn(Opcodes.PUTSTATIC, owner, name, type);
+- }
+-
+- /**
+- * Generates the instruction to push the value of a non static field on the
+- * stack.
+- *
+- * @param owner
+- * the class in which the field is defined.
+- * @param name
+- * the name of the field.
+- * @param type
+- * the type of the field.
+- */
+- public void getField(final Type owner, final String name, final Type type) {
+- fieldInsn(Opcodes.GETFIELD, owner, name, type);
+- }
+-
+- /**
+- * Generates the instruction to store the top stack value in a non static
+- * field.
+- *
+- * @param owner
+- * the class in which the field is defined.
+- * @param name
+- * the name of the field.
+- * @param type
+- * the type of the field.
+- */
+- public void putField(final Type owner, final String name, final Type type) {
+- fieldInsn(Opcodes.PUTFIELD, owner, name, type);
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to invoke methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Generates an invoke method instruction.
+- *
+- * @param opcode
+- * the instruction's opcode.
+- * @param type
+- * the class in which the method is defined.
+- * @param method
+- * the method to be invoked.
+- */
+- private void invokeInsn(final int opcode, final Type type,
+- final Method method, final boolean itf) {
+- String owner = type.getSort() == Type.ARRAY ? type.getDescriptor()
+- : type.getInternalName();
+- mv.visitMethodInsn(opcode, owner, method.getName(),
+- method.getDescriptor(), itf);
+- }
+-
+- /**
+- * Generates the instruction to invoke a normal method.
+- *
+- * @param owner
+- * the class in which the method is defined.
+- * @param method
+- * the method to be invoked.
+- */
+- public void invokeVirtual(final Type owner, final Method method) {
+- invokeInsn(Opcodes.INVOKEVIRTUAL, owner, method, false);
+- }
+-
+- /**
+- * Generates the instruction to invoke a constructor.
+- *
+- * @param type
+- * the class in which the constructor is defined.
+- * @param method
+- * the constructor to be invoked.
+- */
+- public void invokeConstructor(final Type type, final Method method) {
+- invokeInsn(Opcodes.INVOKESPECIAL, type, method, false);
+- }
+-
+- /**
+- * Generates the instruction to invoke a static method.
+- *
+- * @param owner
+- * the class in which the method is defined.
+- * @param method
+- * the method to be invoked.
+- */
+- public void invokeStatic(final Type owner, final Method method) {
+- invokeInsn(Opcodes.INVOKESTATIC, owner, method, false);
+- }
+-
+- /**
+- * Generates the instruction to invoke an interface method.
+- *
+- * @param owner
+- * the class in which the method is defined.
+- * @param method
+- * the method to be invoked.
+- */
+- public void invokeInterface(final Type owner, final Method method) {
+- invokeInsn(Opcodes.INVOKEINTERFACE, owner, method, true);
+- }
+-
+- /**
+- * Generates an invokedynamic instruction.
+- *
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @param bsm
+- * the bootstrap method.
+- * @param bsmArgs
+- * the bootstrap method constant arguments. Each argument must be
+- * an {@link Integer}, {@link Float}, {@link Long},
+- * {@link Double}, {@link String}, {@link Type} or {@link Handle}
+- * value. This method is allowed to modify the content of the
+- * array so a caller should expect that this array may change.
+- */
+- public void invokeDynamic(String name, String desc, Handle bsm,
+- Object... bsmArgs) {
+- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+- }
+-
+- // ------------------------------------------------------------------------
+- // Instructions to create objects and arrays
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Generates a type dependent instruction.
+- *
+- * @param opcode
+- * the instruction's opcode.
+- * @param type
+- * the instruction's operand.
+- */
+- private void typeInsn(final int opcode, final Type type) {
+- mv.visitTypeInsn(opcode, type.getInternalName());
+- }
+-
+- /**
+- * Generates the instruction to create a new object.
+- *
+- * @param type
+- * the class of the object to be created.
+- */
+- public void newInstance(final Type type) {
+- typeInsn(Opcodes.NEW, type);
+- }
+-
+- /**
+- * Generates the instruction to create a new array.
+- *
+- * @param type
+- * the type of the array elements.
+- */
+- public void newArray(final Type type) {
+- int typ;
+- switch (type.getSort()) {
+- case Type.BOOLEAN:
+- typ = Opcodes.T_BOOLEAN;
+- break;
+- case Type.CHAR:
+- typ = Opcodes.T_CHAR;
+- break;
+- case Type.BYTE:
+- typ = Opcodes.T_BYTE;
+- break;
+- case Type.SHORT:
+- typ = Opcodes.T_SHORT;
+- break;
+- case Type.INT:
+- typ = Opcodes.T_INT;
+- break;
+- case Type.FLOAT:
+- typ = Opcodes.T_FLOAT;
+- break;
+- case Type.LONG:
+- typ = Opcodes.T_LONG;
+- break;
+- case Type.DOUBLE:
+- typ = Opcodes.T_DOUBLE;
+- break;
+- default:
+- typeInsn(Opcodes.ANEWARRAY, type);
+- return;
+- }
+- mv.visitIntInsn(Opcodes.NEWARRAY, typ);
+- }
+-
+- // ------------------------------------------------------------------------
+- // Miscelaneous instructions
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Generates the instruction to compute the length of an array.
+- */
+- public void arrayLength() {
+- mv.visitInsn(Opcodes.ARRAYLENGTH);
+- }
+-
+- /**
+- * Generates the instruction to throw an exception.
+- */
+- public void throwException() {
+- mv.visitInsn(Opcodes.ATHROW);
+- }
+-
+- /**
+- * Generates the instructions to create and throw an exception. The
+- * exception class must have a constructor with a single String argument.
+- *
+- * @param type
+- * the class of the exception to be thrown.
+- * @param msg
+- * the detailed message of the exception.
+- */
+- public void throwException(final Type type, final String msg) {
+- newInstance(type);
+- dup();
+- push(msg);
+- invokeConstructor(type, Method.getMethod("void (String)"));
+- throwException();
+- }
+-
+- /**
+- * Generates the instruction to check that the top stack value is of the
+- * given type.
+- *
+- * @param type
+- * a class or interface type.
+- */
+- public void checkCast(final Type type) {
+- if (!type.equals(OBJECT_TYPE)) {
+- typeInsn(Opcodes.CHECKCAST, type);
+- }
+- }
+-
+- /**
+- * Generates the instruction to test if the top stack value is of the given
+- * type.
+- *
+- * @param type
+- * a class or interface type.
+- */
+- public void instanceOf(final Type type) {
+- typeInsn(Opcodes.INSTANCEOF, type);
+- }
+-
+- /**
+- * Generates the instruction to get the monitor of the top stack value.
+- */
+- public void monitorEnter() {
+- mv.visitInsn(Opcodes.MONITORENTER);
+- }
+-
+- /**
+- * Generates the instruction to release the monitor of the top stack value.
+- */
+- public void monitorExit() {
+- mv.visitInsn(Opcodes.MONITOREXIT);
+- }
+-
+- // ------------------------------------------------------------------------
+- // Non instructions
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Marks the end of the visited method.
+- */
+- public void endMethod() {
+- if ((access & Opcodes.ACC_ABSTRACT) == 0) {
+- mv.visitMaxs(0, 0);
+- }
+- mv.visitEnd();
+- }
+-
+- /**
+- * Marks the start of an exception handler.
+- *
+- * @param start
+- * beginning of the exception handler's scope (inclusive).
+- * @param end
+- * end of the exception handler's scope (exclusive).
+- * @param exception
+- * internal name of the type of exceptions handled by the
+- * handler.
+- */
+- public void catchException(final Label start, final Label end,
+- final Type exception) {
+- if (exception == null) {
+- mv.visitTryCatchBlock(start, end, mark(), null);
+- } else {
+- mv.visitTryCatchBlock(start, end, mark(),
+- exception.getInternalName());
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/InstructionAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/InstructionAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/InstructionAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/InstructionAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,1170 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-
+-/**
+- * A {@link MethodVisitor} providing a more detailed API to generate and
+- * transform instructions.
+- *
+- * @author Eric Bruneton
+- */
+-public class InstructionAdapter extends MethodVisitor {
+-
+- public final static Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
+-
+- /**
+- * Creates a new {@link InstructionAdapter}. Subclasses must not use this
+- * constructor . Instead, they must use the
+- * {@link #InstructionAdapter(int, MethodVisitor)} version.
+- *
+- * @param mv
+- * the method visitor to which this adapter delegates calls.
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public InstructionAdapter(final MethodVisitor mv) {
+- this(Opcodes.ASM5, mv);
+- if (getClass() != InstructionAdapter.class) {
+- throw new IllegalStateException();
+- }
+- }
+-
+- /**
+- * Creates a new {@link InstructionAdapter}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param mv
+- * the method visitor to which this adapter delegates calls.
+- */
+- protected InstructionAdapter(final int api, final MethodVisitor mv) {
+- super(api, mv);
+- }
+-
+- @Override
+- public void visitInsn(final int opcode) {
+- switch (opcode) {
+- case Opcodes.NOP:
+- nop();
+- break;
+- case Opcodes.ACONST_NULL:
+- aconst(null);
+- break;
+- case Opcodes.ICONST_M1:
+- case Opcodes.ICONST_0:
+- case Opcodes.ICONST_1:
+- case Opcodes.ICONST_2:
+- case Opcodes.ICONST_3:
+- case Opcodes.ICONST_4:
+- case Opcodes.ICONST_5:
+- iconst(opcode - Opcodes.ICONST_0);
+- break;
+- case Opcodes.LCONST_0:
+- case Opcodes.LCONST_1:
+- lconst(opcode - Opcodes.LCONST_0);
+- break;
+- case Opcodes.FCONST_0:
+- case Opcodes.FCONST_1:
+- case Opcodes.FCONST_2:
+- fconst(opcode - Opcodes.FCONST_0);
+- break;
+- case Opcodes.DCONST_0:
+- case Opcodes.DCONST_1:
+- dconst(opcode - Opcodes.DCONST_0);
+- break;
+- case Opcodes.IALOAD:
+- aload(Type.INT_TYPE);
+- break;
+- case Opcodes.LALOAD:
+- aload(Type.LONG_TYPE);
+- break;
+- case Opcodes.FALOAD:
+- aload(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DALOAD:
+- aload(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.AALOAD:
+- aload(OBJECT_TYPE);
+- break;
+- case Opcodes.BALOAD:
+- aload(Type.BYTE_TYPE);
+- break;
+- case Opcodes.CALOAD:
+- aload(Type.CHAR_TYPE);
+- break;
+- case Opcodes.SALOAD:
+- aload(Type.SHORT_TYPE);
+- break;
+- case Opcodes.IASTORE:
+- astore(Type.INT_TYPE);
+- break;
+- case Opcodes.LASTORE:
+- astore(Type.LONG_TYPE);
+- break;
+- case Opcodes.FASTORE:
+- astore(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DASTORE:
+- astore(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.AASTORE:
+- astore(OBJECT_TYPE);
+- break;
+- case Opcodes.BASTORE:
+- astore(Type.BYTE_TYPE);
+- break;
+- case Opcodes.CASTORE:
+- astore(Type.CHAR_TYPE);
+- break;
+- case Opcodes.SASTORE:
+- astore(Type.SHORT_TYPE);
+- break;
+- case Opcodes.POP:
+- pop();
+- break;
+- case Opcodes.POP2:
+- pop2();
+- break;
+- case Opcodes.DUP:
+- dup();
+- break;
+- case Opcodes.DUP_X1:
+- dupX1();
+- break;
+- case Opcodes.DUP_X2:
+- dupX2();
+- break;
+- case Opcodes.DUP2:
+- dup2();
+- break;
+- case Opcodes.DUP2_X1:
+- dup2X1();
+- break;
+- case Opcodes.DUP2_X2:
+- dup2X2();
+- break;
+- case Opcodes.SWAP:
+- swap();
+- break;
+- case Opcodes.IADD:
+- add(Type.INT_TYPE);
+- break;
+- case Opcodes.LADD:
+- add(Type.LONG_TYPE);
+- break;
+- case Opcodes.FADD:
+- add(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DADD:
+- add(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.ISUB:
+- sub(Type.INT_TYPE);
+- break;
+- case Opcodes.LSUB:
+- sub(Type.LONG_TYPE);
+- break;
+- case Opcodes.FSUB:
+- sub(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DSUB:
+- sub(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.IMUL:
+- mul(Type.INT_TYPE);
+- break;
+- case Opcodes.LMUL:
+- mul(Type.LONG_TYPE);
+- break;
+- case Opcodes.FMUL:
+- mul(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DMUL:
+- mul(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.IDIV:
+- div(Type.INT_TYPE);
+- break;
+- case Opcodes.LDIV:
+- div(Type.LONG_TYPE);
+- break;
+- case Opcodes.FDIV:
+- div(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DDIV:
+- div(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.IREM:
+- rem(Type.INT_TYPE);
+- break;
+- case Opcodes.LREM:
+- rem(Type.LONG_TYPE);
+- break;
+- case Opcodes.FREM:
+- rem(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DREM:
+- rem(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.INEG:
+- neg(Type.INT_TYPE);
+- break;
+- case Opcodes.LNEG:
+- neg(Type.LONG_TYPE);
+- break;
+- case Opcodes.FNEG:
+- neg(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DNEG:
+- neg(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.ISHL:
+- shl(Type.INT_TYPE);
+- break;
+- case Opcodes.LSHL:
+- shl(Type.LONG_TYPE);
+- break;
+- case Opcodes.ISHR:
+- shr(Type.INT_TYPE);
+- break;
+- case Opcodes.LSHR:
+- shr(Type.LONG_TYPE);
+- break;
+- case Opcodes.IUSHR:
+- ushr(Type.INT_TYPE);
+- break;
+- case Opcodes.LUSHR:
+- ushr(Type.LONG_TYPE);
+- break;
+- case Opcodes.IAND:
+- and(Type.INT_TYPE);
+- break;
+- case Opcodes.LAND:
+- and(Type.LONG_TYPE);
+- break;
+- case Opcodes.IOR:
+- or(Type.INT_TYPE);
+- break;
+- case Opcodes.LOR:
+- or(Type.LONG_TYPE);
+- break;
+- case Opcodes.IXOR:
+- xor(Type.INT_TYPE);
+- break;
+- case Opcodes.LXOR:
+- xor(Type.LONG_TYPE);
+- break;
+- case Opcodes.I2L:
+- cast(Type.INT_TYPE, Type.LONG_TYPE);
+- break;
+- case Opcodes.I2F:
+- cast(Type.INT_TYPE, Type.FLOAT_TYPE);
+- break;
+- case Opcodes.I2D:
+- cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.L2I:
+- cast(Type.LONG_TYPE, Type.INT_TYPE);
+- break;
+- case Opcodes.L2F:
+- cast(Type.LONG_TYPE, Type.FLOAT_TYPE);
+- break;
+- case Opcodes.L2D:
+- cast(Type.LONG_TYPE, Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.F2I:
+- cast(Type.FLOAT_TYPE, Type.INT_TYPE);
+- break;
+- case Opcodes.F2L:
+- cast(Type.FLOAT_TYPE, Type.LONG_TYPE);
+- break;
+- case Opcodes.F2D:
+- cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.D2I:
+- cast(Type.DOUBLE_TYPE, Type.INT_TYPE);
+- break;
+- case Opcodes.D2L:
+- cast(Type.DOUBLE_TYPE, Type.LONG_TYPE);
+- break;
+- case Opcodes.D2F:
+- cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);
+- break;
+- case Opcodes.I2B:
+- cast(Type.INT_TYPE, Type.BYTE_TYPE);
+- break;
+- case Opcodes.I2C:
+- cast(Type.INT_TYPE, Type.CHAR_TYPE);
+- break;
+- case Opcodes.I2S:
+- cast(Type.INT_TYPE, Type.SHORT_TYPE);
+- break;
+- case Opcodes.LCMP:
+- lcmp();
+- break;
+- case Opcodes.FCMPL:
+- cmpl(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.FCMPG:
+- cmpg(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DCMPL:
+- cmpl(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.DCMPG:
+- cmpg(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.IRETURN:
+- areturn(Type.INT_TYPE);
+- break;
+- case Opcodes.LRETURN:
+- areturn(Type.LONG_TYPE);
+- break;
+- case Opcodes.FRETURN:
+- areturn(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DRETURN:
+- areturn(Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.ARETURN:
+- areturn(OBJECT_TYPE);
+- break;
+- case Opcodes.RETURN:
+- areturn(Type.VOID_TYPE);
+- break;
+- case Opcodes.ARRAYLENGTH:
+- arraylength();
+- break;
+- case Opcodes.ATHROW:
+- athrow();
+- break;
+- case Opcodes.MONITORENTER:
+- monitorenter();
+- break;
+- case Opcodes.MONITOREXIT:
+- monitorexit();
+- break;
+- default:
+- throw new IllegalArgumentException();
+- }
+- }
+-
+- @Override
+- public void visitIntInsn(final int opcode, final int operand) {
+- switch (opcode) {
+- case Opcodes.BIPUSH:
+- iconst(operand);
+- break;
+- case Opcodes.SIPUSH:
+- iconst(operand);
+- break;
+- case Opcodes.NEWARRAY:
+- switch (operand) {
+- case Opcodes.T_BOOLEAN:
+- newarray(Type.BOOLEAN_TYPE);
+- break;
+- case Opcodes.T_CHAR:
+- newarray(Type.CHAR_TYPE);
+- break;
+- case Opcodes.T_BYTE:
+- newarray(Type.BYTE_TYPE);
+- break;
+- case Opcodes.T_SHORT:
+- newarray(Type.SHORT_TYPE);
+- break;
+- case Opcodes.T_INT:
+- newarray(Type.INT_TYPE);
+- break;
+- case Opcodes.T_FLOAT:
+- newarray(Type.FLOAT_TYPE);
+- break;
+- case Opcodes.T_LONG:
+- newarray(Type.LONG_TYPE);
+- break;
+- case Opcodes.T_DOUBLE:
+- newarray(Type.DOUBLE_TYPE);
+- break;
+- default:
+- throw new IllegalArgumentException();
+- }
+- break;
+- default:
+- throw new IllegalArgumentException();
+- }
+- }
+-
+- @Override
+- public void visitVarInsn(final int opcode, final int var) {
+- switch (opcode) {
+- case Opcodes.ILOAD:
+- load(var, Type.INT_TYPE);
+- break;
+- case Opcodes.LLOAD:
+- load(var, Type.LONG_TYPE);
+- break;
+- case Opcodes.FLOAD:
+- load(var, Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DLOAD:
+- load(var, Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.ALOAD:
+- load(var, OBJECT_TYPE);
+- break;
+- case Opcodes.ISTORE:
+- store(var, Type.INT_TYPE);
+- break;
+- case Opcodes.LSTORE:
+- store(var, Type.LONG_TYPE);
+- break;
+- case Opcodes.FSTORE:
+- store(var, Type.FLOAT_TYPE);
+- break;
+- case Opcodes.DSTORE:
+- store(var, Type.DOUBLE_TYPE);
+- break;
+- case Opcodes.ASTORE:
+- store(var, OBJECT_TYPE);
+- break;
+- case Opcodes.RET:
+- ret(var);
+- break;
+- default:
+- throw new IllegalArgumentException();
+- }
+- }
+-
+- @Override
+- public void visitTypeInsn(final int opcode, final String type) {
+- Type t = Type.getObjectType(type);
+- switch (opcode) {
+- case Opcodes.NEW:
+- anew(t);
+- break;
+- case Opcodes.ANEWARRAY:
+- newarray(t);
+- break;
+- case Opcodes.CHECKCAST:
+- checkcast(t);
+- break;
+- case Opcodes.INSTANCEOF:
+- instanceOf(t);
+- break;
+- default:
+- throw new IllegalArgumentException();
+- }
+- }
+-
+- @Override
+- public void visitFieldInsn(final int opcode, final String owner,
+- final String name, final String desc) {
+- switch (opcode) {
+- case Opcodes.GETSTATIC:
+- getstatic(owner, name, desc);
+- break;
+- case Opcodes.PUTSTATIC:
+- putstatic(owner, name, desc);
+- break;
+- case Opcodes.GETFIELD:
+- getfield(owner, name, desc);
+- break;
+- case Opcodes.PUTFIELD:
+- putfield(owner, name, desc);
+- break;
+- default:
+- throw new IllegalArgumentException();
+- }
+- }
+-
+- @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, final String owner,
+- final String name, final String desc, final boolean itf) {
+- switch (opcode) {
+- case Opcodes.INVOKESPECIAL:
+- invokespecial(owner, name, desc, itf);
+- break;
+- case Opcodes.INVOKEVIRTUAL:
+- invokevirtual(owner, name, desc, itf);
+- break;
+- case Opcodes.INVOKESTATIC:
+- invokestatic(owner, name, desc, itf);
+- break;
+- case Opcodes.INVOKEINTERFACE:
+- invokeinterface(owner, name, desc);
+- break;
+- default:
+- throw new IllegalArgumentException();
+- }
+- }
+-
+- @Override
+- public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+- Object... bsmArgs) {
+- invokedynamic(name, desc, bsm, bsmArgs);
+- }
+-
+- @Override
+- public void visitJumpInsn(final int opcode, final Label label) {
+- switch (opcode) {
+- case Opcodes.IFEQ:
+- ifeq(label);
+- break;
+- case Opcodes.IFNE:
+- ifne(label);
+- break;
+- case Opcodes.IFLT:
+- iflt(label);
+- break;
+- case Opcodes.IFGE:
+- ifge(label);
+- break;
+- case Opcodes.IFGT:
+- ifgt(label);
+- break;
+- case Opcodes.IFLE:
+- ifle(label);
+- break;
+- case Opcodes.IF_ICMPEQ:
+- ificmpeq(label);
+- break;
+- case Opcodes.IF_ICMPNE:
+- ificmpne(label);
+- break;
+- case Opcodes.IF_ICMPLT:
+- ificmplt(label);
+- break;
+- case Opcodes.IF_ICMPGE:
+- ificmpge(label);
+- break;
+- case Opcodes.IF_ICMPGT:
+- ificmpgt(label);
+- break;
+- case Opcodes.IF_ICMPLE:
+- ificmple(label);
+- break;
+- case Opcodes.IF_ACMPEQ:
+- ifacmpeq(label);
+- break;
+- case Opcodes.IF_ACMPNE:
+- ifacmpne(label);
+- break;
+- case Opcodes.GOTO:
+- goTo(label);
+- break;
+- case Opcodes.JSR:
+- jsr(label);
+- break;
+- case Opcodes.IFNULL:
+- ifnull(label);
+- break;
+- case Opcodes.IFNONNULL:
+- ifnonnull(label);
+- break;
+- default:
+- throw new IllegalArgumentException();
+- }
+- }
+-
+- @Override
+- public void visitLabel(final Label label) {
+- mark(label);
+- }
+-
+- @Override
+- public void visitLdcInsn(final Object cst) {
+- if (cst instanceof Integer) {
+- int val = ((Integer) cst).intValue();
+- iconst(val);
+- } else if (cst instanceof Byte) {
+- int val = ((Byte) cst).intValue();
+- iconst(val);
+- } else if (cst instanceof Character) {
+- int val = ((Character) cst).charValue();
+- iconst(val);
+- } else if (cst instanceof Short) {
+- int val = ((Short) cst).intValue();
+- iconst(val);
+- } else if (cst instanceof Boolean) {
+- int val = ((Boolean) cst).booleanValue() ? 1 : 0;
+- iconst(val);
+- } else if (cst instanceof Float) {
+- float val = ((Float) cst).floatValue();
+- fconst(val);
+- } else if (cst instanceof Long) {
+- long val = ((Long) cst).longValue();
+- lconst(val);
+- } else if (cst instanceof Double) {
+- double val = ((Double) cst).doubleValue();
+- dconst(val);
+- } else if (cst instanceof String) {
+- aconst(cst);
+- } else if (cst instanceof Type) {
+- tconst((Type) cst);
+- } else if (cst instanceof Handle) {
+- hconst((Handle) cst);
+- } else {
+- throw new IllegalArgumentException();
+- }
+- }
+-
+- @Override
+- public void visitIincInsn(final int var, final int increment) {
+- iinc(var, increment);
+- }
+-
+- @Override
+- public void visitTableSwitchInsn(final int min, final int max,
+- final Label dflt, final Label... labels) {
+- tableswitch(min, max, dflt, labels);
+- }
+-
+- @Override
+- public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+- final Label[] labels) {
+- lookupswitch(dflt, keys, labels);
+- }
+-
+- @Override
+- public void visitMultiANewArrayInsn(final String desc, final int dims) {
+- multianewarray(desc, dims);
+- }
+-
+- // -----------------------------------------------------------------------
+-
+- public void nop() {
+- mv.visitInsn(Opcodes.NOP);
+- }
+-
+- public void aconst(final Object cst) {
+- if (cst == null) {
+- mv.visitInsn(Opcodes.ACONST_NULL);
+- } else {
+- mv.visitLdcInsn(cst);
+- }
+- }
+-
+- public void iconst(final int cst) {
+- if (cst >= -1 && cst <= 5) {
+- mv.visitInsn(Opcodes.ICONST_0 + cst);
+- } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
+- mv.visitIntInsn(Opcodes.BIPUSH, cst);
+- } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
+- mv.visitIntInsn(Opcodes.SIPUSH, cst);
+- } else {
+- mv.visitLdcInsn(new Integer(cst));
+- }
+- }
+-
+- public void lconst(final long cst) {
+- if (cst == 0L || cst == 1L) {
+- mv.visitInsn(Opcodes.LCONST_0 + (int) cst);
+- } else {
+- mv.visitLdcInsn(new Long(cst));
+- }
+- }
+-
+- public void fconst(final float cst) {
+- int bits = Float.floatToIntBits(cst);
+- if (bits == 0L || bits == 0x3f800000 || bits == 0x40000000) { // 0..2
+- mv.visitInsn(Opcodes.FCONST_0 + (int) cst);
+- } else {
+- mv.visitLdcInsn(new Float(cst));
+- }
+- }
+-
+- public void dconst(final double cst) {
+- long bits = Double.doubleToLongBits(cst);
+- if (bits == 0L || bits == 0x3ff0000000000000L) { // +0.0d and 1.0d
+- mv.visitInsn(Opcodes.DCONST_0 + (int) cst);
+- } else {
+- mv.visitLdcInsn(new Double(cst));
+- }
+- }
+-
+- public void tconst(final Type type) {
+- mv.visitLdcInsn(type);
+- }
+-
+- public void hconst(final Handle handle) {
+- mv.visitLdcInsn(handle);
+- }
+-
+- public void load(final int var, final Type type) {
+- mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), var);
+- }
+-
+- public void aload(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IALOAD));
+- }
+-
+- public void store(final int var, final Type type) {
+- mv.visitVarInsn(type.getOpcode(Opcodes.ISTORE), var);
+- }
+-
+- public void astore(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IASTORE));
+- }
+-
+- public void pop() {
+- mv.visitInsn(Opcodes.POP);
+- }
+-
+- public void pop2() {
+- mv.visitInsn(Opcodes.POP2);
+- }
+-
+- public void dup() {
+- mv.visitInsn(Opcodes.DUP);
+- }
+-
+- public void dup2() {
+- mv.visitInsn(Opcodes.DUP2);
+- }
+-
+- public void dupX1() {
+- mv.visitInsn(Opcodes.DUP_X1);
+- }
+-
+- public void dupX2() {
+- mv.visitInsn(Opcodes.DUP_X2);
+- }
+-
+- public void dup2X1() {
+- mv.visitInsn(Opcodes.DUP2_X1);
+- }
+-
+- public void dup2X2() {
+- mv.visitInsn(Opcodes.DUP2_X2);
+- }
+-
+- public void swap() {
+- mv.visitInsn(Opcodes.SWAP);
+- }
+-
+- public void add(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IADD));
+- }
+-
+- public void sub(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.ISUB));
+- }
+-
+- public void mul(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IMUL));
+- }
+-
+- public void div(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IDIV));
+- }
+-
+- public void rem(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IREM));
+- }
+-
+- public void neg(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.INEG));
+- }
+-
+- public void shl(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.ISHL));
+- }
+-
+- public void shr(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.ISHR));
+- }
+-
+- public void ushr(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IUSHR));
+- }
+-
+- public void and(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IAND));
+- }
+-
+- public void or(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IOR));
+- }
+-
+- public void xor(final Type type) {
+- mv.visitInsn(type.getOpcode(Opcodes.IXOR));
+- }
+-
+- public void iinc(final int var, final int increment) {
+- mv.visitIincInsn(var, increment);
+- }
+-
+- public void cast(final Type from, final Type to) {
+- if (from != to) {
+- if (from == Type.DOUBLE_TYPE) {
+- if (to == Type.FLOAT_TYPE) {
+- mv.visitInsn(Opcodes.D2F);
+- } else if (to == Type.LONG_TYPE) {
+- mv.visitInsn(Opcodes.D2L);
+- } else {
+- mv.visitInsn(Opcodes.D2I);
+- cast(Type.INT_TYPE, to);
+- }
+- } else if (from == Type.FLOAT_TYPE) {
+- if (to == Type.DOUBLE_TYPE) {
+- mv.visitInsn(Opcodes.F2D);
+- } else if (to == Type.LONG_TYPE) {
+- mv.visitInsn(Opcodes.F2L);
+- } else {
+- mv.visitInsn(Opcodes.F2I);
+- cast(Type.INT_TYPE, to);
+- }
+- } else if (from == Type.LONG_TYPE) {
+- if (to == Type.DOUBLE_TYPE) {
+- mv.visitInsn(Opcodes.L2D);
+- } else if (to == Type.FLOAT_TYPE) {
+- mv.visitInsn(Opcodes.L2F);
+- } else {
+- mv.visitInsn(Opcodes.L2I);
+- cast(Type.INT_TYPE, to);
+- }
+- } else {
+- if (to == Type.BYTE_TYPE) {
+- mv.visitInsn(Opcodes.I2B);
+- } else if (to == Type.CHAR_TYPE) {
+- mv.visitInsn(Opcodes.I2C);
+- } else if (to == Type.DOUBLE_TYPE) {
+- mv.visitInsn(Opcodes.I2D);
+- } else if (to == Type.FLOAT_TYPE) {
+- mv.visitInsn(Opcodes.I2F);
+- } else if (to == Type.LONG_TYPE) {
+- mv.visitInsn(Opcodes.I2L);
+- } else if (to == Type.SHORT_TYPE) {
+- mv.visitInsn(Opcodes.I2S);
+- }
+- }
+- }
+- }
+-
+- public void lcmp() {
+- mv.visitInsn(Opcodes.LCMP);
+- }
+-
+- public void cmpl(final Type type) {
+- mv.visitInsn(type == Type.FLOAT_TYPE ? Opcodes.FCMPL : Opcodes.DCMPL);
+- }
+-
+- public void cmpg(final Type type) {
+- mv.visitInsn(type == Type.FLOAT_TYPE ? Opcodes.FCMPG : Opcodes.DCMPG);
+- }
+-
+- public void ifeq(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFEQ, label);
+- }
+-
+- public void ifne(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFNE, label);
+- }
+-
+- public void iflt(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFLT, label);
+- }
+-
+- public void ifge(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFGE, label);
+- }
+-
+- public void ifgt(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFGT, label);
+- }
+-
+- public void ifle(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFLE, label);
+- }
+-
+- public void ificmpeq(final Label label) {
+- mv.visitJumpInsn(Opcodes.IF_ICMPEQ, label);
+- }
+-
+- public void ificmpne(final Label label) {
+- mv.visitJumpInsn(Opcodes.IF_ICMPNE, label);
+- }
+-
+- public void ificmplt(final Label label) {
+- mv.visitJumpInsn(Opcodes.IF_ICMPLT, label);
+- }
+-
+- public void ificmpge(final Label label) {
+- mv.visitJumpInsn(Opcodes.IF_ICMPGE, label);
+- }
+-
+- public void ificmpgt(final Label label) {
+- mv.visitJumpInsn(Opcodes.IF_ICMPGT, label);
+- }
+-
+- public void ificmple(final Label label) {
+- mv.visitJumpInsn(Opcodes.IF_ICMPLE, label);
+- }
+-
+- public void ifacmpeq(final Label label) {
+- mv.visitJumpInsn(Opcodes.IF_ACMPEQ, label);
+- }
+-
+- public void ifacmpne(final Label label) {
+- mv.visitJumpInsn(Opcodes.IF_ACMPNE, label);
+- }
+-
+- public void goTo(final Label label) {
+- mv.visitJumpInsn(Opcodes.GOTO, label);
+- }
+-
+- public void jsr(final Label label) {
+- mv.visitJumpInsn(Opcodes.JSR, label);
+- }
+-
+- public void ret(final int var) {
+- mv.visitVarInsn(Opcodes.RET, var);
+- }
+-
+- public void tableswitch(final int min, final int max, final Label dflt,
+- final Label... labels) {
+- mv.visitTableSwitchInsn(min, max, dflt, labels);
+- }
+-
+- public void lookupswitch(final Label dflt, final int[] keys,
+- final Label[] labels) {
+- mv.visitLookupSwitchInsn(dflt, keys, labels);
+- }
+-
+- public void areturn(final Type t) {
+- mv.visitInsn(t.getOpcode(Opcodes.IRETURN));
+- }
+-
+- public void getstatic(final String owner, final String name,
+- final String desc) {
+- mv.visitFieldInsn(Opcodes.GETSTATIC, owner, name, desc);
+- }
+-
+- public void putstatic(final String owner, final String name,
+- final String desc) {
+- mv.visitFieldInsn(Opcodes.PUTSTATIC, owner, name, desc);
+- }
+-
+- public void getfield(final String owner, final String name,
+- final String desc) {
+- mv.visitFieldInsn(Opcodes.GETFIELD, owner, name, desc);
+- }
+-
+- public void putfield(final String owner, final String name,
+- final String desc) {
+- mv.visitFieldInsn(Opcodes.PUTFIELD, owner, name, desc);
+- }
+-
+- @Deprecated
+- public void invokevirtual(final String owner, final String name,
+- final String desc) {
+- if (api >= Opcodes.ASM5) {
+- invokevirtual(owner, name, desc, false);
+- return;
+- }
+- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc);
+- }
+-
+- public void invokevirtual(final String owner, final String name,
+- final String desc, final boolean itf) {
+- if (api < Opcodes.ASM5) {
+- if (itf) {
+- throw new IllegalArgumentException(
+- "INVOKEVIRTUAL on interfaces require ASM 5");
+- }
+- invokevirtual(owner, name, desc);
+- return;
+- }
+- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc, itf);
+- }
+-
+- @Deprecated
+- public void invokespecial(final String owner, final String name,
+- final String desc) {
+- if (api >= Opcodes.ASM5) {
+- invokespecial(owner, name, desc, false);
+- return;
+- }
+- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, desc, false);
+- }
+-
+- public void invokespecial(final String owner, final String name,
+- final String desc, final boolean itf) {
+- if (api < Opcodes.ASM5) {
+- if (itf) {
+- throw new IllegalArgumentException(
+- "INVOKESPECIAL on interfaces require ASM 5");
+- }
+- invokespecial(owner, name, desc);
+- return;
+- }
+- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, name, desc, itf);
+- }
+-
+- @Deprecated
+- public void invokestatic(final String owner, final String name,
+- final String desc) {
+- if (api >= Opcodes.ASM5) {
+- invokestatic(owner, name, desc, false);
+- return;
+- }
+- mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc, false);
+- }
+-
+- public void invokestatic(final String owner, final String name,
+- final String desc, final boolean itf) {
+- if (api < Opcodes.ASM5) {
+- if (itf) {
+- throw new IllegalArgumentException(
+- "INVOKESTATIC on interfaces require ASM 5");
+- }
+- invokestatic(owner, name, desc);
+- return;
+- }
+- mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc, itf);
+- }
+-
+- public void invokeinterface(final String owner, final String name,
+- final String desc) {
+- mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, owner, name, desc, true);
+- }
+-
+- public void invokedynamic(String name, String desc, Handle bsm,
+- Object[] bsmArgs) {
+- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+- }
+-
+- public void anew(final Type type) {
+- mv.visitTypeInsn(Opcodes.NEW, type.getInternalName());
+- }
+-
+- public void newarray(final Type type) {
+- int typ;
+- switch (type.getSort()) {
+- case Type.BOOLEAN:
+- typ = Opcodes.T_BOOLEAN;
+- break;
+- case Type.CHAR:
+- typ = Opcodes.T_CHAR;
+- break;
+- case Type.BYTE:
+- typ = Opcodes.T_BYTE;
+- break;
+- case Type.SHORT:
+- typ = Opcodes.T_SHORT;
+- break;
+- case Type.INT:
+- typ = Opcodes.T_INT;
+- break;
+- case Type.FLOAT:
+- typ = Opcodes.T_FLOAT;
+- break;
+- case Type.LONG:
+- typ = Opcodes.T_LONG;
+- break;
+- case Type.DOUBLE:
+- typ = Opcodes.T_DOUBLE;
+- break;
+- default:
+- mv.visitTypeInsn(Opcodes.ANEWARRAY, type.getInternalName());
+- return;
+- }
+- mv.visitIntInsn(Opcodes.NEWARRAY, typ);
+- }
+-
+- public void arraylength() {
+- mv.visitInsn(Opcodes.ARRAYLENGTH);
+- }
+-
+- public void athrow() {
+- mv.visitInsn(Opcodes.ATHROW);
+- }
+-
+- public void checkcast(final Type type) {
+- mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());
+- }
+-
+- public void instanceOf(final Type type) {
+- mv.visitTypeInsn(Opcodes.INSTANCEOF, type.getInternalName());
+- }
+-
+- public void monitorenter() {
+- mv.visitInsn(Opcodes.MONITORENTER);
+- }
+-
+- public void monitorexit() {
+- mv.visitInsn(Opcodes.MONITOREXIT);
+- }
+-
+- public void multianewarray(final String desc, final int dims) {
+- mv.visitMultiANewArrayInsn(desc, dims);
+- }
+-
+- public void ifnull(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFNULL, label);
+- }
+-
+- public void ifnonnull(final Label label) {
+- mv.visitJumpInsn(Opcodes.IFNONNULL, label);
+- }
+-
+- public void mark(final Label label) {
+- mv.visitLabel(label);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/JSRInlinerAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/JSRInlinerAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/JSRInlinerAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/JSRInlinerAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,752 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import java.util.AbstractMap;
+-import java.util.ArrayList;
+-import java.util.BitSet;
+-import java.util.HashMap;
+-import java.util.Iterator;
+-import java.util.LinkedList;
+-import java.util.List;
+-import java.util.Map;
+-import java.util.Set;
+-
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-import org.mvel2.asm.tree.InsnList;
+-import org.mvel2.asm.tree.InsnNode;
+-import org.mvel2.asm.tree.JumpInsnNode;
+-import org.mvel2.asm.tree.LabelNode;
+-import org.mvel2.asm.tree.LocalVariableNode;
+-import org.mvel2.asm.tree.LookupSwitchInsnNode;
+-import org.mvel2.asm.tree.MethodNode;
+-import org.mvel2.asm.tree.TableSwitchInsnNode;
+-import org.mvel2.asm.tree.TryCatchBlockNode;
+-
+-/**
+- * A {@link org.mvel2.asm.MethodVisitor} that removes JSR instructions and
+- * inlines the referenced subroutines.
+- *
+- * Explanation of how it works TODO
+- *
+- * @author Niko Matsakis
+- */
+-public class JSRInlinerAdapter extends MethodNode implements Opcodes {
+-
+- private static final boolean LOGGING = false;
+-
+- /**
+- * For each label that is jumped to by a JSR, we create a BitSet instance.
+- */
+- private final Map subroutineHeads = new HashMap();
+-
+- /**
+- * This subroutine instance denotes the line of execution that is not
+- * contained within any subroutine; i.e., the "subroutine" that is executing
+- * when a method first begins.
+- */
+- private final BitSet mainSubroutine = new BitSet();
+-
+- /**
+- * This BitSet contains the index of every instruction that belongs to more
+- * than one subroutine. This should not happen often.
+- */
+- final BitSet dualCitizens = new BitSet();
+-
+- /**
+- * Creates a new JSRInliner. Subclasses must not use this
+- * constructor . Instead, they must use the
+- * {@link #JSRInlinerAdapter(int, MethodVisitor, int, String, String, String, String[])}
+- * version.
+- *
+- * @param mv
+- * the MethodVisitor
to send the resulting inlined
+- * method code to (use null
for none).
+- * @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 null .
+- * @param exceptions
+- * the internal names of the method's exception classes (see
+- * {@link Type#getInternalName() getInternalName}). May be
+- * null .
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public JSRInlinerAdapter(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);
+- if (getClass() != JSRInlinerAdapter.class) {
+- throw new IllegalStateException();
+- }
+- }
+-
+- /**
+- * Creates a new JSRInliner.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param mv
+- * the MethodVisitor
to send the resulting inlined
+- * method code to (use null
for none).
+- * @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 null .
+- * @param exceptions
+- * the internal names of the method's exception classes (see
+- * {@link Type#getInternalName() getInternalName}). May be
+- * null .
+- */
+- protected JSRInlinerAdapter(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;
+- }
+-
+- /**
+- * Detects a JSR instruction and sets a flag to indicate we will need to do
+- * inlining.
+- */
+- @Override
+- public void visitJumpInsn(final int opcode, final Label lbl) {
+- super.visitJumpInsn(opcode, lbl);
+- LabelNode ln = ((JumpInsnNode) instructions.getLast()).label;
+- if (opcode == JSR && !subroutineHeads.containsKey(ln)) {
+- subroutineHeads.put(ln, new BitSet());
+- }
+- }
+-
+- /**
+- * If any JSRs were seen, triggers the inlining process. Otherwise, forwards
+- * the byte codes untouched.
+- */
+- @Override
+- public void visitEnd() {
+- if (!subroutineHeads.isEmpty()) {
+- markSubroutines();
+- if (LOGGING) {
+- log(mainSubroutine.toString());
+- Iterator it = subroutineHeads.values().iterator();
+- while (it.hasNext()) {
+- BitSet sub = it.next();
+- log(sub.toString());
+- }
+- }
+- emitCode();
+- }
+-
+- // Forward the translate opcodes on if appropriate:
+- if (mv != null) {
+- accept(mv);
+- }
+- }
+-
+- /**
+- * Walks the method and determines which internal subroutine(s), if any,
+- * each instruction is a method of.
+- */
+- private void markSubroutines() {
+- BitSet anyvisited = new BitSet();
+-
+- // First walk the main subroutine and find all those instructions which
+- // can be reached without invoking any JSR at all
+- markSubroutineWalk(mainSubroutine, 0, anyvisited);
+-
+- // Go through the head of each subroutine and find any nodes reachable
+- // to that subroutine without following any JSR links.
+- for (Iterator> it = subroutineHeads
+- .entrySet().iterator(); it.hasNext();) {
+- Map.Entry entry = it.next();
+- LabelNode lab = entry.getKey();
+- BitSet sub = entry.getValue();
+- int index = instructions.indexOf(lab);
+- markSubroutineWalk(sub, index, anyvisited);
+- }
+- }
+-
+- /**
+- * Performs a depth first search walking the normal byte code path starting
+- * at index
, and adding each instruction encountered into the
+- * subroutine sub
. After this walk is complete, iterates over
+- * the exception handlers to ensure that we also include those byte codes
+- * which are reachable through an exception that may be thrown during the
+- * execution of the subroutine. Invoked from markSubroutines()
.
+- *
+- * @param sub
+- * the subroutine whose instructions must be computed.
+- * @param index
+- * an instruction of this subroutine.
+- * @param anyvisited
+- * indexes of the already visited instructions, i.e. marked as
+- * part of this subroutine or any previously computed subroutine.
+- */
+- private void markSubroutineWalk(final BitSet sub, final int index,
+- final BitSet anyvisited) {
+- if (LOGGING) {
+- log("markSubroutineWalk: sub=" + sub + " index=" + index);
+- }
+-
+- // First find those instructions reachable via normal execution
+- markSubroutineWalkDFS(sub, index, anyvisited);
+-
+- // Now, make sure we also include any applicable exception handlers
+- boolean loop = true;
+- while (loop) {
+- loop = false;
+- for (Iterator it = tryCatchBlocks.iterator(); it
+- .hasNext();) {
+- TryCatchBlockNode trycatch = it.next();
+-
+- if (LOGGING) {
+- // TODO use of default toString().
+- log("Scanning try/catch " + trycatch);
+- }
+-
+- // If the handler has already been processed, skip it.
+- int handlerindex = instructions.indexOf(trycatch.handler);
+- if (sub.get(handlerindex)) {
+- continue;
+- }
+-
+- int startindex = instructions.indexOf(trycatch.start);
+- int endindex = instructions.indexOf(trycatch.end);
+- int nextbit = sub.nextSetBit(startindex);
+- if (nextbit != -1 && nextbit < endindex) {
+- if (LOGGING) {
+- log("Adding exception handler: " + startindex + '-'
+- + endindex + " due to " + nextbit + " handler "
+- + handlerindex);
+- }
+- markSubroutineWalkDFS(sub, handlerindex, anyvisited);
+- loop = true;
+- }
+- }
+- }
+- }
+-
+- /**
+- * Performs a simple DFS of the instructions, assigning each to the
+- * subroutine sub
. Starts from index
. Invoked only
+- * by markSubroutineWalk()
.
+- *
+- * @param sub
+- * the subroutine whose instructions must be computed.
+- * @param index
+- * an instruction of this subroutine.
+- * @param anyvisited
+- * indexes of the already visited instructions, i.e. marked as
+- * part of this subroutine or any previously computed subroutine.
+- */
+- private void markSubroutineWalkDFS(final BitSet sub, int index,
+- final BitSet anyvisited) {
+- while (true) {
+- AbstractInsnNode node = instructions.get(index);
+-
+- // don't visit a node twice
+- if (sub.get(index)) {
+- return;
+- }
+- sub.set(index);
+-
+- // check for those nodes already visited by another subroutine
+- if (anyvisited.get(index)) {
+- dualCitizens.set(index);
+- if (LOGGING) {
+- log("Instruction #" + index + " is dual citizen.");
+- }
+- }
+- anyvisited.set(index);
+-
+- if (node.getType() == AbstractInsnNode.JUMP_INSN
+- && node.getOpcode() != JSR) {
+- // we do not follow recursively called subroutines here; but any
+- // other sort of branch we do follow
+- JumpInsnNode jnode = (JumpInsnNode) node;
+- int destidx = instructions.indexOf(jnode.label);
+- markSubroutineWalkDFS(sub, destidx, anyvisited);
+- }
+- if (node.getType() == AbstractInsnNode.TABLESWITCH_INSN) {
+- TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node;
+- int destidx = instructions.indexOf(tsnode.dflt);
+- markSubroutineWalkDFS(sub, destidx, anyvisited);
+- for (int i = tsnode.labels.size() - 1; i >= 0; --i) {
+- LabelNode l = tsnode.labels.get(i);
+- destidx = instructions.indexOf(l);
+- markSubroutineWalkDFS(sub, destidx, anyvisited);
+- }
+- }
+- if (node.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN) {
+- LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node;
+- int destidx = instructions.indexOf(lsnode.dflt);
+- markSubroutineWalkDFS(sub, destidx, anyvisited);
+- for (int i = lsnode.labels.size() - 1; i >= 0; --i) {
+- LabelNode l = lsnode.labels.get(i);
+- destidx = instructions.indexOf(l);
+- markSubroutineWalkDFS(sub, destidx, anyvisited);
+- }
+- }
+-
+- // check to see if this opcode falls through to the next instruction
+- // or not; if not, return.
+- switch (instructions.get(index).getOpcode()) {
+- case GOTO:
+- case RET:
+- case TABLESWITCH:
+- case LOOKUPSWITCH:
+- case IRETURN:
+- case LRETURN:
+- case FRETURN:
+- case DRETURN:
+- case ARETURN:
+- case RETURN:
+- case ATHROW:
+- /*
+- * note: this either returns from this subroutine, or a parent
+- * subroutine which invoked it
+- */
+- return;
+- }
+-
+- // Use tail recursion here in the form of an outer while loop to
+- // avoid our stack growing needlessly:
+- index++;
+-
+- // We implicitly assumed above that execution can always fall
+- // through to the next instruction after a JSR. But a subroutine may
+- // never return, in which case the code after the JSR is unreachable
+- // and can be anything. In particular, it can seem to fall off the
+- // end of the method, so we must handle this case here (we could
+- // instead detect whether execution can return or not from a JSR,
+- // but this is more complicated).
+- if (index >= instructions.size()) {
+- return;
+- }
+- }
+- }
+-
+- /**
+- * Creates the new instructions, inlining each instantiation of each
+- * subroutine until the code is fully elaborated.
+- */
+- private void emitCode() {
+- LinkedList worklist = new LinkedList();
+- // Create an instantiation of the "root" subroutine, which is just the
+- // main routine
+- worklist.add(new Instantiation(null, mainSubroutine));
+-
+- // Emit instantiations of each subroutine we encounter, including the
+- // main subroutine
+- InsnList newInstructions = new InsnList();
+- List newTryCatchBlocks = new ArrayList();
+- List newLocalVariables = new ArrayList();
+- while (!worklist.isEmpty()) {
+- Instantiation inst = worklist.removeFirst();
+- emitSubroutine(inst, worklist, newInstructions, newTryCatchBlocks,
+- newLocalVariables);
+- }
+- instructions = newInstructions;
+- tryCatchBlocks = newTryCatchBlocks;
+- localVariables = newLocalVariables;
+- }
+-
+- /**
+- * Emits one instantiation of one subroutine, specified by
+- * instant
. May add new instantiations that are invoked by this
+- * one to the worklist
parameter, and new try/catch blocks to
+- * newTryCatchBlocks
.
+- *
+- * @param instant
+- * the instantiation that must be performed.
+- * @param worklist
+- * list of the instantiations that remain to be done.
+- * @param newInstructions
+- * the instruction list to which the instantiated code must be
+- * appended.
+- * @param newTryCatchBlocks
+- * the exception handler list to which the instantiated handlers
+- * must be appended.
+- */
+- private void emitSubroutine(final Instantiation instant,
+- final List worklist, final InsnList newInstructions,
+- final List newTryCatchBlocks,
+- final List newLocalVariables) {
+- LabelNode duplbl = null;
+-
+- if (LOGGING) {
+- log("--------------------------------------------------------");
+- log("Emitting instantiation of subroutine " + instant.subroutine);
+- }
+-
+- // Emit the relevant instructions for this instantiation, translating
+- // labels and jump targets as we go:
+- for (int i = 0, c = instructions.size(); i < c; i++) {
+- AbstractInsnNode insn = instructions.get(i);
+- Instantiation owner = instant.findOwner(i);
+-
+- // Always remap labels:
+- if (insn.getType() == AbstractInsnNode.LABEL) {
+- // Translate labels into their renamed equivalents.
+- // Avoid adding the same label more than once. Note
+- // that because we own this instruction the gotoTable
+- // and the rangeTable will always agree.
+- LabelNode ilbl = (LabelNode) insn;
+- LabelNode remap = instant.rangeLabel(ilbl);
+- if (LOGGING) {
+- // TODO use of default toString().
+- log("Translating lbl #" + i + ':' + ilbl + " to " + remap);
+- }
+- if (remap != duplbl) {
+- newInstructions.add(remap);
+- duplbl = remap;
+- }
+- continue;
+- }
+-
+- // We don't want to emit instructions that were already
+- // emitted by a subroutine higher on the stack. Note that
+- // it is still possible for a given instruction to be
+- // emitted twice because it may belong to two subroutines
+- // that do not invoke each other.
+- if (owner != instant) {
+- continue;
+- }
+-
+- if (LOGGING) {
+- log("Emitting inst #" + i);
+- }
+-
+- if (insn.getOpcode() == RET) {
+- // Translate RET instruction(s) to a jump to the return label
+- // for the appropriate instantiation. The problem is that the
+- // subroutine may "fall through" to the ret of a parent
+- // subroutine; therefore, to find the appropriate ret label we
+- // find the lowest subroutine on the stack that claims to own
+- // this instruction. See the class javadoc comment for an
+- // explanation on why this technique is safe (note: it is only
+- // safe if the input is verifiable).
+- LabelNode retlabel = null;
+- for (Instantiation p = instant; p != null; p = p.previous) {
+- if (p.subroutine.get(i)) {
+- retlabel = p.returnLabel;
+- }
+- }
+- if (retlabel == null) {
+- // This is only possible if the mainSubroutine owns a RET
+- // instruction, which should never happen for verifiable
+- // code.
+- throw new RuntimeException("Instruction #" + i
+- + " is a RET not owned by any subroutine");
+- }
+- newInstructions.add(new JumpInsnNode(GOTO, retlabel));
+- } else if (insn.getOpcode() == JSR) {
+- LabelNode lbl = ((JumpInsnNode) insn).label;
+- BitSet sub = subroutineHeads.get(lbl);
+- Instantiation newinst = new Instantiation(instant, sub);
+- LabelNode startlbl = newinst.gotoLabel(lbl);
+-
+- if (LOGGING) {
+- log(" Creating instantiation of subr " + sub);
+- }
+-
+- // Rather than JSRing, we will jump to the inline version and
+- // push NULL for what was once the return value. This hack
+- // allows us to avoid doing any sort of data flow analysis to
+- // figure out which instructions manipulate the old return value
+- // pointer which is now known to be unneeded.
+- newInstructions.add(new InsnNode(ACONST_NULL));
+- newInstructions.add(new JumpInsnNode(GOTO, startlbl));
+- newInstructions.add(newinst.returnLabel);
+-
+- // Insert this new instantiation into the queue to be emitted
+- // later.
+- worklist.add(newinst);
+- } else {
+- newInstructions.add(insn.clone(instant));
+- }
+- }
+-
+- // Emit try/catch blocks that are relevant to this method.
+- for (Iterator it = tryCatchBlocks.iterator(); it
+- .hasNext();) {
+- TryCatchBlockNode trycatch = it.next();
+-
+- if (LOGGING) {
+- // TODO use of default toString().
+- log("try catch block original labels=" + trycatch.start + '-'
+- + trycatch.end + "->" + trycatch.handler);
+- }
+-
+- final LabelNode start = instant.rangeLabel(trycatch.start);
+- final LabelNode end = instant.rangeLabel(trycatch.end);
+-
+- // Ignore empty try/catch regions
+- if (start == end) {
+- if (LOGGING) {
+- log(" try catch block empty in this subroutine");
+- }
+- continue;
+- }
+-
+- final LabelNode handler = instant.gotoLabel(trycatch.handler);
+-
+- if (LOGGING) {
+- // TODO use of default toString().
+- log(" try catch block new labels=" + start + '-' + end + "->"
+- + handler);
+- }
+-
+- if (start == null || end == null || handler == null) {
+- throw new RuntimeException("Internal error!");
+- }
+-
+- newTryCatchBlocks.add(new TryCatchBlockNode(start, end, handler,
+- trycatch.type));
+- }
+-
+- for (Iterator it = localVariables.iterator(); it
+- .hasNext();) {
+- LocalVariableNode lvnode = it.next();
+- if (LOGGING) {
+- log("local var " + lvnode.name);
+- }
+- final LabelNode start = instant.rangeLabel(lvnode.start);
+- final LabelNode end = instant.rangeLabel(lvnode.end);
+- if (start == end) {
+- if (LOGGING) {
+- log(" local variable empty in this sub");
+- }
+- continue;
+- }
+- newLocalVariables.add(new LocalVariableNode(lvnode.name,
+- lvnode.desc, lvnode.signature, start, end, lvnode.index));
+- }
+- }
+-
+- private static void log(final String str) {
+- System.err.println(str);
+- }
+-
+- /**
+- * A class that represents an instantiation of a subroutine. Each
+- * instantiation has an associate "stack" --- which is a listing of those
+- * instantiations that were active when this particular instance of this
+- * subroutine was invoked. Each instantiation also has a map from the
+- * original labels of the program to the labels appropriate for this
+- * instantiation, and finally a label to return to.
+- */
+- private class Instantiation extends AbstractMap {
+-
+- /**
+- * Previous instantiations; the stack must be statically predictable to
+- * be inlinable.
+- */
+- final Instantiation previous;
+-
+- /**
+- * The subroutine this is an instantiation of.
+- */
+- public final BitSet subroutine;
+-
+- /**
+- * This table maps Labels from the original source to Labels pointing at
+- * code specific to this instantiation, for use in remapping try/catch
+- * blocks,as well as gotos.
+- *
+- * Note that in the presence of dual citizens instructions, that is,
+- * instructions which belong to more than one subroutine due to the
+- * merging of control flow without a RET instruction, we will map the
+- * target label of a GOTO to the label used by the instantiation lowest
+- * on the stack. This avoids code duplication during inlining in most
+- * cases.
+- *
+- * @see #findOwner(int)
+- */
+- public final Map rangeTable = new HashMap();
+-
+- /**
+- * All returns for this instantiation will be mapped to this label
+- */
+- public final LabelNode returnLabel;
+-
+- Instantiation(final Instantiation prev, final BitSet sub) {
+- previous = prev;
+- subroutine = sub;
+- for (Instantiation p = prev; p != null; p = p.previous) {
+- if (p.subroutine == sub) {
+- throw new RuntimeException("Recursive invocation of " + sub);
+- }
+- }
+-
+- // Determine the label to return to when this subroutine terminates
+- // via RET: note that the main subroutine never terminates via RET.
+- if (prev != null) {
+- returnLabel = new LabelNode();
+- } else {
+- returnLabel = null;
+- }
+-
+- // Each instantiation will remap the labels from the code above to
+- // refer to its particular copy of its own instructions. Note that
+- // we collapse labels which point at the same instruction into one:
+- // this is fairly common as we are often ignoring large chunks of
+- // instructions, so what were previously distinct labels become
+- // duplicates.
+- LabelNode duplbl = null;
+- for (int i = 0, c = instructions.size(); i < c; i++) {
+- AbstractInsnNode insn = instructions.get(i);
+-
+- if (insn.getType() == AbstractInsnNode.LABEL) {
+- LabelNode ilbl = (LabelNode) insn;
+-
+- if (duplbl == null) {
+- // if we already have a label pointing at this spot,
+- // don't recreate it.
+- duplbl = new LabelNode();
+- }
+-
+- // Add an entry in the rangeTable for every label
+- // in the original code which points at the next
+- // instruction of our own to be emitted.
+- rangeTable.put(ilbl, duplbl);
+- } else if (findOwner(i) == this) {
+- // We will emit this instruction, so clear the 'duplbl' flag
+- // since the next Label will refer to a distinct
+- // instruction.
+- duplbl = null;
+- }
+- }
+- }
+-
+- /**
+- * Returns the "owner" of a particular instruction relative to this
+- * instantiation: the owner referes to the Instantiation which will emit
+- * the version of this instruction that we will execute.
+- *
+- * Typically, the return value is either this
or
+- * null
. this
indicates that this
+- * instantiation will generate the version of this instruction that we
+- * will execute, and null
indicates that this instantiation
+- * never executes the given instruction.
+- *
+- * Sometimes, however, an instruction can belong to multiple
+- * subroutines; this is called a "dual citizen" instruction (though it
+- * may belong to more than 2 subroutines), and occurs when multiple
+- * subroutines branch to common points of control. In this case, the
+- * owner is the subroutine that appears lowest on the stack, and which
+- * also owns the instruction in question.
+- *
+- * @param i
+- * the index of the instruction in the original code
+- * @return the "owner" of a particular instruction relative to this
+- * instantiation.
+- */
+- public Instantiation findOwner(final int i) {
+- if (!subroutine.get(i)) {
+- return null;
+- }
+- if (!dualCitizens.get(i)) {
+- return this;
+- }
+- Instantiation own = this;
+- for (Instantiation p = previous; p != null; p = p.previous) {
+- if (p.subroutine.get(i)) {
+- own = p;
+- }
+- }
+- return own;
+- }
+-
+- /**
+- * Looks up the label l
in the gotoTable
, thus
+- * translating it from a Label in the original code, to a Label in the
+- * inlined code that is appropriate for use by an instruction that
+- * branched to the original label.
+- *
+- * @param l
+- * The label we will be translating
+- * @return a label for use by a branch instruction in the inlined code
+- * @see #rangeLabel
+- */
+- public LabelNode gotoLabel(final LabelNode l) {
+- // owner should never be null, because owner is only null
+- // if an instruction cannot be reached from this subroutine
+- Instantiation owner = findOwner(instructions.indexOf(l));
+- return owner.rangeTable.get(l);
+- }
+-
+- /**
+- * Looks up the label l
in the rangeTable
,
+- * thus translating it from a Label in the original code, to a Label in
+- * the inlined code that is appropriate for use by an try/catch or
+- * variable use annotation.
+- *
+- * @param l
+- * The label we will be translating
+- * @return a label for use by a try/catch or variable annotation in the
+- * original code
+- * @see #rangeTable
+- */
+- public LabelNode rangeLabel(final LabelNode l) {
+- return rangeTable.get(l);
+- }
+-
+- // AbstractMap implementation
+-
+- @Override
+- public Set> entrySet() {
+- return null;
+- }
+-
+- @Override
+- public LabelNode get(final Object o) {
+- return gotoLabel((LabelNode) o);
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/LocalVariablesSorter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/LocalVariablesSorter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/LocalVariablesSorter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/LocalVariablesSorter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,381 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.TypePath;
+-
+-/**
+- * A {@link MethodVisitor} that renumbers local variables in their order of
+- * appearance. This adapter allows one to easily add new local variables to a
+- * method. It may be used by inheriting from this class, but the preferred way
+- * of using it is via delegation: the next visitor in the chain can indeed add
+- * new locals when needed by calling {@link #newLocal} on this adapter (this
+- * requires a reference back to this {@link LocalVariablesSorter}).
+- *
+- * @author Chris Nokleberg
+- * @author Eugene Kuleshov
+- * @author Eric Bruneton
+- */
+-public class LocalVariablesSorter extends MethodVisitor {
+-
+- private static final Type OBJECT_TYPE = Type
+- .getObjectType("java/lang/Object");
+-
+- /**
+- * Mapping from old to new local variable indexes. A local variable at index
+- * i of size 1 is remapped to 'mapping[2*i]', while a local variable at
+- * index i of size 2 is remapped to 'mapping[2*i+1]'.
+- */
+- private int[] mapping = new int[40];
+-
+- /**
+- * Array used to store stack map local variable types after remapping.
+- */
+- private Object[] newLocals = new Object[20];
+-
+- /**
+- * Index of the first local variable, after formal parameters.
+- */
+- protected final int firstLocal;
+-
+- /**
+- * Index of the next local variable to be created by {@link #newLocal}.
+- */
+- protected int nextLocal;
+-
+- /**
+- * Indicates if at least one local variable has moved due to remapping.
+- */
+- private boolean changed;
+-
+- /**
+- * Creates a new {@link LocalVariablesSorter}. Subclasses must not use
+- * this constructor . Instead, they must use the
+- * {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version.
+- *
+- * @param access
+- * access flags of the adapted method.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @param mv
+- * the method visitor to which this adapter delegates calls.
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public LocalVariablesSorter(final int access, final String desc,
+- final MethodVisitor mv) {
+- this(Opcodes.ASM5, access, desc, mv);
+- if (getClass() != LocalVariablesSorter.class) {
+- throw new IllegalStateException();
+- }
+- }
+-
+- /**
+- * Creates a new {@link LocalVariablesSorter}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param access
+- * access flags of the adapted method.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @param mv
+- * the method visitor to which this adapter delegates calls.
+- */
+- protected LocalVariablesSorter(final int api, final int access,
+- final String desc, final MethodVisitor mv) {
+- super(api, mv);
+- Type[] args = Type.getArgumentTypes(desc);
+- nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
+- for (int i = 0; i < args.length; i++) {
+- nextLocal += args[i].getSize();
+- }
+- firstLocal = nextLocal;
+- }
+-
+- @Override
+- public void visitVarInsn(final int opcode, final int var) {
+- Type type;
+- switch (opcode) {
+- case Opcodes.LLOAD:
+- case Opcodes.LSTORE:
+- type = Type.LONG_TYPE;
+- break;
+-
+- case Opcodes.DLOAD:
+- case Opcodes.DSTORE:
+- type = Type.DOUBLE_TYPE;
+- break;
+-
+- case Opcodes.FLOAD:
+- case Opcodes.FSTORE:
+- type = Type.FLOAT_TYPE;
+- break;
+-
+- case Opcodes.ILOAD:
+- case Opcodes.ISTORE:
+- type = Type.INT_TYPE;
+- break;
+-
+- default:
+- // case Opcodes.ALOAD:
+- // case Opcodes.ASTORE:
+- // case RET:
+- type = OBJECT_TYPE;
+- break;
+- }
+- mv.visitVarInsn(opcode, remap(var, type));
+- }
+-
+- @Override
+- public void visitIincInsn(final int var, final int increment) {
+- mv.visitIincInsn(remap(var, Type.INT_TYPE), increment);
+- }
+-
+- @Override
+- public void visitMaxs(final int maxStack, final int maxLocals) {
+- mv.visitMaxs(maxStack, nextLocal);
+- }
+-
+- @Override
+- public void visitLocalVariable(final String name, final String desc,
+- final String signature, final Label start, final Label end,
+- final int index) {
+- int newIndex = remap(index, Type.getType(desc));
+- mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
+- }
+-
+- @Override
+- public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+- TypePath typePath, Label[] start, Label[] end, int[] index,
+- String desc, boolean visible) {
+- Type t = Type.getType(desc);
+- int[] newIndex = new int[index.length];
+- for (int i = 0; i < newIndex.length; ++i) {
+- newIndex[i] = remap(index[i], t);
+- }
+- return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
+- newIndex, desc, visible);
+- }
+-
+- @Override
+- public void visitFrame(final int type, final int nLocal,
+- final Object[] local, final int nStack, final Object[] stack) {
+- if (type != Opcodes.F_NEW) { // uncompressed frame
+- throw new IllegalStateException(
+- "ClassReader.accept() should be called with EXPAND_FRAMES flag");
+- }
+-
+- if (!changed) { // optimization for the case where mapping = identity
+- mv.visitFrame(type, nLocal, local, nStack, stack);
+- return;
+- }
+-
+- // creates a copy of newLocals
+- Object[] oldLocals = new Object[newLocals.length];
+- System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
+-
+- updateNewLocals(newLocals);
+-
+- // copies types from 'local' to 'newLocals'
+- // 'newLocals' already contains the variables added with 'newLocal'
+-
+- int index = 0; // old local variable index
+- int number = 0; // old local variable number
+- for (; number < nLocal; ++number) {
+- Object t = local[number];
+- int size = t == Opcodes.LONG || t == Opcodes.DOUBLE ? 2 : 1;
+- if (t != Opcodes.TOP) {
+- Type typ = OBJECT_TYPE;
+- if (t == Opcodes.INTEGER) {
+- typ = Type.INT_TYPE;
+- } else if (t == Opcodes.FLOAT) {
+- typ = Type.FLOAT_TYPE;
+- } else if (t == Opcodes.LONG) {
+- typ = Type.LONG_TYPE;
+- } else if (t == Opcodes.DOUBLE) {
+- typ = Type.DOUBLE_TYPE;
+- } else if (t instanceof String) {
+- typ = Type.getObjectType((String) t);
+- }
+- setFrameLocal(remap(index, typ), t);
+- }
+- index += size;
+- }
+-
+- // removes TOP after long and double types as well as trailing TOPs
+-
+- index = 0;
+- number = 0;
+- for (int i = 0; index < newLocals.length; ++i) {
+- Object t = newLocals[index++];
+- if (t != null && t != Opcodes.TOP) {
+- newLocals[i] = t;
+- number = i + 1;
+- if (t == Opcodes.LONG || t == Opcodes.DOUBLE) {
+- index += 1;
+- }
+- } else {
+- newLocals[i] = Opcodes.TOP;
+- }
+- }
+-
+- // visits remapped frame
+- mv.visitFrame(type, number, newLocals, nStack, stack);
+-
+- // restores original value of 'newLocals'
+- newLocals = oldLocals;
+- }
+-
+- // -------------
+-
+- /**
+- * Creates a new local variable of the given type.
+- *
+- * @param type
+- * the type of the local variable to be created.
+- * @return the identifier of the newly created local variable.
+- */
+- public int newLocal(final Type type) {
+- Object t;
+- switch (type.getSort()) {
+- case Type.BOOLEAN:
+- case Type.CHAR:
+- case Type.BYTE:
+- case Type.SHORT:
+- case Type.INT:
+- t = Opcodes.INTEGER;
+- break;
+- case Type.FLOAT:
+- t = Opcodes.FLOAT;
+- break;
+- case Type.LONG:
+- t = Opcodes.LONG;
+- break;
+- case Type.DOUBLE:
+- t = Opcodes.DOUBLE;
+- break;
+- case Type.ARRAY:
+- t = type.getDescriptor();
+- break;
+- // case Type.OBJECT:
+- default:
+- t = type.getInternalName();
+- break;
+- }
+- int local = newLocalMapping(type);
+- setLocalType(local, type);
+- setFrameLocal(local, t);
+- changed = true;
+- return local;
+- }
+-
+- /**
+- * Notifies subclasses that a new stack map frame is being visited. The
+- * array argument contains the stack map frame types corresponding to the
+- * local variables added with {@link #newLocal}. This method can update
+- * these types in place for the stack map frame being visited. The default
+- * implementation of this method does nothing, i.e. a local variable added
+- * with {@link #newLocal} will have the same type in all stack map frames.
+- * But this behavior is not always the desired one, for instance if a local
+- * variable is added in the middle of a try/catch block: the frame for the
+- * exception handler should have a TOP type for this new local.
+- *
+- * @param newLocals
+- * the stack map frame types corresponding to the local variables
+- * added with {@link #newLocal} (and null for the others). The
+- * format of this array is the same as in
+- * {@link MethodVisitor#visitFrame}, except that long and double
+- * types use two slots. The types for the current stack map frame
+- * must be updated in place in this array.
+- */
+- protected void updateNewLocals(Object[] newLocals) {
+- }
+-
+- /**
+- * Notifies subclasses that a local variable has been added or remapped. The
+- * default implementation of this method does nothing.
+- *
+- * @param local
+- * a local variable identifier, as returned by {@link #newLocal
+- * newLocal()}.
+- * @param type
+- * the type of the value being stored in the local variable.
+- */
+- protected void setLocalType(final int local, final Type type) {
+- }
+-
+- private void setFrameLocal(final int local, final Object type) {
+- int l = newLocals.length;
+- if (local >= l) {
+- Object[] a = new Object[Math.max(2 * l, local + 1)];
+- System.arraycopy(newLocals, 0, a, 0, l);
+- newLocals = a;
+- }
+- newLocals[local] = type;
+- }
+-
+- private int remap(final int var, final Type type) {
+- if (var + type.getSize() <= firstLocal) {
+- return var;
+- }
+- int key = 2 * var + type.getSize() - 1;
+- int size = mapping.length;
+- if (key >= size) {
+- int[] newMapping = new int[Math.max(2 * size, key + 1)];
+- System.arraycopy(mapping, 0, newMapping, 0, size);
+- mapping = newMapping;
+- }
+- int value = mapping[key];
+- if (value == 0) {
+- value = newLocalMapping(type);
+- setLocalType(value, type);
+- mapping[key] = value + 1;
+- } else {
+- value--;
+- }
+- if (value != var) {
+- changed = true;
+- }
+- return value;
+- }
+-
+- protected int newLocalMapping(final Type type) {
+- int local = nextLocal;
+- nextLocal += type.getSize();
+- return local;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/Method.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/Method.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/Method.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/Method.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,282 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import java.util.HashMap;
+-import java.util.Map;
+-
+-import org.mvel2.asm.Type;
+-
+-/**
+- * A named method descriptor.
+- *
+- * @author Juozas Baliuka
+- * @author Chris Nokleberg
+- * @author Eric Bruneton
+- */
+-public class Method {
+-
+- /**
+- * The method name.
+- */
+- private final String name;
+-
+- /**
+- * The method descriptor.
+- */
+- private final String desc;
+-
+- /**
+- * Maps primitive Java type names to their descriptors.
+- */
+- private static final Map DESCRIPTORS;
+-
+- static {
+- DESCRIPTORS = new HashMap();
+- DESCRIPTORS.put("void", "V");
+- DESCRIPTORS.put("byte", "B");
+- DESCRIPTORS.put("char", "C");
+- DESCRIPTORS.put("double", "D");
+- DESCRIPTORS.put("float", "F");
+- DESCRIPTORS.put("int", "I");
+- DESCRIPTORS.put("long", "J");
+- DESCRIPTORS.put("short", "S");
+- DESCRIPTORS.put("boolean", "Z");
+- }
+-
+- /**
+- * Creates a new {@link Method}.
+- *
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor.
+- */
+- public Method(final String name, final String desc) {
+- this.name = name;
+- this.desc = desc;
+- }
+-
+- /**
+- * Creates a new {@link Method}.
+- *
+- * @param name
+- * the method's name.
+- * @param returnType
+- * the method's return type.
+- * @param argumentTypes
+- * the method's argument types.
+- */
+- public Method(final String name, final Type returnType,
+- final Type[] argumentTypes) {
+- this(name, Type.getMethodDescriptor(returnType, argumentTypes));
+- }
+-
+- /**
+- * Creates a new {@link Method}.
+- *
+- * @param m
+- * a java.lang.reflect method descriptor
+- * @return a {@link Method} corresponding to the given Java method
+- * declaration.
+- */
+- public static Method getMethod(java.lang.reflect.Method m) {
+- return new Method(m.getName(), Type.getMethodDescriptor(m));
+- }
+-
+- /**
+- * Creates a new {@link Method}.
+- *
+- * @param c
+- * a java.lang.reflect constructor descriptor
+- * @return a {@link Method} corresponding to the given Java constructor
+- * declaration.
+- */
+- public static Method getMethod(java.lang.reflect.Constructor> c) {
+- return new Method("", Type.getConstructorDescriptor(c));
+- }
+-
+- /**
+- * Returns a {@link Method} corresponding to the given Java method
+- * declaration.
+- *
+- * @param method
+- * a Java method declaration, without argument names, of the form
+- * "returnType name (argumentType1, ... argumentTypeN)", where
+- * the types are in plain Java (e.g. "int", "float",
+- * "java.util.List", ...). Classes of the java.lang package can
+- * be specified by their unqualified name; all other classes
+- * names must be fully qualified.
+- * @return a {@link Method} corresponding to the given Java method
+- * declaration.
+- * @throws IllegalArgumentException
+- * if method
could not get parsed.
+- */
+- public static Method getMethod(final String method)
+- throws IllegalArgumentException {
+- return getMethod(method, false);
+- }
+-
+- /**
+- * Returns a {@link Method} corresponding to the given Java method
+- * declaration.
+- *
+- * @param method
+- * a Java method declaration, without argument names, of the form
+- * "returnType name (argumentType1, ... argumentTypeN)", where
+- * the types are in plain Java (e.g. "int", "float",
+- * "java.util.List", ...). Classes of the java.lang package may
+- * be specified by their unqualified name, depending on the
+- * defaultPackage argument; all other classes names must be fully
+- * qualified.
+- * @param defaultPackage
+- * true if unqualified class names belong to the default package,
+- * or false if they correspond to java.lang classes. For instance
+- * "Object" means "Object" if this option is true, or
+- * "java.lang.Object" otherwise.
+- * @return a {@link Method} corresponding to the given Java method
+- * declaration.
+- * @throws IllegalArgumentException
+- * if method
could not get parsed.
+- */
+- public static Method getMethod(final String method,
+- final boolean defaultPackage) throws IllegalArgumentException {
+- int space = method.indexOf(' ');
+- int start = method.indexOf('(', space) + 1;
+- int end = method.indexOf(')', start);
+- if (space == -1 || start == -1 || end == -1) {
+- throw new IllegalArgumentException();
+- }
+- String returnType = method.substring(0, space);
+- String methodName = method.substring(space + 1, start - 1).trim();
+- StringBuffer sb = new StringBuffer();
+- sb.append('(');
+- int p;
+- do {
+- String s;
+- p = method.indexOf(',', start);
+- if (p == -1) {
+- s = map(method.substring(start, end).trim(), defaultPackage);
+- } else {
+- s = map(method.substring(start, p).trim(), defaultPackage);
+- start = p + 1;
+- }
+- sb.append(s);
+- } while (p != -1);
+- sb.append(')');
+- sb.append(map(returnType, defaultPackage));
+- return new Method(methodName, sb.toString());
+- }
+-
+- private static String map(final String type, final boolean defaultPackage) {
+- if ("".equals(type)) {
+- return type;
+- }
+-
+- StringBuffer sb = new StringBuffer();
+- int index = 0;
+- while ((index = type.indexOf("[]", index) + 1) > 0) {
+- sb.append('[');
+- }
+-
+- String t = type.substring(0, type.length() - sb.length() * 2);
+- String desc = DESCRIPTORS.get(t);
+- if (desc != null) {
+- sb.append(desc);
+- } else {
+- sb.append('L');
+- if (t.indexOf('.') < 0) {
+- if (!defaultPackage) {
+- sb.append("java/lang/");
+- }
+- sb.append(t);
+- } else {
+- sb.append(t.replace('.', '/'));
+- }
+- sb.append(';');
+- }
+- return sb.toString();
+- }
+-
+- /**
+- * Returns the name of the method described by this object.
+- *
+- * @return the name of the method described by this object.
+- */
+- public String getName() {
+- return name;
+- }
+-
+- /**
+- * Returns the descriptor of the method described by this object.
+- *
+- * @return the descriptor of the method described by this object.
+- */
+- public String getDescriptor() {
+- return desc;
+- }
+-
+- /**
+- * Returns the return type of the method described by this object.
+- *
+- * @return the return type of the method described by this object.
+- */
+- public Type getReturnType() {
+- return Type.getReturnType(desc);
+- }
+-
+- /**
+- * Returns the argument types of the method described by this object.
+- *
+- * @return the argument types of the method described by this object.
+- */
+- public Type[] getArgumentTypes() {
+- return Type.getArgumentTypes(desc);
+- }
+-
+- @Override
+- public String toString() {
+- return name + desc;
+- }
+-
+- @Override
+- public boolean equals(final Object o) {
+- if (!(o instanceof Method)) {
+- return false;
+- }
+- Method other = (Method) o;
+- return name.equals(other.name) && desc.equals(other.desc);
+- }
+-
+- @Override
+- public int hashCode() {
+- return name.hashCode() ^ desc.hashCode();
+- }
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/package.html mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/package.html
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/package.html 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/package.html 1970-01-01 01:00:00.000000000 +0100
+@@ -1,48 +0,0 @@
+-
+-
+-
+-Provides some useful class and method adapters. The preferred way of using
+-these adapters is by chaining them together and to custom adapters (instead of
+-inheriting from them) . 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).
+-
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/Remapper.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/Remapper.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/Remapper.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/Remapper.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,223 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.signature.SignatureReader;
+-import org.mvel2.asm.signature.SignatureVisitor;
+-import org.mvel2.asm.signature.SignatureWriter;
+-
+-/**
+- * A class responsible for remapping types and names. Subclasses can override
+- * the following methods:
+- *
+- *
+- * {@link #map(String)} - map type
+- * {@link #mapFieldName(String, String, String)} - map field name
+- * {@link #mapMethodName(String, String, String)} - map method name
+- *
+- *
+- * @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;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingAnnotationAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingAnnotationAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingAnnotationAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingAnnotationAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,79 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.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));
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingClassAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingClassAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingClassAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingClassAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,135 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.ClassVisitor;
+-import org.mvel2.asm.FieldVisitor;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.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);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingFieldAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingFieldAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingFieldAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingFieldAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,71 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.FieldVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.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);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingMethodAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingMethodAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingMethodAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingMethodAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,224 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.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);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingSignatureAdapter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingSignatureAdapter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/RemappingSignatureAdapter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/RemappingSignatureAdapter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,155 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.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();
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/SerialVersionUIDAdder.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/SerialVersionUIDAdder.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/SerialVersionUIDAdder.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/SerialVersionUIDAdder.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,540 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.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.mvel2.asm.ClassVisitor;
+-import org.mvel2.asm.FieldVisitor;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A {@link ClassVisitor} that adds a serial version unique identifier to a
+- * class if missing. Here is typical usage of this class:
+- *
+- *
+- * ClassWriter cw = new ClassWriter(...);
+- * ClassVisitor sv = new SerialVersionUIDAdder(cw);
+- * ClassVisitor ca = new MyClassAdapter(sv);
+- * new ClassReader(orginalClass).accept(ca, false);
+- *
+- *
+- * The SVUID algorithm can be found http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html :
+- *
+- *
+- * The serialVersionUID is computed using the signature of a stream of bytes
+- * that reflect the class definition. The National Institute of Standards and
+- * Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a
+- * signature for the stream. The first two 32-bit quantities are used to form a
+- * 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data
+- * types to a sequence of bytes. The values input to the stream are defined by
+- * the Java Virtual Machine (VM) specification for classes.
+- *
+- * The sequence of items in the stream is as follows:
+- *
+- * 1. The class name written using UTF encoding.
+- * 2. The class modifiers written as a 32-bit integer.
+- * 3. The name of each interface sorted by name written using UTF encoding.
+- * 4. For each field of the class sorted by field name (except private static
+- * and private transient fields):
+- * 1. The name of the field in UTF encoding.
+- * 2. The modifiers of the field written as a 32-bit integer.
+- * 3. The descriptor of the field in UTF encoding
+- * 5. If a class initializer exists, write out the following:
+- * 1. The name of the method, <clinit>, in UTF encoding.
+- * 2. The modifier of the method, java.lang.reflect.Modifier.STATIC,
+- * written as a 32-bit integer.
+- * 3. The descriptor of the method, ()V, in UTF encoding.
+- * 6. For each non-private constructor sorted by method name and signature:
+- * 1. The name of the method, <init>, in UTF encoding.
+- * 2. The modifiers of the method written as a 32-bit integer.
+- * 3. The descriptor of the method in UTF encoding.
+- * 7. For each non-private method sorted by method name and signature:
+- * 1. The name of the method in UTF encoding.
+- * 2. The modifiers of the method written as a 32-bit integer.
+- * 3. The descriptor of the method in UTF encoding.
+- * 8. The SHA-1 algorithm is executed on the stream of bytes produced by
+- * DataOutputStream and produces five 32-bit values sha[0..4].
+- *
+- * 9. The hash value is assembled from the first and second 32-bit values of
+- * the SHA-1 message digest. If the result of the message digest, the five
+- * 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named
+- * sha, the hash value would be computed as follows:
+- *
+- * long hash = ((sha[0] >>> 24) & 0xFF) |
+- * ((sha[0] >>> 16) & 0xFF) << 8 |
+- * ((sha[0] >>> 8) & 0xFF) << 16 |
+- * ((sha[0] >>> 0) & 0xFF) << 24 |
+- * ((sha[1] >>> 24) & 0xFF) << 32 |
+- * ((sha[1] >>> 16) & 0xFF) << 40 |
+- * ((sha[1] >>> 8) & 0xFF) << 48 |
+- * ((sha[1] >>> 0) & 0xFF) << 56;
+- *
+- *
+- * @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- svuidFields;
+-
+- /**
+- * Set to true if the class has static initializer.
+- */
+- private boolean hasStaticInitializer;
+-
+- /**
+- * Collection of non-private constructors.
+- */
+- private Collection
- svuidConstructors;
+-
+- /**
+- * Collection of non-private methods.
+- */
+- private Collection
- svuidMethods;
+-
+- /**
+- * Creates a new {@link SerialVersionUIDAdder}.
Subclasses must not use
+- * this constructor . 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- ();
+- svuidConstructors = new ArrayList
- ();
+- svuidMethods = new ArrayList
- ();
+- }
+-
+- // ------------------------------------------------------------------------
+- // 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 ("
".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 ("".equals(name)) {
+- svuidConstructors.add(new Item(name, mods, desc));
+- } else if (!"".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, , 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("");
+- 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, , 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 DataOutputStream
value
+- * @param dotted
+- * a boolean
value
+- * @exception IOException
+- * if an error occurs
+- */
+- private static void writeItems(final Collection- 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
- {
+-
+- final String name;
+-
+- final int access;
+-
+- final String desc;
+-
+- Item(final String name, final int access, final String desc) {
+- this.name = name;
+- this.access = access;
+- this.desc = desc;
+- }
+-
+- public int compareTo(final Item other) {
+- int retVal = name.compareTo(other.name);
+- if (retVal == 0) {
+- retVal = desc.compareTo(other.desc);
+- }
+- return retVal;
+- }
+-
+- @Override
+- public boolean equals(final Object o) {
+- if (o instanceof Item) {
+- return compareTo((Item) o) == 0;
+- }
+- return false;
+- }
+-
+- @Override
+- public int hashCode() {
+- return (name + desc).hashCode();
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/SimpleRemapper.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/SimpleRemapper.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/SimpleRemapper.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/SimpleRemapper.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,69 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.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
mapping;
+-
+- public SimpleRemapper(Map 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);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/StaticInitMerger.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/StaticInitMerger.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/StaticInitMerger.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/StaticInitMerger.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,97 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.ClassVisitor;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.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 ("".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();
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/TableSwitchGenerator.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/TableSwitchGenerator.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/TableSwitchGenerator.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/TableSwitchGenerator.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,57 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.commons;
+-
+-import org.mvel2.asm.Label;
+-
+-/**
+- * A code generator for switch statements.
+- *
+- * @author Juozas Baliuka
+- * @author Chris Nokleberg
+- * @author Eric Bruneton
+- */
+-public interface TableSwitchGenerator {
+-
+- /**
+- * Generates the code for a switch case.
+- *
+- * @param key
+- * the switch case key.
+- * @param end
+- * a label that corresponds to the end of the switch statement.
+- */
+- void generateCase(int key, Label end);
+-
+- /**
+- * Generates the code for the default switch case.
+- */
+- void generateDefault();
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/TryCatchBlockSorter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/TryCatchBlockSorter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/commons/TryCatchBlockSorter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/commons/TryCatchBlockSorter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,96 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.commons;
+-
+-import java.util.Collections;
+-import java.util.Comparator;
+-
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.tree.MethodNode;
+-import org.mvel2.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 comp = new Comparator() {
+-
+- 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);
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Context.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Context.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Context.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Context.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,145 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm;
+-
+-/**
+- * Information about a class being parsed in a {@link ClassReader}.
+- *
+- * @author Eric Bruneton
+- */
+-class Context {
+-
+- /**
+- * Prototypes of the attributes that must be parsed for this class.
+- */
+- Attribute[] attrs;
+-
+- /**
+- * The {@link ClassReader} option flags for the parsing of this class.
+- */
+- int flags;
+-
+- /**
+- * The buffer used to read strings.
+- */
+- char[] buffer;
+-
+- /**
+- * The start index of each bootstrap method.
+- */
+- int[] bootstrapMethods;
+-
+- /**
+- * The access flags of the method currently being parsed.
+- */
+- int access;
+-
+- /**
+- * The name of the method currently being parsed.
+- */
+- String name;
+-
+- /**
+- * The descriptor of the method currently being parsed.
+- */
+- String desc;
+-
+- /**
+- * The label objects, indexed by bytecode offset, of the method currently
+- * being parsed (only bytecode offsets for which a label is needed have a
+- * non null associated Label object).
+- */
+- Label[] labels;
+-
+- /**
+- * The target of the type annotation currently being parsed.
+- */
+- int typeRef;
+-
+- /**
+- * The path of the type annotation currently being parsed.
+- */
+- TypePath typePath;
+-
+- /**
+- * The offset of the latest stack map frame that has been parsed.
+- */
+- int offset;
+-
+- /**
+- * The labels corresponding to the start of the local variable ranges in the
+- * local variable type annotation currently being parsed.
+- */
+- Label[] start;
+-
+- /**
+- * The labels corresponding to the end of the local variable ranges in the
+- * local variable type annotation currently being parsed.
+- */
+- Label[] end;
+-
+- /**
+- * The local variable indices for each local variable range in the local
+- * variable type annotation currently being parsed.
+- */
+- int[] index;
+-
+- /**
+- * The encoding of the latest stack map frame that has been parsed.
+- */
+- int mode;
+-
+- /**
+- * The number of locals in the latest stack map frame that has been parsed.
+- */
+- int localCount;
+-
+- /**
+- * The number locals in the latest stack map frame that has been parsed,
+- * minus the number of locals in the previous frame.
+- */
+- int localDiff;
+-
+- /**
+- * The local values of the latest stack map frame that has been parsed.
+- */
+- Object[] local;
+-
+- /**
+- * The stack size of the latest stack map frame that has been parsed.
+- */
+- int stackCount;
+-
+- /**
+- * The stack values of the latest stack map frame that has been parsed.
+- */
+- Object[] stack;
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Edge.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Edge.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Edge.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Edge.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,75 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * An edge in the control flow graph of a method body. See {@link Label Label}.
+- *
+- * @author Eric Bruneton
+- */
+-class Edge {
+-
+- /**
+- * Denotes a normal control flow graph edge.
+- */
+- static final int NORMAL = 0;
+-
+- /**
+- * Denotes a control flow graph edge corresponding to an exception handler.
+- * More precisely any {@link Edge} whose {@link #info} is strictly positive
+- * corresponds to an exception handler. The actual value of {@link #info} is
+- * the index, in the {@link ClassWriter} type table, of the exception that
+- * is catched.
+- */
+- static final int EXCEPTION = 0x7FFFFFFF;
+-
+- /**
+- * Information about this control flow graph edge. If
+- * {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative)
+- * stack size in the basic block from which this edge originates. This size
+- * is equal to the stack size at the "jump" instruction to which this edge
+- * corresponds, relatively to the stack size at the beginning of the
+- * originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used,
+- * this field is the kind of this control flow graph edge (i.e. NORMAL or
+- * EXCEPTION).
+- */
+- int info;
+-
+- /**
+- * The successor block of the basic block from which this edge originates.
+- */
+- Label successor;
+-
+- /**
+- * The next edge in the list of successors of the originating basic block.
+- * See {@link Label#successors successors}.
+- */
+- Edge next;
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/FieldVisitor.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/FieldVisitor.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/FieldVisitor.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/FieldVisitor.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,150 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A visitor to visit a Java field. The methods of this class must be called in
+- * the following order: ( visitAnnotation |
+- * visitTypeAnnotation | visitAttribute )* visitEnd .
+- *
+- * @author Eric Bruneton
+- */
+-public abstract class FieldVisitor {
+-
+- /**
+- * The ASM API version implemented by this visitor. The value of this field
+- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- protected final int api;
+-
+- /**
+- * The field visitor to which this visitor must delegate method calls. May
+- * be null.
+- */
+- protected FieldVisitor fv;
+-
+- /**
+- * Constructs a new {@link FieldVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- public FieldVisitor(final int api) {
+- this(api, null);
+- }
+-
+- /**
+- * Constructs a new {@link FieldVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param fv
+- * the field visitor to which this visitor must delegate method
+- * calls. May be null.
+- */
+- public FieldVisitor(final int api, final FieldVisitor fv) {
+- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+- throw new IllegalArgumentException();
+- }
+- this.api = api;
+- this.fv = fv;
+- }
+-
+- /**
+- * Visits an annotation of the field.
+- *
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+- if (fv != null) {
+- return fv.visitAnnotation(desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits an annotation on the type of the field.
+- *
+- * @param typeRef
+- * a reference to the annotated type. The sort of this type
+- * reference must be {@link TypeReference#FIELD FIELD}. See
+- * {@link TypeReference}.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitTypeAnnotation(int typeRef,
+- TypePath typePath, String desc, boolean visible) {
+- if (api < Opcodes.ASM5) {
+- throw new RuntimeException();
+- }
+- if (fv != null) {
+- return fv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits a non standard attribute of the field.
+- *
+- * @param attr
+- * an attribute.
+- */
+- public void visitAttribute(Attribute attr) {
+- if (fv != null) {
+- fv.visitAttribute(attr);
+- }
+- }
+-
+- /**
+- * Visits the end of the field. This method, which is the last one to be
+- * called, is used to inform the visitor that all the annotations and
+- * attributes of the field have been visited.
+- */
+- public void visitEnd() {
+- if (fv != null) {
+- fv.visitEnd();
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/FieldWriter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/FieldWriter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/FieldWriter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/FieldWriter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,329 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * An {@link FieldVisitor} that generates Java fields in bytecode form.
+- *
+- * @author Eric Bruneton
+- */
+-final class FieldWriter extends FieldVisitor {
+-
+- /**
+- * The class writer to which this field must be added.
+- */
+- private final ClassWriter cw;
+-
+- /**
+- * Access flags of this field.
+- */
+- private final int access;
+-
+- /**
+- * The index of the constant pool item that contains the name of this
+- * method.
+- */
+- private final int name;
+-
+- /**
+- * The index of the constant pool item that contains the descriptor of this
+- * field.
+- */
+- private final int desc;
+-
+- /**
+- * The index of the constant pool item that contains the signature of this
+- * field.
+- */
+- private int signature;
+-
+- /**
+- * The index of the constant pool item that contains the constant value of
+- * this field.
+- */
+- private int value;
+-
+- /**
+- * The runtime visible annotations of this field. May be null .
+- */
+- private AnnotationWriter anns;
+-
+- /**
+- * The runtime invisible annotations of this field. May be null .
+- */
+- private AnnotationWriter ianns;
+-
+- /**
+- * The runtime visible type annotations of this field. May be null .
+- */
+- private AnnotationWriter tanns;
+-
+- /**
+- * The runtime invisible type annotations of this field. May be
+- * null .
+- */
+- private AnnotationWriter itanns;
+-
+- /**
+- * The non standard attributes of this field. May be null .
+- */
+- private Attribute attrs;
+-
+- // ------------------------------------------------------------------------
+- // Constructor
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Constructs a new {@link FieldWriter}.
+- *
+- * @param cw
+- * the class writer to which this field must be added.
+- * @param access
+- * the field's access flags (see {@link Opcodes}).
+- * @param name
+- * the field's name.
+- * @param desc
+- * the field's descriptor (see {@link Type}).
+- * @param signature
+- * the field's signature. May be null .
+- * @param value
+- * the field's constant value. May be null .
+- */
+- FieldWriter(final ClassWriter cw, final int access, final String name,
+- final String desc, final String signature, final Object value) {
+- super(Opcodes.ASM5);
+- if (cw.firstField == null) {
+- cw.firstField = this;
+- } else {
+- cw.lastField.fv = this;
+- }
+- cw.lastField = this;
+- this.cw = cw;
+- this.access = access;
+- this.name = cw.newUTF8(name);
+- this.desc = cw.newUTF8(desc);
+- if (ClassReader.SIGNATURES && signature != null) {
+- this.signature = cw.newUTF8(signature);
+- }
+- if (value != null) {
+- this.value = cw.newConstItem(value).index;
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Implementation of the FieldVisitor abstract class
+- // ------------------------------------------------------------------------
+-
+- @Override
+- public AnnotationVisitor visitAnnotation(final String desc,
+- final boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write type, and reserve space for values count
+- bv.putShort(cw.newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
+- if (visible) {
+- aw.next = anns;
+- anns = aw;
+- } else {
+- aw.next = ianns;
+- ianns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+- final TypePath typePath, final String desc, final boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write target_type and target_info
+- AnnotationWriter.putTarget(typeRef, typePath, bv);
+- // write type, and reserve space for values count
+- bv.putShort(cw.newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+- bv.length - 2);
+- if (visible) {
+- aw.next = tanns;
+- tanns = aw;
+- } else {
+- aw.next = itanns;
+- itanns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public void visitAttribute(final Attribute attr) {
+- attr.next = attrs;
+- attrs = attr;
+- }
+-
+- @Override
+- public void visitEnd() {
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns the size of this field.
+- *
+- * @return the size of this field.
+- */
+- int getSize() {
+- int size = 8;
+- if (value != 0) {
+- cw.newUTF8("ConstantValue");
+- size += 8;
+- }
+- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+- if ((cw.version & 0xFFFF) < Opcodes.V1_5
+- || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+- cw.newUTF8("Synthetic");
+- size += 6;
+- }
+- }
+- if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+- cw.newUTF8("Deprecated");
+- size += 6;
+- }
+- if (ClassReader.SIGNATURES && signature != 0) {
+- cw.newUTF8("Signature");
+- size += 8;
+- }
+- if (ClassReader.ANNOTATIONS && anns != null) {
+- cw.newUTF8("RuntimeVisibleAnnotations");
+- size += 8 + anns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && ianns != null) {
+- cw.newUTF8("RuntimeInvisibleAnnotations");
+- size += 8 + ianns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && tanns != null) {
+- cw.newUTF8("RuntimeVisibleTypeAnnotations");
+- size += 8 + tanns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && itanns != null) {
+- cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+- size += 8 + itanns.getSize();
+- }
+- if (attrs != null) {
+- size += attrs.getSize(cw, null, 0, -1, -1);
+- }
+- return size;
+- }
+-
+- /**
+- * Puts the content of this field into the given byte vector.
+- *
+- * @param out
+- * where the content of this field must be put.
+- */
+- void put(final ByteVector out) {
+- final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+- int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+- | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
+- out.putShort(access & ~mask).putShort(name).putShort(desc);
+- int attributeCount = 0;
+- if (value != 0) {
+- ++attributeCount;
+- }
+- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+- if ((cw.version & 0xFFFF) < Opcodes.V1_5
+- || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+- ++attributeCount;
+- }
+- }
+- if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+- ++attributeCount;
+- }
+- if (ClassReader.SIGNATURES && signature != 0) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && anns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && ianns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && tanns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && itanns != null) {
+- ++attributeCount;
+- }
+- if (attrs != null) {
+- attributeCount += attrs.getCount();
+- }
+- out.putShort(attributeCount);
+- if (value != 0) {
+- out.putShort(cw.newUTF8("ConstantValue"));
+- out.putInt(2).putShort(value);
+- }
+- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+- if ((cw.version & 0xFFFF) < Opcodes.V1_5
+- || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+- out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+- }
+- }
+- if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+- out.putShort(cw.newUTF8("Deprecated")).putInt(0);
+- }
+- if (ClassReader.SIGNATURES && signature != 0) {
+- out.putShort(cw.newUTF8("Signature"));
+- out.putInt(2).putShort(signature);
+- }
+- if (ClassReader.ANNOTATIONS && anns != null) {
+- out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
+- anns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && ianns != null) {
+- out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
+- ianns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && tanns != null) {
+- out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+- tanns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && itanns != null) {
+- out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+- itanns.put(out);
+- }
+- if (attrs != null) {
+- attrs.put(cw, null, 0, -1, -1, out);
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Frame.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Frame.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Frame.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Frame.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,1458 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * Information about the input and output stack map frames of a basic block.
+- *
+- * @author Eric Bruneton
+- */
+-final class Frame {
+-
+- /*
+- * Frames are computed in a two steps process: during the visit of each
+- * instruction, the state of the frame at the end of current basic block is
+- * updated by simulating the action of the instruction on the previous state
+- * of this so called "output frame". In visitMaxs, a fix point algorithm is
+- * used to compute the "input frame" of each basic block, i.e. the stack map
+- * frame at the beginning of the basic block, starting from the input frame
+- * of the first basic block (which is computed from the method descriptor),
+- * and by using the previously computed output frames to compute the input
+- * state of the other blocks.
+- *
+- * All output and input frames are stored as arrays of integers. Reference
+- * and array types are represented by an index into a type table (which is
+- * not the same as the constant pool of the class, in order to avoid adding
+- * unnecessary constants in the pool - not all computed frames will end up
+- * being stored in the stack map table). This allows very fast type
+- * comparisons.
+- *
+- * Output stack map frames are computed relatively to the input frame of the
+- * basic block, which is not yet known when output frames are computed. It
+- * is therefore necessary to be able to represent abstract types such as
+- * "the type at position x in the input frame locals" or "the type at
+- * position x from the top of the input frame stack" or even "the type at
+- * position x in the input frame, with y more (or less) array dimensions".
+- * This explains the rather complicated type format used in output frames.
+- *
+- * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a
+- * signed number of array dimensions (from -8 to 7). KIND is either BASE,
+- * LOCAL or STACK. BASE is used for types that are not relative to the input
+- * frame. LOCAL is used for types that are relative to the input local
+- * variable types. STACK is used for types that are relative to the input
+- * stack types. VALUE depends on KIND. For LOCAL types, it is an index in
+- * the input local variable types. For STACK types, it is a position
+- * relatively to the top of input frame stack. For BASE types, it is either
+- * one of the constants defined below, or for OBJECT and UNINITIALIZED
+- * types, a tag and an index in the type table.
+- *
+- * Output frames can contain types of any kind and with a positive or
+- * negative dimension (and even unassigned types, represented by 0 - which
+- * does not correspond to any valid type value). Input frames can only
+- * contain BASE types of positive or null dimension. In all cases the type
+- * table contains only internal type names (array type descriptors are
+- * forbidden - dimensions must be represented through the DIM field).
+- *
+- * The LONG and DOUBLE types are always represented by using two slots (LONG
+- * + TOP or DOUBLE + TOP), for local variable types as well as in the
+- * operand stack. This is necessary to be able to simulate DUPx_y
+- * instructions, whose effect would be dependent on the actual type values
+- * if types were always represented by a single slot in the stack (and this
+- * is not possible, since actual type values are not always known - cf LOCAL
+- * and STACK type kinds).
+- */
+-
+- /**
+- * Mask to get the dimension of a frame type. This dimension is a signed
+- * integer between -8 and 7.
+- */
+- static final int DIM = 0xF0000000;
+-
+- /**
+- * Constant to be added to a type to get a type with one more dimension.
+- */
+- static final int ARRAY_OF = 0x10000000;
+-
+- /**
+- * Constant to be added to a type to get a type with one less dimension.
+- */
+- static final int ELEMENT_OF = 0xF0000000;
+-
+- /**
+- * Mask to get the kind of a frame type.
+- *
+- * @see #BASE
+- * @see #LOCAL
+- * @see #STACK
+- */
+- static final int KIND = 0xF000000;
+-
+- /**
+- * Flag used for LOCAL and STACK types. Indicates that if this type happens
+- * to be a long or double type (during the computations of input frames),
+- * then it must be set to TOP because the second word of this value has been
+- * reused to store other data in the basic block. Hence the first word no
+- * longer stores a valid long or double value.
+- */
+- static final int TOP_IF_LONG_OR_DOUBLE = 0x800000;
+-
+- /**
+- * Mask to get the value of a frame type.
+- */
+- static final int VALUE = 0x7FFFFF;
+-
+- /**
+- * Mask to get the kind of base types.
+- */
+- static final int BASE_KIND = 0xFF00000;
+-
+- /**
+- * Mask to get the value of base types.
+- */
+- static final int BASE_VALUE = 0xFFFFF;
+-
+- /**
+- * Kind of the types that are not relative to an input stack map frame.
+- */
+- static final int BASE = 0x1000000;
+-
+- /**
+- * Base kind of the base reference types. The BASE_VALUE of such types is an
+- * index into the type table.
+- */
+- static final int OBJECT = BASE | 0x700000;
+-
+- /**
+- * Base kind of the uninitialized base types. The BASE_VALUE of such types
+- * in an index into the type table (the Item at that index contains both an
+- * instruction offset and an internal class name).
+- */
+- static final int UNINITIALIZED = BASE | 0x800000;
+-
+- /**
+- * Kind of the types that are relative to the local variable types of an
+- * input stack map frame. The value of such types is a local variable index.
+- */
+- private static final int LOCAL = 0x2000000;
+-
+- /**
+- * Kind of the the types that are relative to the stack of an input stack
+- * map frame. The value of such types is a position relatively to the top of
+- * this stack.
+- */
+- private static final int STACK = 0x3000000;
+-
+- /**
+- * The TOP type. This is a BASE type.
+- */
+- static final int TOP = BASE | 0;
+-
+- /**
+- * The BOOLEAN type. This is a BASE type mainly used for array types.
+- */
+- static final int BOOLEAN = BASE | 9;
+-
+- /**
+- * The BYTE type. This is a BASE type mainly used for array types.
+- */
+- static final int BYTE = BASE | 10;
+-
+- /**
+- * The CHAR type. This is a BASE type mainly used for array types.
+- */
+- static final int CHAR = BASE | 11;
+-
+- /**
+- * The SHORT type. This is a BASE type mainly used for array types.
+- */
+- static final int SHORT = BASE | 12;
+-
+- /**
+- * The INTEGER type. This is a BASE type.
+- */
+- static final int INTEGER = BASE | 1;
+-
+- /**
+- * The FLOAT type. This is a BASE type.
+- */
+- static final int FLOAT = BASE | 2;
+-
+- /**
+- * The DOUBLE type. This is a BASE type.
+- */
+- static final int DOUBLE = BASE | 3;
+-
+- /**
+- * The LONG type. This is a BASE type.
+- */
+- static final int LONG = BASE | 4;
+-
+- /**
+- * The NULL type. This is a BASE type.
+- */
+- static final int NULL = BASE | 5;
+-
+- /**
+- * The UNINITIALIZED_THIS type. This is a BASE type.
+- */
+- static final int UNINITIALIZED_THIS = BASE | 6;
+-
+- /**
+- * The stack size variation corresponding to each JVM instruction. This
+- * stack variation is equal to the size of the values produced by an
+- * instruction, minus the size of the values consumed by this instruction.
+- */
+- static final int[] SIZE;
+-
+- /**
+- * Computes the stack size variation corresponding to each JVM instruction.
+- */
+- static {
+- int i;
+- int[] b = new int[202];
+- String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDD"
+- + "CDCDEEEEEEEEEEEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCD"
+- + "CDCEEEEDDDDDDDCDCDCEFEFDDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFED"
+- + "DDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE";
+- for (i = 0; i < b.length; ++i) {
+- b[i] = s.charAt(i) - 'E';
+- }
+- SIZE = b;
+-
+- // code to generate the above string
+- //
+- // int NA = 0; // not applicable (unused opcode or variable size opcode)
+- //
+- // b = new int[] {
+- // 0, //NOP, // visitInsn
+- // 1, //ACONST_NULL, // -
+- // 1, //ICONST_M1, // -
+- // 1, //ICONST_0, // -
+- // 1, //ICONST_1, // -
+- // 1, //ICONST_2, // -
+- // 1, //ICONST_3, // -
+- // 1, //ICONST_4, // -
+- // 1, //ICONST_5, // -
+- // 2, //LCONST_0, // -
+- // 2, //LCONST_1, // -
+- // 1, //FCONST_0, // -
+- // 1, //FCONST_1, // -
+- // 1, //FCONST_2, // -
+- // 2, //DCONST_0, // -
+- // 2, //DCONST_1, // -
+- // 1, //BIPUSH, // visitIntInsn
+- // 1, //SIPUSH, // -
+- // 1, //LDC, // visitLdcInsn
+- // NA, //LDC_W, // -
+- // NA, //LDC2_W, // -
+- // 1, //ILOAD, // visitVarInsn
+- // 2, //LLOAD, // -
+- // 1, //FLOAD, // -
+- // 2, //DLOAD, // -
+- // 1, //ALOAD, // -
+- // NA, //ILOAD_0, // -
+- // NA, //ILOAD_1, // -
+- // NA, //ILOAD_2, // -
+- // NA, //ILOAD_3, // -
+- // NA, //LLOAD_0, // -
+- // NA, //LLOAD_1, // -
+- // NA, //LLOAD_2, // -
+- // NA, //LLOAD_3, // -
+- // NA, //FLOAD_0, // -
+- // NA, //FLOAD_1, // -
+- // NA, //FLOAD_2, // -
+- // NA, //FLOAD_3, // -
+- // NA, //DLOAD_0, // -
+- // NA, //DLOAD_1, // -
+- // NA, //DLOAD_2, // -
+- // NA, //DLOAD_3, // -
+- // NA, //ALOAD_0, // -
+- // NA, //ALOAD_1, // -
+- // NA, //ALOAD_2, // -
+- // NA, //ALOAD_3, // -
+- // -1, //IALOAD, // visitInsn
+- // 0, //LALOAD, // -
+- // -1, //FALOAD, // -
+- // 0, //DALOAD, // -
+- // -1, //AALOAD, // -
+- // -1, //BALOAD, // -
+- // -1, //CALOAD, // -
+- // -1, //SALOAD, // -
+- // -1, //ISTORE, // visitVarInsn
+- // -2, //LSTORE, // -
+- // -1, //FSTORE, // -
+- // -2, //DSTORE, // -
+- // -1, //ASTORE, // -
+- // NA, //ISTORE_0, // -
+- // NA, //ISTORE_1, // -
+- // NA, //ISTORE_2, // -
+- // NA, //ISTORE_3, // -
+- // NA, //LSTORE_0, // -
+- // NA, //LSTORE_1, // -
+- // NA, //LSTORE_2, // -
+- // NA, //LSTORE_3, // -
+- // NA, //FSTORE_0, // -
+- // NA, //FSTORE_1, // -
+- // NA, //FSTORE_2, // -
+- // NA, //FSTORE_3, // -
+- // NA, //DSTORE_0, // -
+- // NA, //DSTORE_1, // -
+- // NA, //DSTORE_2, // -
+- // NA, //DSTORE_3, // -
+- // NA, //ASTORE_0, // -
+- // NA, //ASTORE_1, // -
+- // NA, //ASTORE_2, // -
+- // NA, //ASTORE_3, // -
+- // -3, //IASTORE, // visitInsn
+- // -4, //LASTORE, // -
+- // -3, //FASTORE, // -
+- // -4, //DASTORE, // -
+- // -3, //AASTORE, // -
+- // -3, //BASTORE, // -
+- // -3, //CASTORE, // -
+- // -3, //SASTORE, // -
+- // -1, //POP, // -
+- // -2, //POP2, // -
+- // 1, //DUP, // -
+- // 1, //DUP_X1, // -
+- // 1, //DUP_X2, // -
+- // 2, //DUP2, // -
+- // 2, //DUP2_X1, // -
+- // 2, //DUP2_X2, // -
+- // 0, //SWAP, // -
+- // -1, //IADD, // -
+- // -2, //LADD, // -
+- // -1, //FADD, // -
+- // -2, //DADD, // -
+- // -1, //ISUB, // -
+- // -2, //LSUB, // -
+- // -1, //FSUB, // -
+- // -2, //DSUB, // -
+- // -1, //IMUL, // -
+- // -2, //LMUL, // -
+- // -1, //FMUL, // -
+- // -2, //DMUL, // -
+- // -1, //IDIV, // -
+- // -2, //LDIV, // -
+- // -1, //FDIV, // -
+- // -2, //DDIV, // -
+- // -1, //IREM, // -
+- // -2, //LREM, // -
+- // -1, //FREM, // -
+- // -2, //DREM, // -
+- // 0, //INEG, // -
+- // 0, //LNEG, // -
+- // 0, //FNEG, // -
+- // 0, //DNEG, // -
+- // -1, //ISHL, // -
+- // -1, //LSHL, // -
+- // -1, //ISHR, // -
+- // -1, //LSHR, // -
+- // -1, //IUSHR, // -
+- // -1, //LUSHR, // -
+- // -1, //IAND, // -
+- // -2, //LAND, // -
+- // -1, //IOR, // -
+- // -2, //LOR, // -
+- // -1, //IXOR, // -
+- // -2, //LXOR, // -
+- // 0, //IINC, // visitIincInsn
+- // 1, //I2L, // visitInsn
+- // 0, //I2F, // -
+- // 1, //I2D, // -
+- // -1, //L2I, // -
+- // -1, //L2F, // -
+- // 0, //L2D, // -
+- // 0, //F2I, // -
+- // 1, //F2L, // -
+- // 1, //F2D, // -
+- // -1, //D2I, // -
+- // 0, //D2L, // -
+- // -1, //D2F, // -
+- // 0, //I2B, // -
+- // 0, //I2C, // -
+- // 0, //I2S, // -
+- // -3, //LCMP, // -
+- // -1, //FCMPL, // -
+- // -1, //FCMPG, // -
+- // -3, //DCMPL, // -
+- // -3, //DCMPG, // -
+- // -1, //IFEQ, // visitJumpInsn
+- // -1, //IFNE, // -
+- // -1, //IFLT, // -
+- // -1, //IFGE, // -
+- // -1, //IFGT, // -
+- // -1, //IFLE, // -
+- // -2, //IF_ICMPEQ, // -
+- // -2, //IF_ICMPNE, // -
+- // -2, //IF_ICMPLT, // -
+- // -2, //IF_ICMPGE, // -
+- // -2, //IF_ICMPGT, // -
+- // -2, //IF_ICMPLE, // -
+- // -2, //IF_ACMPEQ, // -
+- // -2, //IF_ACMPNE, // -
+- // 0, //GOTO, // -
+- // 1, //JSR, // -
+- // 0, //RET, // visitVarInsn
+- // -1, //TABLESWITCH, // visiTableSwitchInsn
+- // -1, //LOOKUPSWITCH, // visitLookupSwitch
+- // -1, //IRETURN, // visitInsn
+- // -2, //LRETURN, // -
+- // -1, //FRETURN, // -
+- // -2, //DRETURN, // -
+- // -1, //ARETURN, // -
+- // 0, //RETURN, // -
+- // NA, //GETSTATIC, // visitFieldInsn
+- // NA, //PUTSTATIC, // -
+- // NA, //GETFIELD, // -
+- // NA, //PUTFIELD, // -
+- // NA, //INVOKEVIRTUAL, // visitMethodInsn
+- // NA, //INVOKESPECIAL, // -
+- // NA, //INVOKESTATIC, // -
+- // NA, //INVOKEINTERFACE, // -
+- // NA, //INVOKEDYNAMIC, // visitInvokeDynamicInsn
+- // 1, //NEW, // visitTypeInsn
+- // 0, //NEWARRAY, // visitIntInsn
+- // 0, //ANEWARRAY, // visitTypeInsn
+- // 0, //ARRAYLENGTH, // visitInsn
+- // NA, //ATHROW, // -
+- // 0, //CHECKCAST, // visitTypeInsn
+- // 0, //INSTANCEOF, // -
+- // -1, //MONITORENTER, // visitInsn
+- // -1, //MONITOREXIT, // -
+- // NA, //WIDE, // NOT VISITED
+- // NA, //MULTIANEWARRAY, // visitMultiANewArrayInsn
+- // -1, //IFNULL, // visitJumpInsn
+- // -1, //IFNONNULL, // -
+- // NA, //GOTO_W, // -
+- // NA, //JSR_W, // -
+- // };
+- // for (i = 0; i < b.length; ++i) {
+- // System.err.print((char)('E' + b[i]));
+- // }
+- // System.err.println();
+- }
+-
+- /**
+- * The label (i.e. basic block) to which these input and output stack map
+- * frames correspond.
+- */
+- Label owner;
+-
+- /**
+- * The input stack map frame locals.
+- */
+- int[] inputLocals;
+-
+- /**
+- * The input stack map frame stack.
+- */
+- int[] inputStack;
+-
+- /**
+- * The output stack map frame locals.
+- */
+- private int[] outputLocals;
+-
+- /**
+- * The output stack map frame stack.
+- */
+- private int[] outputStack;
+-
+- /**
+- * Relative size of the output stack. The exact semantics of this field
+- * depends on the algorithm that is used.
+- *
+- * When only the maximum stack size is computed, this field is the size of
+- * the output stack relatively to the top of the input stack.
+- *
+- * When the stack map frames are completely computed, this field is the
+- * actual number of types in {@link #outputStack}.
+- */
+- private int outputStackTop;
+-
+- /**
+- * Number of types that are initialized in the basic block.
+- *
+- * @see #initializations
+- */
+- private int initializationCount;
+-
+- /**
+- * The types that are initialized in the basic block. A constructor
+- * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
+- * every occurence of this type in the local variables and in the
+- * operand stack. This cannot be done during the first phase of the
+- * algorithm since, during this phase, the local variables and the operand
+- * stack are not completely computed. It is therefore necessary to store the
+- * types on which constructors are invoked in the basic block, in order to
+- * do this replacement during the second phase of the algorithm, where the
+- * frames are fully computed. Note that this array can contain types that
+- * are relative to input locals or to the input stack (see below for the
+- * description of the algorithm).
+- */
+- private int[] initializations;
+-
+- /**
+- * Returns the output frame local variable type at the given index.
+- *
+- * @param local
+- * the index of the local that must be returned.
+- * @return the output frame local variable type at the given index.
+- */
+- private int get(final int local) {
+- if (outputLocals == null || local >= outputLocals.length) {
+- // this local has never been assigned in this basic block,
+- // so it is still equal to its value in the input frame
+- return LOCAL | local;
+- } else {
+- int type = outputLocals[local];
+- if (type == 0) {
+- // this local has never been assigned in this basic block,
+- // so it is still equal to its value in the input frame
+- type = outputLocals[local] = LOCAL | local;
+- }
+- return type;
+- }
+- }
+-
+- /**
+- * Sets the output frame local variable type at the given index.
+- *
+- * @param local
+- * the index of the local that must be set.
+- * @param type
+- * the value of the local that must be set.
+- */
+- private void set(final int local, final int type) {
+- // creates and/or resizes the output local variables array if necessary
+- if (outputLocals == null) {
+- outputLocals = new int[10];
+- }
+- int n = outputLocals.length;
+- if (local >= n) {
+- int[] t = new int[Math.max(local + 1, 2 * n)];
+- System.arraycopy(outputLocals, 0, t, 0, n);
+- outputLocals = t;
+- }
+- // sets the local variable
+- outputLocals[local] = type;
+- }
+-
+- /**
+- * Pushes a new type onto the output frame stack.
+- *
+- * @param type
+- * the type that must be pushed.
+- */
+- private void push(final int type) {
+- // creates and/or resizes the output stack array if necessary
+- if (outputStack == null) {
+- outputStack = new int[10];
+- }
+- int n = outputStack.length;
+- if (outputStackTop >= n) {
+- int[] t = new int[Math.max(outputStackTop + 1, 2 * n)];
+- System.arraycopy(outputStack, 0, t, 0, n);
+- outputStack = t;
+- }
+- // pushes the type on the output stack
+- outputStack[outputStackTop++] = type;
+- // updates the maximun height reached by the output stack, if needed
+- int top = owner.inputStackTop + outputStackTop;
+- if (top > owner.outputStackMax) {
+- owner.outputStackMax = top;
+- }
+- }
+-
+- /**
+- * Pushes a new type onto the output frame stack.
+- *
+- * @param cw
+- * the ClassWriter to which this label belongs.
+- * @param desc
+- * the descriptor of the type to be pushed. Can also be a method
+- * descriptor (in this case this method pushes its return type
+- * onto the output frame stack).
+- */
+- private void push(final ClassWriter cw, final String desc) {
+- int type = type(cw, desc);
+- if (type != 0) {
+- push(type);
+- if (type == LONG || type == DOUBLE) {
+- push(TOP);
+- }
+- }
+- }
+-
+- /**
+- * Returns the int encoding of the given type.
+- *
+- * @param cw
+- * the ClassWriter to which this label belongs.
+- * @param desc
+- * a type descriptor.
+- * @return the int encoding of the given type.
+- */
+- private static int type(final ClassWriter cw, final String desc) {
+- String t;
+- int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
+- switch (desc.charAt(index)) {
+- case 'V':
+- return 0;
+- case 'Z':
+- case 'C':
+- case 'B':
+- case 'S':
+- case 'I':
+- return INTEGER;
+- case 'F':
+- return FLOAT;
+- case 'J':
+- return LONG;
+- case 'D':
+- return DOUBLE;
+- case 'L':
+- // stores the internal name, not the descriptor!
+- t = desc.substring(index + 1, desc.length() - 1);
+- return OBJECT | cw.addType(t);
+- // case '[':
+- default:
+- // extracts the dimensions and the element type
+- int data;
+- int dims = index + 1;
+- while (desc.charAt(dims) == '[') {
+- ++dims;
+- }
+- switch (desc.charAt(dims)) {
+- case 'Z':
+- data = BOOLEAN;
+- break;
+- case 'C':
+- data = CHAR;
+- break;
+- case 'B':
+- data = BYTE;
+- break;
+- case 'S':
+- data = SHORT;
+- break;
+- case 'I':
+- data = INTEGER;
+- break;
+- case 'F':
+- data = FLOAT;
+- break;
+- case 'J':
+- data = LONG;
+- break;
+- case 'D':
+- data = DOUBLE;
+- break;
+- // case 'L':
+- default:
+- // stores the internal name, not the descriptor
+- t = desc.substring(dims + 1, desc.length() - 1);
+- data = OBJECT | cw.addType(t);
+- }
+- return (dims - index) << 28 | data;
+- }
+- }
+-
+- /**
+- * Pops a type from the output frame stack and returns its value.
+- *
+- * @return the type that has been popped from the output frame stack.
+- */
+- private int pop() {
+- if (outputStackTop > 0) {
+- return outputStack[--outputStackTop];
+- } else {
+- // if the output frame stack is empty, pops from the input stack
+- return STACK | -(--owner.inputStackTop);
+- }
+- }
+-
+- /**
+- * Pops the given number of types from the output frame stack.
+- *
+- * @param elements
+- * the number of types that must be popped.
+- */
+- private void pop(final int elements) {
+- if (outputStackTop >= elements) {
+- outputStackTop -= elements;
+- } else {
+- // if the number of elements to be popped is greater than the number
+- // of elements in the output stack, clear it, and pops the remaining
+- // elements from the input stack.
+- owner.inputStackTop -= elements - outputStackTop;
+- outputStackTop = 0;
+- }
+- }
+-
+- /**
+- * Pops a type from the output frame stack.
+- *
+- * @param desc
+- * the descriptor of the type to be popped. Can also be a method
+- * descriptor (in this case this method pops the types
+- * corresponding to the method arguments).
+- */
+- private void pop(final String desc) {
+- char c = desc.charAt(0);
+- if (c == '(') {
+- pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1);
+- } else if (c == 'J' || c == 'D') {
+- pop(2);
+- } else {
+- pop(1);
+- }
+- }
+-
+- /**
+- * Adds a new type to the list of types on which a constructor is invoked in
+- * the basic block.
+- *
+- * @param var
+- * a type on a which a constructor is invoked.
+- */
+- private void init(final int var) {
+- // creates and/or resizes the initializations array if necessary
+- if (initializations == null) {
+- initializations = new int[2];
+- }
+- int n = initializations.length;
+- if (initializationCount >= n) {
+- int[] t = new int[Math.max(initializationCount + 1, 2 * n)];
+- System.arraycopy(initializations, 0, t, 0, n);
+- initializations = t;
+- }
+- // stores the type to be initialized
+- initializations[initializationCount++] = var;
+- }
+-
+- /**
+- * Replaces the given type with the appropriate type if it is one of the
+- * types on which a constructor is invoked in the basic block.
+- *
+- * @param cw
+- * the ClassWriter to which this label belongs.
+- * @param t
+- * a type
+- * @return t or, if t is one of the types on which a constructor is invoked
+- * in the basic block, the type corresponding to this constructor.
+- */
+- private int init(final ClassWriter cw, final int t) {
+- int s;
+- if (t == UNINITIALIZED_THIS) {
+- s = OBJECT | cw.addType(cw.thisName);
+- } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) {
+- String type = cw.typeTable[t & BASE_VALUE].strVal1;
+- s = OBJECT | cw.addType(type);
+- } else {
+- return t;
+- }
+- for (int j = 0; j < initializationCount; ++j) {
+- int u = initializations[j];
+- int dim = u & DIM;
+- int kind = u & KIND;
+- if (kind == LOCAL) {
+- u = dim + inputLocals[u & VALUE];
+- } else if (kind == STACK) {
+- u = dim + inputStack[inputStack.length - (u & VALUE)];
+- }
+- if (t == u) {
+- return s;
+- }
+- }
+- return t;
+- }
+-
+- /**
+- * Initializes the input frame of the first basic block from the method
+- * descriptor.
+- *
+- * @param cw
+- * the ClassWriter to which this label belongs.
+- * @param access
+- * the access flags of the method to which this label belongs.
+- * @param args
+- * the formal parameter types of this method.
+- * @param maxLocals
+- * the maximum number of local variables of this method.
+- */
+- void initInputFrame(final ClassWriter cw, final int access,
+- final Type[] args, final int maxLocals) {
+- inputLocals = new int[maxLocals];
+- inputStack = new int[0];
+- int i = 0;
+- if ((access & Opcodes.ACC_STATIC) == 0) {
+- if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) {
+- inputLocals[i++] = OBJECT | cw.addType(cw.thisName);
+- } else {
+- inputLocals[i++] = UNINITIALIZED_THIS;
+- }
+- }
+- for (int j = 0; j < args.length; ++j) {
+- int t = type(cw, args[j].getDescriptor());
+- inputLocals[i++] = t;
+- if (t == LONG || t == DOUBLE) {
+- inputLocals[i++] = TOP;
+- }
+- }
+- while (i < maxLocals) {
+- inputLocals[i++] = TOP;
+- }
+- }
+-
+- /**
+- * Simulates the action of the given instruction on the output stack frame.
+- *
+- * @param opcode
+- * the opcode of the instruction.
+- * @param arg
+- * the operand of the instruction, if any.
+- * @param cw
+- * the class writer to which this label belongs.
+- * @param item
+- * the operand of the instructions, if any.
+- */
+- void execute(final int opcode, final int arg, final ClassWriter cw,
+- final Item item) {
+- int t1, t2, t3, t4;
+- switch (opcode) {
+- case Opcodes.NOP:
+- case Opcodes.INEG:
+- case Opcodes.LNEG:
+- case Opcodes.FNEG:
+- case Opcodes.DNEG:
+- case Opcodes.I2B:
+- case Opcodes.I2C:
+- case Opcodes.I2S:
+- case Opcodes.GOTO:
+- case Opcodes.RETURN:
+- break;
+- case Opcodes.ACONST_NULL:
+- push(NULL);
+- break;
+- case Opcodes.ICONST_M1:
+- case Opcodes.ICONST_0:
+- case Opcodes.ICONST_1:
+- case Opcodes.ICONST_2:
+- case Opcodes.ICONST_3:
+- case Opcodes.ICONST_4:
+- case Opcodes.ICONST_5:
+- case Opcodes.BIPUSH:
+- case Opcodes.SIPUSH:
+- case Opcodes.ILOAD:
+- push(INTEGER);
+- break;
+- case Opcodes.LCONST_0:
+- case Opcodes.LCONST_1:
+- case Opcodes.LLOAD:
+- push(LONG);
+- push(TOP);
+- break;
+- case Opcodes.FCONST_0:
+- case Opcodes.FCONST_1:
+- case Opcodes.FCONST_2:
+- case Opcodes.FLOAD:
+- push(FLOAT);
+- break;
+- case Opcodes.DCONST_0:
+- case Opcodes.DCONST_1:
+- case Opcodes.DLOAD:
+- push(DOUBLE);
+- push(TOP);
+- break;
+- case Opcodes.LDC:
+- switch (item.type) {
+- case ClassWriter.INT:
+- push(INTEGER);
+- break;
+- case ClassWriter.LONG:
+- push(LONG);
+- push(TOP);
+- break;
+- case ClassWriter.FLOAT:
+- push(FLOAT);
+- break;
+- case ClassWriter.DOUBLE:
+- push(DOUBLE);
+- push(TOP);
+- break;
+- case ClassWriter.CLASS:
+- push(OBJECT | cw.addType("java/lang/Class"));
+- break;
+- case ClassWriter.STR:
+- push(OBJECT | cw.addType("java/lang/String"));
+- break;
+- case ClassWriter.MTYPE:
+- push(OBJECT | cw.addType("java/lang/invoke/MethodType"));
+- break;
+- // case ClassWriter.HANDLE_BASE + [1..9]:
+- default:
+- push(OBJECT | cw.addType("java/lang/invoke/MethodHandle"));
+- }
+- break;
+- case Opcodes.ALOAD:
+- push(get(arg));
+- break;
+- case Opcodes.IALOAD:
+- case Opcodes.BALOAD:
+- case Opcodes.CALOAD:
+- case Opcodes.SALOAD:
+- pop(2);
+- push(INTEGER);
+- break;
+- case Opcodes.LALOAD:
+- case Opcodes.D2L:
+- pop(2);
+- push(LONG);
+- push(TOP);
+- break;
+- case Opcodes.FALOAD:
+- pop(2);
+- push(FLOAT);
+- break;
+- case Opcodes.DALOAD:
+- case Opcodes.L2D:
+- pop(2);
+- push(DOUBLE);
+- push(TOP);
+- break;
+- case Opcodes.AALOAD:
+- pop(1);
+- t1 = pop();
+- push(ELEMENT_OF + t1);
+- break;
+- case Opcodes.ISTORE:
+- case Opcodes.FSTORE:
+- case Opcodes.ASTORE:
+- t1 = pop();
+- set(arg, t1);
+- if (arg > 0) {
+- t2 = get(arg - 1);
+- // if t2 is of kind STACK or LOCAL we cannot know its size!
+- if (t2 == LONG || t2 == DOUBLE) {
+- set(arg - 1, TOP);
+- } else if ((t2 & KIND) != BASE) {
+- set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
+- }
+- }
+- break;
+- case Opcodes.LSTORE:
+- case Opcodes.DSTORE:
+- pop(1);
+- t1 = pop();
+- set(arg, t1);
+- set(arg + 1, TOP);
+- if (arg > 0) {
+- t2 = get(arg - 1);
+- // if t2 is of kind STACK or LOCAL we cannot know its size!
+- if (t2 == LONG || t2 == DOUBLE) {
+- set(arg - 1, TOP);
+- } else if ((t2 & KIND) != BASE) {
+- set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE);
+- }
+- }
+- break;
+- case Opcodes.IASTORE:
+- case Opcodes.BASTORE:
+- case Opcodes.CASTORE:
+- case Opcodes.SASTORE:
+- case Opcodes.FASTORE:
+- case Opcodes.AASTORE:
+- pop(3);
+- break;
+- case Opcodes.LASTORE:
+- case Opcodes.DASTORE:
+- pop(4);
+- break;
+- case Opcodes.POP:
+- case Opcodes.IFEQ:
+- case Opcodes.IFNE:
+- case Opcodes.IFLT:
+- case Opcodes.IFGE:
+- case Opcodes.IFGT:
+- case Opcodes.IFLE:
+- case Opcodes.IRETURN:
+- case Opcodes.FRETURN:
+- case Opcodes.ARETURN:
+- case Opcodes.TABLESWITCH:
+- case Opcodes.LOOKUPSWITCH:
+- case Opcodes.ATHROW:
+- case Opcodes.MONITORENTER:
+- case Opcodes.MONITOREXIT:
+- case Opcodes.IFNULL:
+- case Opcodes.IFNONNULL:
+- pop(1);
+- break;
+- case Opcodes.POP2:
+- case Opcodes.IF_ICMPEQ:
+- case Opcodes.IF_ICMPNE:
+- case Opcodes.IF_ICMPLT:
+- case Opcodes.IF_ICMPGE:
+- case Opcodes.IF_ICMPGT:
+- case Opcodes.IF_ICMPLE:
+- case Opcodes.IF_ACMPEQ:
+- case Opcodes.IF_ACMPNE:
+- case Opcodes.LRETURN:
+- case Opcodes.DRETURN:
+- pop(2);
+- break;
+- case Opcodes.DUP:
+- t1 = pop();
+- push(t1);
+- push(t1);
+- break;
+- case Opcodes.DUP_X1:
+- t1 = pop();
+- t2 = pop();
+- push(t1);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.DUP_X2:
+- t1 = pop();
+- t2 = pop();
+- t3 = pop();
+- push(t1);
+- push(t3);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.DUP2:
+- t1 = pop();
+- t2 = pop();
+- push(t2);
+- push(t1);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.DUP2_X1:
+- t1 = pop();
+- t2 = pop();
+- t3 = pop();
+- push(t2);
+- push(t1);
+- push(t3);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.DUP2_X2:
+- t1 = pop();
+- t2 = pop();
+- t3 = pop();
+- t4 = pop();
+- push(t2);
+- push(t1);
+- push(t4);
+- push(t3);
+- push(t2);
+- push(t1);
+- break;
+- case Opcodes.SWAP:
+- t1 = pop();
+- t2 = pop();
+- push(t1);
+- push(t2);
+- break;
+- case Opcodes.IADD:
+- case Opcodes.ISUB:
+- case Opcodes.IMUL:
+- case Opcodes.IDIV:
+- case Opcodes.IREM:
+- case Opcodes.IAND:
+- case Opcodes.IOR:
+- case Opcodes.IXOR:
+- case Opcodes.ISHL:
+- case Opcodes.ISHR:
+- case Opcodes.IUSHR:
+- case Opcodes.L2I:
+- case Opcodes.D2I:
+- case Opcodes.FCMPL:
+- case Opcodes.FCMPG:
+- pop(2);
+- push(INTEGER);
+- break;
+- case Opcodes.LADD:
+- case Opcodes.LSUB:
+- case Opcodes.LMUL:
+- case Opcodes.LDIV:
+- case Opcodes.LREM:
+- case Opcodes.LAND:
+- case Opcodes.LOR:
+- case Opcodes.LXOR:
+- pop(4);
+- push(LONG);
+- push(TOP);
+- break;
+- case Opcodes.FADD:
+- case Opcodes.FSUB:
+- case Opcodes.FMUL:
+- case Opcodes.FDIV:
+- case Opcodes.FREM:
+- case Opcodes.L2F:
+- case Opcodes.D2F:
+- pop(2);
+- push(FLOAT);
+- break;
+- case Opcodes.DADD:
+- case Opcodes.DSUB:
+- case Opcodes.DMUL:
+- case Opcodes.DDIV:
+- case Opcodes.DREM:
+- pop(4);
+- push(DOUBLE);
+- push(TOP);
+- break;
+- case Opcodes.LSHL:
+- case Opcodes.LSHR:
+- case Opcodes.LUSHR:
+- pop(3);
+- push(LONG);
+- push(TOP);
+- break;
+- case Opcodes.IINC:
+- set(arg, INTEGER);
+- break;
+- case Opcodes.I2L:
+- case Opcodes.F2L:
+- pop(1);
+- push(LONG);
+- push(TOP);
+- break;
+- case Opcodes.I2F:
+- pop(1);
+- push(FLOAT);
+- break;
+- case Opcodes.I2D:
+- case Opcodes.F2D:
+- pop(1);
+- push(DOUBLE);
+- push(TOP);
+- break;
+- case Opcodes.F2I:
+- case Opcodes.ARRAYLENGTH:
+- case Opcodes.INSTANCEOF:
+- pop(1);
+- push(INTEGER);
+- break;
+- case Opcodes.LCMP:
+- case Opcodes.DCMPL:
+- case Opcodes.DCMPG:
+- pop(4);
+- push(INTEGER);
+- break;
+- case Opcodes.JSR:
+- case Opcodes.RET:
+- throw new RuntimeException(
+- "JSR/RET are not supported with computeFrames option");
+- case Opcodes.GETSTATIC:
+- push(cw, item.strVal3);
+- break;
+- case Opcodes.PUTSTATIC:
+- pop(item.strVal3);
+- break;
+- case Opcodes.GETFIELD:
+- pop(1);
+- push(cw, item.strVal3);
+- break;
+- case Opcodes.PUTFIELD:
+- pop(item.strVal3);
+- pop();
+- break;
+- case Opcodes.INVOKEVIRTUAL:
+- case Opcodes.INVOKESPECIAL:
+- case Opcodes.INVOKESTATIC:
+- case Opcodes.INVOKEINTERFACE:
+- pop(item.strVal3);
+- if (opcode != Opcodes.INVOKESTATIC) {
+- t1 = pop();
+- if (opcode == Opcodes.INVOKESPECIAL
+- && item.strVal2.charAt(0) == '<') {
+- init(t1);
+- }
+- }
+- push(cw, item.strVal3);
+- break;
+- case Opcodes.INVOKEDYNAMIC:
+- pop(item.strVal2);
+- push(cw, item.strVal2);
+- break;
+- case Opcodes.NEW:
+- push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg));
+- break;
+- case Opcodes.NEWARRAY:
+- pop();
+- switch (arg) {
+- case Opcodes.T_BOOLEAN:
+- push(ARRAY_OF | BOOLEAN);
+- break;
+- case Opcodes.T_CHAR:
+- push(ARRAY_OF | CHAR);
+- break;
+- case Opcodes.T_BYTE:
+- push(ARRAY_OF | BYTE);
+- break;
+- case Opcodes.T_SHORT:
+- push(ARRAY_OF | SHORT);
+- break;
+- case Opcodes.T_INT:
+- push(ARRAY_OF | INTEGER);
+- break;
+- case Opcodes.T_FLOAT:
+- push(ARRAY_OF | FLOAT);
+- break;
+- case Opcodes.T_DOUBLE:
+- push(ARRAY_OF | DOUBLE);
+- break;
+- // case Opcodes.T_LONG:
+- default:
+- push(ARRAY_OF | LONG);
+- break;
+- }
+- break;
+- case Opcodes.ANEWARRAY:
+- String s = item.strVal1;
+- pop();
+- if (s.charAt(0) == '[') {
+- push(cw, '[' + s);
+- } else {
+- push(ARRAY_OF | OBJECT | cw.addType(s));
+- }
+- break;
+- case Opcodes.CHECKCAST:
+- s = item.strVal1;
+- pop();
+- if (s.charAt(0) == '[') {
+- push(cw, s);
+- } else {
+- push(OBJECT | cw.addType(s));
+- }
+- break;
+- // case Opcodes.MULTIANEWARRAY:
+- default:
+- pop(arg);
+- push(cw, item.strVal1);
+- break;
+- }
+- }
+-
+- /**
+- * Merges the input frame of the given basic block with the input and output
+- * frames of this basic block. Returns true if the input frame of
+- * the given label has been changed by this operation.
+- *
+- * @param cw
+- * the ClassWriter to which this label belongs.
+- * @param frame
+- * the basic block whose input frame must be updated.
+- * @param edge
+- * the kind of the {@link Edge} between this label and 'label'.
+- * See {@link Edge#info}.
+- * @return true if the input frame of the given label has been
+- * changed by this operation.
+- */
+- boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
+- boolean changed = false;
+- int i, s, dim, kind, t;
+-
+- int nLocal = inputLocals.length;
+- int nStack = inputStack.length;
+- if (frame.inputLocals == null) {
+- frame.inputLocals = new int[nLocal];
+- changed = true;
+- }
+-
+- for (i = 0; i < nLocal; ++i) {
+- if (outputLocals != null && i < outputLocals.length) {
+- s = outputLocals[i];
+- if (s == 0) {
+- t = inputLocals[i];
+- } else {
+- dim = s & DIM;
+- kind = s & KIND;
+- if (kind == BASE) {
+- t = s;
+- } else {
+- if (kind == LOCAL) {
+- t = dim + inputLocals[s & VALUE];
+- } else {
+- t = dim + inputStack[nStack - (s & VALUE)];
+- }
+- if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+- && (t == LONG || t == DOUBLE)) {
+- t = TOP;
+- }
+- }
+- }
+- } else {
+- t = inputLocals[i];
+- }
+- if (initializations != null) {
+- t = init(cw, t);
+- }
+- changed |= merge(cw, t, frame.inputLocals, i);
+- }
+-
+- if (edge > 0) {
+- for (i = 0; i < nLocal; ++i) {
+- t = inputLocals[i];
+- changed |= merge(cw, t, frame.inputLocals, i);
+- }
+- if (frame.inputStack == null) {
+- frame.inputStack = new int[1];
+- changed = true;
+- }
+- changed |= merge(cw, edge, frame.inputStack, 0);
+- return changed;
+- }
+-
+- int nInputStack = inputStack.length + owner.inputStackTop;
+- if (frame.inputStack == null) {
+- frame.inputStack = new int[nInputStack + outputStackTop];
+- changed = true;
+- }
+-
+- for (i = 0; i < nInputStack; ++i) {
+- t = inputStack[i];
+- if (initializations != null) {
+- t = init(cw, t);
+- }
+- changed |= merge(cw, t, frame.inputStack, i);
+- }
+- for (i = 0; i < outputStackTop; ++i) {
+- s = outputStack[i];
+- dim = s & DIM;
+- kind = s & KIND;
+- if (kind == BASE) {
+- t = s;
+- } else {
+- if (kind == LOCAL) {
+- t = dim + inputLocals[s & VALUE];
+- } else {
+- t = dim + inputStack[nStack - (s & VALUE)];
+- }
+- if ((s & TOP_IF_LONG_OR_DOUBLE) != 0
+- && (t == LONG || t == DOUBLE)) {
+- t = TOP;
+- }
+- }
+- if (initializations != null) {
+- t = init(cw, t);
+- }
+- changed |= merge(cw, t, frame.inputStack, nInputStack + i);
+- }
+- return changed;
+- }
+-
+- /**
+- * Merges the type at the given index in the given type array with the given
+- * type. Returns true if the type array has been modified by this
+- * operation.
+- *
+- * @param cw
+- * the ClassWriter to which this label belongs.
+- * @param t
+- * the type with which the type array element must be merged.
+- * @param types
+- * an array of types.
+- * @param index
+- * the index of the type that must be merged in 'types'.
+- * @return true if the type array has been modified by this
+- * operation.
+- */
+- private static boolean merge(final ClassWriter cw, int t,
+- final int[] types, final int index) {
+- int u = types[index];
+- if (u == t) {
+- // if the types are equal, merge(u,t)=u, so there is no change
+- return false;
+- }
+- if ((t & ~DIM) == NULL) {
+- if (u == NULL) {
+- return false;
+- }
+- t = NULL;
+- }
+- if (u == 0) {
+- // if types[index] has never been assigned, merge(u,t)=t
+- types[index] = t;
+- return true;
+- }
+- int v;
+- if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) {
+- // if u is a reference type of any dimension
+- if (t == NULL) {
+- // if t is the NULL type, merge(u,t)=u, so there is no change
+- return false;
+- } else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) {
+- // if t and u have the same dimension and same base kind
+- if ((u & BASE_KIND) == OBJECT) {
+- // if t is also a reference type, and if u and t have the
+- // same dimension merge(u,t) = dim(t) | common parent of the
+- // element types of u and t
+- v = (t & DIM) | OBJECT
+- | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE);
+- } else {
+- // if u and t are array types, but not with the same element
+- // type, merge(u,t)=java/lang/Object
+- v = OBJECT | cw.addType("java/lang/Object");
+- }
+- } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) {
+- // if t is any other reference or array type, the merged type
+- // is Object, or min(dim(u), dim(t)) | java/lang/Object is u
+- // and t have different array dimensions
+- int tdim = t & DIM;
+- int udim = u & DIM;
+- v = (udim != tdim ? Math.min(tdim, udim) : 0) | OBJECT
+- | cw.addType("java/lang/Object");
+- } else {
+- // if t is any other type, merge(u,t)=TOP
+- v = TOP;
+- }
+- } else if (u == NULL) {
+- // if u is the NULL type, merge(u,t)=t,
+- // or TOP if t is not a reference type
+- v = (t & BASE_KIND) == OBJECT || (t & DIM) != 0 ? t : TOP;
+- } else {
+- // if u is any other type, merge(u,t)=TOP whatever t
+- v = TOP;
+- }
+- if (u != v) {
+- types[index] = v;
+- return true;
+- }
+- return false;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Handle.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Handle.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Handle.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Handle.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,170 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm;
+-
+-/**
+- * A reference to a field or a method.
+- *
+- * @author Remi Forax
+- * @author Eric Bruneton
+- */
+-public final class Handle {
+-
+- /**
+- * The kind of field or method designated by this Handle. Should be
+- * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+- * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+- * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
+- * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or
+- * {@link Opcodes#H_INVOKEINTERFACE}.
+- */
+- final int tag;
+-
+- /**
+- * The internal name of the class that owns the field or method designated
+- * by this handle.
+- */
+- final String owner;
+-
+- /**
+- * The name of the field or method designated by this handle.
+- */
+- final String name;
+-
+- /**
+- * The descriptor of the field or method designated by this handle.
+- */
+- final String desc;
+-
+- /**
+- * Constructs a new field or method handle.
+- *
+- * @param tag
+- * the kind of field or method designated by this Handle. Must be
+- * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+- * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+- * {@link Opcodes#H_INVOKEVIRTUAL},
+- * {@link Opcodes#H_INVOKESTATIC},
+- * {@link Opcodes#H_INVOKESPECIAL},
+- * {@link Opcodes#H_NEWINVOKESPECIAL} or
+- * {@link Opcodes#H_INVOKEINTERFACE}.
+- * @param owner
+- * the internal name of the class that owns the field or method
+- * designated by this handle.
+- * @param name
+- * the name of the field or method designated by this handle.
+- * @param desc
+- * the descriptor of the field or method designated by this
+- * handle.
+- */
+- public Handle(int tag, String owner, String name, String desc) {
+- this.tag = tag;
+- this.owner = owner;
+- this.name = name;
+- this.desc = desc;
+- }
+-
+- /**
+- * Returns the kind of field or method designated by this handle.
+- *
+- * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC},
+- * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
+- * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
+- * {@link Opcodes#H_INVOKESPECIAL},
+- * {@link Opcodes#H_NEWINVOKESPECIAL} or
+- * {@link Opcodes#H_INVOKEINTERFACE}.
+- */
+- public int getTag() {
+- return tag;
+- }
+-
+- /**
+- * Returns the internal name of the class that owns the field or method
+- * designated by this handle.
+- *
+- * @return the internal name of the class that owns the field or method
+- * designated by this handle.
+- */
+- public String getOwner() {
+- return owner;
+- }
+-
+- /**
+- * Returns the name of the field or method designated by this handle.
+- *
+- * @return the name of the field or method designated by this handle.
+- */
+- public String getName() {
+- return name;
+- }
+-
+- /**
+- * Returns the descriptor of the field or method designated by this handle.
+- *
+- * @return the descriptor of the field or method designated by this handle.
+- */
+- public String getDesc() {
+- return desc;
+- }
+-
+- @Override
+- public boolean equals(Object obj) {
+- if (obj == this) {
+- return true;
+- }
+- if (!(obj instanceof Handle)) {
+- return false;
+- }
+- Handle h = (Handle) obj;
+- return tag == h.tag && owner.equals(h.owner) && name.equals(h.name)
+- && desc.equals(h.desc);
+- }
+-
+- @Override
+- public int hashCode() {
+- return tag + owner.hashCode() * name.hashCode() * desc.hashCode();
+- }
+-
+- /**
+- * Returns the textual representation of this handle. The textual
+- * representation is:
+- *
+- *
+- * owner '.' name desc ' ' '(' tag ')'
+- *
+- *
+- * . As this format is unambiguous, it can be parsed if necessary.
+- */
+- @Override
+- public String toString() {
+- return owner + '.' + name + desc + " (" + tag + ')';
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Handler.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Handler.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Handler.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Handler.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,121 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * Information about an exception handler block.
+- *
+- * @author Eric Bruneton
+- */
+-class Handler {
+-
+- /**
+- * Beginning of the exception handler's scope (inclusive).
+- */
+- Label start;
+-
+- /**
+- * End of the exception handler's scope (exclusive).
+- */
+- Label end;
+-
+- /**
+- * Beginning of the exception handler's code.
+- */
+- Label handler;
+-
+- /**
+- * Internal name of the type of exceptions handled by this handler, or
+- * null to catch any exceptions.
+- */
+- String desc;
+-
+- /**
+- * Constant pool index of the internal name of the type of exceptions
+- * handled by this handler, or 0 to catch any exceptions.
+- */
+- int type;
+-
+- /**
+- * Next exception handler block info.
+- */
+- Handler next;
+-
+- /**
+- * Removes the range between start and end from the given exception
+- * handlers.
+- *
+- * @param h
+- * an exception handler list.
+- * @param start
+- * the start of the range to be removed.
+- * @param end
+- * the end of the range to be removed. Maybe null.
+- * @return the exception handler list with the start-end range removed.
+- */
+- static Handler remove(Handler h, Label start, Label end) {
+- if (h == null) {
+- return null;
+- } else {
+- h.next = remove(h.next, start, end);
+- }
+- int hstart = h.start.position;
+- int hend = h.end.position;
+- int s = start.position;
+- int e = end == null ? Integer.MAX_VALUE : end.position;
+- // if [hstart,hend[ and [s,e[ intervals intersect...
+- if (s < hend && e > hstart) {
+- if (s <= hstart) {
+- if (e >= hend) {
+- // [hstart,hend[ fully included in [s,e[, h removed
+- h = h.next;
+- } else {
+- // [hstart,hend[ minus [s,e[ = [e,hend[
+- h.start = end;
+- }
+- } else if (e >= hend) {
+- // [hstart,hend[ minus [s,e[ = [hstart,s[
+- h.end = start;
+- } else {
+- // [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[
+- Handler g = new Handler();
+- g.start = end;
+- g.end = h.end;
+- g.handler = h.handler;
+- g.desc = h.desc;
+- g.type = h.type;
+- g.next = h.next;
+- h.end = start;
+- h.next = g;
+- }
+- }
+- return h;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Item.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Item.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Item.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Item.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,311 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A constant pool item. Constant pool items can be created with the 'newXXX'
+- * methods in the {@link ClassWriter} class.
+- *
+- * @author Eric Bruneton
+- */
+-final class Item {
+-
+- /**
+- * Index of this item in the constant pool.
+- */
+- int index;
+-
+- /**
+- * Type of this constant pool item. A single class is used to represent all
+- * constant pool item types, in order to minimize the bytecode size of this
+- * package. The value of this field is one of {@link ClassWriter#INT},
+- * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
+- * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8},
+- * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
+- * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
+- * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+- * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
+- *
+- * MethodHandle constant 9 variations are stored using a range of 9 values
+- * from {@link ClassWriter#HANDLE_BASE} + 1 to
+- * {@link ClassWriter#HANDLE_BASE} + 9.
+- *
+- * Special Item types are used for Items that are stored in the ClassWriter
+- * {@link ClassWriter#typeTable}, instead of the constant pool, in order to
+- * avoid clashes with normal constant pool items in the ClassWriter constant
+- * pool's hash table. These special item types are
+- * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
+- * {@link ClassWriter#TYPE_MERGED}.
+- */
+- int type;
+-
+- /**
+- * Value of this item, for an integer item.
+- */
+- int intVal;
+-
+- /**
+- * Value of this item, for a long item.
+- */
+- long longVal;
+-
+- /**
+- * First part of the value of this item, for items that do not hold a
+- * primitive value.
+- */
+- String strVal1;
+-
+- /**
+- * Second part of the value of this item, for items that do not hold a
+- * primitive value.
+- */
+- String strVal2;
+-
+- /**
+- * Third part of the value of this item, for items that do not hold a
+- * primitive value.
+- */
+- String strVal3;
+-
+- /**
+- * The hash code value of this constant pool item.
+- */
+- int hashCode;
+-
+- /**
+- * Link to another constant pool item, used for collision lists in the
+- * constant pool's hash table.
+- */
+- Item next;
+-
+- /**
+- * Constructs an uninitialized {@link Item}.
+- */
+- Item() {
+- }
+-
+- /**
+- * Constructs an uninitialized {@link Item} for constant pool element at
+- * given position.
+- *
+- * @param index
+- * index of the item to be constructed.
+- */
+- Item(final int index) {
+- this.index = index;
+- }
+-
+- /**
+- * Constructs a copy of the given item.
+- *
+- * @param index
+- * index of the item to be constructed.
+- * @param i
+- * the item that must be copied into the item to be constructed.
+- */
+- Item(final int index, final Item i) {
+- this.index = index;
+- type = i.type;
+- intVal = i.intVal;
+- longVal = i.longVal;
+- strVal1 = i.strVal1;
+- strVal2 = i.strVal2;
+- strVal3 = i.strVal3;
+- hashCode = i.hashCode;
+- }
+-
+- /**
+- * Sets this item to an integer item.
+- *
+- * @param intVal
+- * the value of this item.
+- */
+- void set(final int intVal) {
+- this.type = ClassWriter.INT;
+- this.intVal = intVal;
+- this.hashCode = 0x7FFFFFFF & (type + intVal);
+- }
+-
+- /**
+- * Sets this item to a long item.
+- *
+- * @param longVal
+- * the value of this item.
+- */
+- void set(final long longVal) {
+- this.type = ClassWriter.LONG;
+- this.longVal = longVal;
+- this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
+- }
+-
+- /**
+- * Sets this item to a float item.
+- *
+- * @param floatVal
+- * the value of this item.
+- */
+- void set(final float floatVal) {
+- this.type = ClassWriter.FLOAT;
+- this.intVal = Float.floatToRawIntBits(floatVal);
+- this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
+- }
+-
+- /**
+- * Sets this item to a double item.
+- *
+- * @param doubleVal
+- * the value of this item.
+- */
+- void set(final double doubleVal) {
+- this.type = ClassWriter.DOUBLE;
+- this.longVal = Double.doubleToRawLongBits(doubleVal);
+- this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
+- }
+-
+- /**
+- * Sets this item to an item that do not hold a primitive value.
+- *
+- * @param type
+- * the type of this item.
+- * @param strVal1
+- * first part of the value of this item.
+- * @param strVal2
+- * second part of the value of this item.
+- * @param strVal3
+- * third part of the value of this item.
+- */
+- void set(final int type, final String strVal1, final String strVal2,
+- final String strVal3) {
+- this.type = type;
+- this.strVal1 = strVal1;
+- this.strVal2 = strVal2;
+- this.strVal3 = strVal3;
+- switch (type) {
+- case ClassWriter.UTF8:
+- case ClassWriter.STR:
+- case ClassWriter.CLASS:
+- case ClassWriter.MTYPE:
+- case ClassWriter.TYPE_NORMAL:
+- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
+- return;
+- case ClassWriter.NAME_TYPE: {
+- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+- * strVal2.hashCode());
+- return;
+- }
+- // ClassWriter.FIELD:
+- // ClassWriter.METH:
+- // ClassWriter.IMETH:
+- // ClassWriter.HANDLE_BASE + 1..9
+- default:
+- hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+- * strVal2.hashCode() * strVal3.hashCode());
+- }
+- }
+-
+- /**
+- * Sets the item to an InvokeDynamic item.
+- *
+- * @param name
+- * invokedynamic's name.
+- * @param desc
+- * invokedynamic's desc.
+- * @param bsmIndex
+- * zero based index into the class attribute BootrapMethods.
+- */
+- void set(String name, String desc, int bsmIndex) {
+- this.type = ClassWriter.INDY;
+- this.longVal = bsmIndex;
+- this.strVal1 = name;
+- this.strVal2 = desc;
+- this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex
+- * strVal1.hashCode() * strVal2.hashCode());
+- }
+-
+- /**
+- * Sets the item to a BootstrapMethod item.
+- *
+- * @param position
+- * position in byte in the class attribute BootrapMethods.
+- * @param hashCode
+- * hashcode of the item. This hashcode is processed from the
+- * hashcode of the bootstrap method and the hashcode of all
+- * bootstrap arguments.
+- */
+- void set(int position, int hashCode) {
+- this.type = ClassWriter.BSM;
+- this.intVal = position;
+- this.hashCode = hashCode;
+- }
+-
+- /**
+- * Indicates if the given item is equal to this one. This method assumes
+- * that the two items have the same {@link #type} .
+- *
+- * @param i
+- * the item to be compared to this one. Both items must have the
+- * same {@link #type}.
+- * @return true if the given item if equal to this one,
+- * false otherwise.
+- */
+- boolean isEqualTo(final Item i) {
+- switch (type) {
+- case ClassWriter.UTF8:
+- case ClassWriter.STR:
+- case ClassWriter.CLASS:
+- case ClassWriter.MTYPE:
+- case ClassWriter.TYPE_NORMAL:
+- return i.strVal1.equals(strVal1);
+- case ClassWriter.TYPE_MERGED:
+- case ClassWriter.LONG:
+- case ClassWriter.DOUBLE:
+- return i.longVal == longVal;
+- case ClassWriter.INT:
+- case ClassWriter.FLOAT:
+- return i.intVal == intVal;
+- case ClassWriter.TYPE_UNINIT:
+- return i.intVal == intVal && i.strVal1.equals(strVal1);
+- case ClassWriter.NAME_TYPE:
+- return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
+- case ClassWriter.INDY: {
+- return i.longVal == longVal && i.strVal1.equals(strVal1)
+- && i.strVal2.equals(strVal2);
+- }
+- // case ClassWriter.FIELD:
+- // case ClassWriter.METH:
+- // case ClassWriter.IMETH:
+- // case ClassWriter.HANDLE_BASE + 1..9
+- default:
+- return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
+- && i.strVal3.equals(strVal3);
+- }
+- }
+-
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Label.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Label.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Label.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Label.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,560 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A label represents a position in the bytecode of a method. Labels are used
+- * for jump, goto, and switch instructions, and for try catch blocks. A label
+- * designates the instruction that is just after. Note however that there
+- * can be other elements between a label and the instruction it designates (such
+- * as other labels, stack map frames, line numbers, etc.).
+- *
+- * @author Eric Bruneton
+- */
+-public class Label {
+-
+- /**
+- * Indicates if this label is only used for debug attributes. Such a label
+- * is not the start of a basic block, the target of a jump instruction, or
+- * an exception handler. It can be safely ignored in control flow graph
+- * analysis algorithms (for optimization purposes).
+- */
+- static final int DEBUG = 1;
+-
+- /**
+- * Indicates if the position of this label is known.
+- */
+- static final int RESOLVED = 2;
+-
+- /**
+- * Indicates if this label has been updated, after instruction resizing.
+- */
+- static final int RESIZED = 4;
+-
+- /**
+- * Indicates if this basic block has been pushed in the basic block stack.
+- * See {@link MethodWriter#visitMaxs visitMaxs}.
+- */
+- static final int PUSHED = 8;
+-
+- /**
+- * Indicates if this label is the target of a jump instruction, or the start
+- * of an exception handler.
+- */
+- static final int TARGET = 16;
+-
+- /**
+- * Indicates if a stack map frame must be stored for this label.
+- */
+- static final int STORE = 32;
+-
+- /**
+- * Indicates if this label corresponds to a reachable basic block.
+- */
+- static final int REACHABLE = 64;
+-
+- /**
+- * Indicates if this basic block ends with a JSR instruction.
+- */
+- static final int JSR = 128;
+-
+- /**
+- * Indicates if this basic block ends with a RET instruction.
+- */
+- static final int RET = 256;
+-
+- /**
+- * Indicates if this basic block is the start of a subroutine.
+- */
+- static final int SUBROUTINE = 512;
+-
+- /**
+- * Indicates if this subroutine basic block has been visited by a
+- * visitSubroutine(null, ...) call.
+- */
+- static final int VISITED = 1024;
+-
+- /**
+- * Indicates if this subroutine basic block has been visited by a
+- * visitSubroutine(!null, ...) call.
+- */
+- static final int VISITED2 = 2048;
+-
+- /**
+- * Field used to associate user information to a label. Warning: this field
+- * is used by the ASM tree package. In order to use it with the ASM tree
+- * package you must override the
+- * {@link org.mvel2.asm.tree.MethodNode#getLabelNode} method.
+- */
+- public Object info;
+-
+- /**
+- * Flags that indicate the status of this label.
+- *
+- * @see #DEBUG
+- * @see #RESOLVED
+- * @see #RESIZED
+- * @see #PUSHED
+- * @see #TARGET
+- * @see #STORE
+- * @see #REACHABLE
+- * @see #JSR
+- * @see #RET
+- */
+- int status;
+-
+- /**
+- * The line number corresponding to this label, if known.
+- */
+- int line;
+-
+- /**
+- * The position of this label in the code, if known.
+- */
+- int position;
+-
+- /**
+- * Number of forward references to this label, times two.
+- */
+- private int referenceCount;
+-
+- /**
+- * Informations about forward references. Each forward reference is
+- * described by two consecutive integers in this array: the first one is the
+- * position of the first byte of the bytecode instruction that contains the
+- * forward reference, while the second is the position of the first byte of
+- * the forward reference itself. In fact the sign of the first integer
+- * indicates if this reference uses 2 or 4 bytes, and its absolute value
+- * gives the position of the bytecode instruction. This array is also used
+- * as a bitset to store the subroutines to which a basic block belongs. This
+- * information is needed in {@linked MethodWriter#visitMaxs}, after all
+- * forward references have been resolved. Hence the same array can be used
+- * for both purposes without problems.
+- */
+- private int[] srcAndRefPositions;
+-
+- // ------------------------------------------------------------------------
+-
+- /*
+- * Fields for the control flow and data flow graph analysis algorithms (used
+- * to compute the maximum stack size or the stack map frames). A control
+- * flow graph contains one node per "basic block", and one edge per "jump"
+- * from one basic block to another. Each node (i.e., each basic block) is
+- * represented by the Label object that corresponds to the first instruction
+- * of this basic block. Each node also stores the list of its successors in
+- * the graph, as a linked list of Edge objects.
+- *
+- * The control flow analysis algorithms used to compute the maximum stack
+- * size or the stack map frames are similar and use two steps. The first
+- * step, during the visit of each instruction, builds information about the
+- * state of the local variables and the operand stack at the end of each
+- * basic block, called the "output frame", relatively to the frame
+- * state at the beginning of the basic block, which is called the "input
+- * frame", and which is unknown during this step. The second step, in
+- * {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes
+- * information about the input frame of each basic block, from the input
+- * state of the first basic block (known from the method signature), and by
+- * the using the previously computed relative output frames.
+- *
+- * The algorithm used to compute the maximum stack size only computes the
+- * relative output and absolute input stack heights, while the algorithm
+- * used to compute stack map frames computes relative output frames and
+- * absolute input frames.
+- */
+-
+- /**
+- * Start of the output stack relatively to the input stack. The exact
+- * semantics of this field depends on the algorithm that is used.
+- *
+- * When only the maximum stack size is computed, this field is the number of
+- * elements in the input stack.
+- *
+- * When the stack map frames are completely computed, this field is the
+- * offset of the first output stack element relatively to the top of the
+- * input stack. This offset is always negative or null. A null offset means
+- * that the output stack must be appended to the input stack. A -n offset
+- * means that the first n output stack elements must replace the top n input
+- * stack elements, and that the other elements must be appended to the input
+- * stack.
+- */
+- int inputStackTop;
+-
+- /**
+- * Maximum height reached by the output stack, relatively to the top of the
+- * input stack. This maximum is always positive or null.
+- */
+- int outputStackMax;
+-
+- /**
+- * Information about the input and output stack map frames of this basic
+- * block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES}
+- * option is used.
+- */
+- Frame frame;
+-
+- /**
+- * The successor of this label, in the order they are visited. This linked
+- * list does not include labels used for debug info only. If
+- * {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it
+- * does not contain successive labels that denote the same bytecode position
+- * (in this case only the first label appears in this list).
+- */
+- Label successor;
+-
+- /**
+- * The successors of this node in the control flow graph. These successors
+- * are stored in a linked list of {@link Edge Edge} objects, linked to each
+- * other by their {@link Edge#next} field.
+- */
+- Edge successors;
+-
+- /**
+- * The next basic block in the basic block stack. This stack is used in the
+- * main loop of the fix point algorithm used in the second step of the
+- * control flow analysis algorithms. It is also used in
+- * {@link #visitSubroutine} to avoid using a recursive method.
+- *
+- * @see MethodWriter#visitMaxs
+- */
+- Label next;
+-
+- // ------------------------------------------------------------------------
+- // Constructor
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Constructs a new label.
+- */
+- public Label() {
+- }
+-
+- // ------------------------------------------------------------------------
+- // Methods to compute offsets and to manage forward references
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns the offset corresponding to this label. This offset is computed
+- * from the start of the method's bytecode. This method is intended for
+- * {@link Attribute} sub classes, and is normally not needed by class
+- * generators or adapters.
+- *
+- * @return the offset corresponding to this label.
+- * @throws IllegalStateException
+- * if this label is not resolved yet.
+- */
+- public int getOffset() {
+- if ((status & RESOLVED) == 0) {
+- throw new IllegalStateException(
+- "Label offset position has not been resolved yet");
+- }
+- return position;
+- }
+-
+- /**
+- * Puts a reference to this label in the bytecode of a method. If the
+- * position of the label is known, the offset is computed and written
+- * directly. Otherwise, a null offset is written and a new forward reference
+- * is declared for this label.
+- *
+- * @param owner
+- * the code writer that calls this method.
+- * @param out
+- * the bytecode of the method.
+- * @param source
+- * the position of first byte of the bytecode instruction that
+- * contains this label.
+- * @param wideOffset
+- * true if the reference must be stored in 4 bytes, or
+- * false if it must be stored with 2 bytes.
+- * @throws IllegalArgumentException
+- * if this label has not been created by the given code writer.
+- */
+- void put(final MethodWriter owner, final ByteVector out, final int source,
+- final boolean wideOffset) {
+- if ((status & RESOLVED) == 0) {
+- if (wideOffset) {
+- addReference(-1 - source, out.length);
+- out.putInt(-1);
+- } else {
+- addReference(source, out.length);
+- out.putShort(-1);
+- }
+- } else {
+- if (wideOffset) {
+- out.putInt(position - source);
+- } else {
+- out.putShort(position - source);
+- }
+- }
+- }
+-
+- /**
+- * Adds a forward reference to this label. This method must be called only
+- * for a true forward reference, i.e. only if this label is not resolved
+- * yet. For backward references, the offset of the reference can be, and
+- * must be, computed and stored directly.
+- *
+- * @param sourcePosition
+- * the position of the referencing instruction. This position
+- * will be used to compute the offset of this forward reference.
+- * @param referencePosition
+- * the position where the offset for this forward reference must
+- * be stored.
+- */
+- private void addReference(final int sourcePosition,
+- final int referencePosition) {
+- if (srcAndRefPositions == null) {
+- srcAndRefPositions = new int[6];
+- }
+- if (referenceCount >= srcAndRefPositions.length) {
+- int[] a = new int[srcAndRefPositions.length + 6];
+- System.arraycopy(srcAndRefPositions, 0, a, 0,
+- srcAndRefPositions.length);
+- srcAndRefPositions = a;
+- }
+- srcAndRefPositions[referenceCount++] = sourcePosition;
+- srcAndRefPositions[referenceCount++] = referencePosition;
+- }
+-
+- /**
+- * Resolves all forward references to this label. This method must be called
+- * when this label is added to the bytecode of the method, i.e. when its
+- * position becomes known. This method fills in the blanks that where left
+- * in the bytecode by each forward reference previously added to this label.
+- *
+- * @param owner
+- * the code writer that calls this method.
+- * @param position
+- * the position of this label in the bytecode.
+- * @param data
+- * the bytecode of the method.
+- * @return true if a blank that was left for this label was to
+- * small to store the offset. In such a case the corresponding jump
+- * instruction is replaced with a pseudo instruction (using unused
+- * opcodes) using an unsigned two bytes offset. These pseudo
+- * instructions will need to be replaced with true instructions with
+- * wider offsets (4 bytes instead of 2). This is done in
+- * {@link MethodWriter#resizeInstructions}.
+- * @throws IllegalArgumentException
+- * if this label has already been resolved, or if it has not
+- * been created by the given code writer.
+- */
+- boolean resolve(final MethodWriter owner, final int position,
+- final byte[] data) {
+- boolean needUpdate = false;
+- this.status |= RESOLVED;
+- this.position = position;
+- int i = 0;
+- while (i < referenceCount) {
+- int source = srcAndRefPositions[i++];
+- int reference = srcAndRefPositions[i++];
+- int offset;
+- if (source >= 0) {
+- offset = position - source;
+- if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) {
+- /*
+- * changes the opcode of the jump instruction, in order to
+- * be able to find it later (see resizeInstructions in
+- * MethodWriter). These temporary opcodes are similar to
+- * jump instruction opcodes, except that the 2 bytes offset
+- * is unsigned (and can therefore represent values from 0 to
+- * 65535, which is sufficient since the size of a method is
+- * limited to 65535 bytes).
+- */
+- int opcode = data[reference - 1] & 0xFF;
+- if (opcode <= Opcodes.JSR) {
+- // changes IFEQ ... JSR to opcodes 202 to 217
+- data[reference - 1] = (byte) (opcode + 49);
+- } else {
+- // changes IFNULL and IFNONNULL to opcodes 218 and 219
+- data[reference - 1] = (byte) (opcode + 20);
+- }
+- needUpdate = true;
+- }
+- data[reference++] = (byte) (offset >>> 8);
+- data[reference] = (byte) offset;
+- } else {
+- offset = position + source + 1;
+- data[reference++] = (byte) (offset >>> 24);
+- data[reference++] = (byte) (offset >>> 16);
+- data[reference++] = (byte) (offset >>> 8);
+- data[reference] = (byte) offset;
+- }
+- }
+- return needUpdate;
+- }
+-
+- /**
+- * Returns the first label of the series to which this label belongs. For an
+- * isolated label or for the first label in a series of successive labels,
+- * this method returns the label itself. For other labels it returns the
+- * first label of the series.
+- *
+- * @return the first label of the series to which this label belongs.
+- */
+- Label getFirst() {
+- return !ClassReader.FRAMES || frame == null ? this : frame.owner;
+- }
+-
+- // ------------------------------------------------------------------------
+- // Methods related to subroutines
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns true is this basic block belongs to the given subroutine.
+- *
+- * @param id
+- * a subroutine id.
+- * @return true is this basic block belongs to the given subroutine.
+- */
+- boolean inSubroutine(final long id) {
+- if ((status & Label.VISITED) != 0) {
+- return (srcAndRefPositions[(int) (id >>> 32)] & (int) id) != 0;
+- }
+- return false;
+- }
+-
+- /**
+- * Returns true if this basic block and the given one belong to a common
+- * subroutine.
+- *
+- * @param block
+- * another basic block.
+- * @return true if this basic block and the given one belong to a common
+- * subroutine.
+- */
+- boolean inSameSubroutine(final Label block) {
+- if ((status & VISITED) == 0 || (block.status & VISITED) == 0) {
+- return false;
+- }
+- for (int i = 0; i < srcAndRefPositions.length; ++i) {
+- if ((srcAndRefPositions[i] & block.srcAndRefPositions[i]) != 0) {
+- return true;
+- }
+- }
+- return false;
+- }
+-
+- /**
+- * Marks this basic block as belonging to the given subroutine.
+- *
+- * @param id
+- * a subroutine id.
+- * @param nbSubroutines
+- * the total number of subroutines in the method.
+- */
+- void addToSubroutine(final long id, final int nbSubroutines) {
+- if ((status & VISITED) == 0) {
+- status |= VISITED;
+- srcAndRefPositions = new int[(nbSubroutines - 1) / 32 + 1];
+- }
+- srcAndRefPositions[(int) (id >>> 32)] |= (int) id;
+- }
+-
+- /**
+- * Finds the basic blocks that belong to a given subroutine, and marks these
+- * blocks as belonging to this subroutine. This method follows the control
+- * flow graph to find all the blocks that are reachable from the current
+- * block WITHOUT following any JSR target.
+- *
+- * @param JSR
+- * a JSR block that jumps to this subroutine. If this JSR is not
+- * null it is added to the successor of the RET blocks found in
+- * the subroutine.
+- * @param id
+- * the id of this subroutine.
+- * @param nbSubroutines
+- * the total number of subroutines in the method.
+- */
+- void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) {
+- // user managed stack of labels, to avoid using a recursive method
+- // (recursivity can lead to stack overflow with very large methods)
+- Label stack = this;
+- while (stack != null) {
+- // removes a label l from the stack
+- Label l = stack;
+- stack = l.next;
+- l.next = null;
+-
+- if (JSR != null) {
+- if ((l.status & VISITED2) != 0) {
+- continue;
+- }
+- l.status |= VISITED2;
+- // adds JSR to the successors of l, if it is a RET block
+- if ((l.status & RET) != 0) {
+- if (!l.inSameSubroutine(JSR)) {
+- Edge e = new Edge();
+- e.info = l.inputStackTop;
+- e.successor = JSR.successors.successor;
+- e.next = l.successors;
+- l.successors = e;
+- }
+- }
+- } else {
+- // if the l block already belongs to subroutine 'id', continue
+- if (l.inSubroutine(id)) {
+- continue;
+- }
+- // marks the l block as belonging to subroutine 'id'
+- l.addToSubroutine(id, nbSubroutines);
+- }
+- // pushes each successor of l on the stack, except JSR targets
+- Edge e = l.successors;
+- while (e != null) {
+- // if the l block is a JSR block, then 'l.successors.next' leads
+- // to the JSR target (see {@link #visitJumpInsn}) and must
+- // therefore not be followed
+- if ((l.status & Label.JSR) == 0 || e != l.successors.next) {
+- // pushes e.successor on the stack if it not already added
+- if (e.successor.next == null) {
+- e.successor.next = stack;
+- stack = e.successor;
+- }
+- }
+- e = e.next;
+- }
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Overriden Object methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns a string representation of this label.
+- *
+- * @return a string representation of this label.
+- */
+- @Override
+- public String toString() {
+- return "L" + System.identityHashCode(this);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/MethodVisitor.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/MethodVisitor.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/MethodVisitor.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/MethodVisitor.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,880 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A visitor to visit a Java method. The methods of this class must be called in
+- * the following order: ( visitParameter )* [
+- * visitAnnotationDefault ] ( visitAnnotation |
+- * visitTypeAnnotation | visitAttribute )* [
+- * visitCode ( visitFrame | visitX Insn |
+- * visitLabel | visitInsnAnnotation |
+- * visitTryCatchBlock | visitTryCatchBlockAnnotation |
+- * visitLocalVariable | visitLocalVariableAnnotation |
+- * visitLineNumber )* visitMaxs ] visitEnd . In
+- * addition, the visitX Insn and visitLabel methods must
+- * be called in the sequential order of the bytecode instructions of the visited
+- * code, visitInsnAnnotation must be called after the annotated
+- * instruction, visitTryCatchBlock must be called before the
+- * labels passed as arguments have been visited,
+- * visitTryCatchBlockAnnotation must be called after the
+- * corresponding try catch block has been visited, and the
+- * visitLocalVariable , visitLocalVariableAnnotation and
+- * visitLineNumber methods must be called after the labels
+- * passed as arguments have been visited.
+- *
+- * @author Eric Bruneton
+- */
+-public abstract class MethodVisitor {
+-
+- /**
+- * The ASM API version implemented by this visitor. The value of this field
+- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- protected final int api;
+-
+- /**
+- * The method visitor to which this visitor must delegate method calls. May
+- * be null.
+- */
+- protected MethodVisitor mv;
+-
+- /**
+- * Constructs a new {@link MethodVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- public MethodVisitor(final int api) {
+- this(api, null);
+- }
+-
+- /**
+- * Constructs a new {@link MethodVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param mv
+- * the method visitor to which this visitor must delegate method
+- * calls. May be null.
+- */
+- public MethodVisitor(final int api, final MethodVisitor mv) {
+- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+- throw new IllegalArgumentException();
+- }
+- this.api = api;
+- this.mv = mv;
+- }
+-
+- // -------------------------------------------------------------------------
+- // Parameters, annotations and non standard attributes
+- // -------------------------------------------------------------------------
+-
+- /**
+- * Visits a parameter of this method.
+- *
+- * @param name
+- * parameter name or null if none is provided.
+- * @param access
+- * the parameter's access flags, only ACC_FINAL ,
+- * ACC_SYNTHETIC or/and ACC_MANDATED are
+- * allowed (see {@link Opcodes}).
+- */
+- public void visitParameter(String name, int access) {
+- if (api < Opcodes.ASM5) {
+- throw new RuntimeException();
+- }
+- if (mv != null) {
+- mv.visitParameter(name, access);
+- }
+- }
+-
+- /**
+- * Visits the default value of this annotation interface method.
+- *
+- * @return a visitor to the visit the actual default value of this
+- * annotation interface method, or null if this visitor is
+- * not interested in visiting this default value. The 'name'
+- * parameters passed to the methods of this annotation visitor are
+- * ignored. Moreover, exacly one visit method must be called on this
+- * annotation visitor, followed by visitEnd.
+- */
+- public AnnotationVisitor visitAnnotationDefault() {
+- if (mv != null) {
+- return mv.visitAnnotationDefault();
+- }
+- return null;
+- }
+-
+- /**
+- * Visits an annotation of this method.
+- *
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+- if (mv != null) {
+- return mv.visitAnnotation(desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits an annotation on a type in the method signature.
+- *
+- * @param typeRef
+- * a reference to the annotated type. The sort of this type
+- * reference must be {@link TypeReference#METHOD_TYPE_PARAMETER
+- * METHOD_TYPE_PARAMETER},
+- * {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND
+- * METHOD_TYPE_PARAMETER_BOUND},
+- * {@link TypeReference#METHOD_RETURN METHOD_RETURN},
+- * {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER},
+- * {@link TypeReference#METHOD_FORMAL_PARAMETER
+- * METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS
+- * THROWS}. See {@link TypeReference}.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitTypeAnnotation(int typeRef,
+- TypePath typePath, String desc, boolean visible) {
+- if (api < Opcodes.ASM5) {
+- throw new RuntimeException();
+- }
+- if (mv != null) {
+- return mv.visitTypeAnnotation(typeRef, typePath, desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits an annotation of a parameter this method.
+- *
+- * @param parameter
+- * the parameter index.
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitParameterAnnotation(int parameter,
+- String desc, boolean visible) {
+- if (mv != null) {
+- return mv.visitParameterAnnotation(parameter, desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits a non standard attribute of this method.
+- *
+- * @param attr
+- * an attribute.
+- */
+- public void visitAttribute(Attribute attr) {
+- if (mv != null) {
+- mv.visitAttribute(attr);
+- }
+- }
+-
+- /**
+- * Starts the visit of the method's code, if any (i.e. non abstract method).
+- */
+- public void visitCode() {
+- if (mv != null) {
+- mv.visitCode();
+- }
+- }
+-
+- /**
+- * Visits the current state of the local variables and operand stack
+- * elements. This method must(*) be called just before any
+- * instruction i that follows an unconditional branch instruction
+- * such as GOTO or THROW, that is the target of a jump instruction, or that
+- * starts an exception handler block. The visited types must describe the
+- * values of the local variables and of the operand stack elements just
+- * before i is executed.
+- *
+- * (*) this is mandatory only for classes whose version is greater than or
+- * equal to {@link Opcodes#V1_6 V1_6}.
+- *
+- * The frames of a method must be given either in expanded form, or in
+- * compressed form (all frames must use the same format, i.e. you must not
+- * mix expanded and compressed frames within a single method):
+- *
+- * In expanded form, all frames must have the F_NEW type.
+- * In compressed form, frames are basically "deltas" from the state of
+- * the previous frame:
+- *
+- * {@link Opcodes#F_SAME} representing frame with exactly the same
+- * locals as the previous frame and with the empty stack.
+- * {@link Opcodes#F_SAME1} representing frame with exactly the same
+- * locals as the previous frame and with single value on the stack (
+- * nStack
is 1 and stack[0]
contains value for the
+- * type of the stack item).
+- * {@link Opcodes#F_APPEND} representing frame with current locals are
+- * the same as the locals in the previous frame, except that additional
+- * locals are defined (nLocal
is 1, 2 or 3 and
+- * local
elements contains values representing added types).
+- * {@link Opcodes#F_CHOP} representing frame with current locals are the
+- * same as the locals in the previous frame, except that the last 1-3 locals
+- * are absent and with the empty stack (nLocals
is 1, 2 or 3).
+- * {@link Opcodes#F_FULL} representing complete frame data.
+- *
+- *
+- *
+- *
+- * In both cases the first frame, corresponding to the method's parameters
+- * and access flags, is implicit and must not be visited. Also, it is
+- * illegal to visit two or more frames for the same code location (i.e., at
+- * least one instruction must be visited between two calls to visitFrame).
+- *
+- * @param type
+- * the type of this stack map frame. Must be
+- * {@link Opcodes#F_NEW} for expanded frames, or
+- * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
+- * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
+- * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
+- * compressed frames.
+- * @param nLocal
+- * the number of local variables in the visited frame.
+- * @param local
+- * the local variable types in this frame. This array must not be
+- * modified. Primitive types are represented by
+- * {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+- * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+- * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+- * {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+- * represented by a single element). Reference types are
+- * represented by String objects (representing internal names),
+- * and uninitialized types by Label objects (this label
+- * designates the NEW instruction that created this uninitialized
+- * value).
+- * @param nStack
+- * the number of operand stack elements in the visited frame.
+- * @param stack
+- * the operand stack types in this frame. This array must not be
+- * modified. Its content has the same format as the "local"
+- * array.
+- * @throws IllegalStateException
+- * if a frame is visited just after another one, without any
+- * instruction between the two (unless this frame is a
+- * Opcodes#F_SAME frame, in which case it is silently ignored).
+- */
+- public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+- Object[] stack) {
+- if (mv != null) {
+- mv.visitFrame(type, nLocal, local, nStack, stack);
+- }
+- }
+-
+- // -------------------------------------------------------------------------
+- // Normal instructions
+- // -------------------------------------------------------------------------
+-
+- /**
+- * Visits a zero operand instruction.
+- *
+- * @param opcode
+- * the opcode of the instruction to be visited. This opcode is
+- * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
+- * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
+- * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
+- * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
+- * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
+- * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
+- * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
+- * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
+- * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
+- * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
+- * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
+- * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+- * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
+- * or MONITOREXIT.
+- */
+- public void visitInsn(int opcode) {
+- if (mv != null) {
+- mv.visitInsn(opcode);
+- }
+- }
+-
+- /**
+- * Visits an instruction with a single int operand.
+- *
+- * @param opcode
+- * the opcode of the instruction to be visited. This opcode is
+- * either BIPUSH, SIPUSH or NEWARRAY.
+- * @param operand
+- * the operand of the instruction to be visited.
+- * When opcode is BIPUSH, operand value should be between
+- * Byte.MIN_VALUE and Byte.MAX_VALUE.
+- * When opcode is SIPUSH, operand value should be between
+- * Short.MIN_VALUE and Short.MAX_VALUE.
+- * When opcode is NEWARRAY, operand value should be one of
+- * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
+- * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
+- * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
+- * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
+- */
+- public void visitIntInsn(int opcode, int operand) {
+- if (mv != null) {
+- mv.visitIntInsn(opcode, operand);
+- }
+- }
+-
+- /**
+- * Visits a local variable instruction. A local variable instruction is an
+- * instruction that loads or stores the value of a local variable.
+- *
+- * @param opcode
+- * the opcode of the local variable instruction to be visited.
+- * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD,
+- * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
+- * @param var
+- * the operand of the instruction to be visited. This operand is
+- * the index of a local variable.
+- */
+- public void visitVarInsn(int opcode, int var) {
+- if (mv != null) {
+- mv.visitVarInsn(opcode, var);
+- }
+- }
+-
+- /**
+- * Visits a type instruction. A type instruction is an instruction that
+- * takes the internal name of a class as parameter.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be visited. This opcode
+- * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
+- * @param type
+- * the operand of the instruction to be visited. This operand
+- * must be the internal name of an object or array class (see
+- * {@link Type#getInternalName() getInternalName}).
+- */
+- public void visitTypeInsn(int opcode, String type) {
+- if (mv != null) {
+- mv.visitTypeInsn(opcode, type);
+- }
+- }
+-
+- /**
+- * Visits a field instruction. A field instruction is an instruction that
+- * loads or stores the value of a field of an object.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be visited. This opcode
+- * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+- * @param owner
+- * the internal name of the field's owner class (see
+- * {@link Type#getInternalName() getInternalName}).
+- * @param name
+- * the field's name.
+- * @param desc
+- * the field's descriptor (see {@link Type Type}).
+- */
+- public void visitFieldInsn(int opcode, String owner, String name,
+- String desc) {
+- if (mv != null) {
+- mv.visitFieldInsn(opcode, owner, name, desc);
+- }
+- }
+-
+- /**
+- * Visits a method instruction. A method instruction is an instruction that
+- * invokes a method.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be visited. This opcode
+- * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+- * INVOKEINTERFACE.
+- * @param owner
+- * the internal name of the method's owner class (see
+- * {@link Type#getInternalName() getInternalName}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- */
+- @Deprecated
+- public void visitMethodInsn(int opcode, String owner, String name,
+- String desc) {
+- if (api >= Opcodes.ASM5) {
+- boolean itf = opcode == Opcodes.INVOKEINTERFACE;
+- visitMethodInsn(opcode, owner, name, desc, itf);
+- return;
+- }
+- if (mv != null) {
+- mv.visitMethodInsn(opcode, owner, name, desc);
+- }
+- }
+-
+- /**
+- * Visits a method instruction. A method instruction is an instruction that
+- * invokes a method.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be visited. This opcode
+- * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+- * INVOKEINTERFACE.
+- * @param owner
+- * the internal name of the method's owner class (see
+- * {@link Type#getInternalName() getInternalName}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @param itf
+- * if the method's owner class is an interface.
+- */
+- public void visitMethodInsn(int opcode, String owner, String name,
+- String desc, boolean itf) {
+- if (api < Opcodes.ASM5) {
+- if (itf != (opcode == Opcodes.INVOKEINTERFACE)) {
+- throw new IllegalArgumentException(
+- "INVOKESPECIAL/STATIC on interfaces require ASM 5");
+- }
+- visitMethodInsn(opcode, owner, name, desc);
+- return;
+- }
+- if (mv != null) {
+- mv.visitMethodInsn(opcode, owner, name, desc, itf);
+- }
+- }
+-
+- /**
+- * Visits an invokedynamic instruction.
+- *
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type Type}).
+- * @param bsm
+- * the bootstrap method.
+- * @param bsmArgs
+- * the bootstrap method constant arguments. Each argument must be
+- * an {@link Integer}, {@link Float}, {@link Long},
+- * {@link Double}, {@link String}, {@link Type} or {@link Handle}
+- * value. This method is allowed to modify the content of the
+- * array so a caller should expect that this array may change.
+- */
+- public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+- Object... bsmArgs) {
+- if (mv != null) {
+- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+- }
+- }
+-
+- /**
+- * Visits a jump instruction. A jump instruction is an instruction that may
+- * jump to another instruction.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be visited. This opcode
+- * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+- * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+- * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+- * @param label
+- * the operand of the instruction to be visited. This operand is
+- * a label that designates the instruction to which the jump
+- * instruction may jump.
+- */
+- public void visitJumpInsn(int opcode, Label label) {
+- if (mv != null) {
+- mv.visitJumpInsn(opcode, label);
+- }
+- }
+-
+- /**
+- * Visits a label. A label designates the instruction that will be visited
+- * just after it.
+- *
+- * @param label
+- * a {@link Label Label} object.
+- */
+- public void visitLabel(Label label) {
+- if (mv != null) {
+- mv.visitLabel(label);
+- }
+- }
+-
+- // -------------------------------------------------------------------------
+- // Special instructions
+- // -------------------------------------------------------------------------
+-
+- /**
+- * Visits a LDC instruction. Note that new constant types may be added in
+- * future versions of the Java Virtual Machine. To easily detect new
+- * constant types, implementations of this method should check for
+- * unexpected constant types, like this:
+- *
+- *
+- * if (cst instanceof Integer) {
+- * // ...
+- * } else if (cst instanceof Float) {
+- * // ...
+- * } else if (cst instanceof Long) {
+- * // ...
+- * } else if (cst instanceof Double) {
+- * // ...
+- * } else if (cst instanceof String) {
+- * // ...
+- * } else if (cst instanceof Type) {
+- * int sort = ((Type) cst).getSort();
+- * if (sort == Type.OBJECT) {
+- * // ...
+- * } else if (sort == Type.ARRAY) {
+- * // ...
+- * } else if (sort == Type.METHOD) {
+- * // ...
+- * } else {
+- * // throw an exception
+- * }
+- * } else if (cst instanceof Handle) {
+- * // ...
+- * } else {
+- * // throw an exception
+- * }
+- *
+- *
+- * @param cst
+- * the constant to be loaded on the stack. This parameter must be
+- * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+- * {@link Double}, a {@link String}, a {@link Type} of OBJECT or
+- * ARRAY sort for .class constants, for classes whose
+- * version is 49.0, a {@link Type} of METHOD sort or a
+- * {@link Handle} for MethodType and MethodHandle constants, for
+- * classes whose version is 51.0.
+- */
+- public void visitLdcInsn(Object cst) {
+- if (mv != null) {
+- mv.visitLdcInsn(cst);
+- }
+- }
+-
+- /**
+- * Visits an IINC instruction.
+- *
+- * @param var
+- * index of the local variable to be incremented.
+- * @param increment
+- * amount to increment the local variable by.
+- */
+- public void visitIincInsn(int var, int increment) {
+- if (mv != null) {
+- mv.visitIincInsn(var, increment);
+- }
+- }
+-
+- /**
+- * Visits a TABLESWITCH instruction.
+- *
+- * @param min
+- * the minimum key value.
+- * @param max
+- * the maximum key value.
+- * @param dflt
+- * beginning of the default handler block.
+- * @param labels
+- * beginnings of the handler blocks. labels[i] is the
+- * beginning of the handler block for the min + i key.
+- */
+- public void visitTableSwitchInsn(int min, int max, Label dflt,
+- Label... labels) {
+- if (mv != null) {
+- mv.visitTableSwitchInsn(min, max, dflt, labels);
+- }
+- }
+-
+- /**
+- * Visits a LOOKUPSWITCH instruction.
+- *
+- * @param dflt
+- * beginning of the default handler block.
+- * @param keys
+- * the values of the keys.
+- * @param labels
+- * beginnings of the handler blocks. labels[i] is the
+- * beginning of the handler block for the keys[i] key.
+- */
+- public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+- if (mv != null) {
+- mv.visitLookupSwitchInsn(dflt, keys, labels);
+- }
+- }
+-
+- /**
+- * Visits a MULTIANEWARRAY instruction.
+- *
+- * @param desc
+- * an array type descriptor (see {@link Type Type}).
+- * @param dims
+- * number of dimensions of the array to allocate.
+- */
+- public void visitMultiANewArrayInsn(String desc, int dims) {
+- if (mv != null) {
+- mv.visitMultiANewArrayInsn(desc, dims);
+- }
+- }
+-
+- /**
+- * Visits an annotation on an instruction. This method must be called just
+- * after the annotated instruction. It can be called several times
+- * for the same instruction.
+- *
+- * @param typeRef
+- * a reference to the annotated type. The sort of this type
+- * reference must be {@link TypeReference#INSTANCEOF INSTANCEOF},
+- * {@link TypeReference#NEW NEW},
+- * {@link TypeReference#CONSTRUCTOR_REFERENCE
+- * CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE
+- * METHOD_REFERENCE}, {@link TypeReference#CAST CAST},
+- * {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
+- * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT},
+- * {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT
+- * METHOD_INVOCATION_TYPE_ARGUMENT},
+- * {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
+- * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or
+- * {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT
+- * METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitInsnAnnotation(int typeRef,
+- TypePath typePath, String desc, boolean visible) {
+- if (api < Opcodes.ASM5) {
+- throw new RuntimeException();
+- }
+- if (mv != null) {
+- return mv.visitInsnAnnotation(typeRef, typePath, desc, visible);
+- }
+- return null;
+- }
+-
+- // -------------------------------------------------------------------------
+- // Exceptions table entries, debug information, max stack and max locals
+- // -------------------------------------------------------------------------
+-
+- /**
+- * Visits a try catch block.
+- *
+- * @param start
+- * beginning of the exception handler's scope (inclusive).
+- * @param end
+- * end of the exception handler's scope (exclusive).
+- * @param handler
+- * beginning of the exception handler's code.
+- * @param type
+- * internal name of the type of exceptions handled by the
+- * handler, or null to catch any exceptions (for
+- * "finally" blocks).
+- * @throws IllegalArgumentException
+- * if one of the labels has already been visited by this visitor
+- * (by the {@link #visitLabel visitLabel} method).
+- */
+- public void visitTryCatchBlock(Label start, Label end, Label handler,
+- String type) {
+- if (mv != null) {
+- mv.visitTryCatchBlock(start, end, handler, type);
+- }
+- }
+-
+- /**
+- * Visits an annotation on an exception handler type. This method must be
+- * called after the {@link #visitTryCatchBlock} for the annotated
+- * exception handler. It can be called several times for the same exception
+- * handler.
+- *
+- * @param typeRef
+- * a reference to the annotated type. The sort of this type
+- * reference must be {@link TypeReference#EXCEPTION_PARAMETER
+- * EXCEPTION_PARAMETER}. See {@link TypeReference}.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+- TypePath typePath, String desc, boolean visible) {
+- if (api < Opcodes.ASM5) {
+- throw new RuntimeException();
+- }
+- if (mv != null) {
+- return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits a local variable declaration.
+- *
+- * @param name
+- * the name of a local variable.
+- * @param desc
+- * the type descriptor of this local variable.
+- * @param signature
+- * the type signature of this local variable. May be
+- * null if the local variable type does not use generic
+- * types.
+- * @param start
+- * the first instruction corresponding to the scope of this local
+- * variable (inclusive).
+- * @param end
+- * the last instruction corresponding to the scope of this local
+- * variable (exclusive).
+- * @param index
+- * the local variable's index.
+- * @throws IllegalArgumentException
+- * if one of the labels has not already been visited by this
+- * visitor (by the {@link #visitLabel visitLabel} method).
+- */
+- public void visitLocalVariable(String name, String desc, String signature,
+- Label start, Label end, int index) {
+- if (mv != null) {
+- mv.visitLocalVariable(name, desc, signature, start, end, index);
+- }
+- }
+-
+- /**
+- * Visits an annotation on a local variable type.
+- *
+- * @param typeRef
+- * a reference to the annotated type. The sort of this type
+- * reference must be {@link TypeReference#LOCAL_VARIABLE
+- * LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE
+- * RESOURCE_VARIABLE}. See {@link TypeReference}.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param start
+- * the fist instructions corresponding to the continuous ranges
+- * that make the scope of this local variable (inclusive).
+- * @param end
+- * the last instructions corresponding to the continuous ranges
+- * that make the scope of this local variable (exclusive). This
+- * array must have the same size as the 'start' array.
+- * @param index
+- * the local variable's index in each range. This array must have
+- * the same size as the 'start' array.
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- * @return a visitor to visit the annotation values, or null if
+- * this visitor is not interested in visiting this annotation.
+- */
+- public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+- TypePath typePath, Label[] start, Label[] end, int[] index,
+- String desc, boolean visible) {
+- if (api < Opcodes.ASM5) {
+- throw new RuntimeException();
+- }
+- if (mv != null) {
+- return mv.visitLocalVariableAnnotation(typeRef, typePath, start,
+- end, index, desc, visible);
+- }
+- return null;
+- }
+-
+- /**
+- * Visits a line number declaration.
+- *
+- * @param line
+- * a line number. This number refers to the source file from
+- * which the class was compiled.
+- * @param start
+- * the first instruction corresponding to this line number.
+- * @throws IllegalArgumentException
+- * if start has not already been visited by this
+- * visitor (by the {@link #visitLabel visitLabel} method).
+- */
+- public void visitLineNumber(int line, Label start) {
+- if (mv != null) {
+- mv.visitLineNumber(line, start);
+- }
+- }
+-
+- /**
+- * Visits the maximum stack size and the maximum number of local variables
+- * of the method.
+- *
+- * @param maxStack
+- * maximum stack size of the method.
+- * @param maxLocals
+- * maximum number of local variables for the method.
+- */
+- public void visitMaxs(int maxStack, int maxLocals) {
+- if (mv != null) {
+- mv.visitMaxs(maxStack, maxLocals);
+- }
+- }
+-
+- /**
+- * Visits the end of the method. This method, which is the last one to be
+- * called, is used to inform the visitor that all the annotations and
+- * attributes of the method have been visited.
+- */
+- public void visitEnd() {
+- if (mv != null) {
+- mv.visitEnd();
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/MethodWriter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/MethodWriter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/MethodWriter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/MethodWriter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,2913 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * A {@link MethodVisitor} that generates methods in bytecode form. Each visit
+- * method of this class appends the bytecode corresponding to the visited
+- * instruction to a byte vector, in the order these methods are called.
+- *
+- * @author Eric Bruneton
+- * @author Eugene Kuleshov
+- */
+-class MethodWriter extends MethodVisitor {
+-
+- /**
+- * Pseudo access flag used to denote constructors.
+- */
+- static final int ACC_CONSTRUCTOR = 0x80000;
+-
+- /**
+- * Frame has exactly the same locals as the previous stack map frame and
+- * number of stack items is zero.
+- */
+- static final int SAME_FRAME = 0; // to 63 (0-3f)
+-
+- /**
+- * Frame has exactly the same locals as the previous stack map frame and
+- * number of stack items is 1
+- */
+- static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; // to 127 (40-7f)
+-
+- /**
+- * Reserved for future use
+- */
+- static final int RESERVED = 128;
+-
+- /**
+- * Frame has exactly the same locals as the previous stack map frame and
+- * number of stack items is 1. Offset is bigger then 63;
+- */
+- static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; // f7
+-
+- /**
+- * Frame where current locals are the same as the locals in the previous
+- * frame, except that the k last locals are absent. The value of k is given
+- * by the formula 251-frame_type.
+- */
+- static final int CHOP_FRAME = 248; // to 250 (f8-fA)
+-
+- /**
+- * Frame has exactly the same locals as the previous stack map frame and
+- * number of stack items is zero. Offset is bigger then 63;
+- */
+- static final int SAME_FRAME_EXTENDED = 251; // fb
+-
+- /**
+- * Frame where current locals are the same as the locals in the previous
+- * frame, except that k additional locals are defined. The value of k is
+- * given by the formula frame_type-251.
+- */
+- static final int APPEND_FRAME = 252; // to 254 // fc-fe
+-
+- /**
+- * Full frame
+- */
+- static final int FULL_FRAME = 255; // ff
+-
+- /**
+- * Indicates that the stack map frames must be recomputed from scratch. In
+- * this case the maximum stack size and number of local variables is also
+- * recomputed from scratch.
+- *
+- * @see #compute
+- */
+- private static final int FRAMES = 0;
+-
+- /**
+- * Indicates that the maximum stack size and number of local variables must
+- * be automatically computed.
+- *
+- * @see #compute
+- */
+- private static final int MAXS = 1;
+-
+- /**
+- * Indicates that nothing must be automatically computed.
+- *
+- * @see #compute
+- */
+- private static final int NOTHING = 2;
+-
+- /**
+- * The class writer to which this method must be added.
+- */
+- final ClassWriter cw;
+-
+- /**
+- * Access flags of this method.
+- */
+- private int access;
+-
+- /**
+- * The index of the constant pool item that contains the name of this
+- * method.
+- */
+- private final int name;
+-
+- /**
+- * The index of the constant pool item that contains the descriptor of this
+- * method.
+- */
+- private final int desc;
+-
+- /**
+- * The descriptor of this method.
+- */
+- private final String descriptor;
+-
+- /**
+- * The signature of this method.
+- */
+- String signature;
+-
+- /**
+- * If not zero, indicates that the code of this method must be copied from
+- * the ClassReader associated to this writer in cw.cr
. More
+- * precisely, this field gives the index of the first byte to copied from
+- * cw.cr.b
.
+- */
+- int classReaderOffset;
+-
+- /**
+- * If not zero, indicates that the code of this method must be copied from
+- * the ClassReader associated to this writer in cw.cr
. More
+- * precisely, this field gives the number of bytes to copied from
+- * cw.cr.b
.
+- */
+- int classReaderLength;
+-
+- /**
+- * Number of exceptions that can be thrown by this method.
+- */
+- int exceptionCount;
+-
+- /**
+- * The exceptions that can be thrown by this method. More precisely, this
+- * array contains the indexes of the constant pool items that contain the
+- * internal names of these exception classes.
+- */
+- int[] exceptions;
+-
+- /**
+- * The annotation default attribute of this method. May be null .
+- */
+- private ByteVector annd;
+-
+- /**
+- * The runtime visible annotations of this method. May be null .
+- */
+- private AnnotationWriter anns;
+-
+- /**
+- * The runtime invisible annotations of this method. May be null .
+- */
+- private AnnotationWriter ianns;
+-
+- /**
+- * The runtime visible type annotations of this method. May be null
+- * .
+- */
+- private AnnotationWriter tanns;
+-
+- /**
+- * The runtime invisible type annotations of this method. May be
+- * null .
+- */
+- private AnnotationWriter itanns;
+-
+- /**
+- * The runtime visible parameter annotations of this method. May be
+- * null .
+- */
+- private AnnotationWriter[] panns;
+-
+- /**
+- * The runtime invisible parameter annotations of this method. May be
+- * null .
+- */
+- private AnnotationWriter[] ipanns;
+-
+- /**
+- * The number of synthetic parameters of this method.
+- */
+- private int synthetics;
+-
+- /**
+- * The non standard attributes of the method.
+- */
+- private Attribute attrs;
+-
+- /**
+- * The bytecode of this method.
+- */
+- private ByteVector code = new ByteVector();
+-
+- /**
+- * Maximum stack size of this method.
+- */
+- private int maxStack;
+-
+- /**
+- * Maximum number of local variables for this method.
+- */
+- private int maxLocals;
+-
+- /**
+- * Number of local variables in the current stack map frame.
+- */
+- private int currentLocals;
+-
+- /**
+- * Number of stack map frames in the StackMapTable attribute.
+- */
+- private int frameCount;
+-
+- /**
+- * The StackMapTable attribute.
+- */
+- private ByteVector stackMap;
+-
+- /**
+- * The offset of the last frame that was written in the StackMapTable
+- * attribute.
+- */
+- private int previousFrameOffset;
+-
+- /**
+- * The last frame that was written in the StackMapTable attribute.
+- *
+- * @see #frame
+- */
+- private int[] previousFrame;
+-
+- /**
+- * The current stack map frame. The first element contains the offset of the
+- * instruction to which the frame corresponds, the second element is the
+- * number of locals and the third one is the number of stack elements. The
+- * local variables start at index 3 and are followed by the operand stack
+- * values. In summary frame[0] = offset, frame[1] = nLocal, frame[2] =
+- * nStack, frame[3] = nLocal. All types are encoded as integers, with the
+- * same format as the one used in {@link Label}, but limited to BASE types.
+- */
+- private int[] frame;
+-
+- /**
+- * Number of elements in the exception handler list.
+- */
+- private int handlerCount;
+-
+- /**
+- * The first element in the exception handler list.
+- */
+- private Handler firstHandler;
+-
+- /**
+- * The last element in the exception handler list.
+- */
+- private Handler lastHandler;
+-
+- /**
+- * Number of entries in the MethodParameters attribute.
+- */
+- private int methodParametersCount;
+-
+- /**
+- * The MethodParameters attribute.
+- */
+- private ByteVector methodParameters;
+-
+- /**
+- * Number of entries in the LocalVariableTable attribute.
+- */
+- private int localVarCount;
+-
+- /**
+- * The LocalVariableTable attribute.
+- */
+- private ByteVector localVar;
+-
+- /**
+- * Number of entries in the LocalVariableTypeTable attribute.
+- */
+- private int localVarTypeCount;
+-
+- /**
+- * The LocalVariableTypeTable attribute.
+- */
+- private ByteVector localVarType;
+-
+- /**
+- * Number of entries in the LineNumberTable attribute.
+- */
+- private int lineNumberCount;
+-
+- /**
+- * The LineNumberTable attribute.
+- */
+- private ByteVector lineNumber;
+-
+- /**
+- * The start offset of the last visited instruction.
+- */
+- private int lastCodeOffset;
+-
+- /**
+- * The runtime visible type annotations of the code. May be null .
+- */
+- private AnnotationWriter ctanns;
+-
+- /**
+- * The runtime invisible type annotations of the code. May be null .
+- */
+- private AnnotationWriter ictanns;
+-
+- /**
+- * The non standard attributes of the method's code.
+- */
+- private Attribute cattrs;
+-
+- /**
+- * Indicates if some jump instructions are too small and need to be resized.
+- */
+- private boolean resize;
+-
+- /**
+- * The number of subroutines in this method.
+- */
+- private int subroutines;
+-
+- // ------------------------------------------------------------------------
+-
+- /*
+- * Fields for the control flow graph analysis algorithm (used to compute the
+- * maximum stack size). A control flow graph contains one node per "basic
+- * block", and one edge per "jump" from one basic block to another. Each
+- * node (i.e., each basic block) is represented by the Label object that
+- * corresponds to the first instruction of this basic block. Each node also
+- * stores the list of its successors in the graph, as a linked list of Edge
+- * objects.
+- */
+-
+- /**
+- * Indicates what must be automatically computed.
+- *
+- * @see #FRAMES
+- * @see #MAXS
+- * @see #NOTHING
+- */
+- private final int compute;
+-
+- /**
+- * A list of labels. This list is the list of basic blocks in the method,
+- * i.e. a list of Label objects linked to each other by their
+- * {@link Label#successor} field, in the order they are visited by
+- * {@link MethodVisitor#visitLabel}, and starting with the first basic
+- * block.
+- */
+- private Label labels;
+-
+- /**
+- * The previous basic block.
+- */
+- private Label previousBlock;
+-
+- /**
+- * The current basic block.
+- */
+- private Label currentBlock;
+-
+- /**
+- * The (relative) stack size after the last visited instruction. This size
+- * is relative to the beginning of the current basic block, i.e., the true
+- * stack size after the last visited instruction is equal to the
+- * {@link Label#inputStackTop beginStackSize} of the current basic block
+- * plus stackSize .
+- */
+- private int stackSize;
+-
+- /**
+- * The (relative) maximum stack size after the last visited instruction.
+- * This size is relative to the beginning of the current basic block, i.e.,
+- * the true maximum stack size after the last visited instruction is equal
+- * to the {@link Label#inputStackTop beginStackSize} of the current basic
+- * block plus stackSize .
+- */
+- private int maxStackSize;
+-
+- // ------------------------------------------------------------------------
+- // Constructor
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Constructs a new {@link MethodWriter}.
+- *
+- * @param cw
+- * the class writer in which the method must be added.
+- * @param access
+- * the method's access flags (see {@link Opcodes}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link Type}).
+- * @param signature
+- * the method's signature. May be null .
+- * @param exceptions
+- * the internal names of the method's exceptions. May be
+- * null .
+- * @param computeMaxs
+- * true if the maximum stack size and number of local
+- * variables must be automatically computed.
+- * @param computeFrames
+- * true if the stack map tables must be recomputed from
+- * scratch.
+- */
+- MethodWriter(final ClassWriter cw, final int access, final String name,
+- final String desc, final String signature,
+- final String[] exceptions, final boolean computeMaxs,
+- final boolean computeFrames) {
+- super(Opcodes.ASM5);
+- if (cw.firstMethod == null) {
+- cw.firstMethod = this;
+- } else {
+- cw.lastMethod.mv = this;
+- }
+- cw.lastMethod = this;
+- this.cw = cw;
+- this.access = access;
+- if ("".equals(name)) {
+- this.access |= ACC_CONSTRUCTOR;
+- }
+- this.name = cw.newUTF8(name);
+- this.desc = cw.newUTF8(desc);
+- this.descriptor = desc;
+- if (ClassReader.SIGNATURES) {
+- this.signature = signature;
+- }
+- if (exceptions != null && exceptions.length > 0) {
+- exceptionCount = exceptions.length;
+- this.exceptions = new int[exceptionCount];
+- for (int i = 0; i < exceptionCount; ++i) {
+- this.exceptions[i] = cw.newClass(exceptions[i]);
+- }
+- }
+- this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
+- if (computeMaxs || computeFrames) {
+- // updates maxLocals
+- int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
+- if ((access & Opcodes.ACC_STATIC) != 0) {
+- --size;
+- }
+- maxLocals = size;
+- currentLocals = size;
+- // creates and visits the label for the first basic block
+- labels = new Label();
+- labels.status |= Label.PUSHED;
+- visitLabel(labels);
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Implementation of the MethodVisitor abstract class
+- // ------------------------------------------------------------------------
+-
+- @Override
+- public void visitParameter(String name, int access) {
+- if (methodParameters == null) {
+- methodParameters = new ByteVector();
+- }
+- ++methodParametersCount;
+- methodParameters.putShort((name == null) ? 0 : cw.newUTF8(name))
+- .putShort(access);
+- }
+-
+- @Override
+- public AnnotationVisitor visitAnnotationDefault() {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- annd = new ByteVector();
+- return new AnnotationWriter(cw, false, annd, null, 0);
+- }
+-
+- @Override
+- public AnnotationVisitor visitAnnotation(final String desc,
+- final boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write type, and reserve space for values count
+- bv.putShort(cw.newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
+- if (visible) {
+- aw.next = anns;
+- anns = aw;
+- } else {
+- aw.next = ianns;
+- ianns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public AnnotationVisitor visitTypeAnnotation(final int typeRef,
+- final TypePath typePath, final String desc, final boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write target_type and target_info
+- AnnotationWriter.putTarget(typeRef, typePath, bv);
+- // write type, and reserve space for values count
+- bv.putShort(cw.newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+- bv.length - 2);
+- if (visible) {
+- aw.next = tanns;
+- tanns = aw;
+- } else {
+- aw.next = itanns;
+- itanns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public AnnotationVisitor visitParameterAnnotation(final int parameter,
+- final String desc, final boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- if ("Ljava/lang/Synthetic;".equals(desc)) {
+- // workaround for a bug in javac with synthetic parameters
+- // see ClassReader.readParameterAnnotations
+- synthetics = Math.max(synthetics, parameter + 1);
+- return new AnnotationWriter(cw, false, bv, null, 0);
+- }
+- // write type, and reserve space for values count
+- bv.putShort(cw.newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
+- if (visible) {
+- if (panns == null) {
+- panns = new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
+- }
+- aw.next = panns[parameter];
+- panns[parameter] = aw;
+- } else {
+- if (ipanns == null) {
+- ipanns = new AnnotationWriter[Type.getArgumentTypes(descriptor).length];
+- }
+- aw.next = ipanns[parameter];
+- ipanns[parameter] = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public void visitAttribute(final Attribute attr) {
+- if (attr.isCodeAttribute()) {
+- attr.next = cattrs;
+- cattrs = attr;
+- } else {
+- attr.next = attrs;
+- attrs = attr;
+- }
+- }
+-
+- @Override
+- public void visitCode() {
+- }
+-
+- @Override
+- public void visitFrame(final int type, final int nLocal,
+- final Object[] local, final int nStack, final Object[] stack) {
+- if (!ClassReader.FRAMES || compute == FRAMES) {
+- return;
+- }
+-
+- if (type == Opcodes.F_NEW) {
+- if (previousFrame == null) {
+- visitImplicitFirstFrame();
+- }
+- currentLocals = nLocal;
+- int frameIndex = startFrame(code.length, nLocal, nStack);
+- for (int i = 0; i < nLocal; ++i) {
+- if (local[i] instanceof String) {
+- frame[frameIndex++] = Frame.OBJECT
+- | cw.addType((String) local[i]);
+- } else if (local[i] instanceof Integer) {
+- frame[frameIndex++] = ((Integer) local[i]).intValue();
+- } else {
+- frame[frameIndex++] = Frame.UNINITIALIZED
+- | cw.addUninitializedType("",
+- ((Label) local[i]).position);
+- }
+- }
+- for (int i = 0; i < nStack; ++i) {
+- if (stack[i] instanceof String) {
+- frame[frameIndex++] = Frame.OBJECT
+- | cw.addType((String) stack[i]);
+- } else if (stack[i] instanceof Integer) {
+- frame[frameIndex++] = ((Integer) stack[i]).intValue();
+- } else {
+- frame[frameIndex++] = Frame.UNINITIALIZED
+- | cw.addUninitializedType("",
+- ((Label) stack[i]).position);
+- }
+- }
+- endFrame();
+- } else {
+- int delta;
+- if (stackMap == null) {
+- stackMap = new ByteVector();
+- delta = code.length;
+- } else {
+- delta = code.length - previousFrameOffset - 1;
+- if (delta < 0) {
+- if (type == Opcodes.F_SAME) {
+- return;
+- } else {
+- throw new IllegalStateException();
+- }
+- }
+- }
+-
+- switch (type) {
+- case Opcodes.F_FULL:
+- currentLocals = nLocal;
+- stackMap.putByte(FULL_FRAME).putShort(delta).putShort(nLocal);
+- for (int i = 0; i < nLocal; ++i) {
+- writeFrameType(local[i]);
+- }
+- stackMap.putShort(nStack);
+- for (int i = 0; i < nStack; ++i) {
+- writeFrameType(stack[i]);
+- }
+- break;
+- case Opcodes.F_APPEND:
+- currentLocals += nLocal;
+- stackMap.putByte(SAME_FRAME_EXTENDED + nLocal).putShort(delta);
+- for (int i = 0; i < nLocal; ++i) {
+- writeFrameType(local[i]);
+- }
+- break;
+- case Opcodes.F_CHOP:
+- currentLocals -= nLocal;
+- stackMap.putByte(SAME_FRAME_EXTENDED - nLocal).putShort(delta);
+- break;
+- case Opcodes.F_SAME:
+- if (delta < 64) {
+- stackMap.putByte(delta);
+- } else {
+- stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+- }
+- break;
+- case Opcodes.F_SAME1:
+- if (delta < 64) {
+- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+- } else {
+- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
+- .putShort(delta);
+- }
+- writeFrameType(stack[0]);
+- break;
+- }
+-
+- previousFrameOffset = code.length;
+- ++frameCount;
+- }
+-
+- maxStack = Math.max(maxStack, nStack);
+- maxLocals = Math.max(maxLocals, currentLocals);
+- }
+-
+- @Override
+- public void visitInsn(final int opcode) {
+- lastCodeOffset = code.length;
+- // adds the instruction to the bytecode of the method
+- code.putByte(opcode);
+- // update currentBlock
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(opcode, 0, null, null);
+- } else {
+- // updates current and max stack sizes
+- int size = stackSize + Frame.SIZE[opcode];
+- if (size > maxStackSize) {
+- maxStackSize = size;
+- }
+- stackSize = size;
+- }
+- // if opcode == ATHROW or xRETURN, ends current block (no successor)
+- if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
+- || opcode == Opcodes.ATHROW) {
+- noSuccessor();
+- }
+- }
+- }
+-
+- @Override
+- public void visitIntInsn(final int opcode, final int operand) {
+- lastCodeOffset = code.length;
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(opcode, operand, null, null);
+- } else if (opcode != Opcodes.NEWARRAY) {
+- // updates current and max stack sizes only for NEWARRAY
+- // (stack size variation = 0 for BIPUSH or SIPUSH)
+- int size = stackSize + 1;
+- if (size > maxStackSize) {
+- maxStackSize = size;
+- }
+- stackSize = size;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- if (opcode == Opcodes.SIPUSH) {
+- code.put12(opcode, operand);
+- } else { // BIPUSH or NEWARRAY
+- code.put11(opcode, operand);
+- }
+- }
+-
+- @Override
+- public void visitVarInsn(final int opcode, final int var) {
+- lastCodeOffset = code.length;
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(opcode, var, null, null);
+- } else {
+- // updates current and max stack sizes
+- if (opcode == Opcodes.RET) {
+- // no stack change, but end of current block (no successor)
+- currentBlock.status |= Label.RET;
+- // save 'stackSize' here for future use
+- // (see {@link #findSubroutineSuccessors})
+- currentBlock.inputStackTop = stackSize;
+- noSuccessor();
+- } else { // xLOAD or xSTORE
+- int size = stackSize + Frame.SIZE[opcode];
+- if (size > maxStackSize) {
+- maxStackSize = size;
+- }
+- stackSize = size;
+- }
+- }
+- }
+- if (compute != NOTHING) {
+- // updates max locals
+- int n;
+- if (opcode == Opcodes.LLOAD || opcode == Opcodes.DLOAD
+- || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE) {
+- n = var + 2;
+- } else {
+- n = var + 1;
+- }
+- if (n > maxLocals) {
+- maxLocals = n;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- if (var < 4 && opcode != Opcodes.RET) {
+- int opt;
+- if (opcode < Opcodes.ISTORE) {
+- /* ILOAD_0 */
+- opt = 26 + ((opcode - Opcodes.ILOAD) << 2) + var;
+- } else {
+- /* ISTORE_0 */
+- opt = 59 + ((opcode - Opcodes.ISTORE) << 2) + var;
+- }
+- code.putByte(opt);
+- } else if (var >= 256) {
+- code.putByte(196 /* WIDE */).put12(opcode, var);
+- } else {
+- code.put11(opcode, var);
+- }
+- if (opcode >= Opcodes.ISTORE && compute == FRAMES && handlerCount > 0) {
+- visitLabel(new Label());
+- }
+- }
+-
+- @Override
+- public void visitTypeInsn(final int opcode, final String type) {
+- lastCodeOffset = code.length;
+- Item i = cw.newClassItem(type);
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(opcode, code.length, cw, i);
+- } else if (opcode == Opcodes.NEW) {
+- // updates current and max stack sizes only if opcode == NEW
+- // (no stack change for ANEWARRAY, CHECKCAST, INSTANCEOF)
+- int size = stackSize + 1;
+- if (size > maxStackSize) {
+- maxStackSize = size;
+- }
+- stackSize = size;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- code.put12(opcode, i.index);
+- }
+-
+- @Override
+- public void visitFieldInsn(final int opcode, final String owner,
+- final String name, final String desc) {
+- lastCodeOffset = code.length;
+- Item i = cw.newFieldItem(owner, name, desc);
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(opcode, 0, cw, i);
+- } else {
+- int size;
+- // computes the stack size variation
+- char c = desc.charAt(0);
+- switch (opcode) {
+- case Opcodes.GETSTATIC:
+- size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
+- break;
+- case Opcodes.PUTSTATIC:
+- size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
+- break;
+- case Opcodes.GETFIELD:
+- size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
+- break;
+- // case Constants.PUTFIELD:
+- default:
+- size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
+- break;
+- }
+- // updates current and max stack sizes
+- if (size > maxStackSize) {
+- maxStackSize = size;
+- }
+- stackSize = size;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- code.put12(opcode, i.index);
+- }
+-
+- @Override
+- public void visitMethodInsn(final int opcode, final String owner,
+- final String name, final String desc, final boolean itf) {
+- lastCodeOffset = code.length;
+- Item i = cw.newMethodItem(owner, name, desc, itf);
+- int argSize = i.intVal;
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(opcode, 0, cw, i);
+- } else {
+- /*
+- * computes the stack size variation. In order not to recompute
+- * several times this variation for the same Item, we use the
+- * intVal field of this item to store this variation, once it
+- * has been computed. More precisely this intVal field stores
+- * the sizes of the arguments and of the return value
+- * corresponding to desc.
+- */
+- if (argSize == 0) {
+- // the above sizes have not been computed yet,
+- // so we compute them...
+- argSize = Type.getArgumentsAndReturnSizes(desc);
+- // ... and we save them in order
+- // not to recompute them in the future
+- i.intVal = argSize;
+- }
+- int size;
+- if (opcode == Opcodes.INVOKESTATIC) {
+- size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1;
+- } else {
+- size = stackSize - (argSize >> 2) + (argSize & 0x03);
+- }
+- // updates current and max stack sizes
+- if (size > maxStackSize) {
+- maxStackSize = size;
+- }
+- stackSize = size;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- if (opcode == Opcodes.INVOKEINTERFACE) {
+- if (argSize == 0) {
+- argSize = Type.getArgumentsAndReturnSizes(desc);
+- i.intVal = argSize;
+- }
+- code.put12(Opcodes.INVOKEINTERFACE, i.index).put11(argSize >> 2, 0);
+- } else {
+- code.put12(opcode, i.index);
+- }
+- }
+-
+- @Override
+- public void visitInvokeDynamicInsn(final String name, final String desc,
+- final Handle bsm, final Object... bsmArgs) {
+- lastCodeOffset = code.length;
+- Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs);
+- int argSize = i.intVal;
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
+- } else {
+- /*
+- * computes the stack size variation. In order not to recompute
+- * several times this variation for the same Item, we use the
+- * intVal field of this item to store this variation, once it
+- * has been computed. More precisely this intVal field stores
+- * the sizes of the arguments and of the return value
+- * corresponding to desc.
+- */
+- if (argSize == 0) {
+- // the above sizes have not been computed yet,
+- // so we compute them...
+- argSize = Type.getArgumentsAndReturnSizes(desc);
+- // ... and we save them in order
+- // not to recompute them in the future
+- i.intVal = argSize;
+- }
+- int size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1;
+-
+- // updates current and max stack sizes
+- if (size > maxStackSize) {
+- maxStackSize = size;
+- }
+- stackSize = size;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- code.put12(Opcodes.INVOKEDYNAMIC, i.index);
+- code.putShort(0);
+- }
+-
+- @Override
+- public void visitJumpInsn(final int opcode, final Label label) {
+- lastCodeOffset = code.length;
+- Label nextInsn = null;
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(opcode, 0, null, null);
+- // 'label' is the target of a jump instruction
+- label.getFirst().status |= Label.TARGET;
+- // adds 'label' as a successor of this basic block
+- addSuccessor(Edge.NORMAL, label);
+- if (opcode != Opcodes.GOTO) {
+- // creates a Label for the next basic block
+- nextInsn = new Label();
+- }
+- } else {
+- if (opcode == Opcodes.JSR) {
+- if ((label.status & Label.SUBROUTINE) == 0) {
+- label.status |= Label.SUBROUTINE;
+- ++subroutines;
+- }
+- currentBlock.status |= Label.JSR;
+- addSuccessor(stackSize + 1, label);
+- // creates a Label for the next basic block
+- nextInsn = new Label();
+- /*
+- * note that, by construction in this method, a JSR block
+- * has at least two successors in the control flow graph:
+- * the first one leads the next instruction after the JSR,
+- * while the second one leads to the JSR target.
+- */
+- } else {
+- // updates current stack size (max stack size unchanged
+- // because stack size variation always negative in this
+- // case)
+- stackSize += Frame.SIZE[opcode];
+- addSuccessor(stackSize, label);
+- }
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- if ((label.status & Label.RESOLVED) != 0
+- && label.position - code.length < Short.MIN_VALUE) {
+- /*
+- * case of a backward jump with an offset < -32768. In this case we
+- * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
+- * with IFNOTxxx GOTO_W , where IFNOTxxx is the
+- * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where
+- * designates the instruction just after the GOTO_W.
+- */
+- if (opcode == Opcodes.GOTO) {
+- code.putByte(200); // GOTO_W
+- } else if (opcode == Opcodes.JSR) {
+- code.putByte(201); // JSR_W
+- } else {
+- // if the IF instruction is transformed into IFNOT GOTO_W the
+- // next instruction becomes the target of the IFNOT instruction
+- if (nextInsn != null) {
+- nextInsn.status |= Label.TARGET;
+- }
+- code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+- : opcode ^ 1);
+- code.putShort(8); // jump offset
+- code.putByte(200); // GOTO_W
+- }
+- label.put(this, code, code.length - 1, true);
+- } else {
+- /*
+- * case of a backward jump with an offset >= -32768, or of a forward
+- * jump with, of course, an unknown offset. In these cases we store
+- * the offset in 2 bytes (which will be increased in
+- * resizeInstructions, if needed).
+- */
+- code.putByte(opcode);
+- label.put(this, code, code.length - 1, false);
+- }
+- if (currentBlock != null) {
+- if (nextInsn != null) {
+- // if the jump instruction is not a GOTO, the next instruction
+- // is also a successor of this instruction. Calling visitLabel
+- // adds the label of this next instruction as a successor of the
+- // current block, and starts a new basic block
+- visitLabel(nextInsn);
+- }
+- if (opcode == Opcodes.GOTO) {
+- noSuccessor();
+- }
+- }
+- }
+-
+- @Override
+- public void visitLabel(final Label label) {
+- // resolves previous forward references to label, if any
+- resize |= label.resolve(this, code.length, code.data);
+- // updates currentBlock
+- if ((label.status & Label.DEBUG) != 0) {
+- return;
+- }
+- if (compute == FRAMES) {
+- if (currentBlock != null) {
+- if (label.position == currentBlock.position) {
+- // successive labels, do not start a new basic block
+- currentBlock.status |= (label.status & Label.TARGET);
+- label.frame = currentBlock.frame;
+- return;
+- }
+- // ends current block (with one new successor)
+- addSuccessor(Edge.NORMAL, label);
+- }
+- // begins a new current block
+- currentBlock = label;
+- if (label.frame == null) {
+- label.frame = new Frame();
+- label.frame.owner = label;
+- }
+- // updates the basic block list
+- if (previousBlock != null) {
+- if (label.position == previousBlock.position) {
+- previousBlock.status |= (label.status & Label.TARGET);
+- label.frame = previousBlock.frame;
+- currentBlock = previousBlock;
+- return;
+- }
+- previousBlock.successor = label;
+- }
+- previousBlock = label;
+- } else if (compute == MAXS) {
+- if (currentBlock != null) {
+- // ends current block (with one new successor)
+- currentBlock.outputStackMax = maxStackSize;
+- addSuccessor(stackSize, label);
+- }
+- // begins a new current block
+- currentBlock = label;
+- // resets the relative current and max stack sizes
+- stackSize = 0;
+- maxStackSize = 0;
+- // updates the basic block list
+- if (previousBlock != null) {
+- previousBlock.successor = label;
+- }
+- previousBlock = label;
+- }
+- }
+-
+- @Override
+- public void visitLdcInsn(final Object cst) {
+- lastCodeOffset = code.length;
+- Item i = cw.newConstItem(cst);
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(Opcodes.LDC, 0, cw, i);
+- } else {
+- int size;
+- // computes the stack size variation
+- if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
+- size = stackSize + 2;
+- } else {
+- size = stackSize + 1;
+- }
+- // updates current and max stack sizes
+- if (size > maxStackSize) {
+- maxStackSize = size;
+- }
+- stackSize = size;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- int index = i.index;
+- if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
+- code.put12(20 /* LDC2_W */, index);
+- } else if (index >= 256) {
+- code.put12(19 /* LDC_W */, index);
+- } else {
+- code.put11(Opcodes.LDC, index);
+- }
+- }
+-
+- @Override
+- public void visitIincInsn(final int var, final int increment) {
+- lastCodeOffset = code.length;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(Opcodes.IINC, var, null, null);
+- }
+- }
+- if (compute != NOTHING) {
+- // updates max locals
+- int n = var + 1;
+- if (n > maxLocals) {
+- maxLocals = n;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- if ((var > 255) || (increment > 127) || (increment < -128)) {
+- code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var)
+- .putShort(increment);
+- } else {
+- code.putByte(Opcodes.IINC).put11(var, increment);
+- }
+- }
+-
+- @Override
+- public void visitTableSwitchInsn(final int min, final int max,
+- final Label dflt, final Label... labels) {
+- lastCodeOffset = code.length;
+- // adds the instruction to the bytecode of the method
+- int source = code.length;
+- code.putByte(Opcodes.TABLESWITCH);
+- code.putByteArray(null, 0, (4 - code.length % 4) % 4);
+- dflt.put(this, code, source, true);
+- code.putInt(min).putInt(max);
+- for (int i = 0; i < labels.length; ++i) {
+- labels[i].put(this, code, source, true);
+- }
+- // updates currentBlock
+- visitSwitchInsn(dflt, labels);
+- }
+-
+- @Override
+- public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
+- final Label[] labels) {
+- lastCodeOffset = code.length;
+- // adds the instruction to the bytecode of the method
+- int source = code.length;
+- code.putByte(Opcodes.LOOKUPSWITCH);
+- code.putByteArray(null, 0, (4 - code.length % 4) % 4);
+- dflt.put(this, code, source, true);
+- code.putInt(labels.length);
+- for (int i = 0; i < labels.length; ++i) {
+- code.putInt(keys[i]);
+- labels[i].put(this, code, source, true);
+- }
+- // updates currentBlock
+- visitSwitchInsn(dflt, labels);
+- }
+-
+- private void visitSwitchInsn(final Label dflt, final Label[] labels) {
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(Opcodes.LOOKUPSWITCH, 0, null, null);
+- // adds current block successors
+- addSuccessor(Edge.NORMAL, dflt);
+- dflt.getFirst().status |= Label.TARGET;
+- for (int i = 0; i < labels.length; ++i) {
+- addSuccessor(Edge.NORMAL, labels[i]);
+- labels[i].getFirst().status |= Label.TARGET;
+- }
+- } else {
+- // updates current stack size (max stack size unchanged)
+- --stackSize;
+- // adds current block successors
+- addSuccessor(stackSize, dflt);
+- for (int i = 0; i < labels.length; ++i) {
+- addSuccessor(stackSize, labels[i]);
+- }
+- }
+- // ends current block
+- noSuccessor();
+- }
+- }
+-
+- @Override
+- public void visitMultiANewArrayInsn(final String desc, final int dims) {
+- lastCodeOffset = code.length;
+- Item i = cw.newClassItem(desc);
+- // Label currentBlock = this.currentBlock;
+- if (currentBlock != null) {
+- if (compute == FRAMES) {
+- currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i);
+- } else {
+- // updates current stack size (max stack size unchanged because
+- // stack size variation always negative or null)
+- stackSize += 1 - dims;
+- }
+- }
+- // adds the instruction to the bytecode of the method
+- code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims);
+- }
+-
+- @Override
+- public AnnotationVisitor visitInsnAnnotation(int typeRef,
+- TypePath typePath, String desc, boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write target_type and target_info
+- typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
+- AnnotationWriter.putTarget(typeRef, typePath, bv);
+- // write type, and reserve space for values count
+- bv.putShort(cw.newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+- bv.length - 2);
+- if (visible) {
+- aw.next = ctanns;
+- ctanns = aw;
+- } else {
+- aw.next = ictanns;
+- ictanns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public void visitTryCatchBlock(final Label start, final Label end,
+- final Label handler, final String type) {
+- ++handlerCount;
+- Handler h = new Handler();
+- h.start = start;
+- h.end = end;
+- h.handler = handler;
+- h.desc = type;
+- h.type = type != null ? cw.newClass(type) : 0;
+- if (lastHandler == null) {
+- firstHandler = h;
+- } else {
+- lastHandler.next = h;
+- }
+- lastHandler = h;
+- }
+-
+- @Override
+- public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+- TypePath typePath, String desc, boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write target_type and target_info
+- AnnotationWriter.putTarget(typeRef, typePath, bv);
+- // write type, and reserve space for values count
+- bv.putShort(cw.newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+- bv.length - 2);
+- if (visible) {
+- aw.next = ctanns;
+- ctanns = aw;
+- } else {
+- aw.next = ictanns;
+- ictanns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public void visitLocalVariable(final String name, final String desc,
+- final String signature, final Label start, final Label end,
+- final int index) {
+- if (signature != null) {
+- if (localVarType == null) {
+- localVarType = new ByteVector();
+- }
+- ++localVarTypeCount;
+- localVarType.putShort(start.position)
+- .putShort(end.position - start.position)
+- .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(signature))
+- .putShort(index);
+- }
+- if (localVar == null) {
+- localVar = new ByteVector();
+- }
+- ++localVarCount;
+- localVar.putShort(start.position)
+- .putShort(end.position - start.position)
+- .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(desc))
+- .putShort(index);
+- if (compute != NOTHING) {
+- // updates max locals
+- char c = desc.charAt(0);
+- int n = index + (c == 'J' || c == 'D' ? 2 : 1);
+- if (n > maxLocals) {
+- maxLocals = n;
+- }
+- }
+- }
+-
+- @Override
+- public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+- TypePath typePath, Label[] start, Label[] end, int[] index,
+- String desc, boolean visible) {
+- if (!ClassReader.ANNOTATIONS) {
+- return null;
+- }
+- ByteVector bv = new ByteVector();
+- // write target_type and target_info
+- bv.putByte(typeRef >>> 24).putShort(start.length);
+- for (int i = 0; i < start.length; ++i) {
+- bv.putShort(start[i].position)
+- .putShort(end[i].position - start[i].position)
+- .putShort(index[i]);
+- }
+- if (typePath == null) {
+- bv.putByte(0);
+- } else {
+- int length = typePath.b[typePath.offset] * 2 + 1;
+- bv.putByteArray(typePath.b, typePath.offset, length);
+- }
+- // write type, and reserve space for values count
+- bv.putShort(cw.newUTF8(desc)).putShort(0);
+- AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv,
+- bv.length - 2);
+- if (visible) {
+- aw.next = ctanns;
+- ctanns = aw;
+- } else {
+- aw.next = ictanns;
+- ictanns = aw;
+- }
+- return aw;
+- }
+-
+- @Override
+- public void visitLineNumber(final int line, final Label start) {
+- if (lineNumber == null) {
+- lineNumber = new ByteVector();
+- }
+- ++lineNumberCount;
+- lineNumber.putShort(start.position);
+- lineNumber.putShort(line);
+- }
+-
+- @Override
+- public void visitMaxs(final int maxStack, final int maxLocals) {
+- if (resize) {
+- // replaces the temporary jump opcodes introduced by Label.resolve.
+- if (ClassReader.RESIZE) {
+- resizeInstructions();
+- } else {
+- throw new RuntimeException("Method code too large!");
+- }
+- }
+- if (ClassReader.FRAMES && compute == FRAMES) {
+- // completes the control flow graph with exception handler blocks
+- Handler handler = firstHandler;
+- while (handler != null) {
+- Label l = handler.start.getFirst();
+- Label h = handler.handler.getFirst();
+- Label e = handler.end.getFirst();
+- // computes the kind of the edges to 'h'
+- String t = handler.desc == null ? "java/lang/Throwable"
+- : handler.desc;
+- int kind = Frame.OBJECT | cw.addType(t);
+- // h is an exception handler
+- h.status |= Label.TARGET;
+- // adds 'h' as a successor of labels between 'start' and 'end'
+- while (l != e) {
+- // creates an edge to 'h'
+- Edge b = new Edge();
+- b.info = kind;
+- b.successor = h;
+- // adds it to the successors of 'l'
+- b.next = l.successors;
+- l.successors = b;
+- // goes to the next label
+- l = l.successor;
+- }
+- handler = handler.next;
+- }
+-
+- // creates and visits the first (implicit) frame
+- Frame f = labels.frame;
+- Type[] args = Type.getArgumentTypes(descriptor);
+- f.initInputFrame(cw, access, args, this.maxLocals);
+- visitFrame(f);
+-
+- /*
+- * fix point algorithm: mark the first basic block as 'changed'
+- * (i.e. put it in the 'changed' list) and, while there are changed
+- * basic blocks, choose one, mark it as unchanged, and update its
+- * successors (which can be changed in the process).
+- */
+- int max = 0;
+- Label changed = labels;
+- while (changed != null) {
+- // removes a basic block from the list of changed basic blocks
+- Label l = changed;
+- changed = changed.next;
+- l.next = null;
+- f = l.frame;
+- // a reachable jump target must be stored in the stack map
+- if ((l.status & Label.TARGET) != 0) {
+- l.status |= Label.STORE;
+- }
+- // all visited labels are reachable, by definition
+- l.status |= Label.REACHABLE;
+- // updates the (absolute) maximum stack size
+- int blockMax = f.inputStack.length + l.outputStackMax;
+- if (blockMax > max) {
+- max = blockMax;
+- }
+- // updates the successors of the current basic block
+- Edge e = l.successors;
+- while (e != null) {
+- Label n = e.successor.getFirst();
+- boolean change = f.merge(cw, n.frame, e.info);
+- if (change && n.next == null) {
+- // if n has changed and is not already in the 'changed'
+- // list, adds it to this list
+- n.next = changed;
+- changed = n;
+- }
+- e = e.next;
+- }
+- }
+-
+- // visits all the frames that must be stored in the stack map
+- Label l = labels;
+- while (l != null) {
+- f = l.frame;
+- if ((l.status & Label.STORE) != 0) {
+- visitFrame(f);
+- }
+- if ((l.status & Label.REACHABLE) == 0) {
+- // finds start and end of dead basic block
+- Label k = l.successor;
+- int start = l.position;
+- int end = (k == null ? code.length : k.position) - 1;
+- // if non empty basic block
+- if (end >= start) {
+- max = Math.max(max, 1);
+- // replaces instructions with NOP ... NOP ATHROW
+- for (int i = start; i < end; ++i) {
+- code.data[i] = Opcodes.NOP;
+- }
+- code.data[end] = (byte) Opcodes.ATHROW;
+- // emits a frame for this unreachable block
+- int frameIndex = startFrame(start, 0, 1);
+- frame[frameIndex] = Frame.OBJECT
+- | cw.addType("java/lang/Throwable");
+- endFrame();
+- // removes the start-end range from the exception
+- // handlers
+- firstHandler = Handler.remove(firstHandler, l, k);
+- }
+- }
+- l = l.successor;
+- }
+-
+- handler = firstHandler;
+- handlerCount = 0;
+- while (handler != null) {
+- handlerCount += 1;
+- handler = handler.next;
+- }
+-
+- this.maxStack = max;
+- } else if (compute == MAXS) {
+- // completes the control flow graph with exception handler blocks
+- Handler handler = firstHandler;
+- while (handler != null) {
+- Label l = handler.start;
+- Label h = handler.handler;
+- Label e = handler.end;
+- // adds 'h' as a successor of labels between 'start' and 'end'
+- while (l != e) {
+- // creates an edge to 'h'
+- Edge b = new Edge();
+- b.info = Edge.EXCEPTION;
+- b.successor = h;
+- // adds it to the successors of 'l'
+- if ((l.status & Label.JSR) == 0) {
+- b.next = l.successors;
+- l.successors = b;
+- } else {
+- // if l is a JSR block, adds b after the first two edges
+- // to preserve the hypothesis about JSR block successors
+- // order (see {@link #visitJumpInsn})
+- b.next = l.successors.next.next;
+- l.successors.next.next = b;
+- }
+- // goes to the next label
+- l = l.successor;
+- }
+- handler = handler.next;
+- }
+-
+- if (subroutines > 0) {
+- // completes the control flow graph with the RET successors
+- /*
+- * first step: finds the subroutines. This step determines, for
+- * each basic block, to which subroutine(s) it belongs.
+- */
+- // finds the basic blocks that belong to the "main" subroutine
+- int id = 0;
+- labels.visitSubroutine(null, 1, subroutines);
+- // finds the basic blocks that belong to the real subroutines
+- Label l = labels;
+- while (l != null) {
+- if ((l.status & Label.JSR) != 0) {
+- // the subroutine is defined by l's TARGET, not by l
+- Label subroutine = l.successors.next.successor;
+- // if this subroutine has not been visited yet...
+- if ((subroutine.status & Label.VISITED) == 0) {
+- // ...assigns it a new id and finds its basic blocks
+- id += 1;
+- subroutine.visitSubroutine(null, (id / 32L) << 32
+- | (1L << (id % 32)), subroutines);
+- }
+- }
+- l = l.successor;
+- }
+- // second step: finds the successors of RET blocks
+- l = labels;
+- while (l != null) {
+- if ((l.status & Label.JSR) != 0) {
+- Label L = labels;
+- while (L != null) {
+- L.status &= ~Label.VISITED2;
+- L = L.successor;
+- }
+- // the subroutine is defined by l's TARGET, not by l
+- Label subroutine = l.successors.next.successor;
+- subroutine.visitSubroutine(l, 0, subroutines);
+- }
+- l = l.successor;
+- }
+- }
+-
+- /*
+- * control flow analysis algorithm: while the block stack is not
+- * empty, pop a block from this stack, update the max stack size,
+- * compute the true (non relative) begin stack size of the
+- * successors of this block, and push these successors onto the
+- * stack (unless they have already been pushed onto the stack).
+- * Note: by hypothesis, the {@link Label#inputStackTop} of the
+- * blocks in the block stack are the true (non relative) beginning
+- * stack sizes of these blocks.
+- */
+- int max = 0;
+- Label stack = labels;
+- while (stack != null) {
+- // pops a block from the stack
+- Label l = stack;
+- stack = stack.next;
+- // computes the true (non relative) max stack size of this block
+- int start = l.inputStackTop;
+- int blockMax = start + l.outputStackMax;
+- // updates the global max stack size
+- if (blockMax > max) {
+- max = blockMax;
+- }
+- // analyzes the successors of the block
+- Edge b = l.successors;
+- if ((l.status & Label.JSR) != 0) {
+- // ignores the first edge of JSR blocks (virtual successor)
+- b = b.next;
+- }
+- while (b != null) {
+- l = b.successor;
+- // if this successor has not already been pushed...
+- if ((l.status & Label.PUSHED) == 0) {
+- // computes its true beginning stack size...
+- l.inputStackTop = b.info == Edge.EXCEPTION ? 1 : start
+- + b.info;
+- // ...and pushes it onto the stack
+- l.status |= Label.PUSHED;
+- l.next = stack;
+- stack = l;
+- }
+- b = b.next;
+- }
+- }
+- this.maxStack = Math.max(maxStack, max);
+- } else {
+- this.maxStack = maxStack;
+- this.maxLocals = maxLocals;
+- }
+- }
+-
+- @Override
+- public void visitEnd() {
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods: control flow analysis algorithm
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Adds a successor to the {@link #currentBlock currentBlock} block.
+- *
+- * @param info
+- * information about the control flow edge to be added.
+- * @param successor
+- * the successor block to be added to the current block.
+- */
+- private void addSuccessor(final int info, final Label successor) {
+- // creates and initializes an Edge object...
+- Edge b = new Edge();
+- b.info = info;
+- b.successor = successor;
+- // ...and adds it to the successor list of the currentBlock block
+- b.next = currentBlock.successors;
+- currentBlock.successors = b;
+- }
+-
+- /**
+- * Ends the current basic block. This method must be used in the case where
+- * the current basic block does not have any successor.
+- */
+- private void noSuccessor() {
+- if (compute == FRAMES) {
+- Label l = new Label();
+- l.frame = new Frame();
+- l.frame.owner = l;
+- l.resolve(this, code.length, code.data);
+- previousBlock.successor = l;
+- previousBlock = l;
+- } else {
+- currentBlock.outputStackMax = maxStackSize;
+- }
+- currentBlock = null;
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods: stack map frames
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Visits a frame that has been computed from scratch.
+- *
+- * @param f
+- * the frame that must be visited.
+- */
+- private void visitFrame(final Frame f) {
+- int i, t;
+- int nTop = 0;
+- int nLocal = 0;
+- int nStack = 0;
+- int[] locals = f.inputLocals;
+- int[] stacks = f.inputStack;
+- // computes the number of locals (ignores TOP types that are just after
+- // a LONG or a DOUBLE, and all trailing TOP types)
+- for (i = 0; i < locals.length; ++i) {
+- t = locals[i];
+- if (t == Frame.TOP) {
+- ++nTop;
+- } else {
+- nLocal += nTop + 1;
+- nTop = 0;
+- }
+- if (t == Frame.LONG || t == Frame.DOUBLE) {
+- ++i;
+- }
+- }
+- // computes the stack size (ignores TOP types that are just after
+- // a LONG or a DOUBLE)
+- for (i = 0; i < stacks.length; ++i) {
+- t = stacks[i];
+- ++nStack;
+- if (t == Frame.LONG || t == Frame.DOUBLE) {
+- ++i;
+- }
+- }
+- // visits the frame and its content
+- int frameIndex = startFrame(f.owner.position, nLocal, nStack);
+- for (i = 0; nLocal > 0; ++i, --nLocal) {
+- t = locals[i];
+- frame[frameIndex++] = t;
+- if (t == Frame.LONG || t == Frame.DOUBLE) {
+- ++i;
+- }
+- }
+- for (i = 0; i < stacks.length; ++i) {
+- t = stacks[i];
+- frame[frameIndex++] = t;
+- if (t == Frame.LONG || t == Frame.DOUBLE) {
+- ++i;
+- }
+- }
+- endFrame();
+- }
+-
+- /**
+- * Visit the implicit first frame of this method.
+- */
+- private void visitImplicitFirstFrame() {
+- // There can be at most descriptor.length() + 1 locals
+- int frameIndex = startFrame(0, descriptor.length() + 1, 0);
+- if ((access & Opcodes.ACC_STATIC) == 0) {
+- if ((access & ACC_CONSTRUCTOR) == 0) {
+- frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
+- } else {
+- frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
+- }
+- }
+- int i = 1;
+- loop: while (true) {
+- int j = i;
+- switch (descriptor.charAt(i++)) {
+- case 'Z':
+- case 'C':
+- case 'B':
+- case 'S':
+- case 'I':
+- frame[frameIndex++] = 1; // Opcodes.INTEGER;
+- break;
+- case 'F':
+- frame[frameIndex++] = 2; // Opcodes.FLOAT;
+- break;
+- case 'J':
+- frame[frameIndex++] = 4; // Opcodes.LONG;
+- break;
+- case 'D':
+- frame[frameIndex++] = 3; // Opcodes.DOUBLE;
+- break;
+- case '[':
+- while (descriptor.charAt(i) == '[') {
+- ++i;
+- }
+- if (descriptor.charAt(i) == 'L') {
+- ++i;
+- while (descriptor.charAt(i) != ';') {
+- ++i;
+- }
+- }
+- frame[frameIndex++] = Frame.OBJECT
+- | cw.addType(descriptor.substring(j, ++i));
+- break;
+- case 'L':
+- while (descriptor.charAt(i) != ';') {
+- ++i;
+- }
+- frame[frameIndex++] = Frame.OBJECT
+- | cw.addType(descriptor.substring(j + 1, i++));
+- break;
+- default:
+- break loop;
+- }
+- }
+- frame[1] = frameIndex - 3;
+- endFrame();
+- }
+-
+- /**
+- * Starts the visit of a stack map frame.
+- *
+- * @param offset
+- * the offset of the instruction to which the frame corresponds.
+- * @param nLocal
+- * the number of local variables in the frame.
+- * @param nStack
+- * the number of stack elements in the frame.
+- * @return the index of the next element to be written in this frame.
+- */
+- private int startFrame(final int offset, final int nLocal, final int nStack) {
+- int n = 3 + nLocal + nStack;
+- if (frame == null || frame.length < n) {
+- frame = new int[n];
+- }
+- frame[0] = offset;
+- frame[1] = nLocal;
+- frame[2] = nStack;
+- return 3;
+- }
+-
+- /**
+- * Checks if the visit of the current frame {@link #frame} is finished, and
+- * if yes, write it in the StackMapTable attribute.
+- */
+- private void endFrame() {
+- if (previousFrame != null) { // do not write the first frame
+- if (stackMap == null) {
+- stackMap = new ByteVector();
+- }
+- writeFrame();
+- ++frameCount;
+- }
+- previousFrame = frame;
+- frame = null;
+- }
+-
+- /**
+- * Compress and writes the current frame {@link #frame} in the StackMapTable
+- * attribute.
+- */
+- private void writeFrame() {
+- int clocalsSize = frame[1];
+- int cstackSize = frame[2];
+- if ((cw.version & 0xFFFF) < Opcodes.V1_6) {
+- stackMap.putShort(frame[0]).putShort(clocalsSize);
+- writeFrameTypes(3, 3 + clocalsSize);
+- stackMap.putShort(cstackSize);
+- writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
+- return;
+- }
+- int localsSize = previousFrame[1];
+- int type = FULL_FRAME;
+- int k = 0;
+- int delta;
+- if (frameCount == 0) {
+- delta = frame[0];
+- } else {
+- delta = frame[0] - previousFrame[0] - 1;
+- }
+- if (cstackSize == 0) {
+- k = clocalsSize - localsSize;
+- switch (k) {
+- case -3:
+- case -2:
+- case -1:
+- type = CHOP_FRAME;
+- localsSize = clocalsSize;
+- break;
+- case 0:
+- type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
+- break;
+- case 1:
+- case 2:
+- case 3:
+- type = APPEND_FRAME;
+- break;
+- }
+- } else if (clocalsSize == localsSize && cstackSize == 1) {
+- type = delta < 63 ? SAME_LOCALS_1_STACK_ITEM_FRAME
+- : SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
+- }
+- if (type != FULL_FRAME) {
+- // verify if locals are the same
+- int l = 3;
+- for (int j = 0; j < localsSize; j++) {
+- if (frame[l] != previousFrame[l]) {
+- type = FULL_FRAME;
+- break;
+- }
+- l++;
+- }
+- }
+- switch (type) {
+- case SAME_FRAME:
+- stackMap.putByte(delta);
+- break;
+- case SAME_LOCALS_1_STACK_ITEM_FRAME:
+- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+- writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+- break;
+- case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
+- stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED).putShort(
+- delta);
+- writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+- break;
+- case SAME_FRAME_EXTENDED:
+- stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+- break;
+- case CHOP_FRAME:
+- stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+- break;
+- case APPEND_FRAME:
+- stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+- writeFrameTypes(3 + localsSize, 3 + clocalsSize);
+- break;
+- // case FULL_FRAME:
+- default:
+- stackMap.putByte(FULL_FRAME).putShort(delta).putShort(clocalsSize);
+- writeFrameTypes(3, 3 + clocalsSize);
+- stackMap.putShort(cstackSize);
+- writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
+- }
+- }
+-
+- /**
+- * Writes some types of the current frame {@link #frame} into the
+- * StackMapTableAttribute. This method converts types from the format used
+- * in {@link Label} to the format used in StackMapTable attributes. In
+- * particular, it converts type table indexes to constant pool indexes.
+- *
+- * @param start
+- * index of the first type in {@link #frame} to write.
+- * @param end
+- * index of last type in {@link #frame} to write (exclusive).
+- */
+- private void writeFrameTypes(final int start, final int end) {
+- for (int i = start; i < end; ++i) {
+- int t = frame[i];
+- int d = t & Frame.DIM;
+- if (d == 0) {
+- int v = t & Frame.BASE_VALUE;
+- switch (t & Frame.BASE_KIND) {
+- case Frame.OBJECT:
+- stackMap.putByte(7).putShort(
+- cw.newClass(cw.typeTable[v].strVal1));
+- break;
+- case Frame.UNINITIALIZED:
+- stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
+- break;
+- default:
+- stackMap.putByte(v);
+- }
+- } else {
+- StringBuffer buf = new StringBuffer();
+- d >>= 28;
+- while (d-- > 0) {
+- buf.append('[');
+- }
+- if ((t & Frame.BASE_KIND) == Frame.OBJECT) {
+- buf.append('L');
+- buf.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1);
+- buf.append(';');
+- } else {
+- switch (t & 0xF) {
+- case 1:
+- buf.append('I');
+- break;
+- case 2:
+- buf.append('F');
+- break;
+- case 3:
+- buf.append('D');
+- break;
+- case 9:
+- buf.append('Z');
+- break;
+- case 10:
+- buf.append('B');
+- break;
+- case 11:
+- buf.append('C');
+- break;
+- case 12:
+- buf.append('S');
+- break;
+- default:
+- buf.append('J');
+- }
+- }
+- stackMap.putByte(7).putShort(cw.newClass(buf.toString()));
+- }
+- }
+- }
+-
+- private void writeFrameType(final Object type) {
+- if (type instanceof String) {
+- stackMap.putByte(7).putShort(cw.newClass((String) type));
+- } else if (type instanceof Integer) {
+- stackMap.putByte(((Integer) type).intValue());
+- } else {
+- stackMap.putByte(8).putShort(((Label) type).position);
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods: dump bytecode array
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Returns the size of the bytecode of this method.
+- *
+- * @return the size of the bytecode of this method.
+- */
+- final int getSize() {
+- if (classReaderOffset != 0) {
+- return 6 + classReaderLength;
+- }
+- int size = 8;
+- if (code.length > 0) {
+- if (code.length > 65536) {
+- throw new RuntimeException("Method code too large!");
+- }
+- cw.newUTF8("Code");
+- size += 18 + code.length + 8 * handlerCount;
+- if (localVar != null) {
+- cw.newUTF8("LocalVariableTable");
+- size += 8 + localVar.length;
+- }
+- if (localVarType != null) {
+- cw.newUTF8("LocalVariableTypeTable");
+- size += 8 + localVarType.length;
+- }
+- if (lineNumber != null) {
+- cw.newUTF8("LineNumberTable");
+- size += 8 + lineNumber.length;
+- }
+- if (stackMap != null) {
+- boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6;
+- cw.newUTF8(zip ? "StackMapTable" : "StackMap");
+- size += 8 + stackMap.length;
+- }
+- if (ClassReader.ANNOTATIONS && ctanns != null) {
+- cw.newUTF8("RuntimeVisibleTypeAnnotations");
+- size += 8 + ctanns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && ictanns != null) {
+- cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+- size += 8 + ictanns.getSize();
+- }
+- if (cattrs != null) {
+- size += cattrs.getSize(cw, code.data, code.length, maxStack,
+- maxLocals);
+- }
+- }
+- if (exceptionCount > 0) {
+- cw.newUTF8("Exceptions");
+- size += 8 + 2 * exceptionCount;
+- }
+- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+- if ((cw.version & 0xFFFF) < Opcodes.V1_5
+- || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+- cw.newUTF8("Synthetic");
+- size += 6;
+- }
+- }
+- if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+- cw.newUTF8("Deprecated");
+- size += 6;
+- }
+- if (ClassReader.SIGNATURES && signature != null) {
+- cw.newUTF8("Signature");
+- cw.newUTF8(signature);
+- size += 8;
+- }
+- if (methodParameters != null) {
+- cw.newUTF8("MethodParameters");
+- size += 7 + methodParameters.length;
+- }
+- if (ClassReader.ANNOTATIONS && annd != null) {
+- cw.newUTF8("AnnotationDefault");
+- size += 6 + annd.length;
+- }
+- if (ClassReader.ANNOTATIONS && anns != null) {
+- cw.newUTF8("RuntimeVisibleAnnotations");
+- size += 8 + anns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && ianns != null) {
+- cw.newUTF8("RuntimeInvisibleAnnotations");
+- size += 8 + ianns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && tanns != null) {
+- cw.newUTF8("RuntimeVisibleTypeAnnotations");
+- size += 8 + tanns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && itanns != null) {
+- cw.newUTF8("RuntimeInvisibleTypeAnnotations");
+- size += 8 + itanns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && panns != null) {
+- cw.newUTF8("RuntimeVisibleParameterAnnotations");
+- size += 7 + 2 * (panns.length - synthetics);
+- for (int i = panns.length - 1; i >= synthetics; --i) {
+- size += panns[i] == null ? 0 : panns[i].getSize();
+- }
+- }
+- if (ClassReader.ANNOTATIONS && ipanns != null) {
+- cw.newUTF8("RuntimeInvisibleParameterAnnotations");
+- size += 7 + 2 * (ipanns.length - synthetics);
+- for (int i = ipanns.length - 1; i >= synthetics; --i) {
+- size += ipanns[i] == null ? 0 : ipanns[i].getSize();
+- }
+- }
+- if (attrs != null) {
+- size += attrs.getSize(cw, null, 0, -1, -1);
+- }
+- return size;
+- }
+-
+- /**
+- * Puts the bytecode of this method in the given byte vector.
+- *
+- * @param out
+- * the byte vector into which the bytecode of this method must be
+- * copied.
+- */
+- final void put(final ByteVector out) {
+- final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;
+- int mask = ACC_CONSTRUCTOR | Opcodes.ACC_DEPRECATED
+- | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+- | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR);
+- out.putShort(access & ~mask).putShort(name).putShort(desc);
+- if (classReaderOffset != 0) {
+- out.putByteArray(cw.cr.b, classReaderOffset, classReaderLength);
+- return;
+- }
+- int attributeCount = 0;
+- if (code.length > 0) {
+- ++attributeCount;
+- }
+- if (exceptionCount > 0) {
+- ++attributeCount;
+- }
+- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+- if ((cw.version & 0xFFFF) < Opcodes.V1_5
+- || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+- ++attributeCount;
+- }
+- }
+- if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+- ++attributeCount;
+- }
+- if (ClassReader.SIGNATURES && signature != null) {
+- ++attributeCount;
+- }
+- if (methodParameters != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && annd != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && anns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && ianns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && tanns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && itanns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && panns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && ipanns != null) {
+- ++attributeCount;
+- }
+- if (attrs != null) {
+- attributeCount += attrs.getCount();
+- }
+- out.putShort(attributeCount);
+- if (code.length > 0) {
+- int size = 12 + code.length + 8 * handlerCount;
+- if (localVar != null) {
+- size += 8 + localVar.length;
+- }
+- if (localVarType != null) {
+- size += 8 + localVarType.length;
+- }
+- if (lineNumber != null) {
+- size += 8 + lineNumber.length;
+- }
+- if (stackMap != null) {
+- size += 8 + stackMap.length;
+- }
+- if (ClassReader.ANNOTATIONS && ctanns != null) {
+- size += 8 + ctanns.getSize();
+- }
+- if (ClassReader.ANNOTATIONS && ictanns != null) {
+- size += 8 + ictanns.getSize();
+- }
+- if (cattrs != null) {
+- size += cattrs.getSize(cw, code.data, code.length, maxStack,
+- maxLocals);
+- }
+- out.putShort(cw.newUTF8("Code")).putInt(size);
+- out.putShort(maxStack).putShort(maxLocals);
+- out.putInt(code.length).putByteArray(code.data, 0, code.length);
+- out.putShort(handlerCount);
+- if (handlerCount > 0) {
+- Handler h = firstHandler;
+- while (h != null) {
+- out.putShort(h.start.position).putShort(h.end.position)
+- .putShort(h.handler.position).putShort(h.type);
+- h = h.next;
+- }
+- }
+- attributeCount = 0;
+- if (localVar != null) {
+- ++attributeCount;
+- }
+- if (localVarType != null) {
+- ++attributeCount;
+- }
+- if (lineNumber != null) {
+- ++attributeCount;
+- }
+- if (stackMap != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && ctanns != null) {
+- ++attributeCount;
+- }
+- if (ClassReader.ANNOTATIONS && ictanns != null) {
+- ++attributeCount;
+- }
+- if (cattrs != null) {
+- attributeCount += cattrs.getCount();
+- }
+- out.putShort(attributeCount);
+- if (localVar != null) {
+- out.putShort(cw.newUTF8("LocalVariableTable"));
+- out.putInt(localVar.length + 2).putShort(localVarCount);
+- out.putByteArray(localVar.data, 0, localVar.length);
+- }
+- if (localVarType != null) {
+- out.putShort(cw.newUTF8("LocalVariableTypeTable"));
+- out.putInt(localVarType.length + 2).putShort(localVarTypeCount);
+- out.putByteArray(localVarType.data, 0, localVarType.length);
+- }
+- if (lineNumber != null) {
+- out.putShort(cw.newUTF8("LineNumberTable"));
+- out.putInt(lineNumber.length + 2).putShort(lineNumberCount);
+- out.putByteArray(lineNumber.data, 0, lineNumber.length);
+- }
+- if (stackMap != null) {
+- boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6;
+- out.putShort(cw.newUTF8(zip ? "StackMapTable" : "StackMap"));
+- out.putInt(stackMap.length + 2).putShort(frameCount);
+- out.putByteArray(stackMap.data, 0, stackMap.length);
+- }
+- if (ClassReader.ANNOTATIONS && ctanns != null) {
+- out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+- ctanns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && ictanns != null) {
+- out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+- ictanns.put(out);
+- }
+- if (cattrs != null) {
+- cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out);
+- }
+- }
+- if (exceptionCount > 0) {
+- out.putShort(cw.newUTF8("Exceptions")).putInt(
+- 2 * exceptionCount + 2);
+- out.putShort(exceptionCount);
+- for (int i = 0; i < exceptionCount; ++i) {
+- out.putShort(exceptions[i]);
+- }
+- }
+- if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+- if ((cw.version & 0xFFFF) < Opcodes.V1_5
+- || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) {
+- out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+- }
+- }
+- if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+- out.putShort(cw.newUTF8("Deprecated")).putInt(0);
+- }
+- if (ClassReader.SIGNATURES && signature != null) {
+- out.putShort(cw.newUTF8("Signature")).putInt(2)
+- .putShort(cw.newUTF8(signature));
+- }
+- if (methodParameters != null) {
+- out.putShort(cw.newUTF8("MethodParameters"));
+- out.putInt(methodParameters.length + 1).putByte(
+- methodParametersCount);
+- out.putByteArray(methodParameters.data, 0, methodParameters.length);
+- }
+- if (ClassReader.ANNOTATIONS && annd != null) {
+- out.putShort(cw.newUTF8("AnnotationDefault"));
+- out.putInt(annd.length);
+- out.putByteArray(annd.data, 0, annd.length);
+- }
+- if (ClassReader.ANNOTATIONS && anns != null) {
+- out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
+- anns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && ianns != null) {
+- out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
+- ianns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && tanns != null) {
+- out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
+- tanns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && itanns != null) {
+- out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
+- itanns.put(out);
+- }
+- if (ClassReader.ANNOTATIONS && panns != null) {
+- out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
+- AnnotationWriter.put(panns, synthetics, out);
+- }
+- if (ClassReader.ANNOTATIONS && ipanns != null) {
+- out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
+- AnnotationWriter.put(ipanns, synthetics, out);
+- }
+- if (attrs != null) {
+- attrs.put(cw, null, 0, -1, -1, out);
+- }
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W)
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Resizes and replaces the temporary instructions inserted by
+- * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
+- * and instruction addresses consistent. This may require to resize other
+- * existing instructions, or even to introduce new instructions: for
+- * example, increasing the size of an instruction by 2 at the middle of a
+- * method can increases the offset of an IFEQ instruction from 32766 to
+- * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
+- * 32765. This, in turn, may require to increase the size of another jump
+- * instruction, and so on... All these operations are handled automatically
+- * by this method.
+- *
+- * This method must be called after all the method that is being built
+- * has been visited . In particular, the {@link Label Label} objects used
+- * to construct the method are no longer valid after this method has been
+- * called.
+- */
+- private void resizeInstructions() {
+- byte[] b = code.data; // bytecode of the method
+- int u, v, label; // indexes in b
+- int i, j; // loop indexes
+- /*
+- * 1st step: As explained above, resizing an instruction may require to
+- * resize another one, which may require to resize yet another one, and
+- * so on. The first step of the algorithm consists in finding all the
+- * instructions that need to be resized, without modifying the code.
+- * This is done by the following "fix point" algorithm:
+- *
+- * Parse the code to find the jump instructions whose offset will need
+- * more than 2 bytes to be stored (the future offset is computed from
+- * the current offset and from the number of bytes that will be inserted
+- * or removed between the source and target instructions). For each such
+- * instruction, adds an entry in (a copy of) the indexes and sizes
+- * arrays (if this has not already been done in a previous iteration!).
+- *
+- * If at least one entry has been added during the previous step, go
+- * back to the beginning, otherwise stop.
+- *
+- * In fact the real algorithm is complicated by the fact that the size
+- * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
+- * position in the bytecode (because of padding). In order to ensure the
+- * convergence of the algorithm, the number of bytes to be added or
+- * removed from these instructions is over estimated during the previous
+- * loop, and computed exactly only after the loop is finished (this
+- * requires another pass to parse the bytecode of the method).
+- */
+- int[] allIndexes = new int[0]; // copy of indexes
+- int[] allSizes = new int[0]; // copy of sizes
+- boolean[] resize; // instructions to be resized
+- int newOffset; // future offset of a jump instruction
+-
+- resize = new boolean[code.length];
+-
+- // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
+- int state = 3;
+- do {
+- if (state == 3) {
+- state = 2;
+- }
+- u = 0;
+- while (u < b.length) {
+- int opcode = b[u] & 0xFF; // opcode of current instruction
+- int insert = 0; // bytes to be added after this instruction
+-
+- switch (ClassWriter.TYPE[opcode]) {
+- case ClassWriter.NOARG_INSN:
+- case ClassWriter.IMPLVAR_INSN:
+- u += 1;
+- break;
+- case ClassWriter.LABEL_INSN:
+- if (opcode > 201) {
+- // converts temporary opcodes 202 to 217, 218 and
+- // 219 to IFEQ ... JSR (inclusive), IFNULL and
+- // IFNONNULL
+- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+- label = u + readUnsignedShort(b, u + 1);
+- } else {
+- label = u + readShort(b, u + 1);
+- }
+- newOffset = getNewOffset(allIndexes, allSizes, u, label);
+- if (newOffset < Short.MIN_VALUE
+- || newOffset > Short.MAX_VALUE) {
+- if (!resize[u]) {
+- if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+- // two additional bytes will be required to
+- // replace this GOTO or JSR instruction with
+- // a GOTO_W or a JSR_W
+- insert = 2;
+- } else {
+- // five additional bytes will be required to
+- // replace this IFxxx instruction with
+- // IFNOTxxx GOTO_W , where IFNOTxxx
+- // is the "opposite" opcode of IFxxx (i.e.,
+- // IFNE for IFEQ) and where designates
+- // the instruction just after the GOTO_W.
+- insert = 5;
+- }
+- resize[u] = true;
+- }
+- }
+- u += 3;
+- break;
+- case ClassWriter.LABELW_INSN:
+- u += 5;
+- break;
+- case ClassWriter.TABL_INSN:
+- if (state == 1) {
+- // true number of bytes to be added (or removed)
+- // from this instruction = (future number of padding
+- // bytes - current number of padding byte) -
+- // previously over estimated variation =
+- // = ((3 - newOffset%4) - (3 - u%4)) - u%4
+- // = (-newOffset%4 + u%4) - u%4
+- // = -(newOffset & 3)
+- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+- insert = -(newOffset & 3);
+- } else if (!resize[u]) {
+- // over estimation of the number of bytes to be
+- // added to this instruction = 3 - current number
+- // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
+- insert = u & 3;
+- resize[u] = true;
+- }
+- // skips instruction
+- u = u + 4 - (u & 3);
+- u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
+- break;
+- case ClassWriter.LOOK_INSN:
+- if (state == 1) {
+- // like TABL_INSN
+- newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+- insert = -(newOffset & 3);
+- } else if (!resize[u]) {
+- // like TABL_INSN
+- insert = u & 3;
+- resize[u] = true;
+- }
+- // skips instruction
+- u = u + 4 - (u & 3);
+- u += 8 * readInt(b, u + 4) + 8;
+- break;
+- case ClassWriter.WIDE_INSN:
+- opcode = b[u + 1] & 0xFF;
+- if (opcode == Opcodes.IINC) {
+- u += 6;
+- } else {
+- u += 4;
+- }
+- break;
+- case ClassWriter.VAR_INSN:
+- case ClassWriter.SBYTE_INSN:
+- case ClassWriter.LDC_INSN:
+- u += 2;
+- break;
+- case ClassWriter.SHORT_INSN:
+- case ClassWriter.LDCW_INSN:
+- case ClassWriter.FIELDORMETH_INSN:
+- case ClassWriter.TYPE_INSN:
+- case ClassWriter.IINC_INSN:
+- u += 3;
+- break;
+- case ClassWriter.ITFMETH_INSN:
+- case ClassWriter.INDYMETH_INSN:
+- u += 5;
+- break;
+- // case ClassWriter.MANA_INSN:
+- default:
+- u += 4;
+- break;
+- }
+- if (insert != 0) {
+- // adds a new (u, insert) entry in the allIndexes and
+- // allSizes arrays
+- int[] newIndexes = new int[allIndexes.length + 1];
+- int[] newSizes = new int[allSizes.length + 1];
+- System.arraycopy(allIndexes, 0, newIndexes, 0,
+- allIndexes.length);
+- System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
+- newIndexes[allIndexes.length] = u;
+- newSizes[allSizes.length] = insert;
+- allIndexes = newIndexes;
+- allSizes = newSizes;
+- if (insert > 0) {
+- state = 3;
+- }
+- }
+- }
+- if (state < 3) {
+- --state;
+- }
+- } while (state != 0);
+-
+- // 2nd step:
+- // copies the bytecode of the method into a new bytevector, updates the
+- // offsets, and inserts (or removes) bytes as requested.
+-
+- ByteVector newCode = new ByteVector(code.length);
+-
+- u = 0;
+- while (u < code.length) {
+- int opcode = b[u] & 0xFF;
+- switch (ClassWriter.TYPE[opcode]) {
+- case ClassWriter.NOARG_INSN:
+- case ClassWriter.IMPLVAR_INSN:
+- newCode.putByte(opcode);
+- u += 1;
+- break;
+- case ClassWriter.LABEL_INSN:
+- if (opcode > 201) {
+- // changes temporary opcodes 202 to 217 (inclusive), 218
+- // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+- // IFNONNULL
+- opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+- label = u + readUnsignedShort(b, u + 1);
+- } else {
+- label = u + readShort(b, u + 1);
+- }
+- newOffset = getNewOffset(allIndexes, allSizes, u, label);
+- if (resize[u]) {
+- // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+- // with IFNOTxxx GOTO_W , where IFNOTxxx is
+- // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+- // and where designates the instruction just after
+- // the GOTO_W.
+- if (opcode == Opcodes.GOTO) {
+- newCode.putByte(200); // GOTO_W
+- } else if (opcode == Opcodes.JSR) {
+- newCode.putByte(201); // JSR_W
+- } else {
+- newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+- : opcode ^ 1);
+- newCode.putShort(8); // jump offset
+- newCode.putByte(200); // GOTO_W
+- // newOffset now computed from start of GOTO_W
+- newOffset -= 3;
+- }
+- newCode.putInt(newOffset);
+- } else {
+- newCode.putByte(opcode);
+- newCode.putShort(newOffset);
+- }
+- u += 3;
+- break;
+- case ClassWriter.LABELW_INSN:
+- label = u + readInt(b, u + 1);
+- newOffset = getNewOffset(allIndexes, allSizes, u, label);
+- newCode.putByte(opcode);
+- newCode.putInt(newOffset);
+- u += 5;
+- break;
+- case ClassWriter.TABL_INSN:
+- // skips 0 to 3 padding bytes
+- v = u;
+- u = u + 4 - (v & 3);
+- // reads and copies instruction
+- newCode.putByte(Opcodes.TABLESWITCH);
+- newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+- label = v + readInt(b, u);
+- u += 4;
+- newOffset = getNewOffset(allIndexes, allSizes, v, label);
+- newCode.putInt(newOffset);
+- j = readInt(b, u);
+- u += 4;
+- newCode.putInt(j);
+- j = readInt(b, u) - j + 1;
+- u += 4;
+- newCode.putInt(readInt(b, u - 4));
+- for (; j > 0; --j) {
+- label = v + readInt(b, u);
+- u += 4;
+- newOffset = getNewOffset(allIndexes, allSizes, v, label);
+- newCode.putInt(newOffset);
+- }
+- break;
+- case ClassWriter.LOOK_INSN:
+- // skips 0 to 3 padding bytes
+- v = u;
+- u = u + 4 - (v & 3);
+- // reads and copies instruction
+- newCode.putByte(Opcodes.LOOKUPSWITCH);
+- newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
+- label = v + readInt(b, u);
+- u += 4;
+- newOffset = getNewOffset(allIndexes, allSizes, v, label);
+- newCode.putInt(newOffset);
+- j = readInt(b, u);
+- u += 4;
+- newCode.putInt(j);
+- for (; j > 0; --j) {
+- newCode.putInt(readInt(b, u));
+- u += 4;
+- label = v + readInt(b, u);
+- u += 4;
+- newOffset = getNewOffset(allIndexes, allSizes, v, label);
+- newCode.putInt(newOffset);
+- }
+- break;
+- case ClassWriter.WIDE_INSN:
+- opcode = b[u + 1] & 0xFF;
+- if (opcode == Opcodes.IINC) {
+- newCode.putByteArray(b, u, 6);
+- u += 6;
+- } else {
+- newCode.putByteArray(b, u, 4);
+- u += 4;
+- }
+- break;
+- case ClassWriter.VAR_INSN:
+- case ClassWriter.SBYTE_INSN:
+- case ClassWriter.LDC_INSN:
+- newCode.putByteArray(b, u, 2);
+- u += 2;
+- break;
+- case ClassWriter.SHORT_INSN:
+- case ClassWriter.LDCW_INSN:
+- case ClassWriter.FIELDORMETH_INSN:
+- case ClassWriter.TYPE_INSN:
+- case ClassWriter.IINC_INSN:
+- newCode.putByteArray(b, u, 3);
+- u += 3;
+- break;
+- case ClassWriter.ITFMETH_INSN:
+- case ClassWriter.INDYMETH_INSN:
+- newCode.putByteArray(b, u, 5);
+- u += 5;
+- break;
+- // case MANA_INSN:
+- default:
+- newCode.putByteArray(b, u, 4);
+- u += 4;
+- break;
+- }
+- }
+-
+- // updates the stack map frame labels
+- if (compute == FRAMES) {
+- Label l = labels;
+- while (l != null) {
+- /*
+- * Detects the labels that are just after an IF instruction that
+- * has been resized with the IFNOT GOTO_W pattern. These labels
+- * are now the target of a jump instruction (the IFNOT
+- * instruction). Note that we need the original label position
+- * here. getNewOffset must therefore never have been called for
+- * this label.
+- */
+- u = l.position - 3;
+- if (u >= 0 && resize[u]) {
+- l.status |= Label.TARGET;
+- }
+- getNewOffset(allIndexes, allSizes, l);
+- l = l.successor;
+- }
+- // Update the offsets in the uninitialized types
+- for (i = 0; i < cw.typeTable.length; ++i) {
+- Item item = cw.typeTable[i];
+- if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
+- item.intVal = getNewOffset(allIndexes, allSizes, 0,
+- item.intVal);
+- }
+- }
+- // The stack map frames are not serialized yet, so we don't need
+- // to update them. They will be serialized in visitMaxs.
+- } else if (frameCount > 0) {
+- /*
+- * Resizing an existing stack map frame table is really hard. Not
+- * only the table must be parsed to update the offets, but new
+- * frames may be needed for jump instructions that were inserted by
+- * this method. And updating the offsets or inserting frames can
+- * change the format of the following frames, in case of packed
+- * frames. In practice the whole table must be recomputed. For this
+- * the frames are marked as potentially invalid. This will cause the
+- * whole class to be reread and rewritten with the COMPUTE_FRAMES
+- * option (see the ClassWriter.toByteArray method). This is not very
+- * efficient but is much easier and requires much less code than any
+- * other method I can think of.
+- */
+- cw.invalidFrames = true;
+- }
+- // updates the exception handler block labels
+- Handler h = firstHandler;
+- while (h != null) {
+- getNewOffset(allIndexes, allSizes, h.start);
+- getNewOffset(allIndexes, allSizes, h.end);
+- getNewOffset(allIndexes, allSizes, h.handler);
+- h = h.next;
+- }
+- // updates the instructions addresses in the
+- // local var and line number tables
+- for (i = 0; i < 2; ++i) {
+- ByteVector bv = i == 0 ? localVar : localVarType;
+- if (bv != null) {
+- b = bv.data;
+- u = 0;
+- while (u < bv.length) {
+- label = readUnsignedShort(b, u);
+- newOffset = getNewOffset(allIndexes, allSizes, 0, label);
+- writeShort(b, u, newOffset);
+- label += readUnsignedShort(b, u + 2);
+- newOffset = getNewOffset(allIndexes, allSizes, 0, label)
+- - newOffset;
+- writeShort(b, u + 2, newOffset);
+- u += 10;
+- }
+- }
+- }
+- if (lineNumber != null) {
+- b = lineNumber.data;
+- u = 0;
+- while (u < lineNumber.length) {
+- writeShort(
+- b,
+- u,
+- getNewOffset(allIndexes, allSizes, 0,
+- readUnsignedShort(b, u)));
+- u += 4;
+- }
+- }
+- // updates the labels of the other attributes
+- Attribute attr = cattrs;
+- while (attr != null) {
+- Label[] labels = attr.getLabels();
+- if (labels != null) {
+- for (i = labels.length - 1; i >= 0; --i) {
+- getNewOffset(allIndexes, allSizes, labels[i]);
+- }
+- }
+- attr = attr.next;
+- }
+-
+- // replaces old bytecodes with new ones
+- code = newCode;
+- }
+-
+- /**
+- * Reads an unsigned short value in the given byte array.
+- *
+- * @param b
+- * a byte array.
+- * @param index
+- * the start index of the value to be read.
+- * @return the read value.
+- */
+- static int readUnsignedShort(final byte[] b, final int index) {
+- return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
+- }
+-
+- /**
+- * Reads a signed short value in the given byte array.
+- *
+- * @param b
+- * a byte array.
+- * @param index
+- * the start index of the value to be read.
+- * @return the read value.
+- */
+- static short readShort(final byte[] b, final int index) {
+- return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
+- }
+-
+- /**
+- * Reads a signed int value in the given byte array.
+- *
+- * @param b
+- * a byte array.
+- * @param index
+- * the start index of the value to be read.
+- * @return the read value.
+- */
+- static int readInt(final byte[] b, final int index) {
+- return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
+- | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
+- }
+-
+- /**
+- * Writes a short value in the given byte array.
+- *
+- * @param b
+- * a byte array.
+- * @param index
+- * where the first byte of the short value must be written.
+- * @param s
+- * the value to be written in the given byte array.
+- */
+- static void writeShort(final byte[] b, final int index, final int s) {
+- b[index] = (byte) (s >>> 8);
+- b[index + 1] = (byte) s;
+- }
+-
+- /**
+- * Computes the future value of a bytecode offset.
+- *
+- * Note: it is possible to have several entries for the same instruction in
+- * the indexes and sizes : two entries (index=a,size=b) and
+- * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
+- *
+- * @param indexes
+- * current positions of the instructions to be resized. Each
+- * instruction must be designated by the index of its last
+- * byte, plus one (or, in other words, by the index of the
+- * first byte of the next instruction).
+- * @param sizes
+- * the number of bytes to be added to the above
+- * instructions. More precisely, for each i < len ,
+- * sizes [i] bytes will be added at the end of the
+- * instruction designated by indexes [i] or, if
+- * sizes [i] is negative, the last |
+- * sizes[i] | bytes of the instruction will be removed
+- * (the instruction size must not become negative or
+- * null).
+- * @param begin
+- * index of the first byte of the source instruction.
+- * @param end
+- * index of the first byte of the target instruction.
+- * @return the future value of the given bytecode offset.
+- */
+- static int getNewOffset(final int[] indexes, final int[] sizes,
+- final int begin, final int end) {
+- int offset = end - begin;
+- for (int i = 0; i < indexes.length; ++i) {
+- if (begin < indexes[i] && indexes[i] <= end) {
+- // forward jump
+- offset += sizes[i];
+- } else if (end < indexes[i] && indexes[i] <= begin) {
+- // backward jump
+- offset -= sizes[i];
+- }
+- }
+- return offset;
+- }
+-
+- /**
+- * Updates the offset of the given label.
+- *
+- * @param indexes
+- * current positions of the instructions to be resized. Each
+- * instruction must be designated by the index of its last
+- * byte, plus one (or, in other words, by the index of the
+- * first byte of the next instruction).
+- * @param sizes
+- * the number of bytes to be added to the above
+- * instructions. More precisely, for each i < len ,
+- * sizes [i] bytes will be added at the end of the
+- * instruction designated by indexes [i] or, if
+- * sizes [i] is negative, the last |
+- * sizes[i] | bytes of the instruction will be removed
+- * (the instruction size must not become negative or
+- * null).
+- * @param label
+- * the label whose offset must be updated.
+- */
+- static void getNewOffset(final int[] indexes, final int[] sizes,
+- final Label label) {
+- if ((label.status & Label.RESIZED) == 0) {
+- label.position = getNewOffset(indexes, sizes, 0, label.position);
+- label.status |= Label.RESIZED;
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Opcodes.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Opcodes.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/Opcodes.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/Opcodes.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,361 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm;
+-
+-/**
+- * Defines the JVM opcodes, access flags and array type codes. This interface
+- * does not define all the JVM opcodes because some opcodes are automatically
+- * handled. For example, the xLOAD and xSTORE opcodes are automatically replaced
+- * by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n
+- * opcodes are therefore not defined in this interface. Likewise for LDC,
+- * automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and
+- * JSR_W.
+- *
+- * @author Eric Bruneton
+- * @author Eugene Kuleshov
+- */
+-public interface Opcodes {
+-
+- // ASM API versions
+-
+- int ASM4 = 4 << 16 | 0 << 8 | 0;
+- int ASM5 = 5 << 16 | 0 << 8 | 0;
+-
+- // versions
+-
+- int V1_1 = 3 << 16 | 45;
+- int V1_2 = 0 << 16 | 46;
+- int V1_3 = 0 << 16 | 47;
+- int V1_4 = 0 << 16 | 48;
+- int V1_5 = 0 << 16 | 49;
+- int V1_6 = 0 << 16 | 50;
+- int V1_7 = 0 << 16 | 51;
+- int V1_8 = 0 << 16 | 52;
+-
+- // access flags
+-
+- int ACC_PUBLIC = 0x0001; // class, field, method
+- int ACC_PRIVATE = 0x0002; // class, field, method
+- int ACC_PROTECTED = 0x0004; // class, field, method
+- int ACC_STATIC = 0x0008; // field, method
+- int ACC_FINAL = 0x0010; // class, field, method, parameter
+- int ACC_SUPER = 0x0020; // class
+- int ACC_SYNCHRONIZED = 0x0020; // method
+- int ACC_VOLATILE = 0x0040; // field
+- int ACC_BRIDGE = 0x0040; // method
+- int ACC_VARARGS = 0x0080; // method
+- int ACC_TRANSIENT = 0x0080; // field
+- int ACC_NATIVE = 0x0100; // method
+- int ACC_INTERFACE = 0x0200; // class
+- int ACC_ABSTRACT = 0x0400; // class, method
+- int ACC_STRICT = 0x0800; // method
+- int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
+- int ACC_ANNOTATION = 0x2000; // class
+- int ACC_ENUM = 0x4000; // class(?) field inner
+- int ACC_MANDATED = 0x8000; // parameter
+-
+- // ASM specific pseudo access flags
+-
+- int ACC_DEPRECATED = 0x20000; // class, field, method
+-
+- // types for NEWARRAY
+-
+- int T_BOOLEAN = 4;
+- int T_CHAR = 5;
+- int T_FLOAT = 6;
+- int T_DOUBLE = 7;
+- int T_BYTE = 8;
+- int T_SHORT = 9;
+- int T_INT = 10;
+- int T_LONG = 11;
+-
+- // tags for Handle
+-
+- int H_GETFIELD = 1;
+- int H_GETSTATIC = 2;
+- int H_PUTFIELD = 3;
+- int H_PUTSTATIC = 4;
+- int H_INVOKEVIRTUAL = 5;
+- int H_INVOKESTATIC = 6;
+- int H_INVOKESPECIAL = 7;
+- int H_NEWINVOKESPECIAL = 8;
+- int H_INVOKEINTERFACE = 9;
+-
+- // stack map frame types
+-
+- /**
+- * Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}.
+- */
+- int F_NEW = -1;
+-
+- /**
+- * Represents a compressed frame with complete frame data.
+- */
+- int F_FULL = 0;
+-
+- /**
+- * Represents a compressed frame where locals are the same as the locals in
+- * the previous frame, except that additional 1-3 locals are defined, and
+- * with an empty stack.
+- */
+- int F_APPEND = 1;
+-
+- /**
+- * Represents a compressed frame where locals are the same as the locals in
+- * the previous frame, except that the last 1-3 locals are absent and with
+- * an empty stack.
+- */
+- int F_CHOP = 2;
+-
+- /**
+- * Represents a compressed frame with exactly the same locals as the
+- * previous frame and with an empty stack.
+- */
+- int F_SAME = 3;
+-
+- /**
+- * Represents a compressed frame with exactly the same locals as the
+- * previous frame and with a single value on the stack.
+- */
+- int F_SAME1 = 4;
+-
+- Integer TOP = new Integer(0);
+- Integer INTEGER = new Integer(1);
+- Integer FLOAT = new Integer(2);
+- Integer DOUBLE = new Integer(3);
+- Integer LONG = new Integer(4);
+- Integer NULL = new Integer(5);
+- Integer UNINITIALIZED_THIS = new Integer(6);
+-
+- // opcodes // visit method (- = idem)
+-
+- int NOP = 0; // visitInsn
+- int ACONST_NULL = 1; // -
+- int ICONST_M1 = 2; // -
+- int ICONST_0 = 3; // -
+- int ICONST_1 = 4; // -
+- int ICONST_2 = 5; // -
+- int ICONST_3 = 6; // -
+- int ICONST_4 = 7; // -
+- int ICONST_5 = 8; // -
+- int LCONST_0 = 9; // -
+- int LCONST_1 = 10; // -
+- int FCONST_0 = 11; // -
+- int FCONST_1 = 12; // -
+- int FCONST_2 = 13; // -
+- int DCONST_0 = 14; // -
+- int DCONST_1 = 15; // -
+- int BIPUSH = 16; // visitIntInsn
+- int SIPUSH = 17; // -
+- int LDC = 18; // visitLdcInsn
+- // int LDC_W = 19; // -
+- // int LDC2_W = 20; // -
+- int ILOAD = 21; // visitVarInsn
+- int LLOAD = 22; // -
+- int FLOAD = 23; // -
+- int DLOAD = 24; // -
+- int ALOAD = 25; // -
+- // int ILOAD_0 = 26; // -
+- // int ILOAD_1 = 27; // -
+- // int ILOAD_2 = 28; // -
+- // int ILOAD_3 = 29; // -
+- // int LLOAD_0 = 30; // -
+- // int LLOAD_1 = 31; // -
+- // int LLOAD_2 = 32; // -
+- // int LLOAD_3 = 33; // -
+- // int FLOAD_0 = 34; // -
+- // int FLOAD_1 = 35; // -
+- // int FLOAD_2 = 36; // -
+- // int FLOAD_3 = 37; // -
+- // int DLOAD_0 = 38; // -
+- // int DLOAD_1 = 39; // -
+- // int DLOAD_2 = 40; // -
+- // int DLOAD_3 = 41; // -
+- // int ALOAD_0 = 42; // -
+- // int ALOAD_1 = 43; // -
+- // int ALOAD_2 = 44; // -
+- // int ALOAD_3 = 45; // -
+- int IALOAD = 46; // visitInsn
+- int LALOAD = 47; // -
+- int FALOAD = 48; // -
+- int DALOAD = 49; // -
+- int AALOAD = 50; // -
+- int BALOAD = 51; // -
+- int CALOAD = 52; // -
+- int SALOAD = 53; // -
+- int ISTORE = 54; // visitVarInsn
+- int LSTORE = 55; // -
+- int FSTORE = 56; // -
+- int DSTORE = 57; // -
+- int ASTORE = 58; // -
+- // int ISTORE_0 = 59; // -
+- // int ISTORE_1 = 60; // -
+- // int ISTORE_2 = 61; // -
+- // int ISTORE_3 = 62; // -
+- // int LSTORE_0 = 63; // -
+- // int LSTORE_1 = 64; // -
+- // int LSTORE_2 = 65; // -
+- // int LSTORE_3 = 66; // -
+- // int FSTORE_0 = 67; // -
+- // int FSTORE_1 = 68; // -
+- // int FSTORE_2 = 69; // -
+- // int FSTORE_3 = 70; // -
+- // int DSTORE_0 = 71; // -
+- // int DSTORE_1 = 72; // -
+- // int DSTORE_2 = 73; // -
+- // int DSTORE_3 = 74; // -
+- // int ASTORE_0 = 75; // -
+- // int ASTORE_1 = 76; // -
+- // int ASTORE_2 = 77; // -
+- // int ASTORE_3 = 78; // -
+- int IASTORE = 79; // visitInsn
+- int LASTORE = 80; // -
+- int FASTORE = 81; // -
+- int DASTORE = 82; // -
+- int AASTORE = 83; // -
+- int BASTORE = 84; // -
+- int CASTORE = 85; // -
+- int SASTORE = 86; // -
+- int POP = 87; // -
+- int POP2 = 88; // -
+- int DUP = 89; // -
+- int DUP_X1 = 90; // -
+- int DUP_X2 = 91; // -
+- int DUP2 = 92; // -
+- int DUP2_X1 = 93; // -
+- int DUP2_X2 = 94; // -
+- int SWAP = 95; // -
+- int IADD = 96; // -
+- int LADD = 97; // -
+- int FADD = 98; // -
+- int DADD = 99; // -
+- int ISUB = 100; // -
+- int LSUB = 101; // -
+- int FSUB = 102; // -
+- int DSUB = 103; // -
+- int IMUL = 104; // -
+- int LMUL = 105; // -
+- int FMUL = 106; // -
+- int DMUL = 107; // -
+- int IDIV = 108; // -
+- int LDIV = 109; // -
+- int FDIV = 110; // -
+- int DDIV = 111; // -
+- int IREM = 112; // -
+- int LREM = 113; // -
+- int FREM = 114; // -
+- int DREM = 115; // -
+- int INEG = 116; // -
+- int LNEG = 117; // -
+- int FNEG = 118; // -
+- int DNEG = 119; // -
+- int ISHL = 120; // -
+- int LSHL = 121; // -
+- int ISHR = 122; // -
+- int LSHR = 123; // -
+- int IUSHR = 124; // -
+- int LUSHR = 125; // -
+- int IAND = 126; // -
+- int LAND = 127; // -
+- int IOR = 128; // -
+- int LOR = 129; // -
+- int IXOR = 130; // -
+- int LXOR = 131; // -
+- int IINC = 132; // visitIincInsn
+- int I2L = 133; // visitInsn
+- int I2F = 134; // -
+- int I2D = 135; // -
+- int L2I = 136; // -
+- int L2F = 137; // -
+- int L2D = 138; // -
+- int F2I = 139; // -
+- int F2L = 140; // -
+- int F2D = 141; // -
+- int D2I = 142; // -
+- int D2L = 143; // -
+- int D2F = 144; // -
+- int I2B = 145; // -
+- int I2C = 146; // -
+- int I2S = 147; // -
+- int LCMP = 148; // -
+- int FCMPL = 149; // -
+- int FCMPG = 150; // -
+- int DCMPL = 151; // -
+- int DCMPG = 152; // -
+- int IFEQ = 153; // visitJumpInsn
+- int IFNE = 154; // -
+- int IFLT = 155; // -
+- int IFGE = 156; // -
+- int IFGT = 157; // -
+- int IFLE = 158; // -
+- int IF_ICMPEQ = 159; // -
+- int IF_ICMPNE = 160; // -
+- int IF_ICMPLT = 161; // -
+- int IF_ICMPGE = 162; // -
+- int IF_ICMPGT = 163; // -
+- int IF_ICMPLE = 164; // -
+- int IF_ACMPEQ = 165; // -
+- int IF_ACMPNE = 166; // -
+- int GOTO = 167; // -
+- int JSR = 168; // -
+- int RET = 169; // visitVarInsn
+- int TABLESWITCH = 170; // visiTableSwitchInsn
+- int LOOKUPSWITCH = 171; // visitLookupSwitch
+- int IRETURN = 172; // visitInsn
+- int LRETURN = 173; // -
+- int FRETURN = 174; // -
+- int DRETURN = 175; // -
+- int ARETURN = 176; // -
+- int RETURN = 177; // -
+- int GETSTATIC = 178; // visitFieldInsn
+- int PUTSTATIC = 179; // -
+- int GETFIELD = 180; // -
+- int PUTFIELD = 181; // -
+- int INVOKEVIRTUAL = 182; // visitMethodInsn
+- int INVOKESPECIAL = 183; // -
+- int INVOKESTATIC = 184; // -
+- int INVOKEINTERFACE = 185; // -
+- int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
+- int NEW = 187; // visitTypeInsn
+- int NEWARRAY = 188; // visitIntInsn
+- int ANEWARRAY = 189; // visitTypeInsn
+- int ARRAYLENGTH = 190; // visitInsn
+- int ATHROW = 191; // -
+- int CHECKCAST = 192; // visitTypeInsn
+- int INSTANCEOF = 193; // -
+- int MONITORENTER = 194; // visitInsn
+- int MONITOREXIT = 195; // -
+- // int WIDE = 196; // NOT VISITED
+- int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
+- int IFNULL = 198; // visitJumpInsn
+- int IFNONNULL = 199; // -
+- // int GOTO_W = 200; // -
+- // int JSR_W = 201; // -
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/package.html mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/package.html
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/package.html 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/package.html 1970-01-01 01:00:00.000000000 +0100
+@@ -1,87 +0,0 @@
+-
+-
+-
+-Provides a small and fast bytecode manipulation framework.
+-
+-
+-The ASM framework is organized
+-around the {@link org.mvel2.asm.ClassVisitor ClassVisitor},
+-{@link org.mvel2.asm.FieldVisitor FieldVisitor},
+-{@link org.mvel2.asm.MethodVisitor MethodVisitor} and
+-{@link org.mvel2.asm.AnnotationVisitor AnnotationVisitor} abstract classes,
+-which allow one to visit the fields, methods and annotations of a class,
+-including the bytecode instructions of each method.
+-
+-
+- In addition to these main abstract classes, ASM provides a {@link
+- org.mvel2.asm.ClassReader ClassReader} class, that can parse an
+- existing class and make a given visitor visit it. ASM also provides
+- a {@link org.mvel2.asm.ClassWriter ClassWriter} class, which is
+- a visitor that generates Java class files.
+-
+-
+-In order to generate a class from scratch, only the {@link
+-org.mvel2.asm.ClassWriter ClassWriter} class is necessary. Indeed,
+-in order to generate a class, one must just call its visitXxx
+-methods with the appropriate arguments to generate the desired fields
+-and methods. See the "helloworld" example in the ASM distribution for
+-more details about class generation.
+-
+-
+- In order to modify existing classes, one must use a {@link
+- org.mvel2.asm.ClassReader ClassReader} class to analyze
+- the original class, a class modifier, and a {@link org.mvel2.asm.ClassWriter
+- ClassWriter} to construct the modified class. The class modifier
+- is just a {@link org.mvel2.asm.ClassVisitor ClassVisitor}
+- that delegates most of the work to another {@link org.mvel2.asm.ClassVisitor
+- ClassVisitor}, but that sometimes changes some parameter values,
+- or call additional methods, in order to implement the desired
+- modification process. In order to make it easier to implement such
+- class modifiers, the {@link org.mvel2.asm.ClassVisitor
+- ClassVisitor} and {@link org.mvel2.asm.MethodVisitor MethodVisitor}
+- classes delegate by default all the method calls they receive to an
+- optional visitor. See the "adapt" example in the ASM
+- distribution for more details about class modification.
+-
+-
+-The size of the core ASM library, asm.jar , is only 45KB, which is much
+-smaller than the size of the
+-BCEL library (504KB), and than the
+-size of the
+-SERP library (150KB). ASM is also
+-much faster than these tools. Indeed the overhead of a load time class
+-transformation process is of the order of 60% with ASM, 700% or more with BCEL,
+-and 1100% or more with SERP (see the test/perf directory in the ASM
+-distribution)!
+-
+-@since ASM 1.3
+-
+-
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/signature/package.html mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/signature/package.html
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/signature/package.html 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/signature/package.html 1970-01-01 01:00:00.000000000 +0100
+@@ -1,36 +0,0 @@
+-
+-
+-
+-Provides support for type signatures.
+-
+-@since ASM 2.0
+-
+-
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/signature/SignatureReader.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/signature/SignatureReader.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/signature/SignatureReader.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/signature/SignatureReader.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,228 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.signature;
+-
+-/**
+- * A type signature parser to make a signature visitor visit an existing
+- * signature.
+- *
+- * @author Thomas Hallgren
+- * @author Eric Bruneton
+- */
+-public class SignatureReader {
+-
+- /**
+- * The signature to be read.
+- */
+- private final String signature;
+-
+- /**
+- * Constructs a {@link SignatureReader} for the given signature.
+- *
+- * @param signature
+- * A ClassSignature , MethodTypeSignature , or
+- * FieldTypeSignature .
+- */
+- public SignatureReader(final String signature) {
+- this.signature = signature;
+- }
+-
+- /**
+- * Makes the given visitor visit the signature of this
+- * {@link SignatureReader}. This signature is the one specified in the
+- * constructor (see {@link #SignatureReader(String) SignatureReader}). This
+- * method is intended to be called on a {@link SignatureReader} that was
+- * created using a ClassSignature (such as the signature
+- * parameter of the {@link org.mvel2.asm.ClassVisitor#visit
+- * ClassVisitor.visit} method) or a MethodTypeSignature (such as the
+- * signature
parameter of the
+- * {@link org.mvel2.asm.ClassVisitor#visitMethod
+- * ClassVisitor.visitMethod} method).
+- *
+- * @param v
+- * the visitor that must visit this signature.
+- */
+- public void accept(final SignatureVisitor v) {
+- String signature = this.signature;
+- int len = signature.length();
+- int pos;
+- char c;
+-
+- if (signature.charAt(0) == '<') {
+- pos = 2;
+- do {
+- int end = signature.indexOf(':', pos);
+- v.visitFormalTypeParameter(signature.substring(pos - 1, end));
+- pos = end + 1;
+-
+- c = signature.charAt(pos);
+- if (c == 'L' || c == '[' || c == 'T') {
+- pos = parseType(signature, pos, v.visitClassBound());
+- }
+-
+- while ((c = signature.charAt(pos++)) == ':') {
+- pos = parseType(signature, pos, v.visitInterfaceBound());
+- }
+- } while (c != '>');
+- } else {
+- pos = 0;
+- }
+-
+- if (signature.charAt(pos) == '(') {
+- pos++;
+- while (signature.charAt(pos) != ')') {
+- pos = parseType(signature, pos, v.visitParameterType());
+- }
+- pos = parseType(signature, pos + 1, v.visitReturnType());
+- while (pos < len) {
+- pos = parseType(signature, pos + 1, v.visitExceptionType());
+- }
+- } else {
+- pos = parseType(signature, pos, v.visitSuperclass());
+- while (pos < len) {
+- pos = parseType(signature, pos, v.visitInterface());
+- }
+- }
+- }
+-
+- /**
+- * Makes the given visitor visit the signature of this
+- * {@link SignatureReader}. This signature is the one specified in the
+- * constructor (see {@link #SignatureReader(String) SignatureReader}). This
+- * method is intended to be called on a {@link SignatureReader} that was
+- * created using a FieldTypeSignature , such as the
+- * signature
parameter of the
+- * {@link org.mvel2.asm.ClassVisitor#visitField ClassVisitor.visitField}
+- * or {@link org.mvel2.asm.MethodVisitor#visitLocalVariable
+- * MethodVisitor.visitLocalVariable} methods.
+- *
+- * @param v
+- * the visitor that must visit this signature.
+- */
+- public void acceptType(final SignatureVisitor v) {
+- parseType(this.signature, 0, v);
+- }
+-
+- /**
+- * Parses a field type signature and makes the given visitor visit it.
+- *
+- * @param signature
+- * a string containing the signature that must be parsed.
+- * @param pos
+- * index of the first character of the signature to parsed.
+- * @param v
+- * the visitor that must visit this signature.
+- * @return the index of the first character after the parsed signature.
+- */
+- private static int parseType(final String signature, int pos,
+- final SignatureVisitor v) {
+- char c;
+- int start, end;
+- boolean visited, inner;
+- String name;
+-
+- switch (c = signature.charAt(pos++)) {
+- case 'Z':
+- case 'C':
+- case 'B':
+- case 'S':
+- case 'I':
+- case 'F':
+- case 'J':
+- case 'D':
+- case 'V':
+- v.visitBaseType(c);
+- return pos;
+-
+- case '[':
+- return parseType(signature, pos, v.visitArrayType());
+-
+- case 'T':
+- end = signature.indexOf(';', pos);
+- v.visitTypeVariable(signature.substring(pos, end));
+- return end + 1;
+-
+- default: // case 'L':
+- start = pos;
+- visited = false;
+- inner = false;
+- for (;;) {
+- switch (c = signature.charAt(pos++)) {
+- case '.':
+- case ';':
+- if (!visited) {
+- name = signature.substring(start, pos - 1);
+- if (inner) {
+- v.visitInnerClassType(name);
+- } else {
+- v.visitClassType(name);
+- }
+- }
+- if (c == ';') {
+- v.visitEnd();
+- return pos;
+- }
+- start = pos;
+- visited = false;
+- inner = true;
+- break;
+-
+- case '<':
+- name = signature.substring(start, pos - 1);
+- if (inner) {
+- v.visitInnerClassType(name);
+- } else {
+- v.visitClassType(name);
+- }
+- visited = true;
+- top: for (;;) {
+- switch (c = signature.charAt(pos)) {
+- case '>':
+- break top;
+- case '*':
+- ++pos;
+- v.visitTypeArgument();
+- break;
+- case '+':
+- case '-':
+- pos = parseType(signature, pos + 1,
+- v.visitTypeArgument(c));
+- break;
+- default:
+- pos = parseType(signature, pos,
+- v.visitTypeArgument('='));
+- break;
+- }
+- }
+- }
+- }
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/signature/SignatureVisitor.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/signature/SignatureVisitor.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/signature/SignatureVisitor.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/signature/SignatureVisitor.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,238 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.signature;
+-
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A visitor to visit a generic signature. The methods of this interface must be
+- * called in one of the three following orders (the last one is the only valid
+- * order for a {@link SignatureVisitor} that is returned by a method of this
+- * interface):
+- *
+- * ClassSignature = ( visitFormalTypeParameter
+- * visitClassBound ? visitInterfaceBound * )* (
+- * visitSuperClass visitInterface * )
+- * MethodSignature = ( visitFormalTypeParameter
+- * visitClassBound ? visitInterfaceBound * )* (
+- * visitParameterType * visitReturnType
+- * visitExceptionType * )
+- * TypeSignature = visitBaseType |
+- * visitTypeVariable | visitArrayType | (
+- * visitClassType visitTypeArgument * (
+- * visitInnerClassType visitTypeArgument * )* visitEnd
+- * ) )
+- *
+- *
+- * @author Thomas Hallgren
+- * @author Eric Bruneton
+- */
+-public abstract class SignatureVisitor {
+-
+- /**
+- * Wildcard for an "extends" type argument.
+- */
+- public final static char EXTENDS = '+';
+-
+- /**
+- * Wildcard for a "super" type argument.
+- */
+- public final static char SUPER = '-';
+-
+- /**
+- * Wildcard for a normal type argument.
+- */
+- public final static char INSTANCEOF = '=';
+-
+- /**
+- * The ASM API version implemented by this visitor. The value of this field
+- * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- protected final int api;
+-
+- /**
+- * Constructs a new {@link SignatureVisitor}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- public SignatureVisitor(final int api) {
+- if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+- throw new IllegalArgumentException();
+- }
+- this.api = api;
+- }
+-
+- /**
+- * Visits a formal type parameter.
+- *
+- * @param name
+- * the name of the formal parameter.
+- */
+- public void visitFormalTypeParameter(String name) {
+- }
+-
+- /**
+- * Visits the class bound of the last visited formal type parameter.
+- *
+- * @return a non null visitor to visit the signature of the class bound.
+- */
+- public SignatureVisitor visitClassBound() {
+- return this;
+- }
+-
+- /**
+- * Visits an interface bound of the last visited formal type parameter.
+- *
+- * @return a non null visitor to visit the signature of the interface bound.
+- */
+- public SignatureVisitor visitInterfaceBound() {
+- return this;
+- }
+-
+- /**
+- * Visits the type of the super class.
+- *
+- * @return a non null visitor to visit the signature of the super class
+- * type.
+- */
+- public SignatureVisitor visitSuperclass() {
+- return this;
+- }
+-
+- /**
+- * Visits the type of an interface implemented by the class.
+- *
+- * @return a non null visitor to visit the signature of the interface type.
+- */
+- public SignatureVisitor visitInterface() {
+- return this;
+- }
+-
+- /**
+- * Visits the type of a method parameter.
+- *
+- * @return a non null visitor to visit the signature of the parameter type.
+- */
+- public SignatureVisitor visitParameterType() {
+- return this;
+- }
+-
+- /**
+- * Visits the return type of the method.
+- *
+- * @return a non null visitor to visit the signature of the return type.
+- */
+- public SignatureVisitor visitReturnType() {
+- return this;
+- }
+-
+- /**
+- * Visits the type of a method exception.
+- *
+- * @return a non null visitor to visit the signature of the exception type.
+- */
+- public SignatureVisitor visitExceptionType() {
+- return this;
+- }
+-
+- /**
+- * Visits a signature corresponding to a primitive type.
+- *
+- * @param descriptor
+- * the descriptor of the primitive type, or 'V' for void
+- * .
+- */
+- public void visitBaseType(char descriptor) {
+- }
+-
+- /**
+- * Visits a signature corresponding to a type variable.
+- *
+- * @param name
+- * the name of the type variable.
+- */
+- public void visitTypeVariable(String name) {
+- }
+-
+- /**
+- * Visits a signature corresponding to an array type.
+- *
+- * @return a non null visitor to visit the signature of the array element
+- * type.
+- */
+- public SignatureVisitor visitArrayType() {
+- return this;
+- }
+-
+- /**
+- * Starts the visit of a signature corresponding to a class or interface
+- * type.
+- *
+- * @param name
+- * the internal name of the class or interface.
+- */
+- public void visitClassType(String name) {
+- }
+-
+- /**
+- * Visits an inner class.
+- *
+- * @param name
+- * the local name of the inner class in its enclosing class.
+- */
+- public void visitInnerClassType(String name) {
+- }
+-
+- /**
+- * Visits an unbounded type argument of the last visited class or inner
+- * class type.
+- */
+- public void visitTypeArgument() {
+- }
+-
+- /**
+- * Visits a type argument of the last visited class or inner class type.
+- *
+- * @param wildcard
+- * '+', '-' or '='.
+- * @return a non null visitor to visit the signature of the type argument.
+- */
+- public SignatureVisitor visitTypeArgument(char wildcard) {
+- return this;
+- }
+-
+- /**
+- * Ends the visit of a signature corresponding to a class or interface type.
+- */
+- public void visitEnd() {
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/signature/SignatureWriter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/signature/SignatureWriter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/signature/SignatureWriter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/signature/SignatureWriter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,227 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.signature;
+-
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A signature visitor that generates signatures in string format.
+- *
+- * @author Thomas Hallgren
+- * @author Eric Bruneton
+- */
+-public class SignatureWriter extends SignatureVisitor {
+-
+- /**
+- * Buffer used to construct the signature.
+- */
+- private final StringBuffer buf = new StringBuffer();
+-
+- /**
+- * Indicates if the signature contains formal type parameters.
+- */
+- private boolean hasFormals;
+-
+- /**
+- * Indicates if the signature contains method parameter types.
+- */
+- private boolean hasParameters;
+-
+- /**
+- * Stack used to keep track of class types that have arguments. Each element
+- * of this stack is a boolean encoded in one bit. The top of the stack is
+- * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping =
+- * /2.
+- */
+- private int argumentStack;
+-
+- /**
+- * Constructs a new {@link SignatureWriter} object.
+- */
+- public SignatureWriter() {
+- super(Opcodes.ASM5);
+- }
+-
+- // ------------------------------------------------------------------------
+- // Implementation of the SignatureVisitor interface
+- // ------------------------------------------------------------------------
+-
+- @Override
+- public void visitFormalTypeParameter(final String name) {
+- if (!hasFormals) {
+- hasFormals = true;
+- buf.append('<');
+- }
+- buf.append(name);
+- buf.append(':');
+- }
+-
+- @Override
+- public SignatureVisitor visitClassBound() {
+- return this;
+- }
+-
+- @Override
+- public SignatureVisitor visitInterfaceBound() {
+- buf.append(':');
+- return this;
+- }
+-
+- @Override
+- public SignatureVisitor visitSuperclass() {
+- endFormals();
+- return this;
+- }
+-
+- @Override
+- public SignatureVisitor visitInterface() {
+- return this;
+- }
+-
+- @Override
+- public SignatureVisitor visitParameterType() {
+- endFormals();
+- if (!hasParameters) {
+- hasParameters = true;
+- buf.append('(');
+- }
+- return this;
+- }
+-
+- @Override
+- public SignatureVisitor visitReturnType() {
+- endFormals();
+- if (!hasParameters) {
+- buf.append('(');
+- }
+- buf.append(')');
+- return this;
+- }
+-
+- @Override
+- public SignatureVisitor visitExceptionType() {
+- buf.append('^');
+- return this;
+- }
+-
+- @Override
+- public void visitBaseType(final char descriptor) {
+- buf.append(descriptor);
+- }
+-
+- @Override
+- public void visitTypeVariable(final String name) {
+- buf.append('T');
+- buf.append(name);
+- buf.append(';');
+- }
+-
+- @Override
+- public SignatureVisitor visitArrayType() {
+- buf.append('[');
+- return this;
+- }
+-
+- @Override
+- public void visitClassType(final String name) {
+- buf.append('L');
+- buf.append(name);
+- argumentStack *= 2;
+- }
+-
+- @Override
+- public void visitInnerClassType(final String name) {
+- endArguments();
+- buf.append('.');
+- buf.append(name);
+- argumentStack *= 2;
+- }
+-
+- @Override
+- public void visitTypeArgument() {
+- if (argumentStack % 2 == 0) {
+- ++argumentStack;
+- buf.append('<');
+- }
+- buf.append('*');
+- }
+-
+- @Override
+- public SignatureVisitor visitTypeArgument(final char wildcard) {
+- if (argumentStack % 2 == 0) {
+- ++argumentStack;
+- buf.append('<');
+- }
+- if (wildcard != '=') {
+- buf.append(wildcard);
+- }
+- return this;
+- }
+-
+- @Override
+- public void visitEnd() {
+- endArguments();
+- buf.append(';');
+- }
+-
+- /**
+- * Returns the signature that was built by this signature writer.
+- *
+- * @return the signature that was built by this signature writer.
+- */
+- @Override
+- public String toString() {
+- return buf.toString();
+- }
+-
+- // ------------------------------------------------------------------------
+- // Utility methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Ends the formal type parameters section of the signature.
+- */
+- private void endFormals() {
+- if (hasFormals) {
+- hasFormals = false;
+- buf.append('>');
+- }
+- }
+-
+- /**
+- * Ends the type arguments of a class or inner class type.
+- */
+- private void endArguments() {
+- if (argumentStack % 2 != 0) {
+- buf.append('>');
+- }
+- argumentStack /= 2;
+- }
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/AbstractInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/AbstractInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/AbstractInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/AbstractInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,326 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.ArrayList;
+-import java.util.List;
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * A node that represents a bytecode instruction. An instruction can appear
+- * at most once in at most one {@link InsnList} at a time .
+- *
+- * @author Eric Bruneton
+- */
+-public abstract class AbstractInsnNode {
+-
+- /**
+- * The type of {@link InsnNode} instructions.
+- */
+- public static final int INSN = 0;
+-
+- /**
+- * The type of {@link IntInsnNode} instructions.
+- */
+- public static final int INT_INSN = 1;
+-
+- /**
+- * The type of {@link VarInsnNode} instructions.
+- */
+- public static final int VAR_INSN = 2;
+-
+- /**
+- * The type of {@link TypeInsnNode} instructions.
+- */
+- public static final int TYPE_INSN = 3;
+-
+- /**
+- * The type of {@link FieldInsnNode} instructions.
+- */
+- public static final int FIELD_INSN = 4;
+-
+- /**
+- * The type of {@link MethodInsnNode} instructions.
+- */
+- public static final int METHOD_INSN = 5;
+-
+- /**
+- * The type of {@link InvokeDynamicInsnNode} instructions.
+- */
+- public static final int INVOKE_DYNAMIC_INSN = 6;
+-
+- /**
+- * The type of {@link JumpInsnNode} instructions.
+- */
+- public static final int JUMP_INSN = 7;
+-
+- /**
+- * The type of {@link LabelNode} "instructions".
+- */
+- public static final int LABEL = 8;
+-
+- /**
+- * The type of {@link LdcInsnNode} instructions.
+- */
+- public static final int LDC_INSN = 9;
+-
+- /**
+- * The type of {@link IincInsnNode} instructions.
+- */
+- public static final int IINC_INSN = 10;
+-
+- /**
+- * The type of {@link TableSwitchInsnNode} instructions.
+- */
+- public static final int TABLESWITCH_INSN = 11;
+-
+- /**
+- * The type of {@link LookupSwitchInsnNode} instructions.
+- */
+- public static final int LOOKUPSWITCH_INSN = 12;
+-
+- /**
+- * The type of {@link MultiANewArrayInsnNode} instructions.
+- */
+- public static final int MULTIANEWARRAY_INSN = 13;
+-
+- /**
+- * The type of {@link FrameNode} "instructions".
+- */
+- public static final int FRAME = 14;
+-
+- /**
+- * The type of {@link LineNumberNode} "instructions".
+- */
+- public static final int LINE = 15;
+-
+- /**
+- * The opcode of this instruction.
+- */
+- protected int opcode;
+-
+- /**
+- * The runtime visible type annotations of this instruction. This field is
+- * only used for real instructions (i.e. not for labels, frames, or line
+- * number nodes). This list is a list of {@link TypeAnnotationNode} objects.
+- * May be null .
+- *
+- * @associates org.mvel2.asm.tree.TypeAnnotationNode
+- * @label visible
+- */
+- public List visibleTypeAnnotations;
+-
+- /**
+- * The runtime invisible type annotations of this instruction. This field is
+- * only used for real instructions (i.e. not for labels, frames, or line
+- * number nodes). This list is a list of {@link TypeAnnotationNode} objects.
+- * May be null .
+- *
+- * @associates org.mvel2.asm.tree.TypeAnnotationNode
+- * @label invisible
+- */
+- public List invisibleTypeAnnotations;
+-
+- /**
+- * Previous instruction in the list to which this instruction belongs.
+- */
+- AbstractInsnNode prev;
+-
+- /**
+- * Next instruction in the list to which this instruction belongs.
+- */
+- AbstractInsnNode next;
+-
+- /**
+- * Index of this instruction in the list to which it belongs. The value of
+- * this field is correct only when {@link InsnList#cache} is not null. A
+- * value of -1 indicates that this instruction does not belong to any
+- * {@link InsnList}.
+- */
+- int index;
+-
+- /**
+- * Constructs a new {@link AbstractInsnNode}.
+- *
+- * @param opcode
+- * the opcode of the instruction to be constructed.
+- */
+- protected AbstractInsnNode(final int opcode) {
+- this.opcode = opcode;
+- this.index = -1;
+- }
+-
+- /**
+- * Returns the opcode of this instruction.
+- *
+- * @return the opcode of this instruction.
+- */
+- public int getOpcode() {
+- return opcode;
+- }
+-
+- /**
+- * Returns the type of this instruction.
+- *
+- * @return the type of this instruction, i.e. one the constants defined in
+- * this class.
+- */
+- public abstract int getType();
+-
+- /**
+- * Returns the previous instruction in the list to which this instruction
+- * belongs, if any.
+- *
+- * @return the previous instruction in the list to which this instruction
+- * belongs, if any. May be null .
+- */
+- public AbstractInsnNode getPrevious() {
+- return prev;
+- }
+-
+- /**
+- * Returns the next instruction in the list to which this instruction
+- * belongs, if any.
+- *
+- * @return the next instruction in the list to which this instruction
+- * belongs, if any. May be null .
+- */
+- public AbstractInsnNode getNext() {
+- return next;
+- }
+-
+- /**
+- * Makes the given code visitor visit this instruction.
+- *
+- * @param cv
+- * a code visitor.
+- */
+- public abstract void accept(final MethodVisitor cv);
+-
+- /**
+- * Makes the given visitor visit the annotations of this instruction.
+- *
+- * @param mv
+- * a method visitor.
+- */
+- protected final void acceptAnnotations(final MethodVisitor mv) {
+- int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations
+- .size();
+- for (int i = 0; i < n; ++i) {
+- TypeAnnotationNode an = visibleTypeAnnotations.get(i);
+- an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
+- true));
+- }
+- n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+- .size();
+- for (int i = 0; i < n; ++i) {
+- TypeAnnotationNode an = invisibleTypeAnnotations.get(i);
+- an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc,
+- false));
+- }
+- }
+-
+- /**
+- * Returns a copy of this instruction.
+- *
+- * @param labels
+- * a map from LabelNodes to cloned LabelNodes.
+- * @return a copy of this instruction. The returned instruction does not
+- * belong to any {@link InsnList}.
+- */
+- public abstract AbstractInsnNode clone(
+- final Map labels);
+-
+- /**
+- * Returns the clone of the given label.
+- *
+- * @param label
+- * a label.
+- * @param map
+- * a map from LabelNodes to cloned LabelNodes.
+- * @return the clone of the given label.
+- */
+- static LabelNode clone(final LabelNode label,
+- final Map map) {
+- return map.get(label);
+- }
+-
+- /**
+- * Returns the clones of the given labels.
+- *
+- * @param labels
+- * a list of labels.
+- * @param map
+- * a map from LabelNodes to cloned LabelNodes.
+- * @return the clones of the given labels.
+- */
+- static LabelNode[] clone(final List labels,
+- final Map map) {
+- LabelNode[] clones = new LabelNode[labels.size()];
+- for (int i = 0; i < clones.length; ++i) {
+- clones[i] = map.get(labels.get(i));
+- }
+- return clones;
+- }
+-
+- /**
+- * Clones the annotations of the given instruction into this instruction.
+- *
+- * @param insn
+- * the source instruction.
+- * @return this instruction.
+- */
+- protected final AbstractInsnNode cloneAnnotations(
+- final AbstractInsnNode insn) {
+- if (insn.visibleTypeAnnotations != null) {
+- this.visibleTypeAnnotations = new ArrayList();
+- for (int i = 0; i < insn.visibleTypeAnnotations.size(); ++i) {
+- TypeAnnotationNode src = insn.visibleTypeAnnotations.get(i);
+- TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
+- src.typePath, src.desc);
+- src.accept(ann);
+- this.visibleTypeAnnotations.add(ann);
+- }
+- }
+- if (insn.invisibleTypeAnnotations != null) {
+- this.invisibleTypeAnnotations = new ArrayList();
+- for (int i = 0; i < insn.invisibleTypeAnnotations.size(); ++i) {
+- TypeAnnotationNode src = insn.invisibleTypeAnnotations.get(i);
+- TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef,
+- src.typePath, src.desc);
+- src.accept(ann);
+- this.invisibleTypeAnnotations.add(ann);
+- }
+- }
+- return this;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/AnalyzerException.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/AnalyzerException.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/AnalyzerException.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/AnalyzerException.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,61 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-
+-/**
+- * Thrown if a problem occurs during the analysis of a method.
+- *
+- * @author Bing Ran
+- * @author Eric Bruneton
+- */
+-public class AnalyzerException extends Exception {
+-
+- public final AbstractInsnNode node;
+-
+- public AnalyzerException(final AbstractInsnNode node, final String msg) {
+- super(msg);
+- this.node = node;
+- }
+-
+- public AnalyzerException(final AbstractInsnNode node, final String msg,
+- final Throwable exception) {
+- super(msg, exception);
+- this.node = node;
+- }
+-
+- public AnalyzerException(final AbstractInsnNode node, final String msg,
+- final Object expected, final Value encountered) {
+- super((msg == null ? "Expected " : msg + ": expected ") + expected
+- + ", but found " + encountered);
+- this.node = node;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Analyzer.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Analyzer.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Analyzer.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Analyzer.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,549 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.ArrayList;
+-import java.util.HashMap;
+-import java.util.List;
+-import java.util.Map;
+-
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-import org.mvel2.asm.tree.IincInsnNode;
+-import org.mvel2.asm.tree.InsnList;
+-import org.mvel2.asm.tree.JumpInsnNode;
+-import org.mvel2.asm.tree.LabelNode;
+-import org.mvel2.asm.tree.LookupSwitchInsnNode;
+-import org.mvel2.asm.tree.MethodNode;
+-import org.mvel2.asm.tree.TableSwitchInsnNode;
+-import org.mvel2.asm.tree.TryCatchBlockNode;
+-import org.mvel2.asm.tree.VarInsnNode;
+-
+-/**
+- * A semantic bytecode analyzer. This class does not fully check that JSR and
+- * RET instructions are valid.
+- *
+- * @param
+- * type of the Value used for the analysis.
+- *
+- * @author Eric Bruneton
+- */
+-public class Analyzer implements Opcodes {
+-
+- private final Interpreter interpreter;
+-
+- private int n;
+-
+- private InsnList insns;
+-
+- private List[] handlers;
+-
+- private Frame[] frames;
+-
+- private Subroutine[] subroutines;
+-
+- private boolean[] queued;
+-
+- private int[] queue;
+-
+- private int top;
+-
+- /**
+- * Constructs a new {@link Analyzer}.
+- *
+- * @param interpreter
+- * the interpreter to be used to symbolically interpret the
+- * bytecode instructions.
+- */
+- public Analyzer(final Interpreter interpreter) {
+- this.interpreter = interpreter;
+- }
+-
+- /**
+- * Analyzes the given method.
+- *
+- * @param owner
+- * the internal name of the class to which the method belongs.
+- * @param m
+- * the method to be analyzed.
+- * @return the symbolic state of the execution stack frame at each bytecode
+- * instruction of the method. The size of the returned array is
+- * equal to the number of instructions (and labels) of the method. A
+- * given frame is null if and only if the corresponding
+- * instruction cannot be reached (dead code).
+- * @throws AnalyzerException
+- * if a problem occurs during the analysis.
+- */
+- public Frame[] analyze(final String owner, final MethodNode m)
+- throws AnalyzerException {
+- if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
+- frames = (Frame[]) new Frame>[0];
+- return frames;
+- }
+- n = m.instructions.size();
+- insns = m.instructions;
+- handlers = (List[]) new List>[n];
+- frames = (Frame[]) new Frame>[n];
+- subroutines = new Subroutine[n];
+- queued = new boolean[n];
+- queue = new int[n];
+- top = 0;
+-
+- // computes exception handlers for each instruction
+- for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
+- TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
+- int begin = insns.indexOf(tcb.start);
+- int end = insns.indexOf(tcb.end);
+- for (int j = begin; j < end; ++j) {
+- List insnHandlers = handlers[j];
+- if (insnHandlers == null) {
+- insnHandlers = new ArrayList();
+- handlers[j] = insnHandlers;
+- }
+- insnHandlers.add(tcb);
+- }
+- }
+-
+- // computes the subroutine for each instruction:
+- Subroutine main = new Subroutine(null, m.maxLocals, null);
+- List subroutineCalls = new ArrayList();
+- Map subroutineHeads = new HashMap();
+- findSubroutine(0, main, subroutineCalls);
+- while (!subroutineCalls.isEmpty()) {
+- JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0);
+- Subroutine sub = subroutineHeads.get(jsr.label);
+- if (sub == null) {
+- sub = new Subroutine(jsr.label, m.maxLocals, jsr);
+- subroutineHeads.put(jsr.label, sub);
+- findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls);
+- } else {
+- sub.callers.add(jsr);
+- }
+- }
+- for (int i = 0; i < n; ++i) {
+- if (subroutines[i] != null && subroutines[i].start == null) {
+- subroutines[i] = null;
+- }
+- }
+-
+- // initializes the data structures for the control flow analysis
+- Frame current = newFrame(m.maxLocals, m.maxStack);
+- Frame handler = newFrame(m.maxLocals, m.maxStack);
+- current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)));
+- Type[] args = Type.getArgumentTypes(m.desc);
+- int local = 0;
+- if ((m.access & ACC_STATIC) == 0) {
+- Type ctype = Type.getObjectType(owner);
+- current.setLocal(local++, interpreter.newValue(ctype));
+- }
+- for (int i = 0; i < args.length; ++i) {
+- current.setLocal(local++, interpreter.newValue(args[i]));
+- if (args[i].getSize() == 2) {
+- current.setLocal(local++, interpreter.newValue(null));
+- }
+- }
+- while (local < m.maxLocals) {
+- current.setLocal(local++, interpreter.newValue(null));
+- }
+- merge(0, current, null);
+-
+- init(owner, m);
+-
+- // control flow analysis
+- while (top > 0) {
+- int insn = queue[--top];
+- Frame f = frames[insn];
+- Subroutine subroutine = subroutines[insn];
+- queued[insn] = false;
+-
+- AbstractInsnNode insnNode = null;
+- try {
+- insnNode = m.instructions.get(insn);
+- int insnOpcode = insnNode.getOpcode();
+- int insnType = insnNode.getType();
+-
+- if (insnType == AbstractInsnNode.LABEL
+- || insnType == AbstractInsnNode.LINE
+- || insnType == AbstractInsnNode.FRAME) {
+- merge(insn + 1, f, subroutine);
+- newControlFlowEdge(insn, insn + 1);
+- } else {
+- current.init(f).execute(insnNode, interpreter);
+- subroutine = subroutine == null ? null : subroutine.copy();
+-
+- if (insnNode instanceof JumpInsnNode) {
+- JumpInsnNode j = (JumpInsnNode) insnNode;
+- if (insnOpcode != GOTO && insnOpcode != JSR) {
+- merge(insn + 1, current, subroutine);
+- newControlFlowEdge(insn, insn + 1);
+- }
+- int jump = insns.indexOf(j.label);
+- if (insnOpcode == JSR) {
+- merge(jump, current, new Subroutine(j.label,
+- m.maxLocals, j));
+- } else {
+- merge(jump, current, subroutine);
+- }
+- newControlFlowEdge(insn, jump);
+- } else if (insnNode instanceof LookupSwitchInsnNode) {
+- LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
+- int jump = insns.indexOf(lsi.dflt);
+- merge(jump, current, subroutine);
+- newControlFlowEdge(insn, jump);
+- for (int j = 0; j < lsi.labels.size(); ++j) {
+- LabelNode label = lsi.labels.get(j);
+- jump = insns.indexOf(label);
+- merge(jump, current, subroutine);
+- newControlFlowEdge(insn, jump);
+- }
+- } else if (insnNode instanceof TableSwitchInsnNode) {
+- TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
+- int jump = insns.indexOf(tsi.dflt);
+- merge(jump, current, subroutine);
+- newControlFlowEdge(insn, jump);
+- for (int j = 0; j < tsi.labels.size(); ++j) {
+- LabelNode label = tsi.labels.get(j);
+- jump = insns.indexOf(label);
+- merge(jump, current, subroutine);
+- newControlFlowEdge(insn, jump);
+- }
+- } else if (insnOpcode == RET) {
+- if (subroutine == null) {
+- throw new AnalyzerException(insnNode,
+- "RET instruction outside of a sub routine");
+- }
+- for (int i = 0; i < subroutine.callers.size(); ++i) {
+- JumpInsnNode caller = subroutine.callers.get(i);
+- int call = insns.indexOf(caller);
+- if (frames[call] != null) {
+- merge(call + 1, frames[call], current,
+- subroutines[call], subroutine.access);
+- newControlFlowEdge(insn, call + 1);
+- }
+- }
+- } else if (insnOpcode != ATHROW
+- && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
+- if (subroutine != null) {
+- if (insnNode instanceof VarInsnNode) {
+- int var = ((VarInsnNode) insnNode).var;
+- subroutine.access[var] = true;
+- if (insnOpcode == LLOAD || insnOpcode == DLOAD
+- || insnOpcode == LSTORE
+- || insnOpcode == DSTORE) {
+- subroutine.access[var + 1] = true;
+- }
+- } else if (insnNode instanceof IincInsnNode) {
+- int var = ((IincInsnNode) insnNode).var;
+- subroutine.access[var] = true;
+- }
+- }
+- merge(insn + 1, current, subroutine);
+- newControlFlowEdge(insn, insn + 1);
+- }
+- }
+-
+- List insnHandlers = handlers[insn];
+- if (insnHandlers != null) {
+- for (int i = 0; i < insnHandlers.size(); ++i) {
+- TryCatchBlockNode tcb = insnHandlers.get(i);
+- Type type;
+- if (tcb.type == null) {
+- type = Type.getObjectType("java/lang/Throwable");
+- } else {
+- type = Type.getObjectType(tcb.type);
+- }
+- int jump = insns.indexOf(tcb.handler);
+- if (newControlFlowExceptionEdge(insn, tcb)) {
+- handler.init(f);
+- handler.clearStack();
+- handler.push(interpreter.newValue(type));
+- merge(jump, handler, subroutine);
+- }
+- }
+- }
+- } catch (AnalyzerException e) {
+- throw new AnalyzerException(e.node, "Error at instruction "
+- + insn + ": " + e.getMessage(), e);
+- } catch (Exception e) {
+- throw new AnalyzerException(insnNode, "Error at instruction "
+- + insn + ": " + e.getMessage(), e);
+- }
+- }
+-
+- return frames;
+- }
+-
+- private void findSubroutine(int insn, final Subroutine sub,
+- final List calls) throws AnalyzerException {
+- while (true) {
+- if (insn < 0 || insn >= n) {
+- throw new AnalyzerException(null,
+- "Execution can fall off end of the code");
+- }
+- if (subroutines[insn] != null) {
+- return;
+- }
+- subroutines[insn] = sub.copy();
+- AbstractInsnNode node = insns.get(insn);
+-
+- // calls findSubroutine recursively on normal successors
+- if (node instanceof JumpInsnNode) {
+- if (node.getOpcode() == JSR) {
+- // do not follow a JSR, it leads to another subroutine!
+- calls.add(node);
+- } else {
+- JumpInsnNode jnode = (JumpInsnNode) node;
+- findSubroutine(insns.indexOf(jnode.label), sub, calls);
+- }
+- } else if (node instanceof TableSwitchInsnNode) {
+- TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node;
+- findSubroutine(insns.indexOf(tsnode.dflt), sub, calls);
+- for (int i = tsnode.labels.size() - 1; i >= 0; --i) {
+- LabelNode l = tsnode.labels.get(i);
+- findSubroutine(insns.indexOf(l), sub, calls);
+- }
+- } else if (node instanceof LookupSwitchInsnNode) {
+- LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node;
+- findSubroutine(insns.indexOf(lsnode.dflt), sub, calls);
+- for (int i = lsnode.labels.size() - 1; i >= 0; --i) {
+- LabelNode l = lsnode.labels.get(i);
+- findSubroutine(insns.indexOf(l), sub, calls);
+- }
+- }
+-
+- // calls findSubroutine recursively on exception handler successors
+- List insnHandlers = handlers[insn];
+- if (insnHandlers != null) {
+- for (int i = 0; i < insnHandlers.size(); ++i) {
+- TryCatchBlockNode tcb = insnHandlers.get(i);
+- findSubroutine(insns.indexOf(tcb.handler), sub, calls);
+- }
+- }
+-
+- // if insn does not falls through to the next instruction, return.
+- switch (node.getOpcode()) {
+- case GOTO:
+- case RET:
+- case TABLESWITCH:
+- case LOOKUPSWITCH:
+- case IRETURN:
+- case LRETURN:
+- case FRETURN:
+- case DRETURN:
+- case ARETURN:
+- case RETURN:
+- case ATHROW:
+- return;
+- }
+- insn++;
+- }
+- }
+-
+- /**
+- * Returns the symbolic stack frame for each instruction of the last
+- * recently analyzed method.
+- *
+- * @return the symbolic state of the execution stack frame at each bytecode
+- * instruction of the method. The size of the returned array is
+- * equal to the number of instructions (and labels) of the method. A
+- * given frame is null if the corresponding instruction
+- * cannot be reached, or if an error occured during the analysis of
+- * the method.
+- */
+- public Frame[] getFrames() {
+- return frames;
+- }
+-
+- /**
+- * Returns the exception handlers for the given instruction.
+- *
+- * @param insn
+- * the index of an instruction of the last recently analyzed
+- * method.
+- * @return a list of {@link TryCatchBlockNode} objects.
+- */
+- public List getHandlers(final int insn) {
+- return handlers[insn];
+- }
+-
+- /**
+- * Initializes this analyzer. This method is called just before the
+- * execution of control flow analysis loop in #analyze. The default
+- * implementation of this method does nothing.
+- *
+- * @param owner
+- * the internal name of the class to which the method belongs.
+- * @param m
+- * the method to be analyzed.
+- * @throws AnalyzerException
+- * if a problem occurs.
+- */
+- protected void init(String owner, MethodNode m) throws AnalyzerException {
+- }
+-
+- /**
+- * Constructs a new frame with the given size.
+- *
+- * @param nLocals
+- * the maximum number of local variables of the frame.
+- * @param nStack
+- * the maximum stack size of the frame.
+- * @return the created frame.
+- */
+- protected Frame newFrame(final int nLocals, final int nStack) {
+- return new Frame(nLocals, nStack);
+- }
+-
+- /**
+- * Constructs a new frame that is identical to the given frame.
+- *
+- * @param src
+- * a frame.
+- * @return the created frame.
+- */
+- protected Frame newFrame(final Frame extends V> src) {
+- return new Frame(src);
+- }
+-
+- /**
+- * Creates a control flow graph edge. The default implementation of this
+- * method does nothing. It can be overriden in order to construct the
+- * control flow graph of a method (this method is called by the
+- * {@link #analyze analyze} method during its visit of the method's code).
+- *
+- * @param insn
+- * an instruction index.
+- * @param successor
+- * index of a successor instruction.
+- */
+- protected void newControlFlowEdge(final int insn, final int successor) {
+- }
+-
+- /**
+- * Creates a control flow graph edge corresponding to an exception handler.
+- * The default implementation of this method does nothing. It can be
+- * overridden in order to construct the control flow graph of a method (this
+- * method is called by the {@link #analyze analyze} method during its visit
+- * of the method's code).
+- *
+- * @param insn
+- * an instruction index.
+- * @param successor
+- * index of a successor instruction.
+- * @return true if this edge must be considered in the data flow analysis
+- * performed by this analyzer, or false otherwise. The default
+- * implementation of this method always returns true.
+- */
+- protected boolean newControlFlowExceptionEdge(final int insn,
+- final int successor) {
+- return true;
+- }
+-
+- /**
+- * Creates a control flow graph edge corresponding to an exception handler.
+- * The default implementation of this method delegates to
+- * {@link #newControlFlowExceptionEdge(int, int)
+- * newControlFlowExceptionEdge(int, int)}. It can be overridden in order to
+- * construct the control flow graph of a method (this method is called by
+- * the {@link #analyze analyze} method during its visit of the method's
+- * code).
+- *
+- * @param insn
+- * an instruction index.
+- * @param tcb
+- * TryCatchBlockNode corresponding to this edge.
+- * @return true if this edge must be considered in the data flow analysis
+- * performed by this analyzer, or false otherwise. The default
+- * implementation of this method delegates to
+- * {@link #newControlFlowExceptionEdge(int, int)
+- * newControlFlowExceptionEdge(int, int)}.
+- */
+- protected boolean newControlFlowExceptionEdge(final int insn,
+- final TryCatchBlockNode tcb) {
+- return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler));
+- }
+-
+- // -------------------------------------------------------------------------
+-
+- private void merge(final int insn, final Frame frame,
+- final Subroutine subroutine) throws AnalyzerException {
+- Frame oldFrame = frames[insn];
+- Subroutine oldSubroutine = subroutines[insn];
+- boolean changes;
+-
+- if (oldFrame == null) {
+- frames[insn] = newFrame(frame);
+- changes = true;
+- } else {
+- changes = oldFrame.merge(frame, interpreter);
+- }
+-
+- if (oldSubroutine == null) {
+- if (subroutine != null) {
+- subroutines[insn] = subroutine.copy();
+- changes = true;
+- }
+- } else {
+- if (subroutine != null) {
+- changes |= oldSubroutine.merge(subroutine);
+- }
+- }
+- if (changes && !queued[insn]) {
+- queued[insn] = true;
+- queue[top++] = insn;
+- }
+- }
+-
+- private void merge(final int insn, final Frame beforeJSR,
+- final Frame afterRET, final Subroutine subroutineBeforeJSR,
+- final boolean[] access) throws AnalyzerException {
+- Frame oldFrame = frames[insn];
+- Subroutine oldSubroutine = subroutines[insn];
+- boolean changes;
+-
+- afterRET.merge(beforeJSR, access);
+-
+- if (oldFrame == null) {
+- frames[insn] = newFrame(afterRET);
+- changes = true;
+- } else {
+- changes = oldFrame.merge(afterRET, interpreter);
+- }
+-
+- if (oldSubroutine != null && subroutineBeforeJSR != null) {
+- changes |= oldSubroutine.merge(subroutineBeforeJSR);
+- }
+- if (changes && !queued[insn]) {
+- queued[insn] = true;
+- queue[top++] = insn;
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/BasicInterpreter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/BasicInterpreter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/BasicInterpreter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/BasicInterpreter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,358 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.List;
+-
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-import org.mvel2.asm.tree.FieldInsnNode;
+-import org.mvel2.asm.tree.IntInsnNode;
+-import org.mvel2.asm.tree.InvokeDynamicInsnNode;
+-import org.mvel2.asm.tree.LdcInsnNode;
+-import org.mvel2.asm.tree.MethodInsnNode;
+-import org.mvel2.asm.tree.MultiANewArrayInsnNode;
+-import org.mvel2.asm.tree.TypeInsnNode;
+-
+-/**
+- * An {@link Interpreter} for {@link BasicValue} values.
+- *
+- * @author Eric Bruneton
+- * @author Bing Ran
+- */
+-public class BasicInterpreter extends Interpreter implements
+- Opcodes {
+-
+- public BasicInterpreter() {
+- super(ASM5);
+- }
+-
+- protected BasicInterpreter(final int api) {
+- super(api);
+- }
+-
+- @Override
+- public BasicValue newValue(final Type type) {
+- if (type == null) {
+- return BasicValue.UNINITIALIZED_VALUE;
+- }
+- switch (type.getSort()) {
+- case Type.VOID:
+- return null;
+- case Type.BOOLEAN:
+- case Type.CHAR:
+- case Type.BYTE:
+- case Type.SHORT:
+- case Type.INT:
+- return BasicValue.INT_VALUE;
+- case Type.FLOAT:
+- return BasicValue.FLOAT_VALUE;
+- case Type.LONG:
+- return BasicValue.LONG_VALUE;
+- case Type.DOUBLE:
+- return BasicValue.DOUBLE_VALUE;
+- case Type.ARRAY:
+- case Type.OBJECT:
+- return BasicValue.REFERENCE_VALUE;
+- default:
+- throw new Error("Internal error");
+- }
+- }
+-
+- @Override
+- public BasicValue newOperation(final AbstractInsnNode insn)
+- throws AnalyzerException {
+- switch (insn.getOpcode()) {
+- case ACONST_NULL:
+- return newValue(Type.getObjectType("null"));
+- case ICONST_M1:
+- case ICONST_0:
+- case ICONST_1:
+- case ICONST_2:
+- case ICONST_3:
+- case ICONST_4:
+- case ICONST_5:
+- return BasicValue.INT_VALUE;
+- case LCONST_0:
+- case LCONST_1:
+- return BasicValue.LONG_VALUE;
+- case FCONST_0:
+- case FCONST_1:
+- case FCONST_2:
+- return BasicValue.FLOAT_VALUE;
+- case DCONST_0:
+- case DCONST_1:
+- return BasicValue.DOUBLE_VALUE;
+- case BIPUSH:
+- case SIPUSH:
+- return BasicValue.INT_VALUE;
+- case LDC:
+- Object cst = ((LdcInsnNode) insn).cst;
+- if (cst instanceof Integer) {
+- return BasicValue.INT_VALUE;
+- } else if (cst instanceof Float) {
+- return BasicValue.FLOAT_VALUE;
+- } else if (cst instanceof Long) {
+- return BasicValue.LONG_VALUE;
+- } else if (cst instanceof Double) {
+- return BasicValue.DOUBLE_VALUE;
+- } else if (cst instanceof String) {
+- return newValue(Type.getObjectType("java/lang/String"));
+- } else if (cst instanceof Type) {
+- int sort = ((Type) cst).getSort();
+- if (sort == Type.OBJECT || sort == Type.ARRAY) {
+- return newValue(Type.getObjectType("java/lang/Class"));
+- } else if (sort == Type.METHOD) {
+- return newValue(Type
+- .getObjectType("java/lang/invoke/MethodType"));
+- } else {
+- throw new IllegalArgumentException("Illegal LDC constant "
+- + cst);
+- }
+- } else if (cst instanceof Handle) {
+- return newValue(Type
+- .getObjectType("java/lang/invoke/MethodHandle"));
+- } else {
+- throw new IllegalArgumentException("Illegal LDC constant "
+- + cst);
+- }
+- case JSR:
+- return BasicValue.RETURNADDRESS_VALUE;
+- case GETSTATIC:
+- return newValue(Type.getType(((FieldInsnNode) insn).desc));
+- case NEW:
+- return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
+- default:
+- throw new Error("Internal error.");
+- }
+- }
+-
+- @Override
+- public BasicValue copyOperation(final AbstractInsnNode insn,
+- final BasicValue value) throws AnalyzerException {
+- return value;
+- }
+-
+- @Override
+- public BasicValue unaryOperation(final AbstractInsnNode insn,
+- final BasicValue value) throws AnalyzerException {
+- switch (insn.getOpcode()) {
+- case INEG:
+- case IINC:
+- case L2I:
+- case F2I:
+- case D2I:
+- case I2B:
+- case I2C:
+- case I2S:
+- return BasicValue.INT_VALUE;
+- case FNEG:
+- case I2F:
+- case L2F:
+- case D2F:
+- return BasicValue.FLOAT_VALUE;
+- case LNEG:
+- case I2L:
+- case F2L:
+- case D2L:
+- return BasicValue.LONG_VALUE;
+- case DNEG:
+- case I2D:
+- case L2D:
+- case F2D:
+- return BasicValue.DOUBLE_VALUE;
+- case IFEQ:
+- case IFNE:
+- case IFLT:
+- case IFGE:
+- case IFGT:
+- case IFLE:
+- case TABLESWITCH:
+- case LOOKUPSWITCH:
+- case IRETURN:
+- case LRETURN:
+- case FRETURN:
+- case DRETURN:
+- case ARETURN:
+- case PUTSTATIC:
+- return null;
+- case GETFIELD:
+- return newValue(Type.getType(((FieldInsnNode) insn).desc));
+- case NEWARRAY:
+- switch (((IntInsnNode) insn).operand) {
+- case T_BOOLEAN:
+- return newValue(Type.getType("[Z"));
+- case T_CHAR:
+- return newValue(Type.getType("[C"));
+- case T_BYTE:
+- return newValue(Type.getType("[B"));
+- case T_SHORT:
+- return newValue(Type.getType("[S"));
+- case T_INT:
+- return newValue(Type.getType("[I"));
+- case T_FLOAT:
+- return newValue(Type.getType("[F"));
+- case T_DOUBLE:
+- return newValue(Type.getType("[D"));
+- case T_LONG:
+- return newValue(Type.getType("[J"));
+- default:
+- throw new AnalyzerException(insn, "Invalid array type");
+- }
+- case ANEWARRAY:
+- String desc = ((TypeInsnNode) insn).desc;
+- return newValue(Type.getType("[" + Type.getObjectType(desc)));
+- case ARRAYLENGTH:
+- return BasicValue.INT_VALUE;
+- case ATHROW:
+- return null;
+- case CHECKCAST:
+- desc = ((TypeInsnNode) insn).desc;
+- return newValue(Type.getObjectType(desc));
+- case INSTANCEOF:
+- return BasicValue.INT_VALUE;
+- case MONITORENTER:
+- case MONITOREXIT:
+- case IFNULL:
+- case IFNONNULL:
+- return null;
+- default:
+- throw new Error("Internal error.");
+- }
+- }
+-
+- @Override
+- public BasicValue binaryOperation(final AbstractInsnNode insn,
+- final BasicValue value1, final BasicValue value2)
+- throws AnalyzerException {
+- switch (insn.getOpcode()) {
+- case IALOAD:
+- case BALOAD:
+- case CALOAD:
+- case SALOAD:
+- case IADD:
+- case ISUB:
+- case IMUL:
+- case IDIV:
+- case IREM:
+- case ISHL:
+- case ISHR:
+- case IUSHR:
+- case IAND:
+- case IOR:
+- case IXOR:
+- return BasicValue.INT_VALUE;
+- case FALOAD:
+- case FADD:
+- case FSUB:
+- case FMUL:
+- case FDIV:
+- case FREM:
+- return BasicValue.FLOAT_VALUE;
+- case LALOAD:
+- case LADD:
+- case LSUB:
+- case LMUL:
+- case LDIV:
+- case LREM:
+- case LSHL:
+- case LSHR:
+- case LUSHR:
+- case LAND:
+- case LOR:
+- case LXOR:
+- return BasicValue.LONG_VALUE;
+- case DALOAD:
+- case DADD:
+- case DSUB:
+- case DMUL:
+- case DDIV:
+- case DREM:
+- return BasicValue.DOUBLE_VALUE;
+- case AALOAD:
+- return BasicValue.REFERENCE_VALUE;
+- case LCMP:
+- case FCMPL:
+- case FCMPG:
+- case DCMPL:
+- case DCMPG:
+- return BasicValue.INT_VALUE;
+- case IF_ICMPEQ:
+- case IF_ICMPNE:
+- case IF_ICMPLT:
+- case IF_ICMPGE:
+- case IF_ICMPGT:
+- case IF_ICMPLE:
+- case IF_ACMPEQ:
+- case IF_ACMPNE:
+- case PUTFIELD:
+- return null;
+- default:
+- throw new Error("Internal error.");
+- }
+- }
+-
+- @Override
+- public BasicValue ternaryOperation(final AbstractInsnNode insn,
+- final BasicValue value1, final BasicValue value2,
+- final BasicValue value3) throws AnalyzerException {
+- return null;
+- }
+-
+- @Override
+- public BasicValue naryOperation(final AbstractInsnNode insn,
+- final List extends BasicValue> values) throws AnalyzerException {
+- int opcode = insn.getOpcode();
+- if (opcode == MULTIANEWARRAY) {
+- return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc));
+- } else if (opcode == INVOKEDYNAMIC) {
+- return newValue(Type
+- .getReturnType(((InvokeDynamicInsnNode) insn).desc));
+- } else {
+- return newValue(Type.getReturnType(((MethodInsnNode) insn).desc));
+- }
+- }
+-
+- @Override
+- public void returnOperation(final AbstractInsnNode insn,
+- final BasicValue value, final BasicValue expected)
+- throws AnalyzerException {
+- }
+-
+- @Override
+- public BasicValue merge(final BasicValue v, final BasicValue w) {
+- if (!v.equals(w)) {
+- return BasicValue.UNINITIALIZED_VALUE;
+- }
+- return v;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/BasicValue.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/BasicValue.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/BasicValue.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/BasicValue.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,111 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import org.mvel2.asm.Type;
+-
+-/**
+- * A {@link Value} that is represented by its type in a seven types type system.
+- * This type system distinguishes the UNINITIALZED, INT, FLOAT, LONG, DOUBLE,
+- * REFERENCE and RETURNADDRESS types.
+- *
+- * @author Eric Bruneton
+- */
+-public class BasicValue implements Value {
+-
+- public static final BasicValue UNINITIALIZED_VALUE = new BasicValue(null);
+-
+- public static final BasicValue INT_VALUE = new BasicValue(Type.INT_TYPE);
+-
+- public static final BasicValue FLOAT_VALUE = new BasicValue(Type.FLOAT_TYPE);
+-
+- public static final BasicValue LONG_VALUE = new BasicValue(Type.LONG_TYPE);
+-
+- public static final BasicValue DOUBLE_VALUE = new BasicValue(
+- Type.DOUBLE_TYPE);
+-
+- public static final BasicValue REFERENCE_VALUE = new BasicValue(
+- Type.getObjectType("java/lang/Object"));
+-
+- public static final BasicValue RETURNADDRESS_VALUE = new BasicValue(
+- Type.VOID_TYPE);
+-
+- private final Type type;
+-
+- public BasicValue(final Type type) {
+- this.type = type;
+- }
+-
+- public Type getType() {
+- return type;
+- }
+-
+- public int getSize() {
+- return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1;
+- }
+-
+- public boolean isReference() {
+- return type != null
+- && (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY);
+- }
+-
+- @Override
+- public boolean equals(final Object value) {
+- if (value == this) {
+- return true;
+- } else if (value instanceof BasicValue) {
+- if (type == null) {
+- return ((BasicValue) value).type == null;
+- } else {
+- return type.equals(((BasicValue) value).type);
+- }
+- } else {
+- return false;
+- }
+- }
+-
+- @Override
+- public int hashCode() {
+- return type == null ? 0 : type.hashCode();
+- }
+-
+- @Override
+- public String toString() {
+- if (this == UNINITIALIZED_VALUE) {
+- return ".";
+- } else if (this == RETURNADDRESS_VALUE) {
+- return "A";
+- } else if (this == REFERENCE_VALUE) {
+- return "R";
+- } else {
+- return type.getDescriptor();
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/BasicVerifier.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/BasicVerifier.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/BasicVerifier.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/BasicVerifier.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,433 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.List;
+-
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-import org.mvel2.asm.tree.FieldInsnNode;
+-import org.mvel2.asm.tree.InvokeDynamicInsnNode;
+-import org.mvel2.asm.tree.MethodInsnNode;
+-
+-/**
+- * An extended {@link BasicInterpreter} that checks that bytecode instructions
+- * are correctly used.
+- *
+- * @author Eric Bruneton
+- * @author Bing Ran
+- */
+-public class BasicVerifier extends BasicInterpreter {
+-
+- public BasicVerifier() {
+- super(ASM5);
+- }
+-
+- protected BasicVerifier(final int api) {
+- super(api);
+- }
+-
+- @Override
+- public BasicValue copyOperation(final AbstractInsnNode insn,
+- final BasicValue value) throws AnalyzerException {
+- Value expected;
+- switch (insn.getOpcode()) {
+- case ILOAD:
+- case ISTORE:
+- expected = BasicValue.INT_VALUE;
+- break;
+- case FLOAD:
+- case FSTORE:
+- expected = BasicValue.FLOAT_VALUE;
+- break;
+- case LLOAD:
+- case LSTORE:
+- expected = BasicValue.LONG_VALUE;
+- break;
+- case DLOAD:
+- case DSTORE:
+- expected = BasicValue.DOUBLE_VALUE;
+- break;
+- case ALOAD:
+- if (!value.isReference()) {
+- throw new AnalyzerException(insn, null, "an object reference",
+- value);
+- }
+- return value;
+- case ASTORE:
+- if (!value.isReference()
+- && !BasicValue.RETURNADDRESS_VALUE.equals(value)) {
+- throw new AnalyzerException(insn, null,
+- "an object reference or a return address", value);
+- }
+- return value;
+- default:
+- return value;
+- }
+- if (!expected.equals(value)) {
+- throw new AnalyzerException(insn, null, expected, value);
+- }
+- return value;
+- }
+-
+- @Override
+- public BasicValue unaryOperation(final AbstractInsnNode insn,
+- final BasicValue value) throws AnalyzerException {
+- BasicValue expected;
+- switch (insn.getOpcode()) {
+- case INEG:
+- case IINC:
+- case I2F:
+- case I2L:
+- case I2D:
+- case I2B:
+- case I2C:
+- case I2S:
+- case IFEQ:
+- case IFNE:
+- case IFLT:
+- case IFGE:
+- case IFGT:
+- case IFLE:
+- case TABLESWITCH:
+- case LOOKUPSWITCH:
+- case IRETURN:
+- case NEWARRAY:
+- case ANEWARRAY:
+- expected = BasicValue.INT_VALUE;
+- break;
+- case FNEG:
+- case F2I:
+- case F2L:
+- case F2D:
+- case FRETURN:
+- expected = BasicValue.FLOAT_VALUE;
+- break;
+- case LNEG:
+- case L2I:
+- case L2F:
+- case L2D:
+- case LRETURN:
+- expected = BasicValue.LONG_VALUE;
+- break;
+- case DNEG:
+- case D2I:
+- case D2F:
+- case D2L:
+- case DRETURN:
+- expected = BasicValue.DOUBLE_VALUE;
+- break;
+- case GETFIELD:
+- expected = newValue(Type
+- .getObjectType(((FieldInsnNode) insn).owner));
+- break;
+- case CHECKCAST:
+- if (!value.isReference()) {
+- throw new AnalyzerException(insn, null, "an object reference",
+- value);
+- }
+- return super.unaryOperation(insn, value);
+- case ARRAYLENGTH:
+- if (!isArrayValue(value)) {
+- throw new AnalyzerException(insn, null, "an array reference",
+- value);
+- }
+- return super.unaryOperation(insn, value);
+- case ARETURN:
+- case ATHROW:
+- case INSTANCEOF:
+- case MONITORENTER:
+- case MONITOREXIT:
+- case IFNULL:
+- case IFNONNULL:
+- if (!value.isReference()) {
+- throw new AnalyzerException(insn, null, "an object reference",
+- value);
+- }
+- return super.unaryOperation(insn, value);
+- case PUTSTATIC:
+- expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
+- break;
+- default:
+- throw new Error("Internal error.");
+- }
+- if (!isSubTypeOf(value, expected)) {
+- throw new AnalyzerException(insn, null, expected, value);
+- }
+- return super.unaryOperation(insn, value);
+- }
+-
+- @Override
+- public BasicValue binaryOperation(final AbstractInsnNode insn,
+- final BasicValue value1, final BasicValue value2)
+- throws AnalyzerException {
+- BasicValue expected1;
+- BasicValue expected2;
+- switch (insn.getOpcode()) {
+- case IALOAD:
+- expected1 = newValue(Type.getType("[I"));
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case BALOAD:
+- if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+- expected1 = newValue(Type.getType("[Z"));
+- } else {
+- expected1 = newValue(Type.getType("[B"));
+- }
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case CALOAD:
+- expected1 = newValue(Type.getType("[C"));
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case SALOAD:
+- expected1 = newValue(Type.getType("[S"));
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case LALOAD:
+- expected1 = newValue(Type.getType("[J"));
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case FALOAD:
+- expected1 = newValue(Type.getType("[F"));
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case DALOAD:
+- expected1 = newValue(Type.getType("[D"));
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case AALOAD:
+- expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case IADD:
+- case ISUB:
+- case IMUL:
+- case IDIV:
+- case IREM:
+- case ISHL:
+- case ISHR:
+- case IUSHR:
+- case IAND:
+- case IOR:
+- case IXOR:
+- case IF_ICMPEQ:
+- case IF_ICMPNE:
+- case IF_ICMPLT:
+- case IF_ICMPGE:
+- case IF_ICMPGT:
+- case IF_ICMPLE:
+- expected1 = BasicValue.INT_VALUE;
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case FADD:
+- case FSUB:
+- case FMUL:
+- case FDIV:
+- case FREM:
+- case FCMPL:
+- case FCMPG:
+- expected1 = BasicValue.FLOAT_VALUE;
+- expected2 = BasicValue.FLOAT_VALUE;
+- break;
+- case LADD:
+- case LSUB:
+- case LMUL:
+- case LDIV:
+- case LREM:
+- case LAND:
+- case LOR:
+- case LXOR:
+- case LCMP:
+- expected1 = BasicValue.LONG_VALUE;
+- expected2 = BasicValue.LONG_VALUE;
+- break;
+- case LSHL:
+- case LSHR:
+- case LUSHR:
+- expected1 = BasicValue.LONG_VALUE;
+- expected2 = BasicValue.INT_VALUE;
+- break;
+- case DADD:
+- case DSUB:
+- case DMUL:
+- case DDIV:
+- case DREM:
+- case DCMPL:
+- case DCMPG:
+- expected1 = BasicValue.DOUBLE_VALUE;
+- expected2 = BasicValue.DOUBLE_VALUE;
+- break;
+- case IF_ACMPEQ:
+- case IF_ACMPNE:
+- expected1 = BasicValue.REFERENCE_VALUE;
+- expected2 = BasicValue.REFERENCE_VALUE;
+- break;
+- case PUTFIELD:
+- FieldInsnNode fin = (FieldInsnNode) insn;
+- expected1 = newValue(Type.getObjectType(fin.owner));
+- expected2 = newValue(Type.getType(fin.desc));
+- break;
+- default:
+- throw new Error("Internal error.");
+- }
+- if (!isSubTypeOf(value1, expected1)) {
+- throw new AnalyzerException(insn, "First argument", expected1,
+- value1);
+- } else if (!isSubTypeOf(value2, expected2)) {
+- throw new AnalyzerException(insn, "Second argument", expected2,
+- value2);
+- }
+- if (insn.getOpcode() == AALOAD) {
+- return getElementValue(value1);
+- } else {
+- return super.binaryOperation(insn, value1, value2);
+- }
+- }
+-
+- @Override
+- public BasicValue ternaryOperation(final AbstractInsnNode insn,
+- final BasicValue value1, final BasicValue value2,
+- final BasicValue value3) throws AnalyzerException {
+- BasicValue expected1;
+- BasicValue expected3;
+- switch (insn.getOpcode()) {
+- case IASTORE:
+- expected1 = newValue(Type.getType("[I"));
+- expected3 = BasicValue.INT_VALUE;
+- break;
+- case BASTORE:
+- if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
+- expected1 = newValue(Type.getType("[Z"));
+- } else {
+- expected1 = newValue(Type.getType("[B"));
+- }
+- expected3 = BasicValue.INT_VALUE;
+- break;
+- case CASTORE:
+- expected1 = newValue(Type.getType("[C"));
+- expected3 = BasicValue.INT_VALUE;
+- break;
+- case SASTORE:
+- expected1 = newValue(Type.getType("[S"));
+- expected3 = BasicValue.INT_VALUE;
+- break;
+- case LASTORE:
+- expected1 = newValue(Type.getType("[J"));
+- expected3 = BasicValue.LONG_VALUE;
+- break;
+- case FASTORE:
+- expected1 = newValue(Type.getType("[F"));
+- expected3 = BasicValue.FLOAT_VALUE;
+- break;
+- case DASTORE:
+- expected1 = newValue(Type.getType("[D"));
+- expected3 = BasicValue.DOUBLE_VALUE;
+- break;
+- case AASTORE:
+- expected1 = value1;
+- expected3 = BasicValue.REFERENCE_VALUE;
+- break;
+- default:
+- throw new Error("Internal error.");
+- }
+- if (!isSubTypeOf(value1, expected1)) {
+- throw new AnalyzerException(insn, "First argument", "a "
+- + expected1 + " array reference", value1);
+- } else if (!BasicValue.INT_VALUE.equals(value2)) {
+- throw new AnalyzerException(insn, "Second argument",
+- BasicValue.INT_VALUE, value2);
+- } else if (!isSubTypeOf(value3, expected3)) {
+- throw new AnalyzerException(insn, "Third argument", expected3,
+- value3);
+- }
+- return null;
+- }
+-
+- @Override
+- public BasicValue naryOperation(final AbstractInsnNode insn,
+- final List extends BasicValue> values) throws AnalyzerException {
+- int opcode = insn.getOpcode();
+- if (opcode == MULTIANEWARRAY) {
+- for (int i = 0; i < values.size(); ++i) {
+- if (!BasicValue.INT_VALUE.equals(values.get(i))) {
+- throw new AnalyzerException(insn, null,
+- BasicValue.INT_VALUE, values.get(i));
+- }
+- }
+- } else {
+- int i = 0;
+- int j = 0;
+- if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) {
+- Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
+- if (!isSubTypeOf(values.get(i++), newValue(owner))) {
+- throw new AnalyzerException(insn, "Method owner",
+- newValue(owner), values.get(0));
+- }
+- }
+- String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
+- : ((MethodInsnNode) insn).desc;
+- Type[] args = Type.getArgumentTypes(desc);
+- while (i < values.size()) {
+- BasicValue expected = newValue(args[j++]);
+- BasicValue encountered = values.get(i++);
+- if (!isSubTypeOf(encountered, expected)) {
+- throw new AnalyzerException(insn, "Argument " + j,
+- expected, encountered);
+- }
+- }
+- }
+- return super.naryOperation(insn, values);
+- }
+-
+- @Override
+- public void returnOperation(final AbstractInsnNode insn,
+- final BasicValue value, final BasicValue expected)
+- throws AnalyzerException {
+- if (!isSubTypeOf(value, expected)) {
+- throw new AnalyzerException(insn, "Incompatible return type",
+- expected, value);
+- }
+- }
+-
+- protected boolean isArrayValue(final BasicValue value) {
+- return value.isReference();
+- }
+-
+- protected BasicValue getElementValue(final BasicValue objectArrayValue)
+- throws AnalyzerException {
+- return BasicValue.REFERENCE_VALUE;
+- }
+-
+- protected boolean isSubTypeOf(final BasicValue value,
+- final BasicValue expected) {
+- return value.equals(expected);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Frame.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Frame.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Frame.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Frame.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,738 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-import org.mvel2.asm.tree.IincInsnNode;
+-import org.mvel2.asm.tree.InvokeDynamicInsnNode;
+-import org.mvel2.asm.tree.MethodInsnNode;
+-import org.mvel2.asm.tree.MultiANewArrayInsnNode;
+-import org.mvel2.asm.tree.VarInsnNode;
+-
+-/**
+- * A symbolic execution stack frame. A stack frame contains a set of local
+- * variable slots, and an operand stack. Warning: long and double values are
+- * represented by two slots in local variables, and by one slot in
+- * the operand stack.
+- *
+- * @param
+- * type of the Value used for the analysis.
+- *
+- * @author Eric Bruneton
+- */
+-public class Frame {
+-
+- /**
+- * The expected return type of the analyzed method, or null if the
+- * method returns void.
+- */
+- private V returnValue;
+-
+- /**
+- * The local variables and operand stack of this frame.
+- */
+- private V[] values;
+-
+- /**
+- * The number of local variables of this frame.
+- */
+- private int locals;
+-
+- /**
+- * The number of elements in the operand stack.
+- */
+- private int top;
+-
+- /**
+- * Constructs a new frame with the given size.
+- *
+- * @param nLocals
+- * the maximum number of local variables of the frame.
+- * @param nStack
+- * the maximum stack size of the frame.
+- */
+- public Frame(final int nLocals, final int nStack) {
+- this.values = (V[]) new Value[nLocals + nStack];
+- this.locals = nLocals;
+- }
+-
+- /**
+- * Constructs a new frame that is identical to the given frame.
+- *
+- * @param src
+- * a frame.
+- */
+- public Frame(final Frame extends V> src) {
+- this(src.locals, src.values.length - src.locals);
+- init(src);
+- }
+-
+- /**
+- * Copies the state of the given frame into this frame.
+- *
+- * @param src
+- * a frame.
+- * @return this frame.
+- */
+- public Frame init(final Frame extends V> src) {
+- returnValue = src.returnValue;
+- System.arraycopy(src.values, 0, values, 0, values.length);
+- top = src.top;
+- return this;
+- }
+-
+- /**
+- * Sets the expected return type of the analyzed method.
+- *
+- * @param v
+- * the expected return type of the analyzed method, or
+- * null if the method returns void.
+- */
+- public void setReturn(final V v) {
+- returnValue = v;
+- }
+-
+- /**
+- * Returns the maximum number of local variables of this frame.
+- *
+- * @return the maximum number of local variables of this frame.
+- */
+- public int getLocals() {
+- return locals;
+- }
+-
+- /**
+- * Returns the maximum stack size of this frame.
+- *
+- * @return the maximum stack size of this frame.
+- */
+- public int getMaxStackSize() {
+- return values.length - locals;
+- }
+-
+- /**
+- * Returns the value of the given local variable.
+- *
+- * @param i
+- * a local variable index.
+- * @return the value of the given local variable.
+- * @throws IndexOutOfBoundsException
+- * if the variable does not exist.
+- */
+- public V getLocal(final int i) throws IndexOutOfBoundsException {
+- if (i >= locals) {
+- throw new IndexOutOfBoundsException(
+- "Trying to access an inexistant local variable");
+- }
+- return values[i];
+- }
+-
+- /**
+- * Sets the value of the given local variable.
+- *
+- * @param i
+- * a local variable index.
+- * @param value
+- * the new value of this local variable.
+- * @throws IndexOutOfBoundsException
+- * if the variable does not exist.
+- */
+- public void setLocal(final int i, final V value)
+- throws IndexOutOfBoundsException {
+- if (i >= locals) {
+- throw new IndexOutOfBoundsException(
+- "Trying to access an inexistant local variable " + i);
+- }
+- values[i] = value;
+- }
+-
+- /**
+- * Returns the number of values in the operand stack of this frame. Long and
+- * double values are treated as single values.
+- *
+- * @return the number of values in the operand stack of this frame.
+- */
+- public int getStackSize() {
+- return top;
+- }
+-
+- /**
+- * Returns the value of the given operand stack slot.
+- *
+- * @param i
+- * the index of an operand stack slot.
+- * @return the value of the given operand stack slot.
+- * @throws IndexOutOfBoundsException
+- * if the operand stack slot does not exist.
+- */
+- public V getStack(final int i) throws IndexOutOfBoundsException {
+- return values[i + locals];
+- }
+-
+- /**
+- * Clears the operand stack of this frame.
+- */
+- public void clearStack() {
+- top = 0;
+- }
+-
+- /**
+- * Pops a value from the operand stack of this frame.
+- *
+- * @return the value that has been popped from the stack.
+- * @throws IndexOutOfBoundsException
+- * if the operand stack is empty.
+- */
+- public V pop() throws IndexOutOfBoundsException {
+- if (top == 0) {
+- throw new IndexOutOfBoundsException(
+- "Cannot pop operand off an empty stack.");
+- }
+- return values[--top + locals];
+- }
+-
+- /**
+- * Pushes a value into the operand stack of this frame.
+- *
+- * @param value
+- * the value that must be pushed into the stack.
+- * @throws IndexOutOfBoundsException
+- * if the operand stack is full.
+- */
+- public void push(final V value) throws IndexOutOfBoundsException {
+- if (top + locals >= values.length) {
+- throw new IndexOutOfBoundsException(
+- "Insufficient maximum stack size.");
+- }
+- values[top++ + locals] = value;
+- }
+-
+- public void execute(final AbstractInsnNode insn,
+- final Interpreter interpreter) throws AnalyzerException {
+- V value1, value2, value3, value4;
+- List values;
+- int var;
+-
+- switch (insn.getOpcode()) {
+- case Opcodes.NOP:
+- break;
+- case Opcodes.ACONST_NULL:
+- case Opcodes.ICONST_M1:
+- case Opcodes.ICONST_0:
+- case Opcodes.ICONST_1:
+- case Opcodes.ICONST_2:
+- case Opcodes.ICONST_3:
+- case Opcodes.ICONST_4:
+- case Opcodes.ICONST_5:
+- case Opcodes.LCONST_0:
+- case Opcodes.LCONST_1:
+- case Opcodes.FCONST_0:
+- case Opcodes.FCONST_1:
+- case Opcodes.FCONST_2:
+- case Opcodes.DCONST_0:
+- case Opcodes.DCONST_1:
+- case Opcodes.BIPUSH:
+- case Opcodes.SIPUSH:
+- case Opcodes.LDC:
+- push(interpreter.newOperation(insn));
+- break;
+- case Opcodes.ILOAD:
+- case Opcodes.LLOAD:
+- case Opcodes.FLOAD:
+- case Opcodes.DLOAD:
+- case Opcodes.ALOAD:
+- push(interpreter.copyOperation(insn,
+- getLocal(((VarInsnNode) insn).var)));
+- break;
+- case Opcodes.IALOAD:
+- case Opcodes.LALOAD:
+- case Opcodes.FALOAD:
+- case Opcodes.DALOAD:
+- case Opcodes.AALOAD:
+- case Opcodes.BALOAD:
+- case Opcodes.CALOAD:
+- case Opcodes.SALOAD:
+- value2 = pop();
+- value1 = pop();
+- push(interpreter.binaryOperation(insn, value1, value2));
+- break;
+- case Opcodes.ISTORE:
+- case Opcodes.LSTORE:
+- case Opcodes.FSTORE:
+- case Opcodes.DSTORE:
+- case Opcodes.ASTORE:
+- value1 = interpreter.copyOperation(insn, pop());
+- var = ((VarInsnNode) insn).var;
+- setLocal(var, value1);
+- if (value1.getSize() == 2) {
+- setLocal(var + 1, interpreter.newValue(null));
+- }
+- if (var > 0) {
+- Value local = getLocal(var - 1);
+- if (local != null && local.getSize() == 2) {
+- setLocal(var - 1, interpreter.newValue(null));
+- }
+- }
+- break;
+- case Opcodes.IASTORE:
+- case Opcodes.LASTORE:
+- case Opcodes.FASTORE:
+- case Opcodes.DASTORE:
+- case Opcodes.AASTORE:
+- case Opcodes.BASTORE:
+- case Opcodes.CASTORE:
+- case Opcodes.SASTORE:
+- value3 = pop();
+- value2 = pop();
+- value1 = pop();
+- interpreter.ternaryOperation(insn, value1, value2, value3);
+- break;
+- case Opcodes.POP:
+- if (pop().getSize() == 2) {
+- throw new AnalyzerException(insn, "Illegal use of POP");
+- }
+- break;
+- case Opcodes.POP2:
+- if (pop().getSize() == 1) {
+- if (pop().getSize() != 1) {
+- throw new AnalyzerException(insn, "Illegal use of POP2");
+- }
+- }
+- break;
+- case Opcodes.DUP:
+- value1 = pop();
+- if (value1.getSize() != 1) {
+- throw new AnalyzerException(insn, "Illegal use of DUP");
+- }
+- push(value1);
+- push(interpreter.copyOperation(insn, value1));
+- break;
+- case Opcodes.DUP_X1:
+- value1 = pop();
+- value2 = pop();
+- if (value1.getSize() != 1 || value2.getSize() != 1) {
+- throw new AnalyzerException(insn, "Illegal use of DUP_X1");
+- }
+- push(interpreter.copyOperation(insn, value1));
+- push(value2);
+- push(value1);
+- break;
+- case Opcodes.DUP_X2:
+- value1 = pop();
+- if (value1.getSize() == 1) {
+- value2 = pop();
+- if (value2.getSize() == 1) {
+- value3 = pop();
+- if (value3.getSize() == 1) {
+- push(interpreter.copyOperation(insn, value1));
+- push(value3);
+- push(value2);
+- push(value1);
+- break;
+- }
+- } else {
+- push(interpreter.copyOperation(insn, value1));
+- push(value2);
+- push(value1);
+- break;
+- }
+- }
+- throw new AnalyzerException(insn, "Illegal use of DUP_X2");
+- case Opcodes.DUP2:
+- value1 = pop();
+- if (value1.getSize() == 1) {
+- value2 = pop();
+- if (value2.getSize() == 1) {
+- push(value2);
+- push(value1);
+- push(interpreter.copyOperation(insn, value2));
+- push(interpreter.copyOperation(insn, value1));
+- break;
+- }
+- } else {
+- push(value1);
+- push(interpreter.copyOperation(insn, value1));
+- break;
+- }
+- throw new AnalyzerException(insn, "Illegal use of DUP2");
+- case Opcodes.DUP2_X1:
+- value1 = pop();
+- if (value1.getSize() == 1) {
+- value2 = pop();
+- if (value2.getSize() == 1) {
+- value3 = pop();
+- if (value3.getSize() == 1) {
+- push(interpreter.copyOperation(insn, value2));
+- push(interpreter.copyOperation(insn, value1));
+- push(value3);
+- push(value2);
+- push(value1);
+- break;
+- }
+- }
+- } else {
+- value2 = pop();
+- if (value2.getSize() == 1) {
+- push(interpreter.copyOperation(insn, value1));
+- push(value2);
+- push(value1);
+- break;
+- }
+- }
+- throw new AnalyzerException(insn, "Illegal use of DUP2_X1");
+- case Opcodes.DUP2_X2:
+- value1 = pop();
+- if (value1.getSize() == 1) {
+- value2 = pop();
+- if (value2.getSize() == 1) {
+- value3 = pop();
+- if (value3.getSize() == 1) {
+- value4 = pop();
+- if (value4.getSize() == 1) {
+- push(interpreter.copyOperation(insn, value2));
+- push(interpreter.copyOperation(insn, value1));
+- push(value4);
+- push(value3);
+- push(value2);
+- push(value1);
+- break;
+- }
+- } else {
+- push(interpreter.copyOperation(insn, value2));
+- push(interpreter.copyOperation(insn, value1));
+- push(value3);
+- push(value2);
+- push(value1);
+- break;
+- }
+- }
+- } else {
+- value2 = pop();
+- if (value2.getSize() == 1) {
+- value3 = pop();
+- if (value3.getSize() == 1) {
+- push(interpreter.copyOperation(insn, value1));
+- push(value3);
+- push(value2);
+- push(value1);
+- break;
+- }
+- } else {
+- push(interpreter.copyOperation(insn, value1));
+- push(value2);
+- push(value1);
+- break;
+- }
+- }
+- throw new AnalyzerException(insn, "Illegal use of DUP2_X2");
+- case Opcodes.SWAP:
+- value2 = pop();
+- value1 = pop();
+- if (value1.getSize() != 1 || value2.getSize() != 1) {
+- throw new AnalyzerException(insn, "Illegal use of SWAP");
+- }
+- push(interpreter.copyOperation(insn, value2));
+- push(interpreter.copyOperation(insn, value1));
+- break;
+- case Opcodes.IADD:
+- case Opcodes.LADD:
+- case Opcodes.FADD:
+- case Opcodes.DADD:
+- case Opcodes.ISUB:
+- case Opcodes.LSUB:
+- case Opcodes.FSUB:
+- case Opcodes.DSUB:
+- case Opcodes.IMUL:
+- case Opcodes.LMUL:
+- case Opcodes.FMUL:
+- case Opcodes.DMUL:
+- case Opcodes.IDIV:
+- case Opcodes.LDIV:
+- case Opcodes.FDIV:
+- case Opcodes.DDIV:
+- case Opcodes.IREM:
+- case Opcodes.LREM:
+- case Opcodes.FREM:
+- case Opcodes.DREM:
+- value2 = pop();
+- value1 = pop();
+- push(interpreter.binaryOperation(insn, value1, value2));
+- break;
+- case Opcodes.INEG:
+- case Opcodes.LNEG:
+- case Opcodes.FNEG:
+- case Opcodes.DNEG:
+- push(interpreter.unaryOperation(insn, pop()));
+- break;
+- case Opcodes.ISHL:
+- case Opcodes.LSHL:
+- case Opcodes.ISHR:
+- case Opcodes.LSHR:
+- case Opcodes.IUSHR:
+- case Opcodes.LUSHR:
+- case Opcodes.IAND:
+- case Opcodes.LAND:
+- case Opcodes.IOR:
+- case Opcodes.LOR:
+- case Opcodes.IXOR:
+- case Opcodes.LXOR:
+- value2 = pop();
+- value1 = pop();
+- push(interpreter.binaryOperation(insn, value1, value2));
+- break;
+- case Opcodes.IINC:
+- var = ((IincInsnNode) insn).var;
+- setLocal(var, interpreter.unaryOperation(insn, getLocal(var)));
+- break;
+- case Opcodes.I2L:
+- case Opcodes.I2F:
+- case Opcodes.I2D:
+- case Opcodes.L2I:
+- case Opcodes.L2F:
+- case Opcodes.L2D:
+- case Opcodes.F2I:
+- case Opcodes.F2L:
+- case Opcodes.F2D:
+- case Opcodes.D2I:
+- case Opcodes.D2L:
+- case Opcodes.D2F:
+- case Opcodes.I2B:
+- case Opcodes.I2C:
+- case Opcodes.I2S:
+- push(interpreter.unaryOperation(insn, pop()));
+- break;
+- case Opcodes.LCMP:
+- case Opcodes.FCMPL:
+- case Opcodes.FCMPG:
+- case Opcodes.DCMPL:
+- case Opcodes.DCMPG:
+- value2 = pop();
+- value1 = pop();
+- push(interpreter.binaryOperation(insn, value1, value2));
+- break;
+- case Opcodes.IFEQ:
+- case Opcodes.IFNE:
+- case Opcodes.IFLT:
+- case Opcodes.IFGE:
+- case Opcodes.IFGT:
+- case Opcodes.IFLE:
+- interpreter.unaryOperation(insn, pop());
+- break;
+- case Opcodes.IF_ICMPEQ:
+- case Opcodes.IF_ICMPNE:
+- case Opcodes.IF_ICMPLT:
+- case Opcodes.IF_ICMPGE:
+- case Opcodes.IF_ICMPGT:
+- case Opcodes.IF_ICMPLE:
+- case Opcodes.IF_ACMPEQ:
+- case Opcodes.IF_ACMPNE:
+- value2 = pop();
+- value1 = pop();
+- interpreter.binaryOperation(insn, value1, value2);
+- break;
+- case Opcodes.GOTO:
+- break;
+- case Opcodes.JSR:
+- push(interpreter.newOperation(insn));
+- break;
+- case Opcodes.RET:
+- break;
+- case Opcodes.TABLESWITCH:
+- case Opcodes.LOOKUPSWITCH:
+- interpreter.unaryOperation(insn, pop());
+- break;
+- case Opcodes.IRETURN:
+- case Opcodes.LRETURN:
+- case Opcodes.FRETURN:
+- case Opcodes.DRETURN:
+- case Opcodes.ARETURN:
+- value1 = pop();
+- interpreter.unaryOperation(insn, value1);
+- interpreter.returnOperation(insn, value1, returnValue);
+- break;
+- case Opcodes.RETURN:
+- if (returnValue != null) {
+- throw new AnalyzerException(insn, "Incompatible return type");
+- }
+- break;
+- case Opcodes.GETSTATIC:
+- push(interpreter.newOperation(insn));
+- break;
+- case Opcodes.PUTSTATIC:
+- interpreter.unaryOperation(insn, pop());
+- break;
+- case Opcodes.GETFIELD:
+- push(interpreter.unaryOperation(insn, pop()));
+- break;
+- case Opcodes.PUTFIELD:
+- value2 = pop();
+- value1 = pop();
+- interpreter.binaryOperation(insn, value1, value2);
+- break;
+- case Opcodes.INVOKEVIRTUAL:
+- case Opcodes.INVOKESPECIAL:
+- case Opcodes.INVOKESTATIC:
+- case Opcodes.INVOKEINTERFACE: {
+- values = new ArrayList();
+- String desc = ((MethodInsnNode) insn).desc;
+- for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
+- values.add(0, pop());
+- }
+- if (insn.getOpcode() != Opcodes.INVOKESTATIC) {
+- values.add(0, pop());
+- }
+- if (Type.getReturnType(desc) == Type.VOID_TYPE) {
+- interpreter.naryOperation(insn, values);
+- } else {
+- push(interpreter.naryOperation(insn, values));
+- }
+- break;
+- }
+- case Opcodes.INVOKEDYNAMIC: {
+- values = new ArrayList();
+- String desc = ((InvokeDynamicInsnNode) insn).desc;
+- for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) {
+- values.add(0, pop());
+- }
+- if (Type.getReturnType(desc) == Type.VOID_TYPE) {
+- interpreter.naryOperation(insn, values);
+- } else {
+- push(interpreter.naryOperation(insn, values));
+- }
+- break;
+- }
+- case Opcodes.NEW:
+- push(interpreter.newOperation(insn));
+- break;
+- case Opcodes.NEWARRAY:
+- case Opcodes.ANEWARRAY:
+- case Opcodes.ARRAYLENGTH:
+- push(interpreter.unaryOperation(insn, pop()));
+- break;
+- case Opcodes.ATHROW:
+- interpreter.unaryOperation(insn, pop());
+- break;
+- case Opcodes.CHECKCAST:
+- case Opcodes.INSTANCEOF:
+- push(interpreter.unaryOperation(insn, pop()));
+- break;
+- case Opcodes.MONITORENTER:
+- case Opcodes.MONITOREXIT:
+- interpreter.unaryOperation(insn, pop());
+- break;
+- case Opcodes.MULTIANEWARRAY:
+- values = new ArrayList();
+- for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) {
+- values.add(0, pop());
+- }
+- push(interpreter.naryOperation(insn, values));
+- break;
+- case Opcodes.IFNULL:
+- case Opcodes.IFNONNULL:
+- interpreter.unaryOperation(insn, pop());
+- break;
+- default:
+- throw new RuntimeException("Illegal opcode " + insn.getOpcode());
+- }
+- }
+-
+- /**
+- * Merges this frame with the given frame.
+- *
+- * @param frame
+- * a frame.
+- * @param interpreter
+- * the interpreter used to merge values.
+- * @return true if this frame has been changed as a result of the
+- * merge operation, or false otherwise.
+- * @throws AnalyzerException
+- * if the frames have incompatible sizes.
+- */
+- public boolean merge(final Frame extends V> frame,
+- final Interpreter interpreter) throws AnalyzerException {
+- if (top != frame.top) {
+- throw new AnalyzerException(null, "Incompatible stack heights");
+- }
+- boolean changes = false;
+- for (int i = 0; i < locals + top; ++i) {
+- V v = interpreter.merge(values[i], frame.values[i]);
+- if (!v.equals(values[i])) {
+- values[i] = v;
+- changes = true;
+- }
+- }
+- return changes;
+- }
+-
+- /**
+- * Merges this frame with the given frame (case of a RET instruction).
+- *
+- * @param frame
+- * a frame
+- * @param access
+- * the local variables that have been accessed by the subroutine
+- * to which the RET instruction corresponds.
+- * @return true if this frame has been changed as a result of the
+- * merge operation, or false otherwise.
+- */
+- public boolean merge(final Frame extends V> frame, final boolean[] access) {
+- boolean changes = false;
+- for (int i = 0; i < locals; ++i) {
+- if (!access[i] && !values[i].equals(frame.values[i])) {
+- values[i] = frame.values[i];
+- changes = true;
+- }
+- }
+- return changes;
+- }
+-
+- /**
+- * Returns a string representation of this frame.
+- *
+- * @return a string representation of this frame.
+- */
+- @Override
+- public String toString() {
+- StringBuffer b = new StringBuffer();
+- for (int i = 0; i < getLocals(); ++i) {
+- b.append(getLocal(i));
+- }
+- b.append(' ');
+- for (int i = 0; i < getStackSize(); ++i) {
+- b.append(getStack(i).toString());
+- }
+- return b.toString();
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Interpreter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Interpreter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Interpreter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Interpreter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,226 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.List;
+-
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-
+-/**
+- * A semantic bytecode interpreter. More precisely, this interpreter only
+- * manages the computation of values from other values: it does not manage the
+- * transfer of values to or from the stack, and to or from the local variables.
+- * This separation allows a generic bytecode {@link Analyzer} to work with
+- * various semantic interpreters, without needing to duplicate the code to
+- * simulate the transfer of values.
+- *
+- * @param
+- * type of the Value used for the analysis.
+- *
+- * @author Eric Bruneton
+- */
+-public abstract class Interpreter {
+-
+- protected final int api;
+-
+- protected Interpreter(final int api) {
+- this.api = api;
+- }
+-
+- /**
+- * Creates a new value that represents the given type.
+- *
+- * Called for method parameters (including this
), exception
+- * handler variable and with null
type for variables reserved
+- * by long and double types.
+- *
+- * @param type
+- * a primitive or reference type, or null to represent
+- * an uninitialized value.
+- * @return a value that represents the given type. The size of the returned
+- * value must be equal to the size of the given type.
+- */
+- public abstract V newValue(Type type);
+-
+- /**
+- * Interprets a bytecode instruction without arguments. This method is
+- * called for the following opcodes:
+- *
+- * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4,
+- * ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0,
+- * DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW
+- *
+- * @param insn
+- * the bytecode instruction to be interpreted.
+- * @return the result of the interpretation of the given instruction.
+- * @throws AnalyzerException
+- * if an error occured during the interpretation.
+- */
+- public abstract V newOperation(AbstractInsnNode insn)
+- throws AnalyzerException;
+-
+- /**
+- * Interprets a bytecode instruction that moves a value on the stack or to
+- * or from local variables. This method is called for the following opcodes:
+- *
+- * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE,
+- * ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP
+- *
+- * @param insn
+- * the bytecode instruction to be interpreted.
+- * @param value
+- * the value that must be moved by the instruction.
+- * @return the result of the interpretation of the given instruction. The
+- * returned value must be equal to the given value.
+- * @throws AnalyzerException
+- * if an error occured during the interpretation.
+- */
+- public abstract V copyOperation(AbstractInsnNode insn, V value)
+- throws AnalyzerException;
+-
+- /**
+- * Interprets a bytecode instruction with a single argument. This method is
+- * called for the following opcodes:
+- *
+- * INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L,
+- * F2D, D2I, D2L, D2F, I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE,
+- * TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN,
+- * PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST,
+- * INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL
+- *
+- * @param insn
+- * the bytecode instruction to be interpreted.
+- * @param value
+- * the argument of the instruction to be interpreted.
+- * @return the result of the interpretation of the given instruction.
+- * @throws AnalyzerException
+- * if an error occured during the interpretation.
+- */
+- public abstract V unaryOperation(AbstractInsnNode insn, V value)
+- throws AnalyzerException;
+-
+- /**
+- * Interprets a bytecode instruction with two arguments. This method is
+- * called for the following opcodes:
+- *
+- * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD,
+- * LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV,
+- * LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR,
+- * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL,
+- * DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+- * IF_ACMPEQ, IF_ACMPNE, PUTFIELD
+- *
+- * @param insn
+- * the bytecode instruction to be interpreted.
+- * @param value1
+- * the first argument of the instruction to be interpreted.
+- * @param value2
+- * the second argument of the instruction to be interpreted.
+- * @return the result of the interpretation of the given instruction.
+- * @throws AnalyzerException
+- * if an error occured during the interpretation.
+- */
+- public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2)
+- throws AnalyzerException;
+-
+- /**
+- * Interprets a bytecode instruction with three arguments. This method is
+- * called for the following opcodes:
+- *
+- * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE
+- *
+- * @param insn
+- * the bytecode instruction to be interpreted.
+- * @param value1
+- * the first argument of the instruction to be interpreted.
+- * @param value2
+- * the second argument of the instruction to be interpreted.
+- * @param value3
+- * the third argument of the instruction to be interpreted.
+- * @return the result of the interpretation of the given instruction.
+- * @throws AnalyzerException
+- * if an error occured during the interpretation.
+- */
+- public abstract V ternaryOperation(AbstractInsnNode insn, V value1,
+- V value2, V value3) throws AnalyzerException;
+-
+- /**
+- * Interprets a bytecode instruction with a variable number of arguments.
+- * This method is called for the following opcodes:
+- *
+- * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE,
+- * MULTIANEWARRAY and INVOKEDYNAMIC
+- *
+- * @param insn
+- * the bytecode instruction to be interpreted.
+- * @param values
+- * the arguments of the instruction to be interpreted.
+- * @return the result of the interpretation of the given instruction.
+- * @throws AnalyzerException
+- * if an error occured during the interpretation.
+- */
+- public abstract V naryOperation(AbstractInsnNode insn,
+- List extends V> values) throws AnalyzerException;
+-
+- /**
+- * Interprets a bytecode return instruction. This method is called for the
+- * following opcodes:
+- *
+- * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN
+- *
+- * @param insn
+- * the bytecode instruction to be interpreted.
+- * @param value
+- * the argument of the instruction to be interpreted.
+- * @param expected
+- * the expected return type of the analyzed method.
+- * @throws AnalyzerException
+- * if an error occured during the interpretation.
+- */
+- public abstract void returnOperation(AbstractInsnNode insn, V value,
+- V expected) throws AnalyzerException;
+-
+- /**
+- * Merges two values. The merge operation must return a value that
+- * represents both values (for instance, if the two values are two types,
+- * the merged value must be a common super type of the two types. If the two
+- * values are integer intervals, the merged value must be an interval that
+- * contains the previous ones. Likewise for other types of values).
+- *
+- * @param v
+- * a value.
+- * @param w
+- * another value.
+- * @return the merged value. If the merged value is equal to v ,
+- * this method must return v .
+- */
+- public abstract V merge(V v, V w);
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/package.html mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/package.html
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/package.html 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/package.html 1970-01-01 01:00:00.000000000 +0100
+@@ -1,67 +0,0 @@
+-
+-
+-
+-
+-
+-Provides a framework for static code analysis based on the asm.tree package.
+-
+-
+-
+-Basic usage:
+-
+-
+-
+-ClassReader cr = new ClassReader(bytecode);
+-ClassNode cn = new ClassNode();
+-cr.accept(cn, ClassReader.SKIP_DEBUG);
+-
+-List methods = cn.methods;
+-for (int i = 0; i < methods.size(); ++i) {
+- MethodNode method = (MethodNode) methods.get(i);
+- if (method.instructions.size() > 0) {
+- Analyzer a = new Analyzer(new BasicInterpreter());
+- a.analyze(cn.name, method);
+- Frame[] frames = a.getFrames();
+- // Elements of the frames arrray now contains info for each instruction
+- // from the analyzed method. BasicInterpreter creates BasicValue, that
+- // is using simplified type system that distinguishes the UNINITIALZED,
+- // INT, FLOAT, LONG, DOUBLE, REFERENCE and RETURNADDRESS types.
+- ...
+- }
+-}
+-
+-
+-
+-@since ASM 1.4.3
+-
+-
+-
+-
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/SimpleVerifier.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/SimpleVerifier.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/SimpleVerifier.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/SimpleVerifier.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,320 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.List;
+-
+-import org.mvel2.asm.Type;
+-
+-/**
+- * An extended {@link BasicVerifier} that performs more precise verifications.
+- * This verifier computes exact class types, instead of using a single "object
+- * reference" type (as done in the {@link BasicVerifier}).
+- *
+- * @author Eric Bruneton
+- * @author Bing Ran
+- */
+-public class SimpleVerifier extends BasicVerifier {
+-
+- /**
+- * The class that is verified.
+- */
+- private final Type currentClass;
+-
+- /**
+- * The super class of the class that is verified.
+- */
+- private final Type currentSuperClass;
+-
+- /**
+- * The interfaces implemented by the class that is verified.
+- */
+- private final List currentClassInterfaces;
+-
+- /**
+- * If the class that is verified is an interface.
+- */
+- private final boolean isInterface;
+-
+- /**
+- * The loader to use for referenced classes.
+- */
+- private ClassLoader loader = getClass().getClassLoader();
+-
+- /**
+- * Constructs a new {@link SimpleVerifier}.
+- */
+- public SimpleVerifier() {
+- this(null, null, false);
+- }
+-
+- /**
+- * Constructs a new {@link SimpleVerifier} to verify a specific class. This
+- * class will not be loaded into the JVM since it may be incorrect.
+- *
+- * @param currentClass
+- * the class that is verified.
+- * @param currentSuperClass
+- * the super class of the class that is verified.
+- * @param isInterface
+- * if the class that is verified is an interface.
+- */
+- public SimpleVerifier(final Type currentClass,
+- final Type currentSuperClass, final boolean isInterface) {
+- this(currentClass, currentSuperClass, null, isInterface);
+- }
+-
+- /**
+- * Constructs a new {@link SimpleVerifier} to verify a specific class. This
+- * class will not be loaded into the JVM since it may be incorrect.
+- *
+- * @param currentClass
+- * the class that is verified.
+- * @param currentSuperClass
+- * the super class of the class that is verified.
+- * @param currentClassInterfaces
+- * the interfaces implemented by the class that is verified.
+- * @param isInterface
+- * if the class that is verified is an interface.
+- */
+- public SimpleVerifier(final Type currentClass,
+- final Type currentSuperClass,
+- final List currentClassInterfaces, final boolean isInterface) {
+- this(ASM5, currentClass, currentSuperClass, currentClassInterfaces,
+- isInterface);
+- }
+-
+- protected SimpleVerifier(final int api, final Type currentClass,
+- final Type currentSuperClass,
+- final List currentClassInterfaces, final boolean isInterface) {
+- super(api);
+- this.currentClass = currentClass;
+- this.currentSuperClass = currentSuperClass;
+- this.currentClassInterfaces = currentClassInterfaces;
+- this.isInterface = isInterface;
+- }
+-
+- /**
+- * Set the ClassLoader
which will be used to load referenced
+- * classes. This is useful if you are verifying multiple interdependent
+- * classes.
+- *
+- * @param loader
+- * a ClassLoader
to use
+- */
+- public void setClassLoader(final ClassLoader loader) {
+- this.loader = loader;
+- }
+-
+- @Override
+- public BasicValue newValue(final Type type) {
+- if (type == null) {
+- return BasicValue.UNINITIALIZED_VALUE;
+- }
+-
+- boolean isArray = type.getSort() == Type.ARRAY;
+- if (isArray) {
+- switch (type.getElementType().getSort()) {
+- case Type.BOOLEAN:
+- case Type.CHAR:
+- case Type.BYTE:
+- case Type.SHORT:
+- return new BasicValue(type);
+- }
+- }
+-
+- BasicValue v = super.newValue(type);
+- if (BasicValue.REFERENCE_VALUE.equals(v)) {
+- if (isArray) {
+- v = newValue(type.getElementType());
+- String desc = v.getType().getDescriptor();
+- for (int i = 0; i < type.getDimensions(); ++i) {
+- desc = '[' + desc;
+- }
+- v = new BasicValue(Type.getType(desc));
+- } else {
+- v = new BasicValue(type);
+- }
+- }
+- return v;
+- }
+-
+- @Override
+- protected boolean isArrayValue(final BasicValue value) {
+- Type t = value.getType();
+- return t != null
+- && ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY);
+- }
+-
+- @Override
+- protected BasicValue getElementValue(final BasicValue objectArrayValue)
+- throws AnalyzerException {
+- Type arrayType = objectArrayValue.getType();
+- if (arrayType != null) {
+- if (arrayType.getSort() == Type.ARRAY) {
+- return newValue(Type.getType(arrayType.getDescriptor()
+- .substring(1)));
+- } else if ("Lnull;".equals(arrayType.getDescriptor())) {
+- return objectArrayValue;
+- }
+- }
+- throw new Error("Internal error");
+- }
+-
+- @Override
+- protected boolean isSubTypeOf(final BasicValue value,
+- final BasicValue expected) {
+- Type expectedType = expected.getType();
+- Type type = value.getType();
+- switch (expectedType.getSort()) {
+- case Type.INT:
+- case Type.FLOAT:
+- case Type.LONG:
+- case Type.DOUBLE:
+- return type.equals(expectedType);
+- case Type.ARRAY:
+- case Type.OBJECT:
+- if ("Lnull;".equals(type.getDescriptor())) {
+- return true;
+- } else if (type.getSort() == Type.OBJECT
+- || type.getSort() == Type.ARRAY) {
+- return isAssignableFrom(expectedType, type);
+- } else {
+- return false;
+- }
+- default:
+- throw new Error("Internal error");
+- }
+- }
+-
+- @Override
+- public BasicValue merge(final BasicValue v, final BasicValue w) {
+- if (!v.equals(w)) {
+- Type t = v.getType();
+- Type u = w.getType();
+- if (t != null
+- && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) {
+- if (u != null
+- && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) {
+- if ("Lnull;".equals(t.getDescriptor())) {
+- return w;
+- }
+- if ("Lnull;".equals(u.getDescriptor())) {
+- return v;
+- }
+- if (isAssignableFrom(t, u)) {
+- return v;
+- }
+- if (isAssignableFrom(u, t)) {
+- return w;
+- }
+- // TODO case of array classes of the same dimension
+- // TODO should we look also for a common super interface?
+- // problem: there may be several possible common super
+- // interfaces
+- do {
+- if (t == null || isInterface(t)) {
+- return BasicValue.REFERENCE_VALUE;
+- }
+- t = getSuperClass(t);
+- if (isAssignableFrom(t, u)) {
+- return newValue(t);
+- }
+- } while (true);
+- }
+- }
+- return BasicValue.UNINITIALIZED_VALUE;
+- }
+- return v;
+- }
+-
+- protected boolean isInterface(final Type t) {
+- if (currentClass != null && t.equals(currentClass)) {
+- return isInterface;
+- }
+- return getClass(t).isInterface();
+- }
+-
+- protected Type getSuperClass(final Type t) {
+- if (currentClass != null && t.equals(currentClass)) {
+- return currentSuperClass;
+- }
+- Class> c = getClass(t).getSuperclass();
+- return c == null ? null : Type.getType(c);
+- }
+-
+- protected boolean isAssignableFrom(final Type t, final Type u) {
+- if (t.equals(u)) {
+- return true;
+- }
+- if (currentClass != null && t.equals(currentClass)) {
+- if (getSuperClass(u) == null) {
+- return false;
+- } else {
+- if (isInterface) {
+- return u.getSort() == Type.OBJECT
+- || u.getSort() == Type.ARRAY;
+- }
+- return isAssignableFrom(t, getSuperClass(u));
+- }
+- }
+- if (currentClass != null && u.equals(currentClass)) {
+- if (isAssignableFrom(t, currentSuperClass)) {
+- return true;
+- }
+- if (currentClassInterfaces != null) {
+- for (int i = 0; i < currentClassInterfaces.size(); ++i) {
+- Type v = currentClassInterfaces.get(i);
+- if (isAssignableFrom(t, v)) {
+- return true;
+- }
+- }
+- }
+- return false;
+- }
+- Class> tc = getClass(t);
+- if (tc.isInterface()) {
+- tc = Object.class;
+- }
+- return tc.isAssignableFrom(getClass(u));
+- }
+-
+- protected Class> getClass(final Type t) {
+- try {
+- if (t.getSort() == Type.ARRAY) {
+- return Class.forName(t.getDescriptor().replace('/', '.'),
+- false, loader);
+- }
+- return Class.forName(t.getClassName(), false, loader);
+- } catch (ClassNotFoundException e) {
+- throw new RuntimeException(e.toString());
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/SmallSet.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/SmallSet.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/SmallSet.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/SmallSet.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,134 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.AbstractSet;
+-import java.util.HashSet;
+-import java.util.Iterator;
+-import java.util.NoSuchElementException;
+-import java.util.Set;
+-
+-/**
+- * A set of at most two elements.
+- *
+- * @author Eric Bruneton
+- */
+-class SmallSet extends AbstractSet implements Iterator {
+-
+- // if e1 is null, e2 must be null; otherwise e2 must be different from e1
+-
+- E e1, e2;
+-
+- static final Set emptySet() {
+- return new SmallSet(null, null);
+- }
+-
+- SmallSet(final E e1, final E e2) {
+- this.e1 = e1;
+- this.e2 = e2;
+- }
+-
+- // -------------------------------------------------------------------------
+- // Implementation of inherited abstract methods
+- // -------------------------------------------------------------------------
+-
+- @Override
+- public Iterator iterator() {
+- return new SmallSet(e1, e2);
+- }
+-
+- @Override
+- public int size() {
+- return e1 == null ? 0 : (e2 == null ? 1 : 2);
+- }
+-
+- // -------------------------------------------------------------------------
+- // Implementation of the Iterator interface
+- // -------------------------------------------------------------------------
+-
+- public boolean hasNext() {
+- return e1 != null;
+- }
+-
+- public E next() {
+- if (e1 == null) {
+- throw new NoSuchElementException();
+- }
+- E e = e1;
+- e1 = e2;
+- e2 = null;
+- return e;
+- }
+-
+- public void remove() {
+- }
+-
+- // -------------------------------------------------------------------------
+- // Utility methods
+- // -------------------------------------------------------------------------
+-
+- Set union(final SmallSet s) {
+- if ((s.e1 == e1 && s.e2 == e2) || (s.e1 == e2 && s.e2 == e1)) {
+- return this; // if the two sets are equal, return this
+- }
+- if (s.e1 == null) {
+- return this; // if s is empty, return this
+- }
+- if (e1 == null) {
+- return s; // if this is empty, return s
+- }
+- if (s.e2 == null) { // s contains exactly one element
+- if (e2 == null) {
+- return new SmallSet(e1, s.e1); // necessarily e1 != s.e1
+- } else if (s.e1 == e1 || s.e1 == e2) { // s is included in this
+- return this;
+- }
+- }
+- if (e2 == null) { // this contains exactly one element
+- // if (s.e2 == null) { // cannot happen
+- // return new SmallSet(e1, s.e1); // necessarily e1 != s.e1
+- // } else
+- if (e1 == s.e1 || e1 == s.e2) { // this in included in s
+- return s;
+- }
+- }
+- // here we know that there are at least 3 distinct elements
+- HashSet r = new HashSet(4);
+- r.add(e1);
+- if (e2 != null) {
+- r.add(e2);
+- }
+- r.add(s.e1);
+- if (s.e2 != null) {
+- r.add(s.e2);
+- }
+- return r;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/SourceInterpreter.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/SourceInterpreter.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/SourceInterpreter.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/SourceInterpreter.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,198 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.HashSet;
+-import java.util.List;
+-import java.util.Set;
+-
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-import org.mvel2.asm.tree.FieldInsnNode;
+-import org.mvel2.asm.tree.InvokeDynamicInsnNode;
+-import org.mvel2.asm.tree.LdcInsnNode;
+-import org.mvel2.asm.tree.MethodInsnNode;
+-
+-/**
+- * An {@link Interpreter} for {@link SourceValue} values.
+- *
+- * @author Eric Bruneton
+- */
+-public class SourceInterpreter extends Interpreter implements
+- Opcodes {
+-
+- public SourceInterpreter() {
+- super(ASM5);
+- }
+-
+- protected SourceInterpreter(final int api) {
+- super(api);
+- }
+-
+- @Override
+- public SourceValue newValue(final Type type) {
+- if (type == Type.VOID_TYPE) {
+- return null;
+- }
+- return new SourceValue(type == null ? 1 : type.getSize());
+- }
+-
+- @Override
+- public SourceValue newOperation(final AbstractInsnNode insn) {
+- int size;
+- switch (insn.getOpcode()) {
+- case LCONST_0:
+- case LCONST_1:
+- case DCONST_0:
+- case DCONST_1:
+- size = 2;
+- break;
+- case LDC:
+- Object cst = ((LdcInsnNode) insn).cst;
+- size = cst instanceof Long || cst instanceof Double ? 2 : 1;
+- break;
+- case GETSTATIC:
+- size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+- break;
+- default:
+- size = 1;
+- }
+- return new SourceValue(size, insn);
+- }
+-
+- @Override
+- public SourceValue copyOperation(final AbstractInsnNode insn,
+- final SourceValue value) {
+- return new SourceValue(value.getSize(), insn);
+- }
+-
+- @Override
+- public SourceValue unaryOperation(final AbstractInsnNode insn,
+- final SourceValue value) {
+- int size;
+- switch (insn.getOpcode()) {
+- case LNEG:
+- case DNEG:
+- case I2L:
+- case I2D:
+- case L2D:
+- case F2L:
+- case F2D:
+- case D2L:
+- size = 2;
+- break;
+- case GETFIELD:
+- size = Type.getType(((FieldInsnNode) insn).desc).getSize();
+- break;
+- default:
+- size = 1;
+- }
+- return new SourceValue(size, insn);
+- }
+-
+- @Override
+- public SourceValue binaryOperation(final AbstractInsnNode insn,
+- final SourceValue value1, final SourceValue value2) {
+- int size;
+- switch (insn.getOpcode()) {
+- case LALOAD:
+- case DALOAD:
+- case LADD:
+- case DADD:
+- case LSUB:
+- case DSUB:
+- case LMUL:
+- case DMUL:
+- case LDIV:
+- case DDIV:
+- case LREM:
+- case DREM:
+- case LSHL:
+- case LSHR:
+- case LUSHR:
+- case LAND:
+- case LOR:
+- case LXOR:
+- size = 2;
+- break;
+- default:
+- size = 1;
+- }
+- return new SourceValue(size, insn);
+- }
+-
+- @Override
+- public SourceValue ternaryOperation(final AbstractInsnNode insn,
+- final SourceValue value1, final SourceValue value2,
+- final SourceValue value3) {
+- return new SourceValue(1, insn);
+- }
+-
+- @Override
+- public SourceValue naryOperation(final AbstractInsnNode insn,
+- final List extends SourceValue> values) {
+- int size;
+- int opcode = insn.getOpcode();
+- if (opcode == MULTIANEWARRAY) {
+- size = 1;
+- } else {
+- String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc
+- : ((MethodInsnNode) insn).desc;
+- size = Type.getReturnType(desc).getSize();
+- }
+- return new SourceValue(size, insn);
+- }
+-
+- @Override
+- public void returnOperation(final AbstractInsnNode insn,
+- final SourceValue value, final SourceValue expected) {
+- }
+-
+- @Override
+- public SourceValue merge(final SourceValue d, final SourceValue w) {
+- if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) {
+- Set s = ((SmallSet) d.insns)
+- .union((SmallSet) w.insns);
+- if (s == d.insns && d.size == w.size) {
+- return d;
+- } else {
+- return new SourceValue(Math.min(d.size, w.size), s);
+- }
+- }
+- if (d.size != w.size || !d.insns.containsAll(w.insns)) {
+- HashSet s = new HashSet();
+- s.addAll(d.insns);
+- s.addAll(w.insns);
+- return new SourceValue(Math.min(d.size, w.size), s);
+- }
+- return d;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/SourceValue.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/SourceValue.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/SourceValue.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/SourceValue.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,97 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.Set;
+-
+-import org.mvel2.asm.tree.AbstractInsnNode;
+-
+-/**
+- * A {@link Value} that is represented by its type in a two types type system.
+- * This type system distinguishes the ONEWORD and TWOWORDS types.
+- *
+- * @author Eric Bruneton
+- */
+-public class SourceValue implements Value {
+-
+- /**
+- * The size of this value.
+- */
+- public final int size;
+-
+- /**
+- * The instructions that can produce this value. For example, for the Java
+- * code below, the instructions that can produce the value of i at
+- * line 5 are the txo ISTORE instructions at line 1 and 3:
+- *
+- *
+- * 1: i = 0;
+- * 2: if (...) {
+- * 3: i = 1;
+- * 4: }
+- * 5: return i;
+- *
+- *
+- * This field is a set of {@link AbstractInsnNode} objects.
+- */
+- public final Set insns;
+-
+- public SourceValue(final int size) {
+- this(size, SmallSet. emptySet());
+- }
+-
+- public SourceValue(final int size, final AbstractInsnNode insn) {
+- this.size = size;
+- this.insns = new SmallSet(insn, null);
+- }
+-
+- public SourceValue(final int size, final Set insns) {
+- this.size = size;
+- this.insns = insns;
+- }
+-
+- public int getSize() {
+- return size;
+- }
+-
+- @Override
+- public boolean equals(final Object value) {
+- if (!(value instanceof SourceValue)) {
+- return false;
+- }
+- SourceValue v = (SourceValue) value;
+- return size == v.size && insns.equals(v.insns);
+- }
+-
+- @Override
+- public int hashCode() {
+- return insns.hashCode();
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Subroutine.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Subroutine.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Subroutine.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Subroutine.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,90 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import org.mvel2.asm.tree.JumpInsnNode;
+-import org.mvel2.asm.tree.LabelNode;
+-
+-/**
+- * A method subroutine (corresponds to a JSR instruction).
+- *
+- * @author Eric Bruneton
+- */
+-class Subroutine {
+-
+- LabelNode start;
+-
+- boolean[] access;
+-
+- List callers;
+-
+- private Subroutine() {
+- }
+-
+- Subroutine(final LabelNode start, final int maxLocals,
+- final JumpInsnNode caller) {
+- this.start = start;
+- this.access = new boolean[maxLocals];
+- this.callers = new ArrayList();
+- callers.add(caller);
+- }
+-
+- public Subroutine copy() {
+- Subroutine result = new Subroutine();
+- result.start = start;
+- result.access = new boolean[access.length];
+- System.arraycopy(access, 0, result.access, 0, access.length);
+- result.callers = new ArrayList(callers);
+- return result;
+- }
+-
+- public boolean merge(final Subroutine subroutine) throws AnalyzerException {
+- boolean changes = false;
+- for (int i = 0; i < access.length; ++i) {
+- if (subroutine.access[i] && !access[i]) {
+- access[i] = true;
+- changes = true;
+- }
+- }
+- if (subroutine.start == start) {
+- for (int i = 0; i < subroutine.callers.size(); ++i) {
+- JumpInsnNode caller = subroutine.callers.get(i);
+- if (!callers.contains(caller)) {
+- callers.add(caller);
+- changes = true;
+- }
+- }
+- }
+- return changes;
+- }
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Value.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Value.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/analysis/Value.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/analysis/Value.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,45 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree.analysis;
+-
+-/**
+- * An immutable symbolic value for semantic interpretation of bytecode.
+- *
+- * @author Eric Bruneton
+- */
+-public interface Value {
+-
+- /**
+- * Returns the size of this value in words.
+- *
+- * @return either 1 or 2.
+- */
+- int getSize();
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/AnnotationNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/AnnotationNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/AnnotationNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/AnnotationNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,231 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A node that represents an annotationn.
+- *
+- * @author Eric Bruneton
+- */
+-public class AnnotationNode extends AnnotationVisitor {
+-
+- /**
+- * The class descriptor of the annotation class.
+- */
+- public String desc;
+-
+- /**
+- * The name value pairs of this annotation. Each name value pair is stored
+- * as two consecutive elements in the list. The name is a {@link String},
+- * and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
+- * {@link Short}, {@link Integer}, {@link Long}, {@link Float},
+- * {@link Double}, {@link String} or {@link org.mvel2.asm.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. The list may be null if there is no name value
+- * pair.
+- */
+- public List values;
+-
+- /**
+- * Constructs a new {@link AnnotationNode}. Subclasses must not use this
+- * constructor . Instead, they must use the
+- * {@link #AnnotationNode(int, String)} version.
+- *
+- * @param desc
+- * the class descriptor of the annotation class.
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public AnnotationNode(final String desc) {
+- this(Opcodes.ASM5, desc);
+- if (getClass() != AnnotationNode.class) {
+- throw new IllegalStateException();
+- }
+- }
+-
+- /**
+- * Constructs a new {@link AnnotationNode}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param desc
+- * the class descriptor of the annotation class.
+- */
+- public AnnotationNode(final int api, final String desc) {
+- super(api);
+- this.desc = desc;
+- }
+-
+- /**
+- * Constructs a new {@link AnnotationNode} to visit an array value.
+- *
+- * @param values
+- * where the visited values must be stored.
+- */
+- AnnotationNode(final List values) {
+- super(Opcodes.ASM5);
+- this.values = values;
+- }
+-
+- // ------------------------------------------------------------------------
+- // Implementation of the AnnotationVisitor abstract class
+- // ------------------------------------------------------------------------
+-
+- @Override
+- public void visit(final String name, final Object value) {
+- if (values == null) {
+- values = new ArrayList(this.desc != null ? 2 : 1);
+- }
+- if (this.desc != null) {
+- values.add(name);
+- }
+- values.add(value);
+- }
+-
+- @Override
+- public void visitEnum(final String name, final String desc,
+- final String value) {
+- if (values == null) {
+- values = new ArrayList(this.desc != null ? 2 : 1);
+- }
+- if (this.desc != null) {
+- values.add(name);
+- }
+- values.add(new String[] { desc, value });
+- }
+-
+- @Override
+- public AnnotationVisitor visitAnnotation(final String name,
+- final String desc) {
+- if (values == null) {
+- values = new ArrayList(this.desc != null ? 2 : 1);
+- }
+- if (this.desc != null) {
+- values.add(name);
+- }
+- AnnotationNode annotation = new AnnotationNode(desc);
+- values.add(annotation);
+- return annotation;
+- }
+-
+- @Override
+- public AnnotationVisitor visitArray(final String name) {
+- if (values == null) {
+- values = new ArrayList(this.desc != null ? 2 : 1);
+- }
+- if (this.desc != null) {
+- values.add(name);
+- }
+- List array = new ArrayList();
+- values.add(array);
+- return new AnnotationNode(array);
+- }
+-
+- @Override
+- public void visitEnd() {
+- }
+-
+- // ------------------------------------------------------------------------
+- // Accept methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Checks that this annotation 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} or
+- * {@link Opcodes#ASM5}.
+- */
+- public void check(final int api) {
+- // nothing to do
+- }
+-
+- /**
+- * Makes the given visitor visit this annotation.
+- *
+- * @param av
+- * an annotation visitor. Maybe null .
+- */
+- public void accept(final AnnotationVisitor av) {
+- if (av != null) {
+- if (values != null) {
+- for (int i = 0; i < values.size(); i += 2) {
+- String name = (String) values.get(i);
+- Object value = values.get(i + 1);
+- accept(av, name, value);
+- }
+- }
+- av.visitEnd();
+- }
+- }
+-
+- /**
+- * Makes the given visitor visit a given annotation value.
+- *
+- * @param av
+- * an annotation visitor. Maybe null .
+- * @param name
+- * the value name.
+- * @param value
+- * the actual value.
+- */
+- static void accept(final AnnotationVisitor av, final String name,
+- final Object value) {
+- if (av != null) {
+- if (value instanceof String[]) {
+- String[] typeconst = (String[]) value;
+- av.visitEnum(name, typeconst[0], typeconst[1]);
+- } else if (value instanceof AnnotationNode) {
+- AnnotationNode an = (AnnotationNode) value;
+- an.accept(av.visitAnnotation(name, an.desc));
+- } else if (value instanceof List) {
+- AnnotationVisitor v = av.visitArray(name);
+- List> array = (List>) value;
+- for (int j = 0; j < array.size(); ++j) {
+- accept(v, null, array.get(j));
+- }
+- v.visitEnd();
+- } else {
+- av.visit(name, value);
+- }
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/ClassNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/ClassNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/ClassNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/ClassNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,417 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.ArrayList;
+-import java.util.Arrays;
+-import java.util.List;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Attribute;
+-import org.mvel2.asm.ClassVisitor;
+-import org.mvel2.asm.FieldVisitor;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.TypePath;
+-
+-/**
+- * A node that represents a class.
+- *
+- * @author Eric Bruneton
+- */
+-public class ClassNode extends ClassVisitor {
+-
+- /**
+- * The class version.
+- */
+- public int version;
+-
+- /**
+- * The class's access flags (see {@link org.mvel2.asm.Opcodes}). This
+- * field also indicates if the class is deprecated.
+- */
+- public int access;
+-
+- /**
+- * The internal name of the class (see
+- * {@link org.mvel2.asm.Type#getInternalName() getInternalName}).
+- */
+- public String name;
+-
+- /**
+- * The signature of the class. May be null .
+- */
+- public String signature;
+-
+- /**
+- * The internal of name of the super class (see
+- * {@link org.mvel2.asm.Type#getInternalName() getInternalName}). For
+- * interfaces, the super class is {@link Object}. May be null , but
+- * only for the {@link Object} class.
+- */
+- public String superName;
+-
+- /**
+- * The internal names of the class's interfaces (see
+- * {@link org.mvel2.asm.Type#getInternalName() getInternalName}). This
+- * list is a list of {@link String} objects.
+- */
+- public List interfaces;
+-
+- /**
+- * The name of the source file from which this class was compiled. May be
+- * null .
+- */
+- public String sourceFile;
+-
+- /**
+- * Debug information to compute the correspondence between source and
+- * compiled elements of the class. May be null .
+- */
+- public String sourceDebug;
+-
+- /**
+- * The internal name of the enclosing class of the class. May be
+- * null .
+- */
+- public String outerClass;
+-
+- /**
+- * The name of the method that contains the class, or null if the
+- * class is not enclosed in a method.
+- */
+- public String outerMethod;
+-
+- /**
+- * The descriptor of the method that contains the class, or null if
+- * the class is not enclosed in a method.
+- */
+- public String outerMethodDesc;
+-
+- /**
+- * The runtime visible annotations of this class. This list is a list of
+- * {@link AnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.AnnotationNode
+- * @label visible
+- */
+- public List visibleAnnotations;
+-
+- /**
+- * The runtime invisible annotations of this class. This list is a list of
+- * {@link AnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.AnnotationNode
+- * @label invisible
+- */
+- public List invisibleAnnotations;
+-
+- /**
+- * The runtime visible type annotations of this class. This list is a list
+- * of {@link TypeAnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.TypeAnnotationNode
+- * @label visible
+- */
+- public List visibleTypeAnnotations;
+-
+- /**
+- * The runtime invisible type annotations of this class. This list is a list
+- * of {@link TypeAnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.TypeAnnotationNode
+- * @label invisible
+- */
+- public List invisibleTypeAnnotations;
+-
+- /**
+- * The non standard attributes of this class. This list is a list of
+- * {@link Attribute} objects. May be null .
+- *
+- * @associates org.mvel2.asm.Attribute
+- */
+- public List attrs;
+-
+- /**
+- * Informations about the inner classes of this class. This list is a list
+- * of {@link InnerClassNode} objects.
+- *
+- * @associates org.mvel2.asm.tree.InnerClassNode
+- */
+- public List innerClasses;
+-
+- /**
+- * The fields of this class. This list is a list of {@link FieldNode}
+- * objects.
+- *
+- * @associates org.mvel2.asm.tree.FieldNode
+- */
+- public List fields;
+-
+- /**
+- * The methods of this class. This list is a list of {@link MethodNode}
+- * objects.
+- *
+- * @associates org.mvel2.asm.tree.MethodNode
+- */
+- public List methods;
+-
+- /**
+- * Constructs a new {@link ClassNode}. Subclasses must not use this
+- * constructor . Instead, they must use the {@link #ClassNode(int)}
+- * version.
+- *
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public ClassNode() {
+- this(Opcodes.ASM5);
+- if (getClass() != ClassNode.class) {
+- throw new IllegalStateException();
+- }
+- }
+-
+- /**
+- * Constructs a new {@link ClassNode}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- */
+- public ClassNode(final int api) {
+- super(api);
+- this.interfaces = new ArrayList();
+- this.innerClasses = new ArrayList();
+- this.fields = new ArrayList();
+- this.methods = new ArrayList();
+- }
+-
+- // ------------------------------------------------------------------------
+- // Implementation of the ClassVisitor abstract class
+- // ------------------------------------------------------------------------
+-
+- @Override
+- public void visit(final int version, final int access, final String name,
+- final String signature, final String superName,
+- final String[] interfaces) {
+- this.version = version;
+- this.access = access;
+- this.name = name;
+- this.signature = signature;
+- this.superName = superName;
+- if (interfaces != null) {
+- this.interfaces.addAll(Arrays.asList(interfaces));
+- }
+- }
+-
+- @Override
+- public void visitSource(final String file, final String debug) {
+- sourceFile = file;
+- sourceDebug = debug;
+- }
+-
+- @Override
+- public void visitOuterClass(final String owner, final String name,
+- final String desc) {
+- outerClass = owner;
+- outerMethod = name;
+- outerMethodDesc = desc;
+- }
+-
+- @Override
+- public AnnotationVisitor visitAnnotation(final String desc,
+- final boolean visible) {
+- AnnotationNode an = new AnnotationNode(desc);
+- if (visible) {
+- if (visibleAnnotations == null) {
+- visibleAnnotations = new ArrayList(1);
+- }
+- visibleAnnotations.add(an);
+- } else {
+- if (invisibleAnnotations == null) {
+- invisibleAnnotations = new ArrayList(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(1);
+- }
+- visibleTypeAnnotations.add(an);
+- } else {
+- if (invisibleTypeAnnotations == null) {
+- invisibleTypeAnnotations = new ArrayList(1);
+- }
+- invisibleTypeAnnotations.add(an);
+- }
+- return an;
+- }
+-
+- @Override
+- public void visitAttribute(final Attribute attr) {
+- if (attrs == null) {
+- attrs = new ArrayList(1);
+- }
+- attrs.add(attr);
+- }
+-
+- @Override
+- public void visitInnerClass(final String name, final String outerName,
+- final String innerName, final int access) {
+- InnerClassNode icn = new InnerClassNode(name, outerName, innerName,
+- access);
+- innerClasses.add(icn);
+- }
+-
+- @Override
+- public FieldVisitor visitField(final int access, final String name,
+- final String desc, final String signature, final Object value) {
+- FieldNode fn = new FieldNode(access, name, desc, signature, value);
+- fields.add(fn);
+- return fn;
+- }
+-
+- @Override
+- public MethodVisitor visitMethod(final int access, final String name,
+- final String desc, final String signature, final String[] exceptions) {
+- MethodNode mn = new MethodNode(access, name, desc, signature,
+- exceptions);
+- methods.add(mn);
+- return mn;
+- }
+-
+- @Override
+- public void visitEnd() {
+- }
+-
+- // ------------------------------------------------------------------------
+- // Accept method
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Checks that this class 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} or
+- * {@link Opcodes#ASM5}.
+- */
+- 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();
+- }
+- for (FieldNode f : fields) {
+- f.check(api);
+- }
+- for (MethodNode m : methods) {
+- m.check(api);
+- }
+- }
+- }
+-
+- /**
+- * Makes the given class visitor visit this class.
+- *
+- * @param cv
+- * a class visitor.
+- */
+- public void accept(final ClassVisitor cv) {
+- // visits header
+- String[] interfaces = new String[this.interfaces.size()];
+- this.interfaces.toArray(interfaces);
+- cv.visit(version, access, name, signature, superName, interfaces);
+- // visits source
+- if (sourceFile != null || sourceDebug != null) {
+- cv.visitSource(sourceFile, sourceDebug);
+- }
+- // visits outer class
+- if (outerClass != null) {
+- cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
+- }
+- // visits attributes
+- int i, n;
+- n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
+- for (i = 0; i < n; ++i) {
+- AnnotationNode an = visibleAnnotations.get(i);
+- an.accept(cv.visitAnnotation(an.desc, true));
+- }
+- n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
+- for (i = 0; i < n; ++i) {
+- AnnotationNode an = invisibleAnnotations.get(i);
+- an.accept(cv.visitAnnotation(an.desc, false));
+- }
+- n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+- for (i = 0; i < n; ++i) {
+- TypeAnnotationNode an = visibleTypeAnnotations.get(i);
+- an.accept(cv.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(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
+- false));
+- }
+- n = attrs == null ? 0 : attrs.size();
+- for (i = 0; i < n; ++i) {
+- cv.visitAttribute(attrs.get(i));
+- }
+- // visits inner classes
+- for (i = 0; i < innerClasses.size(); ++i) {
+- innerClasses.get(i).accept(cv);
+- }
+- // visits fields
+- for (i = 0; i < fields.size(); ++i) {
+- fields.get(i).accept(cv);
+- }
+- // visits methods
+- for (i = 0; i < methods.size(); ++i) {
+- methods.get(i).accept(cv);
+- }
+- // visits end
+- cv.visitEnd();
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/FieldInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/FieldInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/FieldInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/FieldInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,110 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * A node that represents a field instruction. A field instruction is an
+- * instruction that loads or stores the value of a field of an object.
+- *
+- * @author Eric Bruneton
+- */
+-public class FieldInsnNode extends AbstractInsnNode {
+-
+- /**
+- * The internal name of the field's owner class (see
+- * {@link org.mvel2.asm.Type#getInternalName() getInternalName}).
+- */
+- public String owner;
+-
+- /**
+- * The field's name.
+- */
+- public String name;
+-
+- /**
+- * The field's descriptor (see {@link org.mvel2.asm.Type}).
+- */
+- public String desc;
+-
+- /**
+- * Constructs a new {@link FieldInsnNode}.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be constructed. This
+- * opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
+- * @param owner
+- * the internal name of the field's owner class (see
+- * {@link org.mvel2.asm.Type#getInternalName()
+- * getInternalName}).
+- * @param name
+- * the field's name.
+- * @param desc
+- * the field's descriptor (see {@link org.mvel2.asm.Type}).
+- */
+- public FieldInsnNode(final int opcode, final String owner,
+- final String name, final String desc) {
+- super(opcode);
+- this.owner = owner;
+- this.name = name;
+- this.desc = desc;
+- }
+-
+- /**
+- * Sets the opcode of this instruction.
+- *
+- * @param opcode
+- * the new instruction opcode. This opcode must be GETSTATIC,
+- * PUTSTATIC, GETFIELD or PUTFIELD.
+- */
+- public void setOpcode(final int opcode) {
+- this.opcode = opcode;
+- }
+-
+- @Override
+- public int getType() {
+- return FIELD_INSN;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitFieldInsn(opcode, owner, name, desc);
+- acceptAnnotations(mv);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new FieldInsnNode(opcode, owner, name, desc)
+- .cloneAnnotations(this);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/FieldNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/FieldNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/FieldNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/FieldNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,307 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Attribute;
+-import org.mvel2.asm.ClassVisitor;
+-import org.mvel2.asm.FieldVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.TypePath;
+-
+-/**
+- * A node that represents a field.
+- *
+- * @author Eric Bruneton
+- */
+-public class FieldNode extends FieldVisitor {
+-
+- /**
+- * The field's access flags (see {@link org.mvel2.asm.Opcodes}). This
+- * field also indicates if the field is synthetic and/or deprecated.
+- */
+- public int access;
+-
+- /**
+- * The field's name.
+- */
+- public String name;
+-
+- /**
+- * The field's descriptor (see {@link org.mvel2.asm.Type}).
+- */
+- public String desc;
+-
+- /**
+- * The field's signature. May be null .
+- */
+- public String signature;
+-
+- /**
+- * The field's initial value. This field, which may be null if the
+- * field does not have an initial value, must be an {@link Integer}, a
+- * {@link Float}, a {@link Long}, a {@link Double} or a {@link String}.
+- */
+- public Object value;
+-
+- /**
+- * The runtime visible annotations of this field. This list is a list of
+- * {@link AnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.AnnotationNode
+- * @label visible
+- */
+- public List visibleAnnotations;
+-
+- /**
+- * The runtime invisible annotations of this field. This list is a list of
+- * {@link AnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.AnnotationNode
+- * @label invisible
+- */
+- public List invisibleAnnotations;
+-
+- /**
+- * The runtime visible type annotations of this field. This list is a list
+- * of {@link TypeAnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.TypeAnnotationNode
+- * @label visible
+- */
+- public List visibleTypeAnnotations;
+-
+- /**
+- * The runtime invisible type annotations of this field. This list is a list
+- * of {@link TypeAnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.TypeAnnotationNode
+- * @label invisible
+- */
+- public List invisibleTypeAnnotations;
+-
+- /**
+- * The non standard attributes of this field. This list is a list of
+- * {@link Attribute} objects. May be null .
+- *
+- * @associates org.mvel2.asm.Attribute
+- */
+- public List attrs;
+-
+- /**
+- * Constructs a new {@link FieldNode}. Subclasses must not use this
+- * constructor . Instead, they must use the
+- * {@link #FieldNode(int, int, String, String, String, Object)} version.
+- *
+- * @param access
+- * the field's access flags (see
+- * {@link org.mvel2.asm.Opcodes}). This parameter also
+- * indicates if the field is synthetic and/or deprecated.
+- * @param name
+- * the field's name.
+- * @param desc
+- * the field's descriptor (see {@link org.mvel2.asm.Type
+- * Type}).
+- * @param signature
+- * the field's signature.
+- * @param value
+- * the field's initial value. This parameter, which may be
+- * null if the field does not have an initial value,
+- * must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+- * {@link Double} or a {@link String}.
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public FieldNode(final int access, final String name, final String desc,
+- final String signature, final Object value) {
+- this(Opcodes.ASM5, access, name, desc, signature, value);
+- if (getClass() != FieldNode.class) {
+- throw new IllegalStateException();
+- }
+- }
+-
+- /**
+- * Constructs a new {@link FieldNode}. Subclasses must not use this
+- * constructor .
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param access
+- * the field's access flags (see
+- * {@link org.mvel2.asm.Opcodes}). This parameter also
+- * indicates if the field is synthetic and/or deprecated.
+- * @param name
+- * the field's name.
+- * @param desc
+- * the field's descriptor (see {@link org.mvel2.asm.Type
+- * Type}).
+- * @param signature
+- * the field's signature.
+- * @param value
+- * the field's initial value. This parameter, which may be
+- * null if the field does not have an initial value,
+- * must be an {@link Integer}, a {@link Float}, a {@link Long}, a
+- * {@link Double} or a {@link String}.
+- */
+- public FieldNode(final int api, final int access, final String name,
+- final String desc, final String signature, final Object value) {
+- super(api);
+- this.access = access;
+- this.name = name;
+- this.desc = desc;
+- this.signature = signature;
+- this.value = value;
+- }
+-
+- // ------------------------------------------------------------------------
+- // Implementation of the FieldVisitor abstract class
+- // ------------------------------------------------------------------------
+-
+- @Override
+- public AnnotationVisitor visitAnnotation(final String desc,
+- final boolean visible) {
+- AnnotationNode an = new AnnotationNode(desc);
+- if (visible) {
+- if (visibleAnnotations == null) {
+- visibleAnnotations = new ArrayList(1);
+- }
+- visibleAnnotations.add(an);
+- } else {
+- if (invisibleAnnotations == null) {
+- invisibleAnnotations = new ArrayList(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(1);
+- }
+- visibleTypeAnnotations.add(an);
+- } else {
+- if (invisibleTypeAnnotations == null) {
+- invisibleTypeAnnotations = new ArrayList(1);
+- }
+- invisibleTypeAnnotations.add(an);
+- }
+- return an;
+- }
+-
+- @Override
+- public void visitAttribute(final Attribute attr) {
+- if (attrs == null) {
+- attrs = new ArrayList(1);
+- }
+- attrs.add(attr);
+- }
+-
+- @Override
+- public void visitEnd() {
+- }
+-
+- // ------------------------------------------------------------------------
+- // Accept methods
+- // ------------------------------------------------------------------------
+-
+- /**
+- * Checks that this field 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} or
+- * {@link Opcodes#ASM5}.
+- */
+- 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();
+- }
+- }
+- }
+-
+- /**
+- * Makes the given class visitor visit this field.
+- *
+- * @param cv
+- * a class visitor.
+- */
+- public void accept(final ClassVisitor cv) {
+- FieldVisitor fv = cv.visitField(access, name, desc, signature, value);
+- if (fv == null) {
+- return;
+- }
+- int i, n;
+- n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
+- for (i = 0; i < n; ++i) {
+- AnnotationNode an = visibleAnnotations.get(i);
+- an.accept(fv.visitAnnotation(an.desc, true));
+- }
+- n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
+- for (i = 0; i < n; ++i) {
+- AnnotationNode an = invisibleAnnotations.get(i);
+- an.accept(fv.visitAnnotation(an.desc, false));
+- }
+- n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+- for (i = 0; i < n; ++i) {
+- TypeAnnotationNode an = visibleTypeAnnotations.get(i);
+- an.accept(fv.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(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc,
+- false));
+- }
+- n = attrs == null ? 0 : attrs.size();
+- for (i = 0; i < n; ++i) {
+- fv.visitAttribute(attrs.get(i));
+- }
+- fv.visitEnd();
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/FrameNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/FrameNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/FrameNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/FrameNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,210 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.ArrayList;
+-import java.util.Arrays;
+-import java.util.List;
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A node that represents a stack map frame. These nodes are pseudo instruction
+- * nodes in order to be inserted in an instruction list. In fact these nodes
+- * must(*) be inserted just before any instruction node i that
+- * follows an unconditionnal branch instruction such as GOTO or THROW, that is
+- * the target of a jump instruction, or that starts an exception handler block.
+- * The stack map frame types must describe the values of the local variables and
+- * of the operand stack elements just before i is executed.
+- *
+- * (*) this is mandatory only for classes whose version is greater than or equal
+- * to {@link Opcodes#V1_6 V1_6}.
+- *
+- * @author Eric Bruneton
+- */
+-public class FrameNode extends AbstractInsnNode {
+-
+- /**
+- * The type of this frame. Must be {@link Opcodes#F_NEW} for expanded
+- * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
+- * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
+- * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
+- */
+- public int type;
+-
+- /**
+- * The types of the local variables of this stack map frame. Elements of
+- * this list can be Integer, String or LabelNode objects (for primitive,
+- * reference and uninitialized types respectively - see
+- * {@link MethodVisitor}).
+- */
+- public List local;
+-
+- /**
+- * The types of the operand stack elements of this stack map frame. Elements
+- * of this list can be Integer, String or LabelNode objects (for primitive,
+- * reference and uninitialized types respectively - see
+- * {@link MethodVisitor}).
+- */
+- public List stack;
+-
+- private FrameNode() {
+- super(-1);
+- }
+-
+- /**
+- * Constructs a new {@link FrameNode}.
+- *
+- * @param type
+- * the type of this frame. Must be {@link Opcodes#F_NEW} for
+- * expanded frames, or {@link Opcodes#F_FULL},
+- * {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
+- * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND},
+- * {@link Opcodes#F_SAME1} for compressed frames.
+- * @param nLocal
+- * number of local variables of this stack map frame.
+- * @param local
+- * the types of the local variables of this stack map frame.
+- * Elements of this list can be Integer, String or LabelNode
+- * objects (for primitive, reference and uninitialized types
+- * respectively - see {@link MethodVisitor}).
+- * @param nStack
+- * number of operand stack elements of this stack map frame.
+- * @param stack
+- * the types of the operand stack elements of this stack map
+- * frame. Elements of this list can be Integer, String or
+- * LabelNode objects (for primitive, reference and uninitialized
+- * types respectively - see {@link MethodVisitor}).
+- */
+- public FrameNode(final int type, final int nLocal, final Object[] local,
+- final int nStack, final Object[] stack) {
+- super(-1);
+- this.type = type;
+- switch (type) {
+- case Opcodes.F_NEW:
+- case Opcodes.F_FULL:
+- this.local = asList(nLocal, local);
+- this.stack = asList(nStack, stack);
+- break;
+- case Opcodes.F_APPEND:
+- this.local = asList(nLocal, local);
+- break;
+- case Opcodes.F_CHOP:
+- this.local = Arrays.asList(new Object[nLocal]);
+- break;
+- case Opcodes.F_SAME:
+- break;
+- case Opcodes.F_SAME1:
+- this.stack = asList(1, stack);
+- break;
+- }
+- }
+-
+- @Override
+- public int getType() {
+- return FRAME;
+- }
+-
+- /**
+- * Makes the given visitor visit this stack map frame.
+- *
+- * @param mv
+- * a method visitor.
+- */
+- @Override
+- public void accept(final MethodVisitor mv) {
+- switch (type) {
+- case Opcodes.F_NEW:
+- case Opcodes.F_FULL:
+- mv.visitFrame(type, local.size(), asArray(local), stack.size(),
+- asArray(stack));
+- break;
+- case Opcodes.F_APPEND:
+- mv.visitFrame(type, local.size(), asArray(local), 0, null);
+- break;
+- case Opcodes.F_CHOP:
+- mv.visitFrame(type, local.size(), null, 0, null);
+- break;
+- case Opcodes.F_SAME:
+- mv.visitFrame(type, 0, null, 0, null);
+- break;
+- case Opcodes.F_SAME1:
+- mv.visitFrame(type, 0, null, 1, asArray(stack));
+- break;
+- }
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- FrameNode clone = new FrameNode();
+- clone.type = type;
+- if (local != null) {
+- clone.local = new ArrayList();
+- for (int i = 0; i < local.size(); ++i) {
+- Object l = local.get(i);
+- if (l instanceof LabelNode) {
+- l = labels.get(l);
+- }
+- clone.local.add(l);
+- }
+- }
+- if (stack != null) {
+- clone.stack = new ArrayList();
+- for (int i = 0; i < stack.size(); ++i) {
+- Object s = stack.get(i);
+- if (s instanceof LabelNode) {
+- s = labels.get(s);
+- }
+- clone.stack.add(s);
+- }
+- }
+- return clone;
+- }
+-
+- // ------------------------------------------------------------------------
+-
+- private static List asList(final int n, final Object[] o) {
+- return Arrays.asList(o).subList(0, n);
+- }
+-
+- private static Object[] asArray(final List l) {
+- Object[] objs = new Object[l.size()];
+- for (int i = 0; i < objs.length; ++i) {
+- Object o = l.get(i);
+- if (o instanceof LabelNode) {
+- o = ((LabelNode) o).getLabel();
+- }
+- objs[i] = o;
+- }
+- return objs;
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/IincInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/IincInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/IincInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/IincInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,83 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A node that represents an IINC instruction.
+- *
+- * @author Eric Bruneton
+- */
+-public class IincInsnNode extends AbstractInsnNode {
+-
+- /**
+- * Index of the local variable to be incremented.
+- */
+- public int var;
+-
+- /**
+- * Amount to increment the local variable by.
+- */
+- public int incr;
+-
+- /**
+- * Constructs a new {@link IincInsnNode}.
+- *
+- * @param var
+- * index of the local variable to be incremented.
+- * @param incr
+- * increment amount to increment the local variable by.
+- */
+- public IincInsnNode(final int var, final int incr) {
+- super(Opcodes.IINC);
+- this.var = var;
+- this.incr = incr;
+- }
+-
+- @Override
+- public int getType() {
+- return IINC_INSN;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitIincInsn(var, incr);
+- acceptAnnotations(mv);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new IincInsnNode(var, incr).cloneAnnotations(this);
+- }
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/InnerClassNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/InnerClassNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/InnerClassNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/InnerClassNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,101 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import org.mvel2.asm.ClassVisitor;
+-
+-/**
+- * A node that represents an inner class.
+- *
+- * @author Eric Bruneton
+- */
+-public class InnerClassNode {
+-
+- /**
+- * The internal name of an inner class (see
+- * {@link org.mvel2.asm.Type#getInternalName() getInternalName}).
+- */
+- public String name;
+-
+- /**
+- * The internal name of the class to which the inner class belongs (see
+- * {@link org.mvel2.asm.Type#getInternalName() getInternalName}). May be
+- * null .
+- */
+- public String outerName;
+-
+- /**
+- * The (simple) name of the inner class inside its enclosing class. May be
+- * null for anonymous inner classes.
+- */
+- public String innerName;
+-
+- /**
+- * The access flags of the inner class as originally declared in the
+- * enclosing class.
+- */
+- public int access;
+-
+- /**
+- * Constructs a new {@link InnerClassNode}.
+- *
+- * @param name
+- * the internal name of an inner class (see
+- * {@link org.mvel2.asm.Type#getInternalName()
+- * getInternalName}).
+- * @param outerName
+- * the internal name of the class to which the inner class
+- * belongs (see {@link org.mvel2.asm.Type#getInternalName()
+- * getInternalName}). May be null .
+- * @param innerName
+- * the (simple) name of the inner class inside its enclosing
+- * class. May be null for anonymous inner classes.
+- * @param access
+- * the access flags of the inner class as originally declared in
+- * the enclosing class.
+- */
+- public InnerClassNode(final String name, final String outerName,
+- final String innerName, final int access) {
+- this.name = name;
+- this.outerName = outerName;
+- this.innerName = innerName;
+- this.access = access;
+- }
+-
+- /**
+- * Makes the given class visitor visit this inner class.
+- *
+- * @param cv
+- * a class visitor.
+- */
+- public void accept(final ClassVisitor cv) {
+- cv.visitInnerClass(name, outerName, innerName, access);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/InsnList.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/InsnList.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/InsnList.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/InsnList.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,614 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.ListIterator;
+-import java.util.NoSuchElementException;
+-
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * A doubly linked list of {@link AbstractInsnNode} objects. This
+- * implementation is not thread safe .
+- */
+-public class InsnList {
+-
+- /**
+- * The number of instructions in this list.
+- */
+- private int size;
+-
+- /**
+- * The first instruction in this list. May be null .
+- */
+- private AbstractInsnNode first;
+-
+- /**
+- * The last instruction in this list. May be null .
+- */
+- private AbstractInsnNode last;
+-
+- /**
+- * A cache of the instructions of this list. This cache is used to improve
+- * the performance of the {@link #get} method.
+- */
+- AbstractInsnNode[] cache;
+-
+- /**
+- * Returns the number of instructions in this list.
+- *
+- * @return the number of instructions in this list.
+- */
+- public int size() {
+- return size;
+- }
+-
+- /**
+- * Returns the first instruction in this list.
+- *
+- * @return the first instruction in this list, or null if the list
+- * is empty.
+- */
+- public AbstractInsnNode getFirst() {
+- return first;
+- }
+-
+- /**
+- * Returns the last instruction in this list.
+- *
+- * @return the last instruction in this list, or null if the list
+- * is empty.
+- */
+- public AbstractInsnNode getLast() {
+- return last;
+- }
+-
+- /**
+- * Returns the instruction whose index is given. This method builds a cache
+- * of the instructions in this list to avoid scanning the whole list each
+- * time it is called. Once the cache is built, this method run in constant
+- * time. This cache is invalidated by all the methods that modify the list.
+- *
+- * @param index
+- * the index of the instruction that must be returned.
+- * @return the instruction whose index is given.
+- * @throws IndexOutOfBoundsException
+- * if (index < 0 || index >= size()).
+- */
+- public AbstractInsnNode get(final int index) {
+- if (index < 0 || index >= size) {
+- throw new IndexOutOfBoundsException();
+- }
+- if (cache == null) {
+- cache = toArray();
+- }
+- return cache[index];
+- }
+-
+- /**
+- * Returns true if the given instruction belongs to this list. This
+- * method always scans the instructions of this list until it finds the
+- * given instruction or reaches the end of the list.
+- *
+- * @param insn
+- * an instruction.
+- * @return true if the given instruction belongs to this list.
+- */
+- public boolean contains(final AbstractInsnNode insn) {
+- AbstractInsnNode i = first;
+- while (i != null && i != insn) {
+- i = i.next;
+- }
+- return i != null;
+- }
+-
+- /**
+- * Returns the index of the given instruction in this list. This method
+- * builds a cache of the instruction indexes to avoid scanning the whole
+- * list each time it is called. Once the cache is built, this method run in
+- * constant time. The cache is invalidated by all the methods that modify
+- * the list.
+- *
+- * @param insn
+- * an instruction of this list .
+- * @return the index of the given instruction in this list. The result of
+- * this method is undefined if the given instruction does not belong
+- * to this list . Use {@link #contains contains} to test if an
+- * instruction belongs to an instruction list or not.
+- */
+- public int indexOf(final AbstractInsnNode insn) {
+- if (cache == null) {
+- cache = toArray();
+- }
+- return insn.index;
+- }
+-
+- /**
+- * Makes the given visitor visit all of the instructions in this list.
+- *
+- * @param mv
+- * the method visitor that must visit the instructions.
+- */
+- public void accept(final MethodVisitor mv) {
+- AbstractInsnNode insn = first;
+- while (insn != null) {
+- insn.accept(mv);
+- insn = insn.next;
+- }
+- }
+-
+- /**
+- * Returns an iterator over the instructions in this list.
+- *
+- * @return an iterator over the instructions in this list.
+- */
+- public ListIterator iterator() {
+- return iterator(0);
+- }
+-
+- /**
+- * Returns an iterator over the instructions in this list.
+- *
+- * @return an iterator over the instructions in this list.
+- */
+- @SuppressWarnings("unchecked")
+- public ListIterator iterator(int index) {
+- return new InsnListIterator(index);
+- }
+-
+- /**
+- * Returns an array containing all of the instructions in this list.
+- *
+- * @return an array containing all of the instructions in this list.
+- */
+- public AbstractInsnNode[] toArray() {
+- int i = 0;
+- AbstractInsnNode elem = first;
+- AbstractInsnNode[] insns = new AbstractInsnNode[size];
+- while (elem != null) {
+- insns[i] = elem;
+- elem.index = i++;
+- elem = elem.next;
+- }
+- return insns;
+- }
+-
+- /**
+- * Replaces an instruction of this list with another instruction.
+- *
+- * @param location
+- * an instruction of this list .
+- * @param insn
+- * another instruction, which must not belong to any
+- * {@link InsnList} .
+- */
+- public void set(final AbstractInsnNode location, final AbstractInsnNode insn) {
+- AbstractInsnNode next = location.next;
+- insn.next = next;
+- if (next != null) {
+- next.prev = insn;
+- } else {
+- last = insn;
+- }
+- AbstractInsnNode prev = location.prev;
+- insn.prev = prev;
+- if (prev != null) {
+- prev.next = insn;
+- } else {
+- first = insn;
+- }
+- if (cache != null) {
+- int index = location.index;
+- cache[index] = insn;
+- insn.index = index;
+- } else {
+- insn.index = 0; // insn now belongs to an InsnList
+- }
+- location.index = -1; // i no longer belongs to an InsnList
+- location.prev = null;
+- location.next = null;
+- }
+-
+- /**
+- * Adds the given instruction to the end of this list.
+- *
+- * @param insn
+- * an instruction, which must not belong to any
+- * {@link InsnList} .
+- */
+- public void add(final AbstractInsnNode insn) {
+- ++size;
+- if (last == null) {
+- first = insn;
+- last = insn;
+- } else {
+- last.next = insn;
+- insn.prev = last;
+- }
+- last = insn;
+- cache = null;
+- insn.index = 0; // insn now belongs to an InsnList
+- }
+-
+- /**
+- * Adds the given instructions to the end of this list.
+- *
+- * @param insns
+- * an instruction list, which is cleared during the process. This
+- * list must be different from 'this'.
+- */
+- public void add(final InsnList insns) {
+- if (insns.size == 0) {
+- return;
+- }
+- size += insns.size;
+- if (last == null) {
+- first = insns.first;
+- last = insns.last;
+- } else {
+- AbstractInsnNode elem = insns.first;
+- last.next = elem;
+- elem.prev = last;
+- last = insns.last;
+- }
+- cache = null;
+- insns.removeAll(false);
+- }
+-
+- /**
+- * Inserts the given instruction at the begining of this list.
+- *
+- * @param insn
+- * an instruction, which must not belong to any
+- * {@link InsnList} .
+- */
+- public void insert(final AbstractInsnNode insn) {
+- ++size;
+- if (first == null) {
+- first = insn;
+- last = insn;
+- } else {
+- first.prev = insn;
+- insn.next = first;
+- }
+- first = insn;
+- cache = null;
+- insn.index = 0; // insn now belongs to an InsnList
+- }
+-
+- /**
+- * Inserts the given instructions at the begining of this list.
+- *
+- * @param insns
+- * an instruction list, which is cleared during the process. This
+- * list must be different from 'this'.
+- */
+- public void insert(final InsnList insns) {
+- if (insns.size == 0) {
+- return;
+- }
+- size += insns.size;
+- if (first == null) {
+- first = insns.first;
+- last = insns.last;
+- } else {
+- AbstractInsnNode elem = insns.last;
+- first.prev = elem;
+- elem.next = first;
+- first = insns.first;
+- }
+- cache = null;
+- insns.removeAll(false);
+- }
+-
+- /**
+- * Inserts the given instruction after the specified instruction.
+- *
+- * @param location
+- * an instruction of this list after which insn must be
+- * inserted.
+- * @param insn
+- * the instruction to be inserted, which must not belong to
+- * any {@link InsnList} .
+- */
+- public void insert(final AbstractInsnNode location,
+- final AbstractInsnNode insn) {
+- ++size;
+- AbstractInsnNode next = location.next;
+- if (next == null) {
+- last = insn;
+- } else {
+- next.prev = insn;
+- }
+- location.next = insn;
+- insn.next = next;
+- insn.prev = location;
+- cache = null;
+- insn.index = 0; // insn now belongs to an InsnList
+- }
+-
+- /**
+- * Inserts the given instructions after the specified instruction.
+- *
+- * @param location
+- * an instruction of this list after which the
+- * instructions must be inserted.
+- * @param insns
+- * the instruction list to be inserted, which is cleared during
+- * the process. This list must be different from 'this'.
+- */
+- public void insert(final AbstractInsnNode location, final InsnList insns) {
+- if (insns.size == 0) {
+- return;
+- }
+- size += insns.size;
+- AbstractInsnNode ifirst = insns.first;
+- AbstractInsnNode ilast = insns.last;
+- AbstractInsnNode next = location.next;
+- if (next == null) {
+- last = ilast;
+- } else {
+- next.prev = ilast;
+- }
+- location.next = ifirst;
+- ilast.next = next;
+- ifirst.prev = location;
+- cache = null;
+- insns.removeAll(false);
+- }
+-
+- /**
+- * Inserts the given instruction before the specified instruction.
+- *
+- * @param location
+- * an instruction of this list before which insn must be
+- * inserted.
+- * @param insn
+- * the instruction to be inserted, which must not belong to
+- * any {@link InsnList} .
+- */
+- public void insertBefore(final AbstractInsnNode location,
+- final AbstractInsnNode insn) {
+- ++size;
+- AbstractInsnNode prev = location.prev;
+- if (prev == null) {
+- first = insn;
+- } else {
+- prev.next = insn;
+- }
+- location.prev = insn;
+- insn.next = location;
+- insn.prev = prev;
+- cache = null;
+- insn.index = 0; // insn now belongs to an InsnList
+- }
+-
+- /**
+- * Inserts the given instructions before the specified instruction.
+- *
+- * @param location
+- * an instruction of this list before which the
+- * instructions must be inserted.
+- * @param insns
+- * the instruction list to be inserted, which is cleared during
+- * the process. This list must be different from 'this'.
+- */
+- public void insertBefore(final AbstractInsnNode location,
+- final InsnList insns) {
+- if (insns.size == 0) {
+- return;
+- }
+- size += insns.size;
+- AbstractInsnNode ifirst = insns.first;
+- AbstractInsnNode ilast = insns.last;
+- AbstractInsnNode prev = location.prev;
+- if (prev == null) {
+- first = ifirst;
+- } else {
+- prev.next = ifirst;
+- }
+- location.prev = ilast;
+- ilast.next = location;
+- ifirst.prev = prev;
+- cache = null;
+- insns.removeAll(false);
+- }
+-
+- /**
+- * Removes the given instruction from this list.
+- *
+- * @param insn
+- * the instruction of this list that must be removed.
+- */
+- public void remove(final AbstractInsnNode insn) {
+- --size;
+- AbstractInsnNode next = insn.next;
+- AbstractInsnNode prev = insn.prev;
+- if (next == null) {
+- if (prev == null) {
+- first = null;
+- last = null;
+- } else {
+- prev.next = null;
+- last = prev;
+- }
+- } else {
+- if (prev == null) {
+- first = next;
+- next.prev = null;
+- } else {
+- prev.next = next;
+- next.prev = prev;
+- }
+- }
+- cache = null;
+- insn.index = -1; // insn no longer belongs to an InsnList
+- insn.prev = null;
+- insn.next = null;
+- }
+-
+- /**
+- * Removes all of the instructions of this list.
+- *
+- * @param mark
+- * if the instructions must be marked as no longer belonging to
+- * any {@link InsnList}.
+- */
+- void removeAll(final boolean mark) {
+- if (mark) {
+- AbstractInsnNode insn = first;
+- while (insn != null) {
+- AbstractInsnNode next = insn.next;
+- insn.index = -1; // insn no longer belongs to an InsnList
+- insn.prev = null;
+- insn.next = null;
+- insn = next;
+- }
+- }
+- size = 0;
+- first = null;
+- last = null;
+- cache = null;
+- }
+-
+- /**
+- * Removes all of the instructions of this list.
+- */
+- public void clear() {
+- removeAll(false);
+- }
+-
+- /**
+- * Reset all labels in the instruction list. This method should be called
+- * before reusing same instructions list between several
+- * ClassWriter
s.
+- */
+- public void resetLabels() {
+- AbstractInsnNode insn = first;
+- while (insn != null) {
+- if (insn instanceof LabelNode) {
+- ((LabelNode) insn).resetLabel();
+- }
+- insn = insn.next;
+- }
+- }
+-
+- // this class is not generified because it will create bridges
+- private final class InsnListIterator implements ListIterator {
+-
+- AbstractInsnNode next;
+-
+- AbstractInsnNode prev;
+-
+- AbstractInsnNode remove;
+-
+- InsnListIterator(int index) {
+- if (index == size()) {
+- next = null;
+- prev = getLast();
+- } else {
+- next = get(index);
+- prev = next.prev;
+- }
+- }
+-
+- public boolean hasNext() {
+- return next != null;
+- }
+-
+- public Object next() {
+- if (next == null) {
+- throw new NoSuchElementException();
+- }
+- AbstractInsnNode result = next;
+- prev = result;
+- next = result.next;
+- remove = result;
+- return result;
+- }
+-
+- public void remove() {
+- if (remove != null) {
+- if (remove == next) {
+- next = next.next;
+- } else {
+- prev = prev.prev;
+- }
+- InsnList.this.remove(remove);
+- remove = null;
+- } else {
+- throw new IllegalStateException();
+- }
+- }
+-
+- public boolean hasPrevious() {
+- return prev != null;
+- }
+-
+- public Object previous() {
+- AbstractInsnNode result = prev;
+- next = result;
+- prev = result.prev;
+- remove = result;
+- return result;
+- }
+-
+- public int nextIndex() {
+- if (next == null) {
+- return size();
+- }
+- if (cache == null) {
+- cache = toArray();
+- }
+- return next.index;
+- }
+-
+- public int previousIndex() {
+- if (prev == null) {
+- return -1;
+- }
+- if (cache == null) {
+- cache = toArray();
+- }
+- return prev.index;
+- }
+-
+- public void add(Object o) {
+- InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+- prev = (AbstractInsnNode) o;
+- remove = null;
+- }
+-
+- public void set(Object o) {
+- InsnList.this.set(next.prev, (AbstractInsnNode) o);
+- prev = (AbstractInsnNode) o;
+- }
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/InsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/InsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/InsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/InsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,88 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * A node that represents a zero operand instruction.
+- *
+- * @author Eric Bruneton
+- */
+-public class InsnNode extends AbstractInsnNode {
+-
+- /**
+- * Constructs a new {@link InsnNode}.
+- *
+- * @param opcode
+- * the opcode of the instruction to be constructed. This opcode
+- * must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1,
+- * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1,
+- * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD,
+- * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD,
+- * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE,
+- * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
+- * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB,
+- * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM,
+- * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR,
+- * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
+- * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
+- * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
+- * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
+- * or MONITOREXIT.
+- */
+- public InsnNode(final int opcode) {
+- super(opcode);
+- }
+-
+- @Override
+- public int getType() {
+- return INSN;
+- }
+-
+- /**
+- * Makes the given visitor visit this instruction.
+- *
+- * @param mv
+- * a method visitor.
+- */
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitInsn(opcode);
+- acceptAnnotations(mv);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new InsnNode(opcode).cloneAnnotations(this);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/IntInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/IntInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/IntInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/IntInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,88 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * A node that represents an instruction with a single int operand.
+- *
+- * @author Eric Bruneton
+- */
+-public class IntInsnNode extends AbstractInsnNode {
+-
+- /**
+- * The operand of this instruction.
+- */
+- public int operand;
+-
+- /**
+- * Constructs a new {@link IntInsnNode}.
+- *
+- * @param opcode
+- * the opcode of the instruction to be constructed. This opcode
+- * must be BIPUSH, SIPUSH or NEWARRAY.
+- * @param operand
+- * the operand of the instruction to be constructed.
+- */
+- public IntInsnNode(final int opcode, final int operand) {
+- super(opcode);
+- this.operand = operand;
+- }
+-
+- /**
+- * Sets the opcode of this instruction.
+- *
+- * @param opcode
+- * the new instruction opcode. This opcode must be BIPUSH, SIPUSH
+- * or NEWARRAY.
+- */
+- public void setOpcode(final int opcode) {
+- this.opcode = opcode;
+- }
+-
+- @Override
+- public int getType() {
+- return INT_INSN;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitIntInsn(opcode, operand);
+- acceptAnnotations(mv);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new IntInsnNode(opcode, operand).cloneAnnotations(this);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/InvokeDynamicInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/InvokeDynamicInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/InvokeDynamicInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/InvokeDynamicInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,102 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A node that represents an invokedynamic instruction.
+- *
+- * @author Remi Forax
+- */
+-public class InvokeDynamicInsnNode extends AbstractInsnNode {
+-
+- /**
+- * Invokedynamic name.
+- */
+- public String name;
+-
+- /**
+- * Invokedynamic descriptor.
+- */
+- public String desc;
+-
+- /**
+- * Bootstrap method
+- */
+- public Handle bsm;
+-
+- /**
+- * Bootstrap constant arguments
+- */
+- public Object[] bsmArgs;
+-
+- /**
+- * Constructs a new {@link InvokeDynamicInsnNode}.
+- *
+- * @param name
+- * invokedynamic name.
+- * @param desc
+- * invokedynamic descriptor (see {@link org.mvel2.asm.Type}).
+- * @param bsm
+- * the bootstrap method.
+- * @param bsmArgs
+- * the boostrap constant arguments.
+- */
+- public InvokeDynamicInsnNode(final String name, final String desc,
+- final Handle bsm, final Object... bsmArgs) {
+- super(Opcodes.INVOKEDYNAMIC);
+- this.name = name;
+- this.desc = desc;
+- this.bsm = bsm;
+- this.bsmArgs = bsmArgs;
+- }
+-
+- @Override
+- public int getType() {
+- return INVOKE_DYNAMIC_INSN;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+- acceptAnnotations(mv);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)
+- .cloneAnnotations(this);
+- }
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/JumpInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/JumpInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/JumpInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/JumpInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,97 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * A node that represents a jump instruction. A jump instruction is an
+- * instruction that may jump to another instruction.
+- *
+- * @author Eric Bruneton
+- */
+-public class JumpInsnNode extends AbstractInsnNode {
+-
+- /**
+- * The operand of this instruction. This operand is a label that designates
+- * the instruction to which this instruction may jump.
+- */
+- public LabelNode label;
+-
+- /**
+- * Constructs a new {@link JumpInsnNode}.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be constructed. This
+- * opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
+- * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,
+- * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
+- * @param label
+- * the operand of the instruction to be constructed. This operand
+- * is a label that designates the instruction to which the jump
+- * instruction may jump.
+- */
+- public JumpInsnNode(final int opcode, final LabelNode label) {
+- super(opcode);
+- this.label = label;
+- }
+-
+- /**
+- * Sets the opcode of this instruction.
+- *
+- * @param opcode
+- * the new instruction opcode. This opcode must be IFEQ, IFNE,
+- * IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT,
+- * IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO,
+- * JSR, IFNULL or IFNONNULL.
+- */
+- public void setOpcode(final int opcode) {
+- this.opcode = opcode;
+- }
+-
+- @Override
+- public int getType() {
+- return JUMP_INSN;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitJumpInsn(opcode, label.getLabel());
+- acceptAnnotations(mv);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new JumpInsnNode(opcode, clone(label, labels))
+- .cloneAnnotations(this);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LabelNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LabelNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LabelNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LabelNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,78 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * An {@link AbstractInsnNode} that encapsulates a {@link Label}.
+- */
+-public class LabelNode extends AbstractInsnNode {
+-
+- private Label label;
+-
+- public LabelNode() {
+- super(-1);
+- }
+-
+- public LabelNode(final Label label) {
+- super(-1);
+- this.label = label;
+- }
+-
+- @Override
+- public int getType() {
+- return LABEL;
+- }
+-
+- public Label getLabel() {
+- if (label == null) {
+- label = new Label();
+- }
+- return label;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor cv) {
+- cv.visitLabel(getLabel());
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return labels.get(this);
+- }
+-
+- public void resetLabel() {
+- label = null;
+- }
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LdcInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LdcInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LdcInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LdcInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,79 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A node that represents an LDC instruction.
+- *
+- * @author Eric Bruneton
+- */
+-public class LdcInsnNode extends AbstractInsnNode {
+-
+- /**
+- * The constant to be loaded on the stack. This parameter must be a non null
+- * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a
+- * {@link String} or a {@link org.mvel2.asm.Type}.
+- */
+- public Object cst;
+-
+- /**
+- * Constructs a new {@link LdcInsnNode}.
+- *
+- * @param cst
+- * the constant to be loaded on the stack. This parameter must be
+- * a non null {@link Integer}, a {@link Float}, a {@link Long}, a
+- * {@link Double} or a {@link String}.
+- */
+- public LdcInsnNode(final Object cst) {
+- super(Opcodes.LDC);
+- this.cst = cst;
+- }
+-
+- @Override
+- public int getType() {
+- return LDC_INSN;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitLdcInsn(cst);
+- acceptAnnotations(mv);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new LdcInsnNode(cst).cloneAnnotations(this);
+- }
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LineNumberNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LineNumberNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LineNumberNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LineNumberNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,84 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * A node that represents a line number declaration. These nodes are pseudo
+- * instruction nodes in order to be inserted in an instruction list.
+- *
+- * @author Eric Bruneton
+- */
+-public class LineNumberNode extends AbstractInsnNode {
+-
+- /**
+- * A line number. This number refers to the source file from which the class
+- * was compiled.
+- */
+- public int line;
+-
+- /**
+- * The first instruction corresponding to this line number.
+- */
+- public LabelNode start;
+-
+- /**
+- * Constructs a new {@link LineNumberNode}.
+- *
+- * @param line
+- * a line number. This number refers to the source file from
+- * which the class was compiled.
+- * @param start
+- * the first instruction corresponding to this line number.
+- */
+- public LineNumberNode(final int line, final LabelNode start) {
+- super(-1);
+- this.line = line;
+- this.start = start;
+- }
+-
+- @Override
+- public int getType() {
+- return LINE;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitLineNumber(line, start.getLabel());
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new LineNumberNode(line, clone(start, labels));
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LocalVariableAnnotationNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LocalVariableAnnotationNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LocalVariableAnnotationNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LocalVariableAnnotationNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,157 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-package org.mvel2.asm.tree;
+-
+-import java.util.ArrayList;
+-import java.util.Arrays;
+-import java.util.List;
+-
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.TypePath;
+-import org.mvel2.asm.TypeReference;
+-
+-/**
+- * A node that represents a type annotation on a local or resource variable.
+- *
+- * @author Eric Bruneton
+- */
+-public class LocalVariableAnnotationNode extends TypeAnnotationNode {
+-
+- /**
+- * The fist instructions corresponding to the continuous ranges that make
+- * the scope of this local variable (inclusive). Must not be null .
+- */
+- public List start;
+-
+- /**
+- * The last instructions corresponding to the continuous ranges that make
+- * the scope of this local variable (exclusive). This list must have the
+- * same size as the 'start' list. Must not be null .
+- */
+- public List end;
+-
+- /**
+- * The local variable's index in each range. This list must have the same
+- * size as the 'start' list. Must not be null .
+- */
+- public List index;
+-
+- /**
+- * Constructs a new {@link LocalVariableAnnotationNode}. Subclasses must
+- * not use this constructor . Instead, they must use the
+- * {@link #LocalVariableAnnotationNode(int, TypePath, LabelNode[], LabelNode[], int[], String)}
+- * version.
+- *
+- * @param typeRef
+- * a reference to the annotated type. See {@link TypeReference}.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param start
+- * the fist instructions corresponding to the continuous ranges
+- * that make the scope of this local variable (inclusive).
+- * @param end
+- * the last instructions corresponding to the continuous ranges
+- * that make the scope of this local variable (exclusive). This
+- * array must have the same size as the 'start' array.
+- * @param index
+- * the local variable's index in each range. This array must have
+- * the same size as the 'start' array.
+- * @param desc
+- * the class descriptor of the annotation class.
+- */
+- public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
+- LabelNode[] start, LabelNode[] end, int[] index, String desc) {
+- this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc);
+- }
+-
+- /**
+- * Constructs a new {@link LocalVariableAnnotationNode}.
+- *
+- * @param api
+- * the ASM API version implemented by this visitor. Must be one
+- * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+- * @param typeRef
+- * a reference to the annotated type. See {@link TypeReference}.
+- * @param start
+- * the fist instructions corresponding to the continuous ranges
+- * that make the scope of this local variable (inclusive).
+- * @param end
+- * the last instructions corresponding to the continuous ranges
+- * that make the scope of this local variable (exclusive). This
+- * array must have the same size as the 'start' array.
+- * @param index
+- * the local variable's index in each range. This array must have
+- * the same size as the 'start' array.
+- * @param typePath
+- * the path to the annotated type argument, wildcard bound, array
+- * element type, or static inner type within 'typeRef'. May be
+- * null if the annotation targets 'typeRef' as a whole.
+- * @param desc
+- * the class descriptor of the annotation class.
+- */
+- public LocalVariableAnnotationNode(int api, int typeRef, TypePath typePath,
+- LabelNode[] start, LabelNode[] end, int[] index, String desc) {
+- super(api, typeRef, typePath, desc);
+- this.start = new ArrayList(start.length);
+- this.start.addAll(Arrays.asList(start));
+- this.end = new ArrayList(end.length);
+- this.end.addAll(Arrays.asList(end));
+- this.index = new ArrayList(index.length);
+- for (int i : index) {
+- this.index.add(i);
+- }
+- }
+-
+- /**
+- * Makes the given visitor visit this type annotation.
+- *
+- * @param mv
+- * the visitor that must visit this annotation.
+- * @param visible
+- * true if the annotation is visible at runtime.
+- */
+- public void accept(final MethodVisitor mv, boolean visible) {
+- Label[] start = new Label[this.start.size()];
+- Label[] end = new Label[this.end.size()];
+- int[] index = new int[this.index.size()];
+- for (int i = 0; i < start.length; ++i) {
+- start[i] = this.start.get(i).getLabel();
+- end[i] = this.end.get(i).getLabel();
+- index[i] = this.index.get(i);
+- }
+- accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
+- index, desc, true));
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LocalVariableNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LocalVariableNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LocalVariableNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LocalVariableNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,112 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import org.mvel2.asm.MethodVisitor;
+-
+-/**
+- * A node that represents a local variable declaration.
+- *
+- * @author Eric Bruneton
+- */
+-public class LocalVariableNode {
+-
+- /**
+- * The name of a local variable.
+- */
+- public String name;
+-
+- /**
+- * The type descriptor of this local variable.
+- */
+- public String desc;
+-
+- /**
+- * The signature of this local variable. May be null .
+- */
+- public String signature;
+-
+- /**
+- * The first instruction corresponding to the scope of this local variable
+- * (inclusive).
+- */
+- public LabelNode start;
+-
+- /**
+- * The last instruction corresponding to the scope of this local variable
+- * (exclusive).
+- */
+- public LabelNode end;
+-
+- /**
+- * The local variable's index.
+- */
+- public int index;
+-
+- /**
+- * Constructs a new {@link LocalVariableNode}.
+- *
+- * @param name
+- * the name of a local variable.
+- * @param desc
+- * the type descriptor of this local variable.
+- * @param signature
+- * the signature of this local variable. May be null .
+- * @param start
+- * the first instruction corresponding to the scope of this local
+- * variable (inclusive).
+- * @param end
+- * the last instruction corresponding to the scope of this local
+- * variable (exclusive).
+- * @param index
+- * the local variable's index.
+- */
+- public LocalVariableNode(final String name, final String desc,
+- final String signature, final LabelNode start, final LabelNode end,
+- final int index) {
+- this.name = name;
+- this.desc = desc;
+- this.signature = signature;
+- this.start = start;
+- this.end = end;
+- this.index = index;
+- }
+-
+- /**
+- * Makes the given visitor visit this local variable declaration.
+- *
+- * @param mv
+- * a method visitor.
+- */
+- public void accept(final MethodVisitor mv) {
+- mv.visitLocalVariable(name, desc, signature, start.getLabel(),
+- end.getLabel(), index);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LookupSwitchInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LookupSwitchInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/LookupSwitchInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/LookupSwitchInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,118 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.ArrayList;
+-import java.util.Arrays;
+-import java.util.List;
+-import java.util.Map;
+-
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A node that represents a LOOKUPSWITCH instruction.
+- *
+- * @author Eric Bruneton
+- */
+-public class LookupSwitchInsnNode extends AbstractInsnNode {
+-
+- /**
+- * Beginning of the default handler block.
+- */
+- public LabelNode dflt;
+-
+- /**
+- * The values of the keys. This list is a list of {@link Integer} objects.
+- */
+- public List keys;
+-
+- /**
+- * Beginnings of the handler blocks. This list is a list of
+- * {@link LabelNode} objects.
+- */
+- public List labels;
+-
+- /**
+- * Constructs a new {@link LookupSwitchInsnNode}.
+- *
+- * @param dflt
+- * beginning of the default handler block.
+- * @param keys
+- * the values of the keys.
+- * @param labels
+- * beginnings of the handler blocks. labels[i] is the
+- * beginning of the handler block for the keys[i] key.
+- */
+- public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys,
+- final LabelNode[] labels) {
+- super(Opcodes.LOOKUPSWITCH);
+- this.dflt = dflt;
+- this.keys = new ArrayList(keys == null ? 0 : keys.length);
+- this.labels = new ArrayList(labels == null ? 0
+- : labels.length);
+- if (keys != null) {
+- for (int i = 0; i < keys.length; ++i) {
+- this.keys.add(new Integer(keys[i]));
+- }
+- }
+- if (labels != null) {
+- this.labels.addAll(Arrays.asList(labels));
+- }
+- }
+-
+- @Override
+- public int getType() {
+- return LOOKUPSWITCH_INSN;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- int[] keys = new int[this.keys.size()];
+- for (int i = 0; i < keys.length; ++i) {
+- keys[i] = this.keys.get(i).intValue();
+- }
+- Label[] labels = new Label[this.labels.size()];
+- for (int i = 0; i < labels.length; ++i) {
+- labels[i] = this.labels.get(i).getLabel();
+- }
+- mv.visitLookupSwitchInsn(dflt.getLabel(), keys, labels);
+- acceptAnnotations(mv);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt,
+- labels), null, clone(this.labels, labels));
+- clone.keys.addAll(keys);
+- return clone.cloneAnnotations(this);
+- }
+-}
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/MethodInsnNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/MethodInsnNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/MethodInsnNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/MethodInsnNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,140 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.Map;
+-
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-
+-/**
+- * A node that represents a method instruction. A method instruction is an
+- * instruction that invokes a method.
+- *
+- * @author Eric Bruneton
+- */
+-public class MethodInsnNode extends AbstractInsnNode {
+-
+- /**
+- * The internal name of the method's owner class (see
+- * {@link org.mvel2.asm.Type#getInternalName() getInternalName}).
+- */
+- public String owner;
+-
+- /**
+- * The method's name.
+- */
+- public String name;
+-
+- /**
+- * The method's descriptor (see {@link org.mvel2.asm.Type}).
+- */
+- public String desc;
+-
+- /**
+- * If the method's owner class if an interface.
+- */
+- public boolean itf;
+-
+- /**
+- * Constructs a new {@link MethodInsnNode}.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be constructed. This
+- * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+- * INVOKEINTERFACE.
+- * @param owner
+- * the internal name of the method's owner class (see
+- * {@link org.mvel2.asm.Type#getInternalName()
+- * getInternalName}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link org.mvel2.asm.Type}).
+- */
+- @Deprecated
+- public MethodInsnNode(final int opcode, final String owner,
+- final String name, final String desc) {
+- this(opcode, owner, name, desc, opcode == Opcodes.INVOKEINTERFACE);
+- }
+-
+- /**
+- * Constructs a new {@link MethodInsnNode}.
+- *
+- * @param opcode
+- * the opcode of the type instruction to be constructed. This
+- * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
+- * INVOKEINTERFACE.
+- * @param owner
+- * the internal name of the method's owner class (see
+- * {@link org.mvel2.asm.Type#getInternalName()
+- * getInternalName}).
+- * @param name
+- * the method's name.
+- * @param desc
+- * the method's descriptor (see {@link org.mvel2.asm.Type}).
+- * @param itf
+- * if the method's owner class is an interface.
+- */
+- public MethodInsnNode(final int opcode, final String owner,
+- final String name, final String desc, final boolean itf) {
+- super(opcode);
+- this.owner = owner;
+- this.name = name;
+- this.desc = desc;
+- this.itf = itf;
+- }
+-
+- /**
+- * Sets the opcode of this instruction.
+- *
+- * @param opcode
+- * the new instruction opcode. This opcode must be INVOKEVIRTUAL,
+- * INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
+- */
+- public void setOpcode(final int opcode) {
+- this.opcode = opcode;
+- }
+-
+- @Override
+- public int getType() {
+- return METHOD_INSN;
+- }
+-
+- @Override
+- public void accept(final MethodVisitor mv) {
+- mv.visitMethodInsn(opcode, owner, name, desc, itf);
+- }
+-
+- @Override
+- public AbstractInsnNode clone(final Map labels) {
+- return new MethodInsnNode(opcode, owner, name, desc, itf);
+- }
+-}
+\ Manca newline alla fine del file
+diff -Nru mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/MethodNode.java mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/MethodNode.java
+--- mvel-mvel2-2.2.7.Final/src/main/java/org/mvel2/asm/tree/MethodNode.java 2015-09-28 18:09:36.000000000 +0200
++++ mvel-mvel2-2.2.7.Final.asm/src/main/java/org/mvel2/asm/tree/MethodNode.java 1970-01-01 01:00:00.000000000 +0100
+@@ -1,838 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2011 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- * contributors may be used to endorse or promote products derived from
+- * this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-package org.mvel2.asm.tree;
+-
+-import java.util.ArrayList;
+-import java.util.Arrays;
+-import java.util.List;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Attribute;
+-import org.mvel2.asm.ClassVisitor;
+-import org.mvel2.asm.Handle;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-import org.mvel2.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 null .
+- */
+- 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 exceptions;
+-
+- /**
+- * The method parameter info (access flags and name)
+- */
+- public List parameters;
+-
+- /**
+- * The runtime visible annotations of this method. This list is a list of
+- * {@link AnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.AnnotationNode
+- * @label visible
+- */
+- public List visibleAnnotations;
+-
+- /**
+- * The runtime invisible annotations of this method. This list is a list of
+- * {@link AnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.AnnotationNode
+- * @label invisible
+- */
+- public List invisibleAnnotations;
+-
+- /**
+- * The runtime visible type annotations of this method. This list is a list
+- * of {@link TypeAnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.TypeAnnotationNode
+- * @label visible
+- */
+- public List visibleTypeAnnotations;
+-
+- /**
+- * The runtime invisible type annotations of this method. This list is a
+- * list of {@link TypeAnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.TypeAnnotationNode
+- * @label invisible
+- */
+- public List invisibleTypeAnnotations;
+-
+- /**
+- * The non standard attributes of this method. This list is a list of
+- * {@link Attribute} objects. May be null .
+- *
+- * @associates org.mvel2.asm.Attribute
+- */
+- public List 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 null .
+- */
+- public Object annotationDefault;
+-
+- /**
+- * The runtime visible parameter annotations of this method. These lists are
+- * lists of {@link AnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.AnnotationNode
+- * @label invisible parameters
+- */
+- public List[] visibleParameterAnnotations;
+-
+- /**
+- * The runtime invisible parameter annotations of this method. These lists
+- * are lists of {@link AnnotationNode} objects. May be null .
+- *
+- * @associates org.mvel2.asm.tree.AnnotationNode
+- * @label visible parameters
+- */
+- public List[] invisibleParameterAnnotations;
+-
+- /**
+- * The instructions of this method. This list is a list of
+- * {@link AbstractInsnNode} objects.
+- *
+- * @associates org.mvel2.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.mvel2.asm.tree.TryCatchBlockNode
+- */
+- public List 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 null
+- *
+- * @associates org.mvel2.asm.tree.LocalVariableNode
+- */
+- public List localVariables;
+-
+- /**
+- * The visible local variable annotations of this method. This list is a
+- * list of {@link LocalVariableAnnotationNode} objects. May be null
+- *
+- * @associates org.mvel2.asm.tree.LocalVariableAnnotationNode
+- */
+- public List visibleLocalVariableAnnotations;
+-
+- /**
+- * The invisible local variable annotations of this method. This list is a
+- * list of {@link LocalVariableAnnotationNode} objects. May be null
+- *
+- * @associates org.mvel2.asm.tree.LocalVariableAnnotationNode
+- */
+- public List invisibleLocalVariableAnnotations;
+-
+- /**
+- * If the accept method has been called on this object.
+- */
+- private boolean visited;
+-
+- /**
+- * Constructs an uninitialized {@link MethodNode}. Subclasses must not
+- * use this constructor . Instead, they must use the
+- * {@link #MethodNode(int)} version.
+- *
+- * @throws IllegalStateException
+- * If a subclass calls this constructor.
+- */
+- public MethodNode() {
+- this(Opcodes.ASM5);
+- 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} or {@link Opcodes#ASM5}.
+- */
+- public MethodNode(final int api) {
+- super(api);
+- this.instructions = new InsnList();
+- }
+-
+- /**
+- * Constructs a new {@link MethodNode}. Subclasses must not use this
+- * constructor . 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 null .
+- * @param exceptions
+- * the internal names of the method's exception classes (see
+- * {@link Type#getInternalName() getInternalName}). May be
+- * null .
+- * @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.ASM5, 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} or {@link Opcodes#ASM5}.
+- * @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 null .
+- * @param exceptions
+- * the internal names of the method's exception classes (see
+- * {@link Type#getInternalName() getInternalName}). May be
+- * null .
+- */
+- 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(exceptions == null ? 0
+- : exceptions.length);
+- boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
+- if (!isAbstract) {
+- this.localVariables = new ArrayList(5);
+- }
+- this.tryCatchBlocks = new ArrayList();
+- 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(5);
+- }
+- parameters.add(new ParameterNode(name, access));
+- }
+-
+- @Override
+- public AnnotationVisitor visitAnnotationDefault() {
+- return new AnnotationNode(new ArrayList(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(1);
+- }
+- visibleAnnotations.add(an);
+- } else {
+- if (invisibleAnnotations == null) {
+- invisibleAnnotations = new ArrayList(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