[mvel] Initial import (#825747).

gil gil at fedoraproject.org
Thu Jun 14 14:58:11 UTC 2012


commit 17dea3a2569038e8fa5ccd6ca5754a8534079eaa
Author: gil <puntogil at libero.it>
Date:   Thu Jun 14 15:00:10 2012 +0200

    Initial import (#825747).

 .gitignore                       |    1 +
 mvel-2.0.19-tests.patch          |   81 +
 mvel-2.0.19-use-system-asm.patch |14947 ++++++++++++++++++++++++++++++++++++++
 mvel-script                      |   30 +
 mvel.spec                        |  100 +
 sources                          |    1 +
 6 files changed, 15160 insertions(+), 0 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index e69de29..a9a71eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/mvel-2.0.19.tar.xz
diff --git a/mvel-2.0.19-tests.patch b/mvel-2.0.19-tests.patch
new file mode 100644
index 0000000..0952b9f
--- /dev/null
+++ b/mvel-2.0.19-tests.patch
@@ -0,0 +1,81 @@
+diff -Nru src/test/java/org/mvel2/tests/core/CoreConfidenceTests.java src/test/java/org/mvel2/tests/core-gil/CoreConfidenceTests.java
+--- src/test/java/org/mvel2/tests/core/CoreConfidenceTests.java	2010-11-19 20:22:46.000000000 +0100
++++ src/test/java/org/mvel2/tests/core-gil/CoreConfidenceTests.java	2012-06-05 11:49:46.115541568 +0200
+@@ -3409,20 +3409,6 @@
+     }
+ 
+     public void testJIRA122() {
+-        Serializable s = compileExpression("System.out.println('>'+java.lang.Character.toLowerCase(name.charAt(0))); java.lang.Character.toLowerCase(name.charAt(0)) == 'a'");
+-
+-        OptimizerFactory.setDefaultOptimizer("ASM");
+-
+-        Map map = new HashMap();
+-        map.put("name",
+-                "Adam");
+-
+-        assertEquals(true,
+-                executeExpression(s,
+-                        map));
+-        assertEquals(true,
+-                executeExpression(s,
+-                        map));
+     }
+ 
+     public void testJIRA122b() {
+@@ -4817,25 +4803,6 @@
+     }
+ 
+     public void testMethodScoring() {
+-        OptimizerFactory.setDefaultOptimizer("ASM");
+-        ParserConfiguration pconf = new ParserConfiguration();
+-        for (Method m : StaticMethods.class.getMethods()) {
+-            if (Modifier.isStatic(m.getModifiers())) {
+-                pconf.addImport(m.getName(), m);
+-
+-            }
+-        }
+-        pconf.addImport("TestCase", TestCase.class);
+-        ParserContext pctx = new ParserContext(pconf);
+-
+-        Map<String, Object> vars = new HashMap<String, Object>();
+-
+-        // this is successful
+-        TestCase.assertTrue(StaticMethods.is(StaticMethods.getList(java.util.Formatter.class)));
+-
+-        // this also should be fine
+-        Serializable expr = MVEL.compileExpression("TestCase.assertTrue( is( getList( java.util.Formatter ) ) )", pctx);
+-        executeExpression(expr, vars);
+     }
+ 
+     public static class StaticMethods {
+diff -Nru src/test/java/org/mvel2/tests/core/FunctionsTest.java src/test/java/org/mvel2/tests/core-gil/FunctionsTest.java
+--- src/test/java/org/mvel2/tests/core/FunctionsTest.java	2010-11-19 20:22:46.000000000 +0100
++++ src/test/java/org/mvel2/tests/core-gil/FunctionsTest.java	2012-06-05 11:48:42.213542391 +0200
+@@ -78,27 +78,6 @@
+     }
+ 
+     public void testJIRA207() {
+-        String ex = "x = 0; y = 0;" +
+-                "def foo() { x = 1; System.out.println('Word up'); }\n" +
+-                "def bar() { y = 1;  System.out.println('Peace out'); }\n" +
+-                "def doMany(fps) {\n" +
+-                "foreach(f : fps) { System.out.println(f); f(); }\n" +
+-                "}\n" +
+-                "doMany([foo,bar]);" +
+-                "x == 1 && y == 1;";
+-
+-        Boolean bool;
+-
+-//        Boolean bool = (Boolean) MVEL.eval(ex, new HashMap());
+-//        assertTrue(bool);
+-
+-        OptimizerFactory.setDefaultOptimizer("ASM");
+-        Serializable s = MVEL.compileExpression(ex);
+-
+-        bool = (Boolean) MVEL.executeExpression(s, new HashMap());
+-        assertTrue(bool);
+-
+-        OptimizerFactory.setDefaultOptimizer("dynamic");
+     }
+ 
+ }
diff --git a/mvel-2.0.19-use-system-asm.patch b/mvel-2.0.19-use-system-asm.patch
new file mode 100644
index 0000000..f1eb868
--- /dev/null
+++ b/mvel-2.0.19-use-system-asm.patch
@@ -0,0 +1,14947 @@
+diff -Nru mvel-2.0.19/META-INF/MANIFEST.MF mvel-2.0.19-gil/META-INF/MANIFEST.MF
+--- mvel-2.0.19/META-INF/MANIFEST.MF	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/META-INF/MANIFEST.MF	2012-05-26 20:03:01.182447003 +0200
+@@ -2,53 +2,52 @@
+ Export-Package: org.mvel2;uses:="org.mvel2.util,org.mvel2.conversion,o
+  rg.mvel2.integration.impl,org.mvel2.optimizers.impl.refl.nodes,org.mv
+  el2.integration,org.mvel2.compiler,org.mvel2.ast,org.mvel2.debug";ver
+- sion="2.0.19",org.mvel2.asm;version="2.0.19",org.mvel2.asm.signature;
+- version="2.0.19",org.mvel2.asm.util;uses:="org.mvel2.asm,org.mvel2.as
+- m.signature";version="2.0.19",org.mvel2.ast;uses:="org.mvel2.integrat
+- ion,org.mvel2.optimizers,org.mvel2,org.mvel2.debug,org.mvel2.compiler
+- ,org.mvel2.util,org.mvel2.math,org.mvel2.integration.impl";version="2
+- .0.19",org.mvel2.compiler;uses:="org.mvel2.integration,org.mvel2,org.
+- mvel2.util,org.mvel2.ast,org.mvel2.optimizers,org.mvel2.integration.i
+- mpl,org.mvel2.optimizers.impl.refl.nodes";version="2.0.19",org.mvel2.
+- conversion;uses:="org.mvel2,org.mvel2.compiler";version="2.0.19",org.
+- mvel2.debug;uses:="org.mvel2.integration,org.mvel2.util,org.mvel2.ast
+- ,org.mvel2.compiler,org.mvel2";version="2.0.19",org.mvel2.integration
+- ;uses:="org.mvel2.ast";version="2.0.19",org.mvel2.integration.impl;us
+- es:="org.mvel2.integration,org.mvel2,org.mvel2.ast,org.mvel2.util";ve
+- rsion="2.0.19",org.mvel2.math;uses:="org.mvel2,org.mvel2.debug,org.mv
+- el2.util";version="2.0.19",org.mvel2.optimizers;uses:="org.mvel2,org.
+- mvel2.util,org.mvel2.compiler,org.mvel2.integration,org.mvel2.optimiz
+- ers.dynamic,org.mvel2.optimizers.impl.asm,org.mvel2.optimizers.impl.r
+- efl";version="2.0.19",org.mvel2.optimizers.dynamic;uses:="org.mvel2.c
+- ompiler,org.mvel2.util,org.mvel2.integration,org.mvel2.optimizers,org
+- .mvel2,org.mvel2.optimizers.impl.asm";version="2.0.19",org.mvel2.opti
+- mizers.impl.asm;uses:="org.mvel2.integration,org.mvel2.optimizers.imp
+- l.refl.nodes,org.mvel2.util,org.mvel2.asm,org.mvel2.optimizers,org.mv
+- el2,org.mvel2.compiler,org.mvel2.ast";version="2.0.19",org.mvel2.opti
+- mizers.impl.refl;uses:="org.mvel2.optimizers.impl.refl.nodes,org.mvel
+- 2.integration,org.mvel2.util,org.mvel2.optimizers.impl.refl.collectio
+- n,org.mvel2.optimizers,org.mvel2,org.mvel2.compiler,org.mvel2.ast";ve
+- rsion="2.0.19",org.mvel2.optimizers.impl.refl.collection;uses:="org.m
+- vel2.integration,org.mvel2.compiler,org.mvel2,org.mvel2.util";version
+- ="2.0.19",org.mvel2.optimizers.impl.refl.nodes;uses:="org.mvel2.integ
+- ration,org.mvel2.compiler,org.mvel2,org.mvel2.util,org.mvel2.ast,org.
+- mvel2.optimizers";version="2.0.19",org.mvel2.sh;uses:="org.mvel2,org.
+- mvel2.templates,org.mvel2.integration.impl,org.mvel2.integration,org.
+- mvel2.util,org.mvel2.sh.command.basic,org.mvel2.sh.command.file";vers
+- ion="2.0.19",org.mvel2.sh.command.basic;uses:="org.mvel2.sh,org.mvel2
+- .sh.text,org.mvel2.util,org.mvel2";version="2.0.19",org.mvel2.sh.comm
+- and.file;uses:="org.mvel2.sh";version="2.0.19",org.mvel2.sh.text;uses
+- :="org.mvel2.util";version="2.0.19",org.mvel2.templates;uses:="org.mv
+- el2.templates.res,org.mvel2.templates.util,org.mvel2,org.mvel2.util,o
+- rg.mvel2.integration.impl,org.mvel2.integration,org.mvel2.templates.u
+- til.io";version="2.0.19",org.mvel2.templates.res;uses:="org.mvel2.tem
+- plates,org.mvel2.integration,org.mvel2.templates.util,org.mvel2,org.m
+- vel2.util,org.mvel2.integration.impl";version="2.0.19",org.mvel2.temp
+- lates.util;uses:="org.mvel2.templates.res,org.mvel2.templates,org.mve
+- l2.util";version="2.0.19",org.mvel2.templates.util.io;uses:="org.mvel
+- 2.templates.util,org.mvel2.util";version="2.0.19",org.mvel2.util;uses
+- :="org.mvel2.ast,org.mvel2.integration,org.mvel2,org.mvel2.compiler,o
+- rg.mvel2.integration.impl,org.mvel2.math,sun.misc";version="2.0.19"
++ sion="2.0.19",org.mvel2.ast;uses:="org.mvel2.integration,org.mvel2.op
++ timizers,org.mvel2,org.mvel2.debug,org.mvel2.compiler,org.mvel2.util,
++ org.mvel2.math,org.mvel2.integration.impl";version="2.0.19",org.mvel2.
++ compiler;uses:="org.mvel2.integration,org.mvel2,org.mvel2.util,org.mve
++ l2.ast,org.mvel2.optimizers,org.mvel2.integration.impl,org.mvel2.optim
++ izers.impl.refl.nodes";version="2.0.19",org.mvel2.conversion;uses:="or
++ g.mvel2,org.mvel2.compiler";version="2.0.19",org.mvel2.debug;uses:="or
++ g.mvel2.integration,org.mvel2.util,org.mvel2.ast,org.mvel2.compiler,or
++ g.mvel2";version="2.0.19",org.mvel2.integration;uses:="org.mvel2.ast";
++ version="2.0.19",org.mvel2.integration.impl;uses:="org.mvel2.integrati
++ on,org.mvel2,org.mvel2.ast,org.mvel2.util";version="2.0.19",org.mvel2.
++ math;uses:="org.mvel2,org.mvel2.debug,org.mvel2.util";version="2.0.19"
++ ,org.mvel2.optimizers;uses:="org.mvel2,org.mvel2.util,org.mvel2.compil
++ er,org.mvel2.integration,org.mvel2.optimizers.dynamic,org.mvel2.optimi
++ zers.impl.asm,org.mvel2.optimizers.impl.refl";version="2.0.19",org.mve
++ l2.optimizers.dynamic;uses:="org.mvel2.compiler,org.mvel2.util,org.mve
++ l2.integration,org.mvel2.optimizers,org.mvel2,org.mvel2.optimizers.imp
++ l.asm";version="2.0.19",org.mvel2.optimizers.impl.asm;uses:="org.mvel2
++ .integration,org.mvel2.optimizers.impl.refl.nodes,org.mvel2.util,org.o
++ bjectweb.asm,org.mvel2.optimizers,org.mvel2,org.mvel2.compiler,org.mvel
++ 2.ast";version="2.0.19",org.mvel2.optimizers.impl.refl;uses:="org.mvel2
++ .optimizers.impl.refl.nodes,org.mvel2.integration,org.mvel2.util,org.mv
++ el2.optimizers.impl.refl.collection,org.mvel2.optimizers,org.mvel2,org.
++ mvel2.compiler,org.mvel2.ast";version="2.0.19",org.mvel2.optimizers.imp
++ l.refl.collection;uses:="org.mvel2.integration,org.mvel2.compiler,org.m
++ vel2,org.mvel2.util";version="2.0.19",org.mvel2.optimizers.impl.refl.no
++ des;uses:="org.mvel2.integration,org.mvel2.compiler,org.mvel2,org.mvel2
++ .util,org.mvel2.ast,org.mvel2.optimizers";version="2.0.19",org.mvel2.sh
++ ;uses:="org.mvel2,org.mvel2.templates,org.mvel2.integration.impl,org.mve
++ l2.integration,org.mvel2.util,org.mvel2.sh.command.basic,org.mvel2.sh.co
++ mmand.file";version="2.0.19",org.mvel2.sh.command.basic;uses:="org.mvel2
++ .sh,org.mvel2.sh.text,org.mvel2.util,org.mvel2";version="2.0.19",org.mve
++ l2.sh.command.file;uses:="org.mvel2.sh";version="2.0.19",org.mvel2.sh.te
++ xt;uses:="org.mvel2.util";version="2.0.19",org.mvel2.templates;uses:="or
++ g.mvel2.templates.res,org.mvel2.templates.util,org.mvel2,org.mvel2.util,o
++ rg.mvel2.integration.impl,org.mvel2.integration,org.mvel2.templates.util.
++ io";version="2.0.19",org.mvel2.templates.res;uses:="org.mvel2.templates,
++ org.mvel2.integration,org.mvel2.templates.util,org.mvel2,org.mvel2.util,
++ org.mvel2.integration.impl";version="2.0.19",org.mvel2.templates.util;use
++ s:="org.mvel2.templates.res,org.mvel2.templates,org.mvel2.util";version="
++ 2.0.19",org.mvel2.templates.util.io;uses:="org.mvel2.templates.util,org.m
++ vel2.util";version="2.0.19",org.mvel2.util;uses:="org.mvel2.ast,org.mvel
++ 2.integration,org.mvel2,org.mvel2.compiler,org.mvel2.integration.impl,or
++ g.mvel2.math,sun.misc";version="2.0.19",org.objectweb.asm;version="3.3.1"
++ ,org.objectweb.asm.signature;version="3.3.1",org.mvel2.asm.util;uses:="o
++ rg.objectweb.asm,org.objectweb.asm.signature";version="3.3.1"
+ Bundle-Version: 2.0.19
+ Tool: Bnd-0.0.357
+ Bundle-Name: mvel2
+@@ -56,19 +55,17 @@
+ Created-By: 1.6.0_21 (Apple Inc.)
+ Bundle-ManifestVersion: 2
+ Bundle-SymbolicName: org.mvel2
+-Import-Package: org.mvel2;version="2.0",org.mvel2.asm;version="2.0",or
+- g.mvel2.asm.signature;version="2.0",org.mvel2.asm.util;version="2.0",
+- org.mvel2.ast;version="2.0",org.mvel2.compiler;version="2.0",org.mvel
+- 2.conversion;version="2.0",org.mvel2.debug;version="2.0",org.mvel2.in
+- tegration;version="2.0",org.mvel2.integration.impl;version="2.0",org.
+- mvel2.math;version="2.0",org.mvel2.optimizers;version="2.0",org.mvel2
+- .optimizers.dynamic;version="2.0",org.mvel2.optimizers.impl.asm;versi
+- on="2.0",org.mvel2.optimizers.impl.refl;version="2.0",org.mvel2.optim
+- izers.impl.refl.collection;version="2.0",org.mvel2.optimizers.impl.re
+- fl.nodes;version="2.0",org.mvel2.sh;version="2.0",org.mvel2.sh.comman
+- d.basic;version="2.0",org.mvel2.sh.command.file;version="2.0",org.mve
+- l2.sh.text;version="2.0",org.mvel2.templates;version="2.0",org.mvel2.
+- templates.res;version="2.0",org.mvel2.templates.util;version="2.0",or
+- g.mvel2.templates.util.io;version="2.0",org.mvel2.util;version="2.0",
+- sun.misc;resolution:=optional
++Import-Package: org.mvel2;version="2.0",org.mvel2.ast;version="2.0",
++ org.mvel2.compiler;version="2.0",org.mvel2.conversion;version="2.0",
++ org.mvel2.debug;version="2.0",org.mvel2.integration;version="2.0",o
++ rg.mvel2.integration.impl;version="2.0",org.mvel2.math;version="2.0",
++ org.mvel2.optimizers;version="2.0",org.mvel2.optimizers.dynamic;versi
++ on="2.0",org.mvel2.optimizers.impl.asm;version="2.0",org.mvel2.optimi
++ zers.impl.refl;version="2.0",org.mvel2.optimizers.impl.refl.collectio
++ n;version="2.0",org.mvel2.optimizers.impl.refl.nodes;version="2.0",or
++ g.mvel2.sh;version="2.0",org.mvel2.sh.command.basic;version="2.0",org
++ .mvel2.sh.command.file;version="2.0",org.mvel2.sh.text;version="2.0",
++ org.mvel2.templates;version="2.0",org.mvel2.templates.res;version="2.0"
++ ,org.mvel2.templates.util;version="2.0",org.mvel2.templates.util.io;ver
++ sion="2.0",org.mvel2.util;version="2.0",sun.misc;resolution:=optional
+ 
+diff -Nru mvel-2.0.19/pom.xml mvel-2.0.19-gil/pom.xml
+--- mvel-2.0.19/pom.xml	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/pom.xml	2012-05-26 19:29:54.883461242 +0200
+@@ -20,13 +20,13 @@
+     </pluginRepositories>
+ 
+     <build>
+-        <extensions>
++        <!--extensions>
+             <extension>
+                 <groupId>org.apache.maven.wagon</groupId>
+                 <artifactId>wagon-webdav</artifactId>
+                 <version>1.0-beta-2</version>
+             </extension>
+-        </extensions>
++        </extensions-->
+ 
+         <plugins>
+             <plugin>
+@@ -156,6 +156,19 @@
+ 
+     <dependencies>
+         <dependency>
++            <groupId>asm</groupId>
++            <artifactId>asm</artifactId>
++            <version>3.3.1</version>
++            <scope>compile</scope>
++        </dependency>
++        <dependency>
++            <groupId>asm</groupId>
++            <artifactId>asm-util</artifactId>
++            <version>3.3.1</version>
++            <scope>compile</scope>
++        </dependency>
++	
++        <dependency>
+             <groupId>junit</groupId>
+             <artifactId>junit</artifactId>
+             <version>3.8.1</version>
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/AnnotationVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/AnnotationVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/AnnotationVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/AnnotationVisitor.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-2005 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 interface must be
+- * called in the following order: (<tt>visit<tt> | <tt>visitEnum<tt> |
+- * <tt>visitAnnotation<tt> | <tt>visitArray<tt>)* <tt>visitEnd<tt>.
+- *
+- * @author Eric Bruneton
+- * @author Eugene Kuleshov
+- */
+-public interface AnnotationVisitor {
+-
+-    /**
+-     * 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}. 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).
+-     */
+-    void visit(String name, Object 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.
+-     */
+-    void visitEnum(String name, String desc, String value);
+-
+-    /**
+-     * Visits a nested annotation value of the annotation.
+-     *
+-     * @param name the value name.
+-     * @param desc the class descriptor of the nested annotation class.
+-     * @return a visitor to visit the actual nested annotation value, or
+-     *         <tt>null</tt> if this visitor is not interested in visiting
+-     *         this nested annotation. <i>The nested annotation value must be
+-     *         fully visited before calling other methods on this annotation
+-     *         visitor</i>.
+-     */
+-    AnnotationVisitor visitAnnotation(String name, String desc);
+-
+-    /**
+-     * Visits an array value of the annotation. Note that arrays of primitive
+-     * types (such as byte, boolean, short, char, int, long, float or double)
+-     * can be passed as value to {@link #visit visit}. This is what
+-     * {@link ClassReader} does.
+-     *
+-     * @param name the value name.
+-     * @return a visitor to visit the actual array value elements, or
+-     *         <tt>null</tt> if this visitor is not interested in visiting
+-     *         these values. The 'name' parameters passed to the methods of this
+-     *         visitor are ignored. <i>All the array values must be visited
+-     *         before calling other methods on this annotation visitor</i>.
+-     */
+-    AnnotationVisitor visitArray(String name);
+-
+-    /**
+-     * Visits the end of the annotation.
+-     */
+-    void visitEnd();
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/AnnotationWriter.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/AnnotationWriter.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/AnnotationWriter.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/AnnotationWriter.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,322 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 implements AnnotationVisitor {
+-
+-    /**
+-     * The class writer to which this annotation must be added.
+-     */
+-    private final ClassWriter cw;
+-
+-    /**
+-     * The number of values in this annotation.
+-     */
+-    private int size;
+-
+-    /**
+-     * <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation
+-     * writers used for annotation default and annotation arrays use unnamed
+-     * values.
+-     */
+-    private final boolean named;
+-
+-    /**
+-     * The annotation values in bytecode form. This byte vector only contains
+-     * the values themselves, i.e. the number of values must be stored as a
+-     * unsigned short just before these bytes.
+-     */
+-    private final ByteVector bv;
+-
+-    /**
+-     * The byte vector to be used to store the number of values of this
+-     * annotation. See {@link #bv}.
+-     */
+-    private final ByteVector parent;
+-
+-    /**
+-     * Where the number of values of this annotation must be stored in
+-     * {@link #parent}.
+-     */
+-    private final int offset;
+-
+-    /**
+-     * Next annotation writer. This field is used to store annotation lists.
+-     */
+-    AnnotationWriter next;
+-
+-    /**
+-     * Previous annotation writer. This field is used to store annotation lists.
+-     */
+-    AnnotationWriter prev;
+-
+-    // ------------------------------------------------------------------------
+-    // Constructor
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Constructs a new {@link AnnotationWriter}.
+-     *
+-     * @param cw     the class writer to which this annotation must be added.
+-     * @param named  <tt>true<tt> if values are named, <tt>false</tt> otherwise.
+-     * @param bv     where the annotation values must be stored.
+-     * @param parent where the number of annotation values must be stored.
+-     * @param offset where in <tt>parent</tt> the number of annotation values must
+-     *               be stored.
+-     */
+-    AnnotationWriter(
+-            final ClassWriter cw,
+-            final boolean named,
+-            final ByteVector bv,
+-            final ByteVector parent,
+-            final int offset) {
+-        this.cw = cw;
+-        this.named = named;
+-        this.bv = bv;
+-        this.parent = parent;
+-        this.offset = offset;
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Implementation of the AnnotationVisitor interface
+-    // ------------------------------------------------------------------------
+-
+-    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);
+-        }
+-    }
+-
+-    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));
+-    }
+-
+-    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);
+-    }
+-
+-    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);
+-    }
+-
+-    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 out   where the annotations must be put.
+-     */
+-    static void put(final AnnotationWriter[] panns, final ByteVector out) {
+-        int size = 1 + 2 * panns.length;
+-        for (int i = 0; i < panns.length; ++i) {
+-            size += panns[i] == null ? 0 : panns[i].getSize();
+-        }
+-        out.putInt(size).putByte(panns.length);
+-        for (int i = 0; i < panns.length; ++i) {
+-            AnnotationWriter aw = panns[i];
+-            AnnotationWriter last = null;
+-            int n = 0;
+-            while (aw != null) {
+-                ++n;
+-                aw.visitEnd(); // in case user forgot to call visitEnd
+-                aw.prev = last;
+-                last = aw;
+-                aw = aw.next;
+-            }
+-            out.putShort(n);
+-            aw = last;
+-            while (aw != null) {
+-                out.putByteArray(aw.bv.data, 0, aw.bv.length);
+-                aw = aw.prev;
+-            }
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/Attribute.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Attribute.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/Attribute.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Attribute.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,250 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 <tt>null</tt>.
+-     */
+-    Attribute next;
+-
+-    /**
+-     * Constructs a new empty attribute.
+-     *
+-     * @param type the type of the attribute.
+-     */
+-    protected Attribute(final String type) {
+-        this.type = type;
+-    }
+-
+-    /**
+-     * Returns <tt>true</tt> if this type of attribute is unknown. The default
+-     * implementation of this method always returns <tt>true</tt>.
+-     *
+-     * @return <tt>true</tt> if this type of attribute is unknown.
+-     */
+-    public boolean isUnknown() {
+-        return true;
+-    }
+-
+-    /**
+-     * Returns <tt>true</tt> if this type of attribute is a code attribute.
+-     *
+-     * @return <tt>true</tt> if this type of attribute is a code attribute.
+-     */
+-    public boolean isCodeAttribute() {
+-        return false;
+-    }
+-
+-    /**
+-     * Returns the labels corresponding to this attribute.
+-     *
+-     * @return the labels corresponding to this attribute, or <tt>null</tt> if
+-     *         this attribute is not a code attribute that contains labels.
+-     */
+-    protected Label[] getLabels() {
+-        return null;
+-    }
+-
+-    /**
+-     * Reads a {@link #type type} attribute. This method must return a <i>new</i>
+-     * {@link Attribute} object, of type {@link #type type}, corresponding to
+-     * the <tt>len</tt> bytes starting at the given offset, in the given class
+-     * reader.
+-     *
+-     * @param cr      the class that contains the attribute to be read.
+-     * @param off     index of the first byte of the attribute's content in {@link
+-     *                ClassReader#b cr.b}. The 6 attribute header bytes, containing the
+-     *                type and the length of the attribute, are not taken into account
+-     *                here.
+-     * @param len     the length of the attribute's content.
+-     * @param buf     buffer to be used to call
+-     *                {@link ClassReader#readUTF8 readUTF8},
+-     *                {@link ClassReader#readClass(int,char[]) readClass} or
+-     *                {@link ClassReader#readConst readConst}.
+-     * @param codeOff index of the first byte of code's attribute content in
+-     *                {@link ClassReader#b cr.b}, or -1 if the attribute to be read is
+-     *                not a code attribute. The 6 attribute header bytes, containing the
+-     *                type and the length of the attribute, are not taken into account
+-     *                here.
+-     * @param labels  the labels of the method's code, or <tt>null</tt> if the
+-     *                attribute to be read is not a code attribute.
+-     * @return a <i>new</i> {@link Attribute} object corresponding to the given
+-     *         bytes.
+-     */
+-    protected Attribute read(
+-            final ClassReader cr,
+-            final int off,
+-            final int len,
+-            final char[] buf,
+-            final int codeOff,
+-            final Label[] labels) {
+-        Attribute attr = new Attribute(type);
+-        attr.value = new byte[len];
+-        System.arraycopy(cr.b, off, attr.value, 0, len);
+-        return attr;
+-    }
+-
+-    /**
+-     * Returns the byte array form of this attribute.
+-     *
+-     * @param cw        the class to which this attribute must be added. This parameter
+-     *                  can be used to add to the constant pool of this class the items
+-     *                  that corresponds to this attribute.
+-     * @param code      the bytecode of the method corresponding to this code
+-     *                  attribute, or <tt>null</tt> if this attribute is not a code
+-     *                  attributes.
+-     * @param len       the length of the bytecode of the method corresponding to this
+-     *                  code attribute, or <tt>null</tt> if this attribute is not a code
+-     *                  attribute.
+-     * @param maxStack  the maximum stack size of the method corresponding to
+-     *                  this code attribute, or -1 if this attribute is not a code
+-     *                  attribute.
+-     * @param maxLocals the maximum number of local variables of the method
+-     *                  corresponding to this code attribute, or -1 if this attribute is
+-     *                  not a code attribute.
+-     * @return the byte array form of this attribute.
+-     */
+-    protected ByteVector write(
+-            final ClassWriter cw,
+-            final byte[] code,
+-            final int len,
+-            final int maxStack,
+-            final int maxLocals) {
+-        ByteVector v = new ByteVector();
+-        v.data = value;
+-        v.length = value.length;
+-        return v;
+-    }
+-
+-    /**
+-     * Returns the length of the attribute list that begins with this attribute.
+-     *
+-     * @return the length of the attribute list that begins with this attribute.
+-     */
+-    final int getCount() {
+-        int count = 0;
+-        Attribute attr = this;
+-        while (attr != null) {
+-            count += 1;
+-            attr = attr.next;
+-        }
+-        return count;
+-    }
+-
+-    /**
+-     * Returns the size of all the attributes in this attribute list.
+-     *
+-     * @param cw        the class writer to be used to convert the attributes into byte
+-     *                  arrays, with the {@link #write write} method.
+-     * @param code      the bytecode of the method corresponding to these code
+-     *                  attributes, or <tt>null</tt> if these attributes are not code
+-     *                  attributes.
+-     * @param len       the length of the bytecode of the method corresponding to
+-     *                  these code attributes, or <tt>null</tt> if these attributes are
+-     *                  not code attributes.
+-     * @param maxStack  the maximum stack size of the method corresponding to
+-     *                  these code attributes, or -1 if these attributes are not code
+-     *                  attributes.
+-     * @param maxLocals the maximum number of local variables of the method
+-     *                  corresponding to these code attributes, or -1 if these attributes
+-     *                  are not code attributes.
+-     * @return the size of all the attributes in this attribute list. This size
+-     *         includes the size of the attribute headers.
+-     */
+-    final int getSize(
+-            final ClassWriter cw,
+-            final byte[] code,
+-            final int len,
+-            final int maxStack,
+-            final int maxLocals) {
+-        Attribute attr = this;
+-        int size = 0;
+-        while (attr != null) {
+-            cw.newUTF8(attr.type);
+-            size += attr.write(cw, code, len, maxStack, maxLocals).length + 6;
+-            attr = attr.next;
+-        }
+-        return size;
+-    }
+-
+-    /**
+-     * Writes all the attributes of this attribute list in the given byte
+-     * vector.
+-     *
+-     * @param cw        the class writer to be used to convert the attributes into byte
+-     *                  arrays, with the {@link #write write} method.
+-     * @param code      the bytecode of the method corresponding to these code
+-     *                  attributes, or <tt>null</tt> if these attributes are not code
+-     *                  attributes.
+-     * @param len       the length of the bytecode of the method corresponding to
+-     *                  these code attributes, or <tt>null</tt> if these attributes are
+-     *                  not code attributes.
+-     * @param maxStack  the maximum stack size of the method corresponding to
+-     *                  these code attributes, or -1 if these attributes are not code
+-     *                  attributes.
+-     * @param maxLocals the maximum number of local variables of the method
+-     *                  corresponding to these code attributes, or -1 if these attributes
+-     *                  are not code attributes.
+-     * @param out       where the attributes must be written.
+-     */
+-    final void put(
+-            final ClassWriter cw,
+-            final byte[] code,
+-            final int len,
+-            final int maxStack,
+-            final int maxLocals,
+-            final ByteVector out) {
+-        Attribute attr = this;
+-        while (attr != null) {
+-            ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);
+-            out.putShort(cw.newUTF8(attr.type)).putInt(b.length);
+-            out.putByteArray(b.data, 0, b.length);
+-            attr = attr.next;
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/ByteVector.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ByteVector.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/ByteVector.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ByteVector.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,297 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.
+-     * @return this byte vector.
+-     */
+-    public ByteVector putUTF8(final String s) {
+-        int charLength = s.length();
+-        if (length + 2 + charLength > data.length) {
+-            enlarge(2 + charLength);
+-        }
+-        int len = length;
+-        byte[] data = this.data;
+-        // optimistic algorithm: instead of computing the byte length and then
+-        // serializing the string (which requires two loops), we assume the byte
+-        // length is equal to char length (which is the most frequent case), and
+-        // we start serializing the string right away. During the serialization,
+-        // if we find that this assumption is wrong, we continue with the
+-        // general method.
+-        data[len++] = (byte) (charLength >>> 8);
+-        data[len++] = (byte) charLength;
+-        for (int i = 0; i < charLength; ++i) {
+-            char c = s.charAt(i);
+-            if (c >= '\001' && c <= '\177') {
+-                data[len++] = (byte) c;
+-            }
+-            else {
+-                int byteLength = i;
+-                for (int j = i; j < charLength; ++j) {
+-                    c = s.charAt(j);
+-                    if (c >= '\001' && c <= '\177') {
+-                        byteLength++;
+-                    }
+-                    else if (c > '\u07FF') {
+-                        byteLength += 3;
+-                    }
+-                    else {
+-                        byteLength += 2;
+-                    }
+-                }
+-                data[length] = (byte) (byteLength >>> 8);
+-                data[length + 1] = (byte) byteLength;
+-                if (length + 2 + byteLength > data.length) {
+-                    length = len;
+-                    enlarge(2 + byteLength);
+-                    data = this.data;
+-                }
+-                for (int j = i; j < charLength; ++j) {
+-                    c = s.charAt(j);
+-                    if (c >= '\001' && c <= '\177') {
+-                        data[len++] = (byte) c;
+-                    }
+-                    else if (c > '\u07FF') {
+-                        data[len++] = (byte) (0xE0 | c >> 12 & 0xF);
+-                        data[len++] = (byte) (0x80 | c >> 6 & 0x3F);
+-                        data[len++] = (byte) (0x80 | c & 0x3F);
+-                    }
+-                    else {
+-                        data[len++] = (byte) (0xC0 | c >> 6 & 0x1F);
+-                        data[len++] = (byte) (0x80 | c & 0x3F);
+-                    }
+-                }
+-                break;
+-            }
+-        }
+-        length = len;
+-        return this;
+-    }
+-
+-    /**
+-     * Puts an array of bytes into this byte vector. The byte vector is
+-     * automatically enlarged if necessary.
+-     *
+-     * @param b   an array of bytes. May be <tt>null</tt> to put <tt>len</tt>
+-     *            null bytes into this byte vector.
+-     * @param off index of the fist byte of b that must be copied.
+-     * @param len number of bytes of b that must be copied.
+-     * @return this byte vector.
+-     */
+-    public ByteVector putByteArray(final byte[] b, final int off, final int len) {
+-        if (length + len > data.length) {
+-            enlarge(len);
+-        }
+-        if (b != null) {
+-            System.arraycopy(b, off, data, length, len);
+-        }
+-        length += len;
+-        return this;
+-    }
+-
+-    /**
+-     * Enlarge this byte vector so that it can receive n more bytes.
+-     *
+-     * @param size number of additional bytes that this byte vector should be
+-     *             able to receive.
+-     */
+-    private void enlarge(final int size) {
+-        int length1 = 2 * data.length;
+-        int length2 = length + size;
+-        byte[] newData = new byte[length1 > length2 ? length1 : length2];
+-        System.arraycopy(data, 0, newData, 0, length);
+-        data = newData;
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/ClassAdapter.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ClassAdapter.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/ClassAdapter.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ClassAdapter.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,115 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 empty {@link ClassVisitor} that delegates to another {@link ClassVisitor}.
+- * This class can be used as a super class to quickly implement usefull class
+- * adapter classes, just by overriding the necessary methods.
+- *
+- * @author Eric Bruneton
+- */
+-public class ClassAdapter implements ClassVisitor {
+-
+-    /**
+-     * The {@link ClassVisitor} to which this adapter delegates calls.
+-     */
+-    protected ClassVisitor cv;
+-
+-    /**
+-     * Constructs a new {@link ClassAdapter} object.
+-     *
+-     * @param cv the class visitor to which this adapter must delegate calls.
+-     */
+-    public ClassAdapter(final ClassVisitor cv) {
+-        this.cv = cv;
+-    }
+-
+-    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);
+-    }
+-
+-    public void visitSource(final String source, final String debug) {
+-        cv.visitSource(source, debug);
+-    }
+-
+-    public void visitOuterClass(
+-            final String owner,
+-            final String name,
+-            final String desc) {
+-        cv.visitOuterClass(owner, name, desc);
+-    }
+-
+-    public AnnotationVisitor visitAnnotation(
+-            final String desc,
+-            final boolean visible) {
+-        return cv.visitAnnotation(desc, visible);
+-    }
+-
+-    public void visitAttribute(final Attribute attr) {
+-        cv.visitAttribute(attr);
+-    }
+-
+-    public void visitInnerClass(
+-            final String name,
+-            final String outerName,
+-            final String innerName,
+-            final int access) {
+-        cv.visitInnerClass(name, outerName, innerName, access);
+-    }
+-
+-    public FieldVisitor visitField(
+-            final int access,
+-            final String name,
+-            final String desc,
+-            final String signature,
+-            final Object value) {
+-        return cv.visitField(access, name, desc, signature, value);
+-    }
+-
+-    public MethodVisitor visitMethod(
+-            final int access,
+-            final String name,
+-            final String desc,
+-            final String signature,
+-            final String[] exceptions) {
+-        return cv.visitMethod(access, name, desc, signature, exceptions);
+-    }
+-
+-    public void visitEnd() {
+-        cv.visitEnd();
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/ClassReader.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ClassReader.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/ClassReader.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ClassReader.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,2012 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 {
+-
+-    /**
+-     * Flag to skip method code. If this class is set <code>CODE</code>
+-     * attribute won't be visited. This can be used, for example, to retrieve
+-     * annotations for methods and method parameters.
+-     */
+-    public final static 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 final static 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 final static 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 final static int EXPAND_FRAMES = 8;
+-
+-    /**
+-     * The class to be parsed. <i>The content of this array must not be
+-     * modified. This field is intended for {@link Attribute} sub classes, and
+-     * is normally not needed by class generators or adapters.</i>
+-     */
+-    public final byte[] b;
+-
+-    /**
+-     * The start index of each constant pool item in {@link #b b}, plus one.
+-     * The one byte offset skips the constant pool item tag that indicates its
+-     * type.
+-     */
+-    private final int[] items;
+-
+-    /**
+-     * The String objects corresponding to the CONSTANT_Utf8 items. This cache
+-     * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item,
+-     * which GREATLY improves performances (by a factor 2 to 3). This caching
+-     * strategy could be extended to all constant pool items, but its benefit
+-     * would not be so great for these items (because they are much less
+-     * expensive to parse than CONSTANT_Utf8 items).
+-     */
+-    private final String[] strings;
+-
+-    /**
+-     * Maximum length of the strings contained in the constant pool of the
+-     * class.
+-     */
+-    private final int maxStringLength;
+-
+-    /**
+-     * Start index of the class header information (access, name...) in
+-     * {@link #b b}.
+-     */
+-    public final int header;
+-
+-    // ------------------------------------------------------------------------
+-    // Constructors
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Constructs a new {@link ClassReader} object.
+-     *
+-     * @param b the bytecode of the class to be read.
+-     */
+-    public ClassReader(final byte[] b) {
+-        this(b, 0, b.length);
+-    }
+-
+-    /**
+-     * Constructs a new {@link ClassReader} object.
+-     *
+-     * @param b   the bytecode of the class to be read.
+-     * @param off the start offset of the class data.
+-     * @param len the length of the class data.
+-     */
+-    public ClassReader(final byte[] b, final int off, final int len) {
+-        this.b = b;
+-        // 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:
+-                    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.CLASS:
+-                    // case ClassWriter.STR:
+-                default:
+-                    size = 3;
+-                    break;
+-            }
+-            index += size;
+-        }
+-        maxStringLength = max;
+-        // the class header information starts just after the constant pool
+-        header = index;
+-    }
+-
+-    /**
+-     * Returns the class's access flags (see {@link Opcodes}). This value may
+-     * not reflect Deprecated and Synthetic flags when bytecode is before 1.5
+-     * and those flags are represented by attributes.
+-     *
+-     * @return the class access flags
+-     * @see ClassVisitor#visit(int,int,String,String,String,String[])
+-     */
+-    public int getAccess() {
+-        return readUnsignedShort(header);
+-    }
+-
+-    /**
+-     * Returns the internal name of the class (see
+-     * {@link Type#getInternalName() getInternalName}).
+-     *
+-     * @return the internal class name
+-     * @see ClassVisitor#visit(int,int,String,String,String,String[])
+-     */
+-    public String getClassName() {
+-        return readClass(header + 2, new char[maxStringLength]);
+-    }
+-
+-    /**
+-     * Returns the internal of name of the super class (see
+-     * {@link Type#getInternalName() getInternalName}). For interfaces, the
+-     * super class is {@link Object}.
+-     *
+-     * @return the internal name of super class, or <tt>null</tt> for
+-     *         {@link Object} class.
+-     * @see ClassVisitor#visit(int,int,String,String,String,String[])
+-     */
+-    public String getSuperName() {
+-        int n = items[readUnsignedShort(header + 4)];
+-        return n == 0 ? null : readUTF8(n, new char[maxStringLength]);
+-    }
+-
+-    /**
+-     * Returns the internal names of the class's interfaces (see
+-     * {@link Type#getInternalName() getInternalName}).
+-     *
+-     * @return the array of internal names for all implemented interfaces or
+-     *         <tt>null</tt>.
+-     * @see ClassVisitor#visit(int,int,String,String,String,String[])
+-     */
+-    public String[] getInterfaces() {
+-        int index = header + 6;
+-        int n = readUnsignedShort(index);
+-        String[] interfaces = new String[n];
+-        if (n > 0) {
+-            char[] buf = new char[maxStringLength];
+-            for (int i = 0; i < n; ++i) {
+-                index += 2;
+-                interfaces[i] = readClass(index, buf);
+-            }
+-        }
+-        return interfaces;
+-    }
+-
+-    /**
+-     * Copies the constant pool data into the given {@link ClassWriter}. Should
+-     * be called before the {@link #accept(ClassVisitor,int)} method.
+-     *
+-     * @param classWriter the {@link ClassWriter} to copy constant pool into.
+-     */
+-    void copyPool(final ClassWriter classWriter) {
+-        char[] buf = new char[maxStringLength];
+-        int ll = items.length;
+-        Item[] items2 = new Item[ll];
+-        for (int i = 1; i < ll; i++) {
+-            int index = items[i];
+-            int tag = b[index - 1];
+-            Item item = new Item(i);
+-            int nameType;
+-            switch (tag) {
+-                case ClassWriter.FIELD:
+-                case ClassWriter.METH:
+-                case ClassWriter.IMETH:
+-                    nameType = items[readUnsignedShort(index + 2)];
+-                    item.set(tag,
+-                            readClass(index, buf),
+-                            readUTF8(nameType, buf),
+-                            readUTF8(nameType + 2, buf));
+-                    break;
+-
+-                case ClassWriter.INT:
+-                    item.set(readInt(index));
+-                    break;
+-
+-                case ClassWriter.FLOAT:
+-                    item.set(Float.intBitsToFloat(readInt(index)));
+-                    break;
+-
+-                case ClassWriter.NAME_TYPE:
+-                    item.set(tag,
+-                            readUTF8(index, buf),
+-                            readUTF8(index + 2, buf),
+-                            null);
+-                    break;
+-
+-                case ClassWriter.LONG:
+-                    item.set(readLong(index));
+-                    ++i;
+-                    break;
+-
+-                case ClassWriter.DOUBLE:
+-                    item.set(Double.longBitsToDouble(readLong(index)));
+-                    ++i;
+-                    break;
+-
+-                case ClassWriter.UTF8: {
+-                    String s = strings[i];
+-                    if (s == null) {
+-                        index = items[i];
+-                        s = strings[i] = readUTF(index + 2,
+-                                readUnsignedShort(index),
+-                                buf);
+-                    }
+-                    item.set(tag, s, null, null);
+-                }
+-                break;
+-
+-                // case ClassWriter.STR:
+-                // case ClassWriter.CLASS:
+-                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;
+-    }
+-
+-    /**
+-     * 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));
+-    }
+-
+-    /**
+-     * Constructs a new {@link ClassReader} object.
+-     *
+-     * @param name the fully qualified name of the class to be read.
+-     * @throws IOException if an exception occurs during reading.
+-     */
+-    public ClassReader(final String name) throws IOException {
+-        this(ClassLoader.getSystemResourceAsStream(name.replace('.', '/')
+-                + ".class"));
+-    }
+-
+-    /**
+-     * Reads the bytecode of a class.
+-     *
+-     * @param is an input stream from which to read the class.
+-     * @return the bytecode read from the given input stream.
+-     * @throws IOException if a problem occurs during reading.
+-     */
+-    private static byte[] readClass(final InputStream is) throws IOException {
+-        if (is == null) {
+-            throw new IOException("Class not found");
+-        }
+-        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) {
+-                byte[] c = new byte[b.length + 1000];
+-                System.arraycopy(b, 0, c, 0, len);
+-                b = c;
+-            }
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // 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}.
+-     */
+-    public void accept(final ClassVisitor classVisitor, final int flags) {
+-        accept(classVisitor, new Attribute[0], flags);
+-    }
+-
+-    /**
+-     * Makes the given visitor visit the Java class of this {@link ClassReader}.
+-     * This class is the one specified in the constructor (see
+-     * {@link #ClassReader(byte[]) ClassReader}).
+-     *
+-     * @param classVisitor the visitor that must visit this class.
+-     * @param attrs        prototypes of the attributes that must be parsed during the
+-     *                     visit of the class. Any attribute whose type is not equal to the
+-     *                     type of one the prototypes will not be parsed: its byte array
+-     *                     value will be passed unchanged to the ClassWriter. <i>This may
+-     *                     corrupt it if this value contains references to the constant pool,
+-     *                     or has syntactic or semantic links with a class element that has
+-     *                     been transformed by a class adapter between the reader and the
+-     *                     writer</i>.
+-     * @param flags        option flags that can be used to modify the default behavior
+-     *                     of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES}.
+-     */
+-    public void accept(
+-            final ClassVisitor classVisitor,
+-            final Attribute[] attrs,
+-            final int flags) {
+-        byte[] b = this.b; // the bytecode array
+-        char[] c = new char[maxStringLength]; // buffer used to read strings
+-        int i, j, k; // loop variables
+-        int u, v, w; // indexes in b
+-        Attribute attr;
+-
+-        int access;
+-        String name;
+-        String desc;
+-        String attrName;
+-        String signature;
+-        int anns = 0;
+-        int ianns = 0;
+-        Attribute cattrs = null;
+-
+-        // visits the header
+-        u = header;
+-        access = readUnsignedShort(u);
+-        name = readClass(u + 2, c);
+-        v = items[readUnsignedShort(u + 4)];
+-        String superClassName = v == 0 ? null : readUTF8(v, c);
+-        String[] implementedItfs = new String[readUnsignedShort(u + 6)];
+-        w = 0;
+-        u += 8;
+-        for (i = 0; i < implementedItfs.length; ++i) {
+-            implementedItfs[i] = readClass(u, c);
+-            u += 2;
+-        }
+-
+-        boolean skipCode = (flags & SKIP_CODE) != 0;
+-        boolean skipDebug = (flags & SKIP_DEBUG) != 0;
+-        boolean unzip = (flags & EXPAND_FRAMES) != 0;
+-
+-        // skips fields and methods
+-        v = u;
+-        i = readUnsignedShort(v);
+-        v += 2;
+-        for (; i > 0; --i) {
+-            j = readUnsignedShort(v + 6);
+-            v += 8;
+-            for (; j > 0; --j) {
+-                v += 6 + readInt(v + 2);
+-            }
+-        }
+-        i = readUnsignedShort(v);
+-        v += 2;
+-        for (; i > 0; --i) {
+-            j = readUnsignedShort(v + 6);
+-            v += 8;
+-            for (; j > 0; --j) {
+-                v += 6 + readInt(v + 2);
+-            }
+-        }
+-        // reads the class's attributes
+-        signature = null;
+-        String sourceFile = null;
+-        String sourceDebug = null;
+-        String enclosingOwner = null;
+-        String enclosingName = null;
+-        String enclosingDesc = null;
+-
+-        i = readUnsignedShort(v);
+-        v += 2;
+-        for (; i > 0; --i) {
+-            attrName = readUTF8(v, c);
+-            // tests are sorted in decreasing frequency order
+-            // (based on frequencies observed on typical classes)
+-            if (attrName.equals("SourceFile")) {
+-                sourceFile = readUTF8(v + 6, c);
+-            }
+-            else if (attrName.equals("InnerClasses")) {
+-                w = v + 6;
+-            }
+-            else if (attrName.equals("EnclosingMethod")) {
+-                enclosingOwner = readClass(v + 6, c);
+-                int item = readUnsignedShort(v + 8);
+-                if (item != 0) {
+-                    enclosingName = readUTF8(items[item], c);
+-                    enclosingDesc = readUTF8(items[item] + 2, c);
+-                }
+-            }
+-            else if (attrName.equals("Signature")) {
+-                signature = readUTF8(v + 6, c);
+-            }
+-            else if (attrName.equals("RuntimeVisibleAnnotations")) {
+-                anns = v + 6;
+-            }
+-            else if (attrName.equals("Deprecated")) {
+-                access |= Opcodes.ACC_DEPRECATED;
+-            }
+-            else if (attrName.equals("Synthetic")) {
+-                access |= Opcodes.ACC_SYNTHETIC;
+-            }
+-            else if (attrName.equals("SourceDebugExtension")) {
+-                int len = readInt(v + 2);
+-                sourceDebug = readUTF(v + 6, len, new char[len]);
+-            }
+-            else if (attrName.equals("RuntimeInvisibleAnnotations")) {
+-                ianns = v + 6;
+-            }
+-            else {
+-                attr = readAttribute(attrs,
+-                        attrName,
+-                        v + 6,
+-                        readInt(v + 2),
+-                        c,
+-                        -1,
+-                        null);
+-                if (attr != null) {
+-                    attr.next = cattrs;
+-                    cattrs = attr;
+-                }
+-            }
+-            v += 6 + readInt(v + 2);
+-        }
+-        // calls the visit method
+-        classVisitor.visit(readInt(4),
+-                access,
+-                name,
+-                signature,
+-                superClassName,
+-                implementedItfs);
+-
+-        // calls the visitSource method
+-        if (!skipDebug && (sourceFile != null || sourceDebug != null)) {
+-            classVisitor.visitSource(sourceFile, sourceDebug);
+-        }
+-
+-        // calls the visitOuterClass method
+-        if (enclosingOwner != null) {
+-            classVisitor.visitOuterClass(enclosingOwner,
+-                    enclosingName,
+-                    enclosingDesc);
+-        }
+-
+-        // visits the class annotations
+-        for (i = 1; i >= 0; --i) {
+-            v = i == 0 ? ianns : anns;
+-            if (v != 0) {
+-                j = readUnsignedShort(v);
+-                v += 2;
+-                for (; j > 0; --j) {
+-                    v = readAnnotationValues(v + 2,
+-                            c,
+-                            true,
+-                            classVisitor.visitAnnotation(readUTF8(v, c), i != 0));
+-                }
+-            }
+-        }
+-
+-        // visits the class attributes
+-        while (cattrs != null) {
+-            attr = cattrs.next;
+-            cattrs.next = null;
+-            classVisitor.visitAttribute(cattrs);
+-            cattrs = attr;
+-        }
+-
+-        // calls the visitInnerClass method
+-        if (w != 0) {
+-            i = readUnsignedShort(w);
+-            w += 2;
+-            for (; i > 0; --i) {
+-                classVisitor.visitInnerClass(readUnsignedShort(w) == 0
+-                        ? null
+-                        : readClass(w, c), readUnsignedShort(w + 2) == 0
+-                        ? null
+-                        : readClass(w + 2, c), readUnsignedShort(w + 4) == 0
+-                        ? null
+-                        : readUTF8(w + 4, c), readUnsignedShort(w + 6));
+-                w += 8;
+-            }
+-        }
+-
+-        // visits the fields
+-        i = readUnsignedShort(u);
+-        u += 2;
+-        for (; i > 0; --i) {
+-            access = readUnsignedShort(u);
+-            name = readUTF8(u + 2, c);
+-            desc = readUTF8(u + 4, c);
+-            // visits the field's attributes and looks for a ConstantValue
+-            // attribute
+-            int fieldValueItem = 0;
+-            signature = null;
+-            anns = 0;
+-            ianns = 0;
+-            cattrs = null;
+-
+-            j = readUnsignedShort(u + 6);
+-            u += 8;
+-            for (; j > 0; --j) {
+-                attrName = readUTF8(u, c);
+-                // tests are sorted in decreasing frequency order
+-                // (based on frequencies observed on typical classes)
+-                if (attrName.equals("ConstantValue")) {
+-                    fieldValueItem = readUnsignedShort(u + 6);
+-                }
+-                else if (attrName.equals("Signature")) {
+-                    signature = readUTF8(u + 6, c);
+-                }
+-                else if (attrName.equals("Deprecated")) {
+-                    access |= Opcodes.ACC_DEPRECATED;
+-                }
+-                else if (attrName.equals("Synthetic")) {
+-                    access |= Opcodes.ACC_SYNTHETIC;
+-                }
+-                else if (attrName.equals("RuntimeVisibleAnnotations")) {
+-                    anns = u + 6;
+-                }
+-                else if (attrName.equals("RuntimeInvisibleAnnotations")) {
+-                    ianns = u + 6;
+-                }
+-                else {
+-                    attr = readAttribute(attrs,
+-                            attrName,
+-                            u + 6,
+-                            readInt(u + 2),
+-                            c,
+-                            -1,
+-                            null);
+-                    if (attr != null) {
+-                        attr.next = cattrs;
+-                        cattrs = attr;
+-                    }
+-                }
+-                u += 6 + readInt(u + 2);
+-            }
+-            // visits the field
+-            FieldVisitor fv = classVisitor.visitField(access,
+-                    name,
+-                    desc,
+-                    signature,
+-                    fieldValueItem == 0 ? null : readConst(fieldValueItem, c));
+-            // visits the field annotations and attributes
+-            if (fv != null) {
+-                for (j = 1; j >= 0; --j) {
+-                    v = j == 0 ? ianns : anns;
+-                    if (v != 0) {
+-                        k = readUnsignedShort(v);
+-                        v += 2;
+-                        for (; k > 0; --k) {
+-                            v = readAnnotationValues(v + 2,
+-                                    c,
+-                                    true,
+-                                    fv.visitAnnotation(readUTF8(v, c), j != 0));
+-                        }
+-                    }
+-                }
+-                while (cattrs != null) {
+-                    attr = cattrs.next;
+-                    cattrs.next = null;
+-                    fv.visitAttribute(cattrs);
+-                    cattrs = attr;
+-                }
+-                fv.visitEnd();
+-            }
+-        }
+-
+-        // visits the methods
+-        i = readUnsignedShort(u);
+-        u += 2;
+-        for (; i > 0; --i) {
+-            int u0 = u + 6;
+-            access = readUnsignedShort(u);
+-            name = readUTF8(u + 2, c);
+-            desc = readUTF8(u + 4, c);
+-            signature = null;
+-            anns = 0;
+-            ianns = 0;
+-            int dann = 0;
+-            int mpanns = 0;
+-            int impanns = 0;
+-            cattrs = null;
+-            v = 0;
+-            w = 0;
+-
+-            // looks for Code and Exceptions attributes
+-            j = readUnsignedShort(u + 6);
+-            u += 8;
+-            for (; j > 0; --j) {
+-                attrName = readUTF8(u, c);
+-                int attrSize = readInt(u + 2);
+-                u += 6;
+-                // tests are sorted in decreasing frequency order
+-                // (based on frequencies observed on typical classes)
+-                if (attrName.equals("Code")) {
+-                    if (!skipCode) {
+-                        v = u;
+-                    }
+-                }
+-                else if (attrName.equals("Exceptions")) {
+-                    w = u;
+-                }
+-                else if (attrName.equals("Signature")) {
+-                    signature = readUTF8(u, c);
+-                }
+-                else if (attrName.equals("Deprecated")) {
+-                    access |= Opcodes.ACC_DEPRECATED;
+-                }
+-                else if (attrName.equals("RuntimeVisibleAnnotations")) {
+-                    anns = u;
+-                }
+-                else if (attrName.equals("AnnotationDefault")) {
+-                    dann = u;
+-                }
+-                else if (attrName.equals("Synthetic")) {
+-                    access |= Opcodes.ACC_SYNTHETIC;
+-                }
+-                else if (attrName.equals("RuntimeInvisibleAnnotations")) {
+-                    ianns = u;
+-                }
+-                else if (attrName.equals("RuntimeVisibleParameterAnnotations")) {
+-                    mpanns = u;
+-                }
+-                else if (attrName.equals("RuntimeInvisibleParameterAnnotations")) {
+-                    impanns = u;
+-                }
+-                else {
+-                    attr = readAttribute(attrs,
+-                            attrName,
+-                            u,
+-                            attrSize,
+-                            c,
+-                            -1,
+-                            null);
+-                    if (attr != null) {
+-                        attr.next = cattrs;
+-                        cattrs = attr;
+-                    }
+-                }
+-                u += attrSize;
+-            }
+-            // reads declared exceptions
+-            String[] exceptions;
+-            if (w == 0) {
+-                exceptions = null;
+-            }
+-            else {
+-                exceptions = new String[readUnsignedShort(w)];
+-                w += 2;
+-                for (j = 0; j < exceptions.length; ++j) {
+-                    exceptions[j] = readClass(w, c);
+-                    w += 2;
+-                }
+-            }
+-
+-            // visits the method's code, if any
+-            MethodVisitor mv = classVisitor.visitMethod(access,
+-                    name,
+-                    desc,
+-                    signature,
+-                    exceptions);
+-
+-            if (mv != null) {
+-                /*
+-                 * 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 (mv instanceof MethodWriter) {
+-                    MethodWriter mw = (MethodWriter) mv;
+-                    if (mw.cw.cr == this) {
+-                        if (signature == mw.signature) {
+-                            boolean sameExceptions = false;
+-                            if (exceptions == null) {
+-                                sameExceptions = mw.exceptionCount == 0;
+-                            }
+-                            else {
+-                                if (exceptions.length == mw.exceptionCount) {
+-                                    sameExceptions = true;
+-                                    for (j = exceptions.length - 1; j >= 0; --j) {
+-                                        w -= 2;
+-                                        if (mw.exceptions[j] != readUnsignedShort(w)) {
+-                                            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 = u0;
+-                                mw.classReaderLength = u - u0;
+-                                continue;
+-                            }
+-                        }
+-                    }
+-                }
+-
+-                if (dann != 0) {
+-                    AnnotationVisitor dv = mv.visitAnnotationDefault();
+-                    readAnnotationValue(dann, c, null, dv);
+-                    if (dv != null) {
+-                        dv.visitEnd();
+-                    }
+-                }
+-                for (j = 1; j >= 0; --j) {
+-                    w = j == 0 ? ianns : anns;
+-                    if (w != 0) {
+-                        k = readUnsignedShort(w);
+-                        w += 2;
+-                        for (; k > 0; --k) {
+-                            w = readAnnotationValues(w + 2,
+-                                    c,
+-                                    true,
+-                                    mv.visitAnnotation(readUTF8(w, c), j != 0));
+-                        }
+-                    }
+-                }
+-                if (mpanns != 0) {
+-                    readParameterAnnotations(mpanns, c, true, mv);
+-                }
+-                if (impanns != 0) {
+-                    readParameterAnnotations(impanns, c, false, mv);
+-                }
+-                while (cattrs != null) {
+-                    attr = cattrs.next;
+-                    cattrs.next = null;
+-                    mv.visitAttribute(cattrs);
+-                    cattrs = attr;
+-                }
+-            }
+-
+-            if (mv != null && v != 0) {
+-                int maxStack = readUnsignedShort(v);
+-                int maxLocals = readUnsignedShort(v + 2);
+-                int codeLength = readInt(v + 4);
+-                v += 8;
+-
+-                int codeStart = v;
+-                int codeEnd = v + codeLength;
+-
+-                mv.visitCode();
+-
+-                // 1st phase: finds the labels
+-                int label;
+-                Label[] labels = new Label[codeLength + 1];
+-                while (v < codeEnd) {
+-                    int opcode = b[v] & 0xFF;
+-                    switch (ClassWriter.TYPE[opcode]) {
+-                        case ClassWriter.NOARG_INSN:
+-                        case ClassWriter.IMPLVAR_INSN:
+-                            v += 1;
+-                            break;
+-                        case ClassWriter.LABEL_INSN:
+-                            label = v - codeStart + readShort(v + 1);
+-                            if (labels[label] == null) {
+-                                labels[label] = new Label();
+-                            }
+-                            v += 3;
+-                            break;
+-                        case ClassWriter.LABELW_INSN:
+-                            label = v - codeStart + readInt(v + 1);
+-                            if (labels[label] == null) {
+-                                labels[label] = new Label();
+-                            }
+-                            v += 5;
+-                            break;
+-                        case ClassWriter.WIDE_INSN:
+-                            opcode = b[v + 1] & 0xFF;
+-                            if (opcode == Opcodes.IINC) {
+-                                v += 6;
+-                            }
+-                            else {
+-                                v += 4;
+-                            }
+-                            break;
+-                        case ClassWriter.TABL_INSN:
+-                            // skips 0 to 3 padding bytes
+-                            w = v - codeStart;
+-                            v = v + 4 - (w & 3);
+-                            // reads instruction
+-                            label = w + readInt(v);
+-                            if (labels[label] == null) {
+-                                labels[label] = new Label();
+-                            }
+-                            j = readInt(v + 8) - readInt(v + 4) + 1;
+-                            v += 12;
+-                            for (; j > 0; --j) {
+-                                label = w + readInt(v);
+-                                v += 4;
+-                                if (labels[label] == null) {
+-                                    labels[label] = new Label();
+-                                }
+-                            }
+-                            break;
+-                        case ClassWriter.LOOK_INSN:
+-                            // skips 0 to 3 padding bytes
+-                            w = v - codeStart;
+-                            v = v + 4 - (w & 3);
+-                            // reads instruction
+-                            label = w + readInt(v);
+-                            if (labels[label] == null) {
+-                                labels[label] = new Label();
+-                            }
+-                            j = readInt(v + 4);
+-                            v += 8;
+-                            for (; j > 0; --j) {
+-                                label = w + readInt(v + 4);
+-                                v += 8;
+-                                if (labels[label] == null) {
+-                                    labels[label] = new Label();
+-                                }
+-                            }
+-                            break;
+-                        case ClassWriter.VAR_INSN:
+-                        case ClassWriter.SBYTE_INSN:
+-                        case ClassWriter.LDC_INSN:
+-                            v += 2;
+-                            break;
+-                        case ClassWriter.SHORT_INSN:
+-                        case ClassWriter.LDCW_INSN:
+-                        case ClassWriter.FIELDORMETH_INSN:
+-                        case ClassWriter.TYPE_INSN:
+-                        case ClassWriter.IINC_INSN:
+-                            v += 3;
+-                            break;
+-                        case ClassWriter.ITFMETH_INSN:
+-                            v += 5;
+-                            break;
+-                            // case MANA_INSN:
+-                        default:
+-                            v += 4;
+-                            break;
+-                    }
+-                }
+-                // parses the try catch entries
+-                j = readUnsignedShort(v);
+-                v += 2;
+-                for (; j > 0; --j) {
+-                    label = readUnsignedShort(v);
+-                    Label start = labels[label];
+-                    if (start == null) {
+-                        labels[label] = start = new Label();
+-                    }
+-                    label = readUnsignedShort(v + 2);
+-                    Label end = labels[label];
+-                    if (end == null) {
+-                        labels[label] = end = new Label();
+-                    }
+-                    label = readUnsignedShort(v + 4);
+-                    Label handler = labels[label];
+-                    if (handler == null) {
+-                        labels[label] = handler = new Label();
+-                    }
+-                    int type = readUnsignedShort(v + 6);
+-                    if (type == 0) {
+-                        mv.visitTryCatchBlock(start, end, handler, null);
+-                    }
+-                    else {
+-                        mv.visitTryCatchBlock(start,
+-                                end,
+-                                handler,
+-                                readUTF8(items[type], c));
+-                    }
+-                    v += 8;
+-                }
+-                // parses the local variable, line number tables, and code
+-                // attributes
+-                int varTable = 0;
+-                int varTypeTable = 0;
+-                int stackMap = 0;
+-                int frameCount = 0;
+-                int frameMode = 0;
+-                int frameOffset = 0;
+-                int frameLocalCount = 0;
+-                int frameLocalDiff = 0;
+-                int frameStackCount = 0;
+-                Object[] frameLocal = null;
+-                Object[] frameStack = null;
+-                boolean zip = true;
+-                cattrs = null;
+-                j = readUnsignedShort(v);
+-                v += 2;
+-                for (; j > 0; --j) {
+-                    attrName = readUTF8(v, c);
+-                    if (attrName.equals("LocalVariableTable")) {
+-                        if (!skipDebug) {
+-                            varTable = v + 6;
+-                            k = readUnsignedShort(v + 6);
+-                            w = v + 8;
+-                            for (; k > 0; --k) {
+-                                label = readUnsignedShort(w);
+-                                if (labels[label] == null) {
+-                                    labels[label] = new Label(true);
+-                                }
+-                                label += readUnsignedShort(w + 2);
+-                                if (labels[label] == null) {
+-                                    labels[label] = new Label(true);
+-                                }
+-                                w += 10;
+-                            }
+-                        }
+-                    }
+-                    else if (attrName.equals("LocalVariableTypeTable")) {
+-                        varTypeTable = v + 6;
+-                    }
+-                    else if (attrName.equals("LineNumberTable")) {
+-                        if (!skipDebug) {
+-                            k = readUnsignedShort(v + 6);
+-                            w = v + 8;
+-                            for (; k > 0; --k) {
+-                                label = readUnsignedShort(w);
+-                                if (labels[label] == null) {
+-                                    labels[label] = new Label(true);
+-                                }
+-                                labels[label].line = readUnsignedShort(w + 2);
+-                                w += 4;
+-                            }
+-                        }
+-                    }
+-                    else if (attrName.equals("StackMapTable")) {
+-                        if ((flags & SKIP_FRAMES) == 0) {
+-                            stackMap = v + 8;
+-                            frameCount = readUnsignedShort(v + 6);
+-                        }
+-                        /*
+-                         * 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.
+-                         */
+-                        //
+-                        // but for UNINITIALIZED type offsets?
+-                    }
+-                    else if (attrName.equals("StackMap")) {
+-                        if ((flags & SKIP_FRAMES) == 0) {
+-                            stackMap = v + 8;
+-                            frameCount = readUnsignedShort(v + 6);
+-                            zip = false;
+-                        }
+-                        /*
+-                         * 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 (k = 0; k < attrs.length; ++k) {
+-                            if (attrs[k].type.equals(attrName)) {
+-                                attr = attrs[k].read(this,
+-                                        v + 6,
+-                                        readInt(v + 2),
+-                                        c,
+-                                        codeStart - 8,
+-                                        labels);
+-                                if (attr != null) {
+-                                    attr.next = cattrs;
+-                                    cattrs = attr;
+-                                }
+-                            }
+-                        }
+-                    }
+-                    v += 6 + readInt(v + 2);
+-                }
+-
+-                // 2nd phase: visits each instruction
+-                if (stackMap != 0) {
+-                    // creates the very first (implicit) frame from the method
+-                    // descriptor
+-                    frameLocal = new Object[maxLocals];
+-                    frameStack = new Object[maxStack];
+-                    if (unzip) {
+-                        int local = 0;
+-                        if ((access & Opcodes.ACC_STATIC) == 0) {
+-                            if (name.equals("<init>")) {
+-                                frameLocal[local++] = Opcodes.UNINITIALIZED_THIS;
+-                            }
+-                            else {
+-                                frameLocal[local++] = readClass(header + 2, c);
+-                            }
+-                        }
+-                        j = 1;
+-                        loop:
+-                        while (true) {
+-                            k = j;
+-                            switch (desc.charAt(j++)) {
+-                                case 'Z':
+-                                case 'C':
+-                                case 'B':
+-                                case 'S':
+-                                case 'I':
+-                                    frameLocal[local++] = Opcodes.INTEGER;
+-                                    break;
+-                                case 'F':
+-                                    frameLocal[local++] = Opcodes.FLOAT;
+-                                    break;
+-                                case 'J':
+-                                    frameLocal[local++] = Opcodes.LONG;
+-                                    break;
+-                                case 'D':
+-                                    frameLocal[local++] = Opcodes.DOUBLE;
+-                                    break;
+-                                case '[':
+-                                    while (desc.charAt(j) == '[') {
+-                                        ++j;
+-                                    }
+-                                    if (desc.charAt(j) == 'L') {
+-                                        ++j;
+-                                        while (desc.charAt(j) != ';') {
+-                                            ++j;
+-                                        }
+-                                    }
+-                                    frameLocal[local++] = desc.substring(k, ++j);
+-                                    break;
+-                                case 'L':
+-                                    while (desc.charAt(j) != ';') {
+-                                        ++j;
+-                                    }
+-                                    frameLocal[local++] = desc.substring(k + 1,
+-                                            j++);
+-                                    break;
+-                                default:
+-                                    break loop;
+-                            }
+-                        }
+-                        frameLocalCount = local;
+-                    }
+-                    /*
+-                     * 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
+-                     */
+-                    frameOffset = -1;
+-                }
+-                v = codeStart;
+-                Label l;
+-                while (v < codeEnd) {
+-                    w = v - codeStart;
+-
+-                    l = labels[w];
+-                    if (l != null) {
+-                        mv.visitLabel(l);
+-                        if (!skipDebug && l.line > 0) {
+-                            mv.visitLineNumber(l.line, l);
+-                        }
+-                    }
+-
+-                    while (frameLocal != null
+-                            && (frameOffset == w || frameOffset == -1)) {
+-                        // if there is a frame for this offset,
+-                        // makes the visitor visit it,
+-                        // and reads the next frame if there is one.
+-                        if (!zip || unzip) {
+-                            mv.visitFrame(Opcodes.F_NEW,
+-                                    frameLocalCount,
+-                                    frameLocal,
+-                                    frameStackCount,
+-                                    frameStack);
+-                        }
+-                        else if (frameOffset != -1) {
+-                            mv.visitFrame(frameMode,
+-                                    frameLocalDiff,
+-                                    frameLocal,
+-                                    frameStackCount,
+-                                    frameStack);
+-                        }
+-
+-                        if (frameCount > 0) {
+-                            int tag, delta, n;
+-                            if (zip) {
+-                                tag = b[stackMap++] & 0xFF;
+-                            }
+-                            else {
+-                                tag = MethodWriter.FULL_FRAME;
+-                                frameOffset = -1;
+-                            }
+-                            frameLocalDiff = 0;
+-                            if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) {
+-                                delta = tag;
+-                                frameMode = Opcodes.F_SAME;
+-                                frameStackCount = 0;
+-                            }
+-                            else if (tag < MethodWriter.RESERVED) {
+-                                delta = tag
+-                                        - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME;
+-                                stackMap = readFrameType(frameStack,
+-                                        0,
+-                                        stackMap,
+-                                        c,
+-                                        labels);
+-                                frameMode = Opcodes.F_SAME1;
+-                                frameStackCount = 1;
+-                            }
+-                            else {
+-                                delta = readUnsignedShort(stackMap);
+-                                stackMap += 2;
+-                                if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) {
+-                                    stackMap = readFrameType(frameStack,
+-                                            0,
+-                                            stackMap,
+-                                            c,
+-                                            labels);
+-                                    frameMode = Opcodes.F_SAME1;
+-                                    frameStackCount = 1;
+-                                }
+-                                else if (tag >= MethodWriter.CHOP_FRAME
+-                                        && tag < MethodWriter.SAME_FRAME_EXTENDED) {
+-                                    frameMode = Opcodes.F_CHOP;
+-                                    frameLocalDiff = MethodWriter.SAME_FRAME_EXTENDED
+-                                            - tag;
+-                                    frameLocalCount -= frameLocalDiff;
+-                                    frameStackCount = 0;
+-                                }
+-                                else if (tag == MethodWriter.SAME_FRAME_EXTENDED) {
+-                                    frameMode = Opcodes.F_SAME;
+-                                    frameStackCount = 0;
+-                                }
+-                                else if (tag < MethodWriter.FULL_FRAME) {
+-                                    j = unzip ? frameLocalCount : 0;
+-                                    for (k = tag
+-                                            - MethodWriter.SAME_FRAME_EXTENDED; k > 0; k--) {
+-                                        stackMap = readFrameType(frameLocal,
+-                                                j++,
+-                                                stackMap,
+-                                                c,
+-                                                labels);
+-                                    }
+-                                    frameMode = Opcodes.F_APPEND;
+-                                    frameLocalDiff = tag
+-                                            - MethodWriter.SAME_FRAME_EXTENDED;
+-                                    frameLocalCount += frameLocalDiff;
+-                                    frameStackCount = 0;
+-                                }
+-                                else { // if (tag == FULL_FRAME) {
+-                                    frameMode = Opcodes.F_FULL;
+-                                    n = frameLocalDiff = frameLocalCount = readUnsignedShort(stackMap);
+-                                    stackMap += 2;
+-                                    for (j = 0; n > 0; n--) {
+-                                        stackMap = readFrameType(frameLocal,
+-                                                j++,
+-                                                stackMap,
+-                                                c,
+-                                                labels);
+-                                    }
+-                                    n = frameStackCount = readUnsignedShort(stackMap);
+-                                    stackMap += 2;
+-                                    for (j = 0; n > 0; n--) {
+-                                        stackMap = readFrameType(frameStack,
+-                                                j++,
+-                                                stackMap,
+-                                                c,
+-                                                labels);
+-                                    }
+-                                }
+-                            }
+-                            frameOffset += delta + 1;
+-                            if (labels[frameOffset] == null) {
+-                                labels[frameOffset] = new Label();
+-                            }
+-
+-                            --frameCount;
+-                        }
+-                        else {
+-                            frameLocal = null;
+-                        }
+-                    }
+-
+-                    int opcode = b[v] & 0xFF;
+-                    switch (ClassWriter.TYPE[opcode]) {
+-                        case ClassWriter.NOARG_INSN:
+-                            mv.visitInsn(opcode);
+-                            v += 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);
+-                            }
+-                            v += 1;
+-                            break;
+-                        case ClassWriter.LABEL_INSN:
+-                            mv.visitJumpInsn(opcode, labels[w
+-                                    + readShort(v + 1)]);
+-                            v += 3;
+-                            break;
+-                        case ClassWriter.LABELW_INSN:
+-                            mv.visitJumpInsn(opcode - 33, labels[w
+-                                    + readInt(v + 1)]);
+-                            v += 5;
+-                            break;
+-                        case ClassWriter.WIDE_INSN:
+-                            opcode = b[v + 1] & 0xFF;
+-                            if (opcode == Opcodes.IINC) {
+-                                mv.visitIincInsn(readUnsignedShort(v + 2),
+-                                        readShort(v + 4));
+-                                v += 6;
+-                            }
+-                            else {
+-                                mv.visitVarInsn(opcode,
+-                                        readUnsignedShort(v + 2));
+-                                v += 4;
+-                            }
+-                            break;
+-                        case ClassWriter.TABL_INSN:
+-                            // skips 0 to 3 padding bytes
+-                            v = v + 4 - (w & 3);
+-                            // reads instruction
+-                            label = w + readInt(v);
+-                            int min = readInt(v + 4);
+-                            int max = readInt(v + 8);
+-                            v += 12;
+-                            Label[] table = new Label[max - min + 1];
+-                            for (j = 0; j < table.length; ++j) {
+-                                table[j] = labels[w + readInt(v)];
+-                                v += 4;
+-                            }
+-                            mv.visitTableSwitchInsn(min,
+-                                    max,
+-                                    labels[label],
+-                                    table);
+-                            break;
+-                        case ClassWriter.LOOK_INSN:
+-                            // skips 0 to 3 padding bytes
+-                            v = v + 4 - (w & 3);
+-                            // reads instruction
+-                            label = w + readInt(v);
+-                            j = readInt(v + 4);
+-                            v += 8;
+-                            int[] keys = new int[j];
+-                            Label[] values = new Label[j];
+-                            for (j = 0; j < keys.length; ++j) {
+-                                keys[j] = readInt(v);
+-                                values[j] = labels[w + readInt(v + 4)];
+-                                v += 8;
+-                            }
+-                            mv.visitLookupSwitchInsn(labels[label],
+-                                    keys,
+-                                    values);
+-                            break;
+-                        case ClassWriter.VAR_INSN:
+-                            mv.visitVarInsn(opcode, b[v + 1] & 0xFF);
+-                            v += 2;
+-                            break;
+-                        case ClassWriter.SBYTE_INSN:
+-                            mv.visitIntInsn(opcode, b[v + 1]);
+-                            v += 2;
+-                            break;
+-                        case ClassWriter.SHORT_INSN:
+-                            mv.visitIntInsn(opcode, readShort(v + 1));
+-                            v += 3;
+-                            break;
+-                        case ClassWriter.LDC_INSN:
+-                            mv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c));
+-                            v += 2;
+-                            break;
+-                        case ClassWriter.LDCW_INSN:
+-                            mv.visitLdcInsn(readConst(readUnsignedShort(v + 1),
+-                                    c));
+-                            v += 3;
+-                            break;
+-                        case ClassWriter.FIELDORMETH_INSN:
+-                        case ClassWriter.ITFMETH_INSN:
+-                            int cpIndex = items[readUnsignedShort(v + 1)];
+-                            String iowner = readClass(cpIndex, c);
+-                            cpIndex = items[readUnsignedShort(cpIndex + 2)];
+-                            String iname = readUTF8(cpIndex, c);
+-                            String idesc = readUTF8(cpIndex + 2, c);
+-                            if (opcode < Opcodes.INVOKEVIRTUAL) {
+-                                mv.visitFieldInsn(opcode, iowner, iname, idesc);
+-                            }
+-                            else {
+-                                mv.visitMethodInsn(opcode, iowner, iname, idesc);
+-                            }
+-                            if (opcode == Opcodes.INVOKEINTERFACE) {
+-                                v += 5;
+-                            }
+-                            else {
+-                                v += 3;
+-                            }
+-                            break;
+-                        case ClassWriter.TYPE_INSN:
+-                            mv.visitTypeInsn(opcode, readClass(v + 1, c));
+-                            v += 3;
+-                            break;
+-                        case ClassWriter.IINC_INSN:
+-                            mv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]);
+-                            v += 3;
+-                            break;
+-                            // case MANA_INSN:
+-                        default:
+-                            mv.visitMultiANewArrayInsn(readClass(v + 1, c),
+-                                    b[v + 3] & 0xFF);
+-                            v += 4;
+-                            break;
+-                    }
+-                }
+-                l = labels[codeEnd - codeStart];
+-                if (l != null) {
+-                    mv.visitLabel(l);
+-                }
+-                // visits the local variable tables
+-                if (!skipDebug && varTable != 0) {
+-                    int[] typeTable = null;
+-                    if (varTypeTable != 0) {
+-                        k = readUnsignedShort(varTypeTable) * 3;
+-                        w = varTypeTable + 2;
+-                        typeTable = new int[k];
+-                        while (k > 0) {
+-                            typeTable[--k] = w + 6; // signature
+-                            typeTable[--k] = readUnsignedShort(w + 8); // index
+-                            typeTable[--k] = readUnsignedShort(w); // start
+-                            w += 10;
+-                        }
+-                    }
+-                    k = readUnsignedShort(varTable);
+-                    w = varTable + 2;
+-                    for (; k > 0; --k) {
+-                        int start = readUnsignedShort(w);
+-                        int length = readUnsignedShort(w + 2);
+-                        int index = readUnsignedShort(w + 8);
+-                        String vsignature = null;
+-                        if (typeTable != null) {
+-                            for (int a = 0; a < typeTable.length; a += 3) {
+-                                if (typeTable[a] == start
+-                                        && typeTable[a + 1] == index) {
+-                                    vsignature = readUTF8(typeTable[a + 2], c);
+-                                    break;
+-                                }
+-                            }
+-                        }
+-                        mv.visitLocalVariable(readUTF8(w + 4, c),
+-                                readUTF8(w + 6, c),
+-                                vsignature,
+-                                labels[start],
+-                                labels[start + length],
+-                                index);
+-                        w += 10;
+-                    }
+-                }
+-                // visits the other attributes
+-                while (cattrs != null) {
+-                    attr = cattrs.next;
+-                    cattrs.next = null;
+-                    mv.visitAttribute(cattrs);
+-                    cattrs = attr;
+-                }
+-                // visits the max stack and max locals values
+-                mv.visitMaxs(maxStack, maxLocals);
+-            }
+-
+-            if (mv != null) {
+-                mv.visitEnd();
+-            }
+-        }
+-
+-        // visits the end of the class
+-        classVisitor.visitEnd();
+-    }
+-
+-    /**
+-     * Reads parameter annotations and makes the given visitor visit them.
+-     *
+-     * @param v       start offset in {@link #b b} of the annotations to be read.
+-     * @param buf     buffer to be used to call {@link #readUTF8 readUTF8},
+-     *                {@link #readClass(int,char[]) readClass} or
+-     *                {@link #readConst readConst}.
+-     * @param visible <tt>true</tt> if the annotations to be read are visible
+-     *                at runtime.
+-     * @param mv      the visitor that must visit the annotations.
+-     */
+-    private void readParameterAnnotations(
+-            int v,
+-            final char[] buf,
+-            final boolean visible,
+-            final MethodVisitor mv) {
+-        int n = b[v++] & 0xFF;
+-        for (int i = 0; i < n; ++i) {
+-            int j = readUnsignedShort(v);
+-            v += 2;
+-            for (; j > 0; --j) {
+-                v = readAnnotationValues(v + 2,
+-                        buf,
+-                        true,
+-                        mv.visitParameterAnnotation(i,
+-                                readUTF8(v, buf),
+-                                visible));
+-            }
+-        }
+-    }
+-
+-    /**
+-     * Reads the values of an annotation and makes the given visitor visit them.
+-     *
+-     * @param v     the start offset in {@link #b b} of the values to be read
+-     *              (including the unsigned short that gives the number of values).
+-     * @param buf   buffer to be used to call {@link #readUTF8 readUTF8},
+-     *              {@link #readClass(int,char[]) readClass} or
+-     *              {@link #readConst readConst}.
+-     * @param named if the annotation values are named or not.
+-     * @param av    the visitor that must visit the values.
+-     * @return the end offset of the annotation values.
+-     */
+-    private int readAnnotationValues(
+-            int v,
+-            final char[] buf,
+-            final boolean named,
+-            final AnnotationVisitor av) {
+-        int i = readUnsignedShort(v);
+-        v += 2;
+-        if (named) {
+-            for (; i > 0; --i) {
+-                v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av);
+-            }
+-        }
+-        else {
+-            for (; i > 0; --i) {
+-                v = readAnnotationValue(v, buf, null, av);
+-            }
+-        }
+-        if (av != null) {
+-            av.visitEnd();
+-        }
+-        return v;
+-    }
+-
+-    /**
+-     * Reads a value of an annotation and makes the given visitor visit it.
+-     *
+-     * @param v    the start offset in {@link #b b} of the value to be read (<i>not
+-     *             including the value name constant pool index</i>).
+-     * @param buf  buffer to be used to call {@link #readUTF8 readUTF8},
+-     *             {@link #readClass(int,char[]) readClass} or
+-     *             {@link #readConst readConst}.
+-     * @param name the name of the value to be read.
+-     * @param av   the visitor that must visit the value.
+-     * @return the end offset of the annotation value.
+-     */
+-    private int readAnnotationValue(
+-            int v,
+-            final char[] buf,
+-            final String name,
+-            final AnnotationVisitor av) {
+-        int i;
+-        if (av == null) {
+-            switch (b[v] & 0xFF) {
+-                case 'e': // enum_const_value
+-                    return v + 5;
+-                case '@': // annotation_value
+-                    return readAnnotationValues(v + 3, buf, true, null);
+-                case '[': // array_value
+-                    return readAnnotationValues(v + 1, buf, false, null);
+-                default:
+-                    return v + 3;
+-            }
+-        }
+-        switch (b[v++] & 0xFF) {
+-            case 'I': // pointer to CONSTANT_Integer
+-            case 'J': // pointer to CONSTANT_Long
+-            case 'F': // pointer to CONSTANT_Float
+-            case 'D': // pointer to CONSTANT_Double
+-                av.visit(name, readConst(readUnsignedShort(v), buf));
+-                v += 2;
+-                break;
+-            case 'B': // pointer to CONSTANT_Byte
+-                av.visit(name,
+-                        new Byte((byte) readInt(items[readUnsignedShort(v)])));
+-                v += 2;
+-                break;
+-            case 'Z': // pointer to CONSTANT_Boolean
+-                av.visit(name, readInt(items[readUnsignedShort(v)]) == 0
+-                        ? Boolean.FALSE
+-                        : Boolean.TRUE);
+-                v += 2;
+-                break;
+-            case 'S': // pointer to CONSTANT_Short
+-                av.visit(name,
+-                        new Short((short) readInt(items[readUnsignedShort(v)])));
+-                v += 2;
+-                break;
+-            case 'C': // pointer to CONSTANT_Char
+-                av.visit(name,
+-                        new Character((char) readInt(items[readUnsignedShort(v)])));
+-                v += 2;
+-                break;
+-            case 's': // pointer to CONSTANT_Utf8
+-                av.visit(name, readUTF8(v, buf));
+-                v += 2;
+-                break;
+-            case 'e': // enum_const_value
+-                av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf));
+-                v += 4;
+-                break;
+-            case 'c': // class_info
+-                av.visit(name, Type.getType(readUTF8(v, buf)));
+-                v += 2;
+-                break;
+-            case '@': // annotation_value
+-                v = readAnnotationValues(v + 2,
+-                        buf,
+-                        true,
+-                        av.visitAnnotation(name, readUTF8(v, buf)));
+-                break;
+-            case '[': // array_value
+-                int size = readUnsignedShort(v);
+-                v += 2;
+-                if (size == 0) {
+-                    return readAnnotationValues(v - 2,
+-                            buf,
+-                            false,
+-                            av.visitArray(name));
+-                }
+-                switch (this.b[v++] & 0xFF) {
+-                    case 'B':
+-                        byte[] bv = new byte[size];
+-                        for (i = 0; i < size; i++) {
+-                            bv[i] = (byte) readInt(items[readUnsignedShort(v)]);
+-                            v += 3;
+-                        }
+-                        av.visit(name, bv);
+-                        --v;
+-                        break;
+-                    case 'Z':
+-                        boolean[] zv = new boolean[size];
+-                        for (i = 0; i < size; i++) {
+-                            zv[i] = readInt(items[readUnsignedShort(v)]) != 0;
+-                            v += 3;
+-                        }
+-                        av.visit(name, zv);
+-                        --v;
+-                        break;
+-                    case 'S':
+-                        short[] sv = new short[size];
+-                        for (i = 0; i < size; i++) {
+-                            sv[i] = (short) readInt(items[readUnsignedShort(v)]);
+-                            v += 3;
+-                        }
+-                        av.visit(name, sv);
+-                        --v;
+-                        break;
+-                    case 'C':
+-                        char[] cv = new char[size];
+-                        for (i = 0; i < size; i++) {
+-                            cv[i] = (char) readInt(items[readUnsignedShort(v)]);
+-                            v += 3;
+-                        }
+-                        av.visit(name, cv);
+-                        --v;
+-                        break;
+-                    case 'I':
+-                        int[] iv = new int[size];
+-                        for (i = 0; i < size; i++) {
+-                            iv[i] = readInt(items[readUnsignedShort(v)]);
+-                            v += 3;
+-                        }
+-                        av.visit(name, iv);
+-                        --v;
+-                        break;
+-                    case 'J':
+-                        long[] lv = new long[size];
+-                        for (i = 0; i < size; i++) {
+-                            lv[i] = readLong(items[readUnsignedShort(v)]);
+-                            v += 3;
+-                        }
+-                        av.visit(name, lv);
+-                        --v;
+-                        break;
+-                    case 'F':
+-                        float[] fv = new float[size];
+-                        for (i = 0; i < size; i++) {
+-                            fv[i] = Float.intBitsToFloat(readInt(items[readUnsignedShort(v)]));
+-                            v += 3;
+-                        }
+-                        av.visit(name, fv);
+-                        --v;
+-                        break;
+-                    case 'D':
+-                        double[] dv = new double[size];
+-                        for (i = 0; i < size; i++) {
+-                            dv[i] = Double.longBitsToDouble(readLong(items[readUnsignedShort(v)]));
+-                            v += 3;
+-                        }
+-                        av.visit(name, dv);
+-                        --v;
+-                        break;
+-                    default:
+-                        v = readAnnotationValues(v - 3,
+-                                buf,
+-                                false,
+-                                av.visitArray(name));
+-                }
+-        }
+-        return v;
+-    }
+-
+-    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
+-                int offset = readUnsignedShort(v);
+-                if (labels[offset] == null) {
+-                    labels[offset] = new Label();
+-                }
+-                frame[index] = labels[offset];
+-                v += 2;
+-        }
+-        return v;
+-    }
+-
+-    /**
+-     * Reads an attribute in {@link #b b}.
+-     *
+-     * @param attrs   prototypes of the attributes that must be parsed during the
+-     *                visit of the class. Any attribute whose type is not equal to the
+-     *                type of one the prototypes is ignored (i.e. an empty
+-     *                {@link Attribute} instance is returned).
+-     * @param type    the type of the attribute.
+-     * @param off     index of the first byte of the attribute's content in
+-     *                {@link #b b}. The 6 attribute header bytes, containing the type
+-     *                and the length of the attribute, are not taken into account here
+-     *                (they have already been read).
+-     * @param len     the length of the attribute's content.
+-     * @param buf     buffer to be used to call {@link #readUTF8 readUTF8},
+-     *                {@link #readClass(int,char[]) readClass} or
+-     *                {@link #readConst readConst}.
+-     * @param codeOff index of the first byte of code's attribute content in
+-     *                {@link #b b}, or -1 if the attribute to be read is not a code
+-     *                attribute. The 6 attribute header bytes, containing the type and
+-     *                the length of the attribute, are not taken into account here.
+-     * @param labels  the labels of the method's code, or <tt>null</tt> if the
+-     *                attribute to be read is not a code attribute.
+-     * @return the attribute that has been read, or <tt>null</tt> to skip this
+-     *         attribute.
+-     */
+-    private Attribute readAttribute(
+-            final Attribute[] attrs,
+-            final String type,
+-            final int off,
+-            final int len,
+-            final char[] buf,
+-            final int codeOff,
+-            final Label[] labels) {
+-        for (int i = 0; i < attrs.length; ++i) {
+-            if (attrs[i].type.equals(type)) {
+-                return attrs[i].read(this, off, len, buf, codeOff, labels);
+-            }
+-        }
+-        return new Attribute(type).read(this, off, len, null, -1, null);
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods: low level parsing
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Returns the start index of the constant pool item in {@link #b b}, plus
+-     * one. <i>This method is intended for {@link Attribute} sub classes, and is
+-     * normally not needed by class generators or adapters.</i>
+-     *
+-     * @param item the index a constant pool item.
+-     * @return the start index of the constant pool item in {@link #b b}, plus
+-     *         one.
+-     */
+-    public int getItem(final int item) {
+-        return items[item];
+-    }
+-
+-    /**
+-     * Reads a byte value in {@link #b b}. <i>This method is intended for
+-     * {@link Attribute} sub classes, and is normally not needed by class
+-     * generators or adapters.</i>
+-     *
+-     * @param index the start index of the value to be read in {@link #b b}.
+-     * @return the read value.
+-     */
+-    public int readByte(final int index) {
+-        return b[index] & 0xFF;
+-    }
+-
+-    /**
+-     * Reads an unsigned short value in {@link #b b}. <i>This method is
+-     * intended for {@link Attribute} sub classes, and is normally not needed by
+-     * class generators or adapters.</i>
+-     *
+-     * @param index the start index of the value to be read in {@link #b b}.
+-     * @return the read value.
+-     */
+-    public int readUnsignedShort(final int index) {
+-        byte[] b = this.b;
+-        return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
+-    }
+-
+-    /**
+-     * Reads a signed short value in {@link #b b}. <i>This method is intended
+-     * for {@link Attribute} sub classes, and is normally not needed by class
+-     * generators or adapters.</i>
+-     *
+-     * @param index the start index of the value to be read in {@link #b b}.
+-     * @return the read value.
+-     */
+-    public short readShort(final int index) {
+-        byte[] b = this.b;
+-        return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
+-    }
+-
+-    /**
+-     * Reads a signed int value in {@link #b b}. <i>This method is intended for
+-     * {@link Attribute} sub classes, and is normally not needed by class
+-     * generators or adapters.</i>
+-     *
+-     * @param index the start index of the value to be read in {@link #b b}.
+-     * @return the read value.
+-     */
+-    public int readInt(final int index) {
+-        byte[] b = this.b;
+-        return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
+-                | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
+-    }
+-
+-    /**
+-     * Reads a signed long value in {@link #b b}. <i>This method is intended
+-     * for {@link Attribute} sub classes, and is normally not needed by class
+-     * generators or adapters.</i>
+-     *
+-     * @param index the start index of the value to be read in {@link #b b}.
+-     * @return the read value.
+-     */
+-    public long readLong(final int index) {
+-        long l1 = readInt(index);
+-        long l0 = readInt(index + 4) & 0xFFFFFFFFL;
+-        return (l1 << 32) | l0;
+-    }
+-
+-    /**
+-     * Reads an UTF8 string constant pool item in {@link #b b}. <i>This method
+-     * is intended for {@link Attribute} sub classes, and is normally not needed
+-     * by class generators or adapters.</i>
+-     *
+-     * @param index the start index of an unsigned short value in {@link #b b},
+-     *              whose value is the index of an UTF8 constant pool item.
+-     * @param buf   buffer to be used to read the item. This buffer must be
+-     *              sufficiently large. It is not automatically resized.
+-     * @return the String corresponding to the specified UTF8 item.
+-     */
+-    public String readUTF8(int index, final char[] buf) {
+-        int item = readUnsignedShort(index);
+-        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, d, e;
+-        while (index < endIndex) {
+-            c = b[index++] & 0xFF;
+-            switch (c >> 4) {
+-                case 0:
+-                case 1:
+-                case 2:
+-                case 3:
+-                case 4:
+-                case 5:
+-                case 6:
+-                case 7:
+-                    // 0xxxxxxx
+-                    buf[strLen++] = (char) c;
+-                    break;
+-                case 12:
+-                case 13:
+-                    // 110x xxxx 10xx xxxx
+-                    d = b[index++];
+-                    buf[strLen++] = (char) (((c & 0x1F) << 6) | (d & 0x3F));
+-                    break;
+-                default:
+-                    // 1110 xxxx 10xx xxxx 10xx xxxx
+-                    d = b[index++];
+-                    e = b[index++];
+-                    buf[strLen++] = (char) (((c & 0x0F) << 12)
+-                            | ((d & 0x3F) << 6) | (e & 0x3F));
+-                    break;
+-            }
+-        }
+-        return new String(buf, 0, strLen);
+-    }
+-
+-    /**
+-     * Reads a class constant pool item in {@link #b b}. <i>This method is
+-     * intended for {@link Attribute} sub classes, and is normally not needed by
+-     * class generators or adapters.</i>
+-     *
+-     * @param index the start index of an unsigned short value in {@link #b b},
+-     *              whose value is the index of a class constant pool item.
+-     * @param buf   buffer to be used to read the item. This buffer must be
+-     *              sufficiently large. It is not automatically resized.
+-     * @return the String corresponding to the specified class item.
+-     */
+-    public String readClass(final int index, final char[] buf) {
+-        // computes the start index of the CONSTANT_Class item in b
+-        // and reads the CONSTANT_Utf8 item designated by
+-        // the first two bytes of this CONSTANT_Class item
+-        return readUTF8(items[readUnsignedShort(index)], buf);
+-    }
+-
+-    /**
+-     * Reads a numeric or string constant pool item in {@link #b b}. <i>This
+-     * method is intended for {@link Attribute} sub classes, and is normally not
+-     * needed by class generators or adapters.</i>
+-     *
+-     * @param item the index of a constant pool item.
+-     * @param buf  buffer to be used to read the item. This buffer must be
+-     *             sufficiently large. It is not automatically resized.
+-     * @return the {@link Integer}, {@link Float}, {@link Long},
+-     *         {@link Double}, {@link String} or {@link Type} 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:
+-                String s = readUTF8(index, buf);
+-                return s.charAt(0) == '['
+-                        ? Type.getType(s)
+-                        : Type.getObjectType(s);
+-                // case ClassWriter.STR:
+-            default:
+-                return readUTF8(index, buf);
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/ClassVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ClassVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/ClassVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ClassVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,196 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 interface must be called
+- * in the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
+- * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
+- * <tt>visitAttribute</tt> )* (<tt>visitInnerClass</tt> |
+- * <tt>visitField</tt> | <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
+- *
+- * @author Eric Bruneton
+- */
+-public interface ClassVisitor {
+-
+-    /**
+-     * Visits the header of the class.
+-     *
+-     * @param version    the class version.
+-     * @param access     the class's access flags (see {@link Opcodes}). This
+-     *                   parameter also indicates if the class is deprecated.
+-     * @param name       the internal name of the class (see
+-     *                   {@link Type#getInternalName() getInternalName}).
+-     * @param signature  the signature of this class. May be <tt>null</tt> if
+-     *                   the class is not a generic one, and does not extend or implement
+-     *                   generic classes or interfaces.
+-     * @param superName  the internal of name of the super class (see
+-     *                   {@link Type#getInternalName() getInternalName}). For interfaces,
+-     *                   the super class is {@link Object}. May be <tt>null</tt>, but
+-     *                   only for the {@link Object} class.
+-     * @param interfaces the internal names of the class's interfaces (see
+-     *                   {@link Type#getInternalName() getInternalName}). May be
+-     *                   <tt>null</tt>.
+-     */
+-    void visit(
+-            int version,
+-            int access,
+-            String name,
+-            String signature,
+-            String superName,
+-            String[] interfaces);
+-
+-    /**
+-     * Visits the source of the class.
+-     *
+-     * @param source the name of the source file from which the class was
+-     *               compiled. May be <tt>null</tt>.
+-     * @param debug  additional debug information to compute the correspondance
+-     *               between source and compiled elements of the class. May be
+-     *               <tt>null</tt>.
+-     */
+-    void visitSource(String source, String debug);
+-
+-    /**
+-     * Visits the enclosing class of the class. This method must be called only
+-     * if the class has an enclosing class.
+-     *
+-     * @param owner internal name of the enclosing class of the class.
+-     * @param name  the name of the method that contains the class, or
+-     *              <tt>null</tt> if the class is not enclosed in a method of its
+-     *              enclosing class.
+-     * @param desc  the descriptor of the method that contains the class, or
+-     *              <tt>null</tt> if the class is not enclosed in a method of its
+-     *              enclosing class.
+-     */
+-    void visitOuterClass(String owner, String name, String desc);
+-
+-    /**
+-     * Visits an annotation of the class.
+-     *
+-     * @param desc    the class descriptor of the annotation class.
+-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+-     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+-     *         this visitor is not interested in visiting this annotation.
+-     */
+-    AnnotationVisitor visitAnnotation(String desc, boolean visible);
+-
+-    /**
+-     * Visits a non standard attribute of the class.
+-     *
+-     * @param attr an attribute.
+-     */
+-    void visitAttribute(Attribute attr);
+-
+-    /**
+-     * Visits information about an inner class. This inner class is not
+-     * necessarily a member of the class being visited.
+-     *
+-     * @param name      the internal name of an inner class (see
+-     *                  {@link Type#getInternalName() getInternalName}).
+-     * @param outerName the internal name of the class to which the inner class
+-     *                  belongs (see {@link Type#getInternalName() getInternalName}). May
+-     *                  be <tt>null</tt> for not member classes.
+-     * @param innerName the (simple) name of the inner class inside its
+-     *                  enclosing class. May be <tt>null</tt> for anonymous inner
+-     *                  classes.
+-     * @param access    the access flags of the inner class as originally declared
+-     *                  in the enclosing class.
+-     */
+-    void visitInnerClass(
+-            String name,
+-            String outerName,
+-            String innerName,
+-            int access);
+-
+-    /**
+-     * Visits a field of the class.
+-     *
+-     * @param access    the field's access flags (see {@link Opcodes}). This
+-     *                  parameter also indicates if the field is synthetic and/or
+-     *                  deprecated.
+-     * @param name      the field's name.
+-     * @param desc      the field's descriptor (see {@link Type Type}).
+-     * @param signature the field's signature. May be <tt>null</tt> if the
+-     *                  field's type does not use generic types.
+-     * @param value     the field's initial value. This parameter, which may be
+-     *                  <tt>null</tt> if the field does not have an initial value, must
+-     *                  be an {@link Integer}, a {@link Float}, a {@link Long}, a
+-     *                  {@link Double} or a {@link String} (for <tt>int</tt>,
+-     *                  <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
+-     *                  respectively). <i>This parameter is only used for static fields</i>.
+-     *                  Its value is ignored for non static fields, which must be
+-     *                  initialized through bytecode instructions in constructors or
+-     *                  methods.
+-     * @return a visitor to visit field annotations and attributes, or
+-     *         <tt>null</tt> if this class visitor is not interested in
+-     *         visiting these annotations and attributes.
+-     */
+-    FieldVisitor visitField(
+-            int access,
+-            String name,
+-            String desc,
+-            String signature,
+-            Object value);
+-
+-    /**
+-     * Visits a method of the class. This method <i>must</i> return a new
+-     * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is
+-     * called, i.e., it should not return a previously returned visitor.
+-     *
+-     * @param access     the method's access flags (see {@link Opcodes}). This
+-     *                   parameter also indicates if the method is synthetic and/or
+-     *                   deprecated.
+-     * @param name       the method's name.
+-     * @param desc       the method's descriptor (see {@link Type Type}).
+-     * @param signature  the method's signature. May be <tt>null</tt> if the
+-     *                   method parameters, return type and exceptions do not use generic
+-     *                   types.
+-     * @param exceptions the internal names of the method's exception classes
+-     *                   (see {@link Type#getInternalName() getInternalName}). May be
+-     *                   <tt>null</tt>.
+-     * @return an object to visit the byte code of the method, or <tt>null</tt>
+-     *         if this class visitor is not interested in visiting the code of
+-     *         this method.
+-     */
+-    MethodVisitor visitMethod(
+-            int access,
+-            String name,
+-            String desc,
+-            String signature,
+-            String[] exceptions);
+-
+-    /**
+-     * 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.
+-     */
+-    void visitEnd();
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/ClassWriter.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ClassWriter.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/ClassWriter.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/ClassWriter.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1342 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 implements 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 final static 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 final static int COMPUTE_FRAMES = 2;
+-
+-    /**
+-     * The type of instructions without any argument.
+-     */
+-    final static int NOARG_INSN = 0;
+-
+-    /**
+-     * The type of instructions with an signed byte argument.
+-     */
+-    final static int SBYTE_INSN = 1;
+-
+-    /**
+-     * The type of instructions with an signed short argument.
+-     */
+-    final static int SHORT_INSN = 2;
+-
+-    /**
+-     * The type of instructions with a local variable index argument.
+-     */
+-    final static int VAR_INSN = 3;
+-
+-    /**
+-     * The type of instructions with an implicit local variable index argument.
+-     */
+-    final static int IMPLVAR_INSN = 4;
+-
+-    /**
+-     * The type of instructions with a type descriptor argument.
+-     */
+-    final static int TYPE_INSN = 5;
+-
+-    /**
+-     * The type of field and method invocations instructions.
+-     */
+-    final static int FIELDORMETH_INSN = 6;
+-
+-    /**
+-     * The type of the INVOKEINTERFACE instruction.
+-     */
+-    final static int ITFMETH_INSN = 7;
+-
+-    /**
+-     * The type of instructions with a 2 bytes bytecode offset label.
+-     */
+-    final static int LABEL_INSN = 8;
+-
+-    /**
+-     * The type of instructions with a 4 bytes bytecode offset label.
+-     */
+-    final static int LABELW_INSN = 9;
+-
+-    /**
+-     * The type of the LDC instruction.
+-     */
+-    final static int LDC_INSN = 10;
+-
+-    /**
+-     * The type of the LDC_W and LDC2_W instructions.
+-     */
+-    final static int LDCW_INSN = 11;
+-
+-    /**
+-     * The type of the IINC instruction.
+-     */
+-    final static int IINC_INSN = 12;
+-
+-    /**
+-     * The type of the TABLESWITCH instruction.
+-     */
+-    final static int TABL_INSN = 13;
+-
+-    /**
+-     * The type of the LOOKUPSWITCH instruction.
+-     */
+-    final static int LOOK_INSN = 14;
+-
+-    /**
+-     * The type of the MULTIANEWARRAY instruction.
+-     */
+-    final static int MANA_INSN = 15;
+-
+-    /**
+-     * The type of the WIDE instruction.
+-     */
+-    final static int WIDE_INSN = 16;
+-
+-    /**
+-     * The instruction types of all JVM opcodes.
+-     */
+-    static byte[] TYPE;
+-
+-    /**
+-     * The type of CONSTANT_Class constant pool items.
+-     */
+-    final static int CLASS = 7;
+-
+-    /**
+-     * The type of CONSTANT_Fieldref constant pool items.
+-     */
+-    final static int FIELD = 9;
+-
+-    /**
+-     * The type of CONSTANT_Methodref constant pool items.
+-     */
+-    final static int METH = 10;
+-
+-    /**
+-     * The type of CONSTANT_InterfaceMethodref constant pool items.
+-     */
+-    final static int IMETH = 11;
+-
+-    /**
+-     * The type of CONSTANT_String constant pool items.
+-     */
+-    final static int STR = 8;
+-
+-    /**
+-     * The type of CONSTANT_Integer constant pool items.
+-     */
+-    final static int INT = 3;
+-
+-    /**
+-     * The type of CONSTANT_Float constant pool items.
+-     */
+-    final static int FLOAT = 4;
+-
+-    /**
+-     * The type of CONSTANT_Long constant pool items.
+-     */
+-    final static int LONG = 5;
+-
+-    /**
+-     * The type of CONSTANT_Double constant pool items.
+-     */
+-    final static int DOUBLE = 6;
+-
+-    /**
+-     * The type of CONSTANT_NameAndType constant pool items.
+-     */
+-    final static int NAME_TYPE = 12;
+-
+-    /**
+-     * The type of CONSTANT_Utf8 constant pool items.
+-     */
+-    final static int UTF8 = 1;
+-
+-    /**
+-     * 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.
+-     */
+-    final static int TYPE_NORMAL = 13;
+-
+-    /**
+-     * 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.
+-     */
+-    final static int TYPE_UNINIT = 14;
+-
+-    /**
+-     * 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.
+-     */
+-    final static int TYPE_MERGED = 15;
+-
+-    /**
+-     * 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.
+-     */
+-    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.
+-     */
+-    Item key;
+-
+-    /**
+-     * A reusable key used to look for items in the {@link #items} hash table.
+-     */
+-    Item key2;
+-
+-    /**
+-     * A reusable key used to look for items in the {@link #items} hash table.
+-     */
+-    Item key3;
+-
+-    /**
+-     * A type table used to temporarily store internal names that will not
+-     * necessarily be stored in the constant pool. This type table is used by
+-     * the control flow and data flow analysis algorithm used to compute stack
+-     * map frames from scratch. This array associates to each index <tt>i</tt>
+-     * the Item whose index is <tt>i</tt>. All Item objects stored in this
+-     * array are also stored in the {@link #items} hash table. These two arrays
+-     * allow to retrieve an Item from its index or, conversly, to get the index
+-     * of an Item from its value. Each Item stores an internal name in its
+-     * {@link Item#strVal1} field.
+-     */
+-    Item[] typeTable;
+-
+-    /**
+-     * Number of elements in the {@link #typeTable} array.
+-     */
+-    private short typeCount;
+-
+-    /**
+-     * The access flags of this class.
+-     */
+-    private int access;
+-
+-    /**
+-     * The constant pool item that contains the internal name of this class.
+-     */
+-    private int name;
+-
+-    /**
+-     * The internal name of this class.
+-     */
+-    String thisName;
+-
+-    /**
+-     * The constant pool item that contains the signature of this class.
+-     */
+-    private int signature;
+-
+-    /**
+-     * The constant pool item that contains the internal name of the super class
+-     * of this class.
+-     */
+-    private int superName;
+-
+-    /**
+-     * Number of interfaces implemented or extended by this class or interface.
+-     */
+-    private int interfaceCount;
+-
+-    /**
+-     * The interfaces implemented or extended by this class or interface. More
+-     * precisely, this array contains the indexes of the constant pool items
+-     * that contain the internal names of these interfaces.
+-     */
+-    private int[] interfaces;
+-
+-    /**
+-     * The index of the constant pool item that contains the name of the source
+-     * file from which this class was compiled.
+-     */
+-    private int sourceFile;
+-
+-    /**
+-     * The SourceDebug attribute of this class.
+-     */
+-    private ByteVector sourceDebug;
+-
+-    /**
+-     * The constant pool item that contains the name of the enclosing class of
+-     * this class.
+-     */
+-    private int enclosingMethodOwner;
+-
+-    /**
+-     * The constant pool item that contains the name and descriptor of the
+-     * enclosing method of this class.
+-     */
+-    private int enclosingMethod;
+-
+-    /**
+-     * The runtime visible annotations of this class.
+-     */
+-    private AnnotationWriter anns;
+-
+-    /**
+-     * The runtime invisible annotations of this class.
+-     */
+-    private AnnotationWriter ianns;
+-
+-    /**
+-     * The non standard attributes of this class.
+-     */
+-    private Attribute attrs;
+-
+-    /**
+-     * The number of entries in the InnerClasses attribute.
+-     */
+-    private int innerClassesCount;
+-
+-    /**
+-     * The InnerClasses attribute.
+-     */
+-    private ByteVector innerClasses;
+-
+-    /**
+-     * The fields of this class. These fields are stored in a linked list of
+-     * {@link FieldWriter} objects, linked to each other by their
+-     * {@link FieldWriter#next} field. This field stores the first element of
+-     * 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#next} 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#next} 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#next} field. This field stores the last element of
+-     * this list.
+-     */
+-    MethodWriter lastMethod;
+-
+-    /**
+-     * <tt>true</tt> if the maximum stack size and number of local variables
+-     * must be automatically computed.
+-     */
+-    private boolean computeMaxs;
+-
+-    /**
+-     * <tt>true</tt> if the stack map frames must be recomputed from scratch.
+-     */
+-    private boolean computeFrames;
+-
+-    /**
+-     * <tt>true</tt> if the stack map tables of this class are invalid. The
+-     * {@link MethodWriter#resizeInstructions} method cannot transform existing
+-     * stack map tables, and so produces potentially invalid classes when it is
+-     * executed. In this case the class is reread and rewritten with the
+-     * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
+-     * stack map tables when this option is used).
+-     */
+-    boolean invalidFrames;
+-
+-    // ------------------------------------------------------------------------
+-    // Static initializer
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Computes the instruction types of JVM opcodes.
+-     */
+-    static {
+-        int i;
+-        byte[] b = new byte[220];
+-        String s = "AAAAAAAAAAAAAAAABCKLLDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
+-                + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+-                + "AAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAIIIIIIIIIIIIIIIIDNOAA"
+-                + "AAAAGGGGGGGHAFBFAAFFAAQPIIJJIIIIIIIIIIIIIIIIII";
+-        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;
+-        //
+-        // // 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) {
+-        index = 1;
+-        pool = new ByteVector();
+-        items = new Item[256];
+-        threshold = (int) (0.75d * items.length);
+-        key = new Item();
+-        key2 = new Item();
+-        key3 = 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:
+-     * <p/>
+-     * <ul> <li>The constant pool from the original class is copied as is in
+-     * the new class, which saves time. New constant pool entries will be added
+-     * at the end if necessary, but unused constant pool entries <i>won't be
+-     * removed</i>.</li> <li>Methods that are not transformed are copied as
+-     * is in the new class, directly from the original class bytecode (i.e.
+-     * without emitting visit events for all the method instructions), which
+-     * saves a <i>lot</i> of time. Untransformed methods are detected by the
+-     * fact that the {@link ClassReader} receives {@link MethodVisitor} objects
+-     * that come from a {@link ClassWriter} (and not from a custom
+-     * {@link ClassAdapter} or any other {@link ClassVisitor} instance).</li>
+-     * </ul>
+-     *
+-     * @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. 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 interface
+-    // ------------------------------------------------------------------------
+-
+-    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 = newClass(name);
+-        thisName = name;
+-        if (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]);
+-            }
+-        }
+-    }
+-
+-    public void visitSource(final String file, final String debug) {
+-        if (file != null) {
+-            sourceFile = newUTF8(file);
+-        }
+-        if (debug != null) {
+-            sourceDebug = new ByteVector().putUTF8(debug);
+-        }
+-    }
+-
+-    public void visitOuterClass(
+-            final String owner,
+-            final String name,
+-            final String desc) {
+-        enclosingMethodOwner = newClass(owner);
+-        if (name != null && desc != null) {
+-            enclosingMethod = newNameType(name, desc);
+-        }
+-    }
+-
+-    public AnnotationVisitor visitAnnotation(
+-            final String desc,
+-            final boolean visible) {
+-        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;
+-    }
+-
+-    public void visitAttribute(final Attribute attr) {
+-        attr.next = attrs;
+-        attrs = attr;
+-    }
+-
+-    public void visitInnerClass(
+-            final String name,
+-            final String outerName,
+-            final String innerName,
+-            final int access) {
+-        if (innerClasses == null) {
+-            innerClasses = new ByteVector();
+-        }
+-        ++innerClassesCount;
+-        innerClasses.putShort(name == null ? 0 : newClass(name));
+-        innerClasses.putShort(outerName == null ? 0 : newClass(outerName));
+-        innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName));
+-        innerClasses.putShort(access);
+-    }
+-
+-    public 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);
+-    }
+-
+-    public 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);
+-    }
+-
+-    public 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() {
+-        // 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 = fb.next;
+-        }
+-        int nbMethods = 0;
+-        MethodWriter mb = firstMethod;
+-        while (mb != null) {
+-            ++nbMethods;
+-            size += mb.getSize();
+-            mb = mb.next;
+-        }
+-        int attributeCount = 0;
+-        if (signature != 0) {
+-            ++attributeCount;
+-            size += 8;
+-            newUTF8("Signature");
+-        }
+-        if (sourceFile != 0) {
+-            ++attributeCount;
+-            size += 8;
+-            newUTF8("SourceFile");
+-        }
+-        if (sourceDebug != null) {
+-            ++attributeCount;
+-            size += sourceDebug.length + 4;
+-            newUTF8("SourceDebugExtension");
+-        }
+-        if (enclosingMethodOwner != 0) {
+-            ++attributeCount;
+-            size += 10;
+-            newUTF8("EnclosingMethod");
+-        }
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            ++attributeCount;
+-            size += 6;
+-            newUTF8("Deprecated");
+-        }
+-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
+-                && (version & 0xffff) < Opcodes.V1_5) {
+-            ++attributeCount;
+-            size += 6;
+-            newUTF8("Synthetic");
+-        }
+-        if (innerClasses != null) {
+-            ++attributeCount;
+-            size += 8 + innerClasses.length;
+-            newUTF8("InnerClasses");
+-        }
+-        if (anns != null) {
+-            ++attributeCount;
+-            size += 8 + anns.getSize();
+-            newUTF8("RuntimeVisibleAnnotations");
+-        }
+-        if (ianns != null) {
+-            ++attributeCount;
+-            size += 8 + ianns.getSize();
+-            newUTF8("RuntimeInvisibleAnnotations");
+-        }
+-        if (attrs != null) {
+-            attributeCount += attrs.getCount();
+-            size += attrs.getSize(this, null, 0, -1, -1);
+-        }
+-        size += pool.length;
+-        // allocates a byte vector of this size, in order to avoid unnecessary
+-        // arraycopy operations in the ByteVector.enlarge() method
+-        ByteVector out = new ByteVector(size);
+-        out.putInt(0xCAFEBABE).putInt(version);
+-        out.putShort(index).putByteArray(pool.data, 0, pool.length);
+-        out.putShort(access).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 = fb.next;
+-        }
+-        out.putShort(nbMethods);
+-        mb = firstMethod;
+-        while (mb != null) {
+-            mb.put(out);
+-            mb = mb.next;
+-        }
+-        out.putShort(attributeCount);
+-        if (signature != 0) {
+-            out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
+-        }
+-        if (sourceFile != 0) {
+-            out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile);
+-        }
+-        if (sourceDebug != null) {
+-            int len = sourceDebug.length - 2;
+-            out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
+-            out.putByteArray(sourceDebug.data, 2, len);
+-        }
+-        if (enclosingMethodOwner != 0) {
+-            out.putShort(newUTF8("EnclosingMethod")).putInt(4);
+-            out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
+-        }
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            out.putShort(newUTF8("Deprecated")).putInt(0);
+-        }
+-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
+-                && (version & 0xffff) < Opcodes.V1_5) {
+-            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 (anns != null) {
+-            out.putShort(newUTF8("RuntimeVisibleAnnotations"));
+-            anns.put(out);
+-        }
+-        if (ianns != null) {
+-            out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
+-            ianns.put(out);
+-        }
+-        if (attrs != null) {
+-            attrs.put(this, null, 0, -1, -1, out);
+-        }
+-        if (invalidFrames) {
+-            ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
+-            new ClassReader(out.data).accept(cw, ClassReader.SKIP_FRAMES);
+-            return cw.toByteArray();
+-        }
+-        return out.data;
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods: constant pool management
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Adds a number or string constant to the constant pool of the class being
+-     * build. Does nothing if the constant pool already contains a similar item.
+-     *
+-     * @param cst the value of the constant to be added to the constant pool.
+-     *            This parameter must be an {@link Integer}, a {@link Float}, a
+-     *            {@link Long}, a {@link Double}, a {@link String} or a
+-     *            {@link Type}.
+-     * @return a new or already existing constant item with the given value.
+-     */
+-    Item newConstItem(final Object cst) {
+-        if (cst instanceof Integer) {
+-            int val = ((Integer) cst).intValue();
+-            return newInteger(val);
+-        }
+-        else if (cst instanceof Byte) {
+-            int val = ((Byte) cst).intValue();
+-            return newInteger(val);
+-        }
+-        else if (cst instanceof Character) {
+-            int val = ((Character) cst).charValue();
+-            return newInteger(val);
+-        }
+-        else if (cst instanceof Short) {
+-            int val = ((Short) cst).intValue();
+-            return newInteger(val);
+-        }
+-        else if (cst instanceof Boolean) {
+-            int val = ((Boolean) cst).booleanValue() ? 1 : 0;
+-            return newInteger(val);
+-        }
+-        else if (cst instanceof Float) {
+-            float val = ((Float) cst).floatValue();
+-            return newFloat(val);
+-        }
+-        else if (cst instanceof Long) {
+-            long val = ((Long) cst).longValue();
+-            return newLong(val);
+-        }
+-        else if (cst instanceof Double) {
+-            double val = ((Double) cst).doubleValue();
+-            return newDouble(val);
+-        }
+-        else if (cst instanceof String) {
+-            return newString((String) cst);
+-        }
+-        else if (cst instanceof Type) {
+-            Type t = (Type) cst;
+-            return newClassItem(t.getSort() == Type.OBJECT
+-                    ? t.getInternalName()
+-                    : t.getDescriptor());
+-        }
+-        else {
+-            throw new IllegalArgumentException("value " + cst);
+-        }
+-    }
+-
+-    /**
+-     * Adds a number or string constant to the constant pool of the class being
+-     * build. Does nothing if the constant pool already contains a similar item.
+-     * <i>This method is intended for {@link Attribute} sub classes, and is
+-     * normally not needed by class generators or adapters.</i>
+-     *
+-     * @param cst the value of the constant to be added to the constant pool.
+-     *            This parameter must be an {@link Integer}, a {@link Float}, a
+-     *            {@link Long}, a {@link Double} or a {@link String}.
+-     * @return the index of a new or already existing constant item with the
+-     *         given value.
+-     */
+-    public int newConst(final Object cst) {
+-        return newConstItem(cst).index;
+-    }
+-
+-    /**
+-     * Adds an UTF8 string to the constant pool of the class being build. Does
+-     * nothing if the constant pool already contains a similar item. <i>This
+-     * method is intended for {@link Attribute} sub classes, and is normally not
+-     * needed by class generators or adapters.</i>
+-     *
+-     * @param value the String value.
+-     * @return the index of a new or already existing UTF8 item.
+-     */
+-    public int newUTF8(final String value) {
+-        key.set(UTF8, value, null, null);
+-        Item result = get(key);
+-        if (result == null) {
+-            pool.putByte(UTF8).putUTF8(value);
+-            result = new Item(index++, key);
+-            put(result);
+-        }
+-        return result.index;
+-    }
+-
+-    /**
+-     * Adds a class reference to the constant pool of the class being build.
+-     * Does nothing if the constant pool already contains a similar item.
+-     * <i>This method is intended for {@link Attribute} sub classes, and is
+-     * normally not needed by class generators or adapters.</i>
+-     *
+-     * @param value the internal name of the class.
+-     * @return a new or already existing class reference item.
+-     */
+-    Item newClassItem(final String value) {
+-        key2.set(CLASS, value, null, null);
+-        Item result = get(key2);
+-        if (result == null) {
+-            pool.put12(CLASS, newUTF8(value));
+-            result = new Item(index++, key2);
+-            put(result);
+-        }
+-        return result;
+-    }
+-
+-    /**
+-     * Adds a class reference to the constant pool of the class being build.
+-     * Does nothing if the constant pool already contains a similar item.
+-     * <i>This method is intended for {@link Attribute} sub classes, and is
+-     * normally not needed by class generators or adapters.</i>
+-     *
+-     * @param value the internal name of the class.
+-     * @return the index of a new or already existing class reference item.
+-     */
+-    public int newClass(final String value) {
+-        return newClassItem(value).index;
+-    }
+-
+-    /**
+-     * Adds a field reference to the constant pool of the class being build.
+-     * Does nothing if the constant pool already contains a similar item.
+-     *
+-     * @param owner the internal name of the field's owner class.
+-     * @param name  the field's name.
+-     * @param desc  the field's descriptor.
+-     * @return a new or already existing field reference item.
+-     */
+-    Item newFieldItem(final String owner, final String name, final String desc) {
+-        key3.set(FIELD, owner, name, desc);
+-        Item result = get(key3);
+-        if (result == null) {
+-            put122(FIELD, newClass(owner), newNameType(name, desc));
+-            result = new Item(index++, key3);
+-            put(result);
+-        }
+-        return result;
+-    }
+-
+-    /**
+-     * Adds a field reference to the constant pool of the class being build.
+-     * Does nothing if the constant pool already contains a similar item.
+-     * <i>This method is intended for {@link Attribute} sub classes, and is
+-     * normally not needed by class generators or adapters.</i>
+-     *
+-     * @param owner the internal name of the field's owner class.
+-     * @param name  the field's name.
+-     * @param desc  the field's descriptor.
+-     * @return the index of a new or already existing field reference item.
+-     */
+-    public int newField(final String owner, final String name, final String desc) {
+-        return newFieldItem(owner, name, desc).index;
+-    }
+-
+-    /**
+-     * Adds a method reference to the constant pool of the class being build.
+-     * Does nothing if the constant pool already contains a similar item.
+-     *
+-     * @param owner the internal name of the method's owner class.
+-     * @param name  the method's name.
+-     * @param desc  the method's descriptor.
+-     * @param itf   <tt>true</tt> if <tt>owner</tt> is an interface.
+-     * @return a new or already existing method reference item.
+-     */
+-    Item newMethodItem(
+-            final String owner,
+-            final String name,
+-            final String desc,
+-            final boolean itf) {
+-        int type = itf ? IMETH : METH;
+-        key3.set(type, owner, name, desc);
+-        Item result = get(key3);
+-        if (result == null) {
+-            put122(type, newClass(owner), newNameType(name, desc));
+-            result = new Item(index++, key3);
+-            put(result);
+-        }
+-        return result;
+-    }
+-
+-    /**
+-     * Adds a method reference to the constant pool of the class being build.
+-     * Does nothing if the constant pool already contains a similar item.
+-     * <i>This method is intended for {@link Attribute} sub classes, and is
+-     * normally not needed by class generators or adapters.</i>
+-     *
+-     * @param owner the internal name of the method's owner class.
+-     * @param name  the method's name.
+-     * @param desc  the method's descriptor.
+-     * @param itf   <tt>true</tt> if <tt>owner</tt> is an interface.
+-     * @return the index of a new or already existing method reference item.
+-     */
+-    public int newMethod(
+-            final String owner,
+-            final String name,
+-            final String desc,
+-            final boolean itf) {
+-        return newMethodItem(owner, name, desc, itf).index;
+-    }
+-
+-    /**
+-     * Adds an integer to the constant pool of the class being build. Does
+-     * nothing if the constant pool already contains a similar item.
+-     *
+-     * @param value the int value.
+-     * @return a new or already existing int item.
+-     */
+-    Item newInteger(final int value) {
+-        key.set(value);
+-        Item result = get(key);
+-        if (result == null) {
+-            pool.putByte(INT).putInt(value);
+-            result = new Item(index++, key);
+-            put(result);
+-        }
+-        return result;
+-    }
+-
+-    /**
+-     * Adds a float to the constant pool of the class being build. Does nothing
+-     * if the constant pool already contains a similar item.
+-     *
+-     * @param value the float value.
+-     * @return a new or already existing float item.
+-     */
+-    Item newFloat(final float value) {
+-        key.set(value);
+-        Item result = get(key);
+-        if (result == null) {
+-            pool.putByte(FLOAT).putInt(key.intVal);
+-            result = new Item(index++, key);
+-            put(result);
+-        }
+-        return result;
+-    }
+-
+-    /**
+-     * Adds a long to the constant pool of the class being build. Does nothing
+-     * if the constant pool already contains a similar item.
+-     *
+-     * @param value the long value.
+-     * @return a new or already existing long item.
+-     */
+-    Item newLong(final long value) {
+-        key.set(value);
+-        Item result = get(key);
+-        if (result == null) {
+-            pool.putByte(LONG).putLong(value);
+-            result = new Item(index, key);
+-            put(result);
+-            index += 2;
+-        }
+-        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);
+-            put(result);
+-            index += 2;
+-        }
+-        return result;
+-    }
+-
+-    /**
+-     * Adds a string to the constant pool of the class being build. Does nothing
+-     * if the constant pool already contains a similar item.
+-     *
+-     * @param value the String value.
+-     * @return a new or already existing string item.
+-     */
+-    private Item newString(final String value) {
+-        key2.set(STR, value, null, null);
+-        Item result = get(key2);
+-        if (result == null) {
+-            pool.put12(STR, newUTF8(value));
+-            result = new Item(index++, key2);
+-            put(result);
+-        }
+-        return result;
+-    }
+-
+-    /**
+-     * Adds a name and type to the constant pool of the class being build. Does
+-     * nothing if the constant pool already contains a similar item. <i>This
+-     * method is intended for {@link Attribute} sub classes, and is normally not
+-     * needed by class generators or adapters.</i>
+-     *
+-     * @param name a name.
+-     * @param desc a type descriptor.
+-     * @return the index of a new or already existing name and type item.
+-     */
+-    public int newNameType(final String name, final String desc) {
+-        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.index;
+-    }
+-
+-    /**
+-     * Adds the given internal name to {@link #typeTable} and returns its index.
+-     * Does nothing if the type table already contains this internal name.
+-     *
+-     * @param type the internal name to be added to the type table.
+-     * @return the index of this internal name in the type table.
+-     */
+-    int addType(final String type) {
+-        key.set(TYPE_NORMAL, type, null, null);
+-        Item result = get(key);
+-        if (result == null) {
+-            result = addType(key);
+-        }
+-        return result.index;
+-    }
+-
+-    /**
+-     * Adds the given "uninitialized" type to {@link #typeTable} and returns its
+-     * index. This method is used for UNINITIALIZED types, made of an internal
+-     * name and a bytecode offset.
+-     *
+-     * @param type   the internal name to be added to the type table.
+-     * @param offset the bytecode offset of the NEW instruction that created
+-     *               this UNINITIALIZED type value.
+-     * @return the index of this internal name in the type table.
+-     */
+-    int addUninitializedType(final String type, final int offset) {
+-        key.type = TYPE_UNINIT;
+-        key.intVal = offset;
+-        key.strVal1 = type;
+-        key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset);
+-        Item result = get(key);
+-        if (result == null) {
+-            result = addType(key);
+-        }
+-        return result.index;
+-    }
+-
+-    /**
+-     * Adds the given Item to {@link #typeTable}.
+-     *
+-     * @param item the value to be added to the type table.
+-     * @return the added Item, which a new Item instance with the same value as
+-     *         the given Item.
+-     */
+-    private Item addType(final Item item) {
+-        ++typeCount;
+-        Item result = new Item(typeCount, key);
+-        put(result);
+-        if (typeTable == null) {
+-            typeTable = new Item[16];
+-        }
+-        if (typeCount == typeTable.length) {
+-            Item[] newTable = new Item[2 * typeTable.length];
+-            System.arraycopy(typeTable, 0, newTable, 0, typeTable.length);
+-            typeTable = newTable;
+-        }
+-        typeTable[typeCount] = result;
+-        return result;
+-    }
+-
+-    /**
+-     * Returns the index of the common super type of the two given types. This
+-     * method calls {@link #getCommonSuperClass} and caches the result in the
+-     * {@link #items} hash table to speedup future calls with the same
+-     * parameters.
+-     *
+-     * @param type1 index of an internal name in {@link #typeTable}.
+-     * @param type2 index of an internal name in {@link #typeTable}.
+-     * @return the index of the common super type of the two given types.
+-     */
+-    int getMergedType(final int type1, final int type2) {
+-        key2.type = TYPE_MERGED;
+-        key2.longVal = type1 | (((long) type2) << 32);
+-        key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2);
+-        Item result = get(key2);
+-        if (result == null) {
+-            String t = typeTable[type1].strVal1;
+-            String u = typeTable[type2].strVal1;
+-            key2.intVal = addType(getCommonSuperClass(t, u));
+-            result = new Item((short) 0, key2);
+-            put(result);
+-        }
+-        return result.intVal;
+-    }
+-
+-    /**
+-     * Returns the common super type of the two given types. The default
+-     * implementation of this method <i>loads<i> the two given classes and uses
+-     * the java.lang.Class methods to find the common super class. It can be
+-     * overriden 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;
+-        try {
+-            c = Thread.currentThread().getContextClassLoader().loadClass(type1.replace('/', '.'));
+-            d = Thread.currentThread().getContextClassLoader().loadClass(type2.replace('/', '.'));
+-        }
+-        catch (ClassNotFoundException e) {
+-            throw new RuntimeException(e);
+-        }
+-        if (c.isAssignableFrom(d)) {
+-            return type1;
+-        }
+-        if (d.isAssignableFrom(c)) {
+-            return type2;
+-        }
+-        if (c.isInterface() || d.isInterface()) {
+-            return "java/lang/Object";
+-        }
+-        else {
+-            do {
+-                c = c.getSuperclass();
+-            }
+-            while (!c.isAssignableFrom(d));
+-            return c.getName().replace('.', '/');
+-        }
+-    }
+-
+-    /**
+-     * Returns the constant pool's hash table item which is equal to the given
+-     * item.
+-     *
+-     * @param key a constant pool item.
+-     * @return the constant pool's hash table item which is equal to the given
+-     *         item, or <tt>null</tt> if there is no such item.
+-     */
+-    private Item get(final Item key) {
+-        Item i = items[key.hashCode % items.length];
+-        while (i != null && !key.isEqualTo(i)) {
+-            i = i.next;
+-        }
+-        return i;
+-    }
+-
+-    /**
+-     * Puts the given item in the constant pool's hash table. The hash table
+-     * <i>must</i> not already contains this item.
+-     *
+-     * @param i the item to be added to the constant pool's hash table.
+-     */
+-    private void put(final Item i) {
+-        if (index > 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);
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/Edge.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Edge.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/Edge.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/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-2005 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.
+-     */
+-    final static 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.
+-     */
+-    final static 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 ast 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 ast. 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 ast of the basic ast from which this edge originates.
+-     */
+-    Label successor;
+-
+-    /**
+-     * The next edge in the list of successors of the originating basic ast.
+-     * See {@link Label#successors successors}.
+-     */
+-    Edge next;
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/FieldVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/FieldVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/FieldVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/FieldVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,64 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 interface must be called
+- * in the following order: ( <tt>visitAnnotation</tt> |
+- * <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
+- *
+- * @author Eric Bruneton
+- */
+-public interface FieldVisitor {
+-
+-    /**
+-     * Visits an annotation of the field.
+-     *
+-     * @param desc    the class descriptor of the annotation class.
+-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+-     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+-     *         this visitor is not interested in visiting this annotation.
+-     */
+-    AnnotationVisitor visitAnnotation(String desc, boolean visible);
+-
+-    /**
+-     * Visits a non standard attribute of the field.
+-     *
+-     * @param attr an attribute.
+-     */
+-    void visitAttribute(Attribute attr);
+-
+-    /**
+-     * Visits the end of the field. This method, which is the last one to be
+-     * called, is used to inform the visitor that all the annotations and
+-     * attributes of the field have been visited.
+-     */
+-    void visitEnd();
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/FieldWriter.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/FieldWriter.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/FieldWriter.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/FieldWriter.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,263 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 implements FieldVisitor {
+-
+-    /**
+-     * Next field writer (see {@link ClassWriter#firstField firstField}).
+-     */
+-    FieldWriter next;
+-
+-    /**
+-     * The class writer to which this field must be added.
+-     */
+-    private ClassWriter cw;
+-
+-    /**
+-     * Access flags of this field.
+-     */
+-    private int access;
+-
+-    /**
+-     * The index of the constant pool item that contains the name of this
+-     * method.
+-     */
+-    private int name;
+-
+-    /**
+-     * The index of the constant pool item that contains the descriptor of this
+-     * field.
+-     */
+-    private int desc;
+-
+-    /**
+-     * The index of the constant pool item that contains the signature of this
+-     * field.
+-     */
+-    private int signature;
+-
+-    /**
+-     * The index of the constant pool item that contains the constant value of
+-     * this field.
+-     */
+-    private int value;
+-
+-    /**
+-     * The runtime visible annotations of this field. May be <tt>null</tt>.
+-     */
+-    private AnnotationWriter anns;
+-
+-    /**
+-     * The runtime invisible annotations of this field. May be <tt>null</tt>.
+-     */
+-    private AnnotationWriter ianns;
+-
+-    /**
+-     * The non standard attributes of this field. May be <tt>null</tt>.
+-     */
+-    private Attribute attrs;
+-
+-    // ------------------------------------------------------------------------
+-    // Constructor
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Constructs a new {@link FieldWriter}.
+-     *
+-     * @param cw        the class writer to which this field must be added.
+-     * @param access    the field's access flags (see {@link Opcodes}).
+-     * @param name      the field's name.
+-     * @param desc      the field's descriptor (see {@link Type}).
+-     * @param signature the field's signature. May be <tt>null</tt>.
+-     * @param value     the field's constant value. May be <tt>null</tt>.
+-     */
+-    protected FieldWriter(
+-            final ClassWriter cw,
+-            final int access,
+-            final String name,
+-            final String desc,
+-            final String signature,
+-            final Object value) {
+-        if (cw.firstField == null) {
+-            cw.firstField = this;
+-        }
+-        else {
+-            cw.lastField.next = this;
+-        }
+-        cw.lastField = this;
+-        this.cw = cw;
+-        this.access = access;
+-        this.name = cw.newUTF8(name);
+-        this.desc = cw.newUTF8(desc);
+-        if (signature != null) {
+-            this.signature = cw.newUTF8(signature);
+-        }
+-        if (value != null) {
+-            this.value = cw.newConstItem(value).index;
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Implementation of the FieldVisitor interface
+-    // ------------------------------------------------------------------------
+-
+-    public AnnotationVisitor visitAnnotation(
+-            final String desc,
+-            final boolean visible) {
+-        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;
+-    }
+-
+-    public void visitAttribute(final Attribute attr) {
+-        attr.next = attrs;
+-        attrs = attr;
+-    }
+-
+-    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
+-                && (cw.version & 0xffff) < Opcodes.V1_5) {
+-            cw.newUTF8("Synthetic");
+-            size += 6;
+-        }
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            cw.newUTF8("Deprecated");
+-            size += 6;
+-        }
+-        if (signature != 0) {
+-            cw.newUTF8("Signature");
+-            size += 8;
+-        }
+-        if (anns != null) {
+-            cw.newUTF8("RuntimeVisibleAnnotations");
+-            size += 8 + anns.getSize();
+-        }
+-        if (ianns != null) {
+-            cw.newUTF8("RuntimeInvisibleAnnotations");
+-            size += 8 + ianns.getSize();
+-        }
+-        if (attrs != null) {
+-            size += attrs.getSize(cw, null, 0, -1, -1);
+-        }
+-        return size;
+-    }
+-
+-    /**
+-     * Puts the content of this field into the given byte vector.
+-     *
+-     * @param out where the content of this field must be put.
+-     */
+-    void put(final ByteVector out) {
+-        out.putShort(access).putShort(name).putShort(desc);
+-        int attributeCount = 0;
+-        if (value != 0) {
+-            ++attributeCount;
+-        }
+-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
+-                && (cw.version & 0xffff) < Opcodes.V1_5) {
+-            ++attributeCount;
+-        }
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            ++attributeCount;
+-        }
+-        if (signature != 0) {
+-            ++attributeCount;
+-        }
+-        if (anns != null) {
+-            ++attributeCount;
+-        }
+-        if (ianns != null) {
+-            ++attributeCount;
+-        }
+-        if (attrs != null) {
+-            attributeCount += attrs.getCount();
+-        }
+-        out.putShort(attributeCount);
+-        if (value != 0) {
+-            out.putShort(cw.newUTF8("ConstantValue"));
+-            out.putInt(2).putShort(value);
+-        }
+-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
+-                && (cw.version & 0xffff) < Opcodes.V1_5) {
+-            out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+-        }
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            out.putShort(cw.newUTF8("Deprecated")).putInt(0);
+-        }
+-        if (signature != 0) {
+-            out.putShort(cw.newUTF8("Signature"));
+-            out.putInt(2).putShort(signature);
+-        }
+-        if (anns != null) {
+-            out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
+-            anns.put(out);
+-        }
+-        if (ianns != null) {
+-            out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
+-            ianns.put(out);
+-        }
+-        if (attrs != null) {
+-            attrs.put(cw, null, 0, -1, -1, out);
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/Frame.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Frame.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/Frame.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Frame.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1421 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 ast.
+- *
+- * @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 ast 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 ast, i.e. the stack map
+-     * frame at the begining of the basic ast, starting from the input frame
+-     * of the first basic ast (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.
+-     * 
+-     * OutputAppender stack map frames are computed relatively to the input frame of the
+-     * basic ast, which is not yet known when output frames are computed. It
+-     * is therefore necessary to be able to represent abstract types such as
+-     * "the type at position x in the input frame locals" or "the type at
+-     * position x from the top of the input frame stack" or even "the type at
+-     * position x in the input frame, with y more (or less) array dimensions".
+-     * This explains the rather complicated type format used in output frames.
+-     * 
+-     * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a
+-     * signed number of array dimensions (from -8 to 7). KIND is either BASE,
+-     * LOCAL or STACK. BASE is used for types that are not relative to the input
+-     * frame. LOCAL is used for types that are relative to the input local
+-     * variable types. STACK is used for types that are relative to the input
+-     * stack types. VALUE depends on KIND. For LOCAL types, it is an index in
+-     * the input local variable types. For STACK types, it is a position
+-     * relatively to the top of input frame stack. For BASE types, it is either
+-     * one of the constants defined in FrameVisitor, or for OBJECT and
+-     * UNINITIALIZED types, a tag and an index in the type table.
+-     * 
+-     * OutputAppender 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.
+-     */
+-    final static int DIM = 0xF0000000;
+-
+-    /**
+-     * Constant to be added to a type to get a type with one more dimension.
+-     */
+-    final static int ARRAY_OF = 0x10000000;
+-
+-    /**
+-     * Constant to be added to a type to get a type with one less dimension.
+-     */
+-    final static int ELEMENT_OF = 0xF0000000;
+-
+-    /**
+-     * Mask to get the kind of a frame type.
+-     *
+-     * @see #BASE
+-     * @see #LOCAL
+-     * @see #STACK
+-     */
+-    final static int KIND = 0xF000000;
+-
+-    /**
+-     * Mask to get the value of a frame type.
+-     */
+-    final static int VALUE = 0xFFFFFF;
+-
+-    /**
+-     * Mask to get the kind of base types.
+-     */
+-    final static int BASE_KIND = 0xFF00000;
+-
+-    /**
+-     * Mask to get the value of base types.
+-     */
+-    final static int BASE_VALUE = 0xFFFFF;
+-
+-    /**
+-     * Kind of the types that are not relative to an input stack map frame.
+-     */
+-    final static int BASE = 0x1000000;
+-
+-    /**
+-     * Base kind of the base reference types. The BASE_VALUE of such types is an
+-     * index into the type table.
+-     */
+-    final static 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).
+-     */
+-    final static 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 final static 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 final static int STACK = 0x3000000;
+-
+-    /**
+-     * The TOP type. This is a BASE type.
+-     */
+-    final static int TOP = BASE | 0;
+-
+-    /**
+-     * The BOOLEAN type. This is a BASE type mainly used for array types.
+-     */
+-    final static int BOOLEAN = BASE | 9;
+-
+-    /**
+-     * The BYTE type. This is a BASE type mainly used for array types.
+-     */
+-    final static int BYTE = BASE | 10;
+-
+-    /**
+-     * The CHAR type. This is a BASE type mainly used for array types.
+-     */
+-    final static int CHAR = BASE | 11;
+-
+-    /**
+-     * The SHORT type. This is a BASE type mainly used for array types.
+-     */
+-    final static int SHORT = BASE | 12;
+-
+-    /**
+-     * The INTEGER type. This is a BASE type.
+-     */
+-    final static int INTEGER = BASE | 1;
+-
+-    /**
+-     * The FLOAT type. This is a BASE type.
+-     */
+-    final static int FLOAT = BASE | 2;
+-
+-    /**
+-     * The DOUBLE type. This is a BASE type.
+-     */
+-    final static int DOUBLE = BASE | 3;
+-
+-    /**
+-     * The LONG type. This is a BASE type.
+-     */
+-    final static int LONG = BASE | 4;
+-
+-    /**
+-     * The NULL type. This is a BASE type.
+-     */
+-    final static int NULL = BASE | 5;
+-
+-    /**
+-     * The UNINITIALIZED_THIS type. This is a BASE type.
+-     */
+-    final static 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.
+-     */
+-    final static 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, //UNUSED, // NOT VISITED
+-        // 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 ast) 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.
+-     * <p/>
+-     * 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.
+-     * <p/>
+-     * 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 ast.
+-     *
+-     * @see #initializations
+-     */
+-    private int initializationCount;
+-
+-    /**
+-     * The types that are initialized in the basic ast. A constructor
+-     * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace
+-     * <i>every occurence</i> of this type in the local variables and in the
+-     * operand stack. This cannot be done during the first phase of the
+-     * algorithm since, during this phase, the local variables and the operand
+-     * stack are not completely computed. It is therefore necessary to store the
+-     * types on which constructors are invoked in the basic ast, 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 ast,
+-            // 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 ast,
+-                // 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 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((MethodWriter.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 ast.
+-     *
+-     * @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 ast.
+-     *
+-     * @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 ast, 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 ast 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:
+-                    default:
+-                        push(OBJECT | cw.addType("java/lang/String"));
+-                }
+-                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);
+-                    }
+-                }
+-                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);
+-                    }
+-                }
+-                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.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 ast with the input and output
+-     * frames of this basic ast. Returns <tt>true</tt> if the input frame of
+-     * the given label has been changed by this operation.
+-     *
+-     * @param cw    the ClassWriter to which this label belongs.
+-     * @param frame the basic ast whose input frame must be updated.
+-     * @param edge  the kind of the {@link Edge} between this label and 'label'.
+-     *              See {@link Edge#info}.
+-     * @return <tt>true</tt> if the input frame of the given label has been
+-     *         changed by this operation.
+-     */
+-    boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
+-        boolean changed = false;
+-        int i, s, dim, kind, t;
+-
+-        int nLocal = inputLocals.length;
+-        int nStack = inputStack.length;
+-        if (frame.inputLocals == null) {
+-            frame.inputLocals = new int[nLocal];
+-            changed = true;
+-        }
+-
+-        for (i = 0; i < nLocal; ++i) {
+-            if (outputLocals != null && i < outputLocals.length) {
+-                s = outputLocals[i];
+-                if (s == 0) {
+-                    t = inputLocals[i];
+-                }
+-                else {
+-                    dim = s & DIM;
+-                    kind = s & KIND;
+-                    if (kind == LOCAL) {
+-                        t = dim + inputLocals[s & VALUE];
+-                    }
+-                    else if (kind == STACK) {
+-                        t = dim + inputStack[nStack - (s & VALUE)];
+-                    }
+-                    else {
+-                        t = s;
+-                    }
+-                }
+-            }
+-            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 == LOCAL) {
+-                t = dim + inputLocals[s & VALUE];
+-            }
+-            else if (kind == STACK) {
+-                t = dim + inputStack[nStack - (s & VALUE)];
+-            }
+-            else {
+-                t = s;
+-            }
+-            if (initializations != null) {
+-                t = init(cw, t);
+-            }
+-            changed |= merge(cw, t, frame.inputStack, nInputStack + i);
+-        }
+-        return changed;
+-    }
+-
+-    /**
+-     * Merges the type at the given index in the given type array with the given
+-     * type. Returns <tt>true</tt> if the type array has been modified by this
+-     * operation.
+-     *
+-     * @param cw    the ClassWriter to which this label belongs.
+-     * @param t     the type with which the type array element must be merged.
+-     * @param types an array of types.
+-     * @param index the index of the type that must be merged in 'types'.
+-     * @return <tt>true</tt> if the type array has been modified by this
+-     *         operation.
+-     */
+-    private boolean merge(
+-            final ClassWriter cw,
+-            int t,
+-            final int[] types,
+-            final int index) {
+-        int u = types[index];
+-        if (u == t) {
+-            // if the types are equal, merge(u,t)=u, so there is no change
+-            return false;
+-        }
+-        if ((t & ~DIM) == NULL) {
+-            if (u == NULL) {
+-                return false;
+-            }
+-            t = NULL;
+-        }
+-        if (u == 0) {
+-            // if types[index] has never been assigned, merge(u,t)=t
+-            types[index] = t;
+-            return true;
+-        }
+-        int v;
+-        if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) {
+-            // if u is a reference type of any dimension
+-            if (t == NULL) {
+-                // if t is the NULL type, merge(u,t)=u, so there is no change
+-                return false;
+-            }
+-            else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) {
+-                if ((u & BASE_KIND) == OBJECT) {
+-                    // if t is also a reference type, and if u and t have the
+-                    // same dimension merge(u,t) = dim(t) | common parent of the
+-                    // element types of u and t
+-                    v = (t & DIM) | OBJECT
+-                            | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE);
+-                }
+-                else {
+-                    // if u and t are array types, but not with the same element
+-                    // type, merge(u,t)=java/lang/Object
+-                    v = OBJECT | cw.addType("java/lang/Object");
+-                }
+-            }
+-            else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) {
+-                // if t is any other reference or array type,
+-                // merge(u,t)=java/lang/Object
+-                v = OBJECT | cw.addType("java/lang/Object");
+-            }
+-            else {
+-                // if t is any other type, merge(u,t)=TOP
+-                v = TOP;
+-            }
+-        }
+-        else if (u == NULL) {
+-            // if u is the NULL type, merge(u,t)=t,
+-            // or TOP if t is not a reference type
+-            v = (t & BASE_KIND) == OBJECT || (t & DIM) != 0 ? t : TOP;
+-        }
+-        else {
+-            // if u is any other type, merge(u,t)=TOP whatever t
+-            v = TOP;
+-        }
+-        if (u != v) {
+-            types[index] = v;
+-            return true;
+-        }
+-        return false;
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/Handler.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Handler.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/Handler.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Handler.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,70 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 ast.
+- *
+- * @author Eric Bruneton
+- */
+-class Handler {
+-
+-    /**
+-     * Beginning of the exception handler's scope (inclusive).
+-     */
+-    Label start;
+-
+-    /**
+-     * End of the exception handler's scope (exclusive).
+-     */
+-    Label end;
+-
+-    /**
+-     * Beginning of the exception handler's code.
+-     */
+-    Label handler;
+-
+-    /**
+-     * Internal name of the type of exceptions handled by this handler, or
+-     * <tt>null</tt> to catch any exceptions.
+-     */
+-    String desc;
+-
+-    /**
+-     * Constant pool index of the internal name of the type of exceptions
+-     * handled by this handler, or 0 to catch any exceptions.
+-     */
+-    int type;
+-
+-    /**
+-     * Next exception handler ast info.
+-     */
+-    Handler next;
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/Item.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Item.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/Item.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Item.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-2005 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}.
+-     * <p/>
+-     * 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.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:
+-            default:
+-                hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+-                        * strVal2.hashCode() * strVal3.hashCode());
+-        }
+-    }
+-
+-    /**
+-     * Indicates if the given item is equal to this one.
+-     *
+-     * @param i the item to be compared to this one.
+-     * @return <tt>true</tt> if the given item if equal to this one,
+-     *         <tt>false</tt> otherwise.
+-     */
+-    boolean isEqualTo(final Item i) {
+-        if (i.type == type) {
+-            switch (type) {
+-                case ClassWriter.INT:
+-                case ClassWriter.FLOAT:
+-                    return i.intVal == intVal;
+-                case ClassWriter.TYPE_MERGED:
+-                case ClassWriter.LONG:
+-                case ClassWriter.DOUBLE:
+-                    return i.longVal == longVal;
+-                case ClassWriter.UTF8:
+-                case ClassWriter.STR:
+-                case ClassWriter.CLASS:
+-                case ClassWriter.TYPE_NORMAL:
+-                    return i.strVal1.equals(strVal1);
+-                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);
+-                    // ClassWriter.FIELD:
+-                    // ClassWriter.METH:
+-                    // ClassWriter.IMETH:
+-                default:
+-                    return i.strVal1.equals(strVal1)
+-                            && i.strVal2.equals(strVal2)
+-                            && i.strVal3.equals(strVal3);
+-            }
+-        }
+-        return false;
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/Label.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Label.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/Label.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Label.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,422 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.
+- *
+- * @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 ast, the target of a jump instruction, or
+-     * an exception handler. It can be safely ignored in control flow graph
+-     * analysis algorithms (for optimization purposes).
+-     */
+-    final static int DEBUG = 1;
+-
+-    /**
+-     * Indicates if the position of this label is known.
+-     */
+-    final static int RESOLVED = 2;
+-
+-    /**
+-     * Indicates if this label has been updated, after instruction resizing.
+-     */
+-    final static int RESIZED = 4;
+-
+-    /**
+-     * Indicates if this basic ast has been pushed in the basic ast stack.
+-     * See {@link MethodWriter#visitMaxs visitMaxs}.
+-     */
+-    final static int PUSHED = 8;
+-
+-    /**
+-     * Indicates if this label is the target of a jump instruction, or the start
+-     * of an exception handler.
+-     */
+-    final static int TARGET = 16;
+-
+-    /**
+-     * Indicates if a stack map frame must be stored for this label.
+-     */
+-    final static int STORE = 32;
+-
+-    /**
+-     * Indicates if this label corresponds to a reachable basic ast.
+-     */
+-    final static int REACHABLE = 64;
+-
+-    /**
+-     * Indicates if this basic ast ends with a JSR instruction.
+-     */
+-    final static int JSR = 128;
+-
+-    /**
+-     * Indicates if this basic ast ends with a RET instruction.
+-     */
+-    final static int RET = 256;
+-
+-    /**
+-     * Field used to associate user information to a label.
+-     */
+-    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.
+-     */
+-    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 ast", and one edge per "jump"
+-     * from one basic ast to another. Each node (i.e., each basic ast) is
+-     * represented by the Label object that corresponds to the first instruction
+-     * of this basic ast. 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 ast, called the "output frame", <i>relatively</i> to the frame
+-     * state at the beginning of the basic ast, which is called the "input
+-     * frame", and which is <i>unknown</i> during this step. The second step,
+-     * in {@link MethodWriter#visitMaxs}, is a fix point algorithm that
+-     * computes information about the input frame of each basic ast, from the
+-     * input state of the first basic ast (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.
+-     * <p/>
+-     * When only the maximum stack size is computed, this field is the number of
+-     * elements in the input stack.
+-     * <p/>
+-     * 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
+-     * ast. 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 ast in the basic ast 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.
+-     *
+-     * @see MethodWriter#visitMaxs
+-     */
+-    Label next;
+-
+-    // ------------------------------------------------------------------------
+-    // Constructor
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Constructs a new label.
+-     */
+-    public Label() {
+-    }
+-
+-    /**
+-     * Constructs a new label.
+-     *
+-     * @param debug if this label is only used for debug attributes.
+-     */
+-    Label(final boolean debug) {
+-        this.status = debug ? DEBUG : 0;
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Methods to compute offsets and to manage forward references
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Returns the offset corresponding to this label. This offset is computed
+-     * from the start of the method's bytecode. <i>This method is intended for
+-     * {@link Attribute} sub classes, and is normally not needed by class
+-     * generators or adapters.</i>
+-     *
+-     * @return the offset corresponding to this label.
+-     * @throws IllegalStateException if this label is not resolved yet.
+-     */
+-    public int getOffset() {
+-        if ((status & RESOLVED) == 0) {
+-            throw new IllegalStateException("Label offset position has not been resolved yet");
+-        }
+-        return position;
+-    }
+-
+-    /**
+-     * Puts a reference to this label in the bytecode of a method. If the
+-     * position of the label is known, the offset is computed and written
+-     * directly. Otherwise, a null offset is written and a new forward reference
+-     * is declared for this label.
+-     *
+-     * @param owner      the code writer that calls this method.
+-     * @param out        the bytecode of the method.
+-     * @param source     the position of first byte of the bytecode instruction that
+-     *                   contains this label.
+-     * @param wideOffset <tt>true</tt> if the reference must be stored in 4
+-     *                   bytes, or <tt>false</tt> if it must be stored with 2 bytes.
+-     * @throws IllegalArgumentException if this label has not been created by
+-     *                                  the given code writer.
+-     */
+-    void put(
+-            final MethodWriter owner,
+-            final ByteVector out,
+-            final int source,
+-            final boolean wideOffset) {
+-        if ((status & RESOLVED) != 0) {
+-            if (wideOffset) {
+-                out.putInt(position - source);
+-            }
+-            else {
+-                out.putShort(position - source);
+-            }
+-        }
+-        else {
+-            if (wideOffset) {
+-                addReference(-1 - source, out.length);
+-                out.putInt(-1);
+-            }
+-            else {
+-                addReference(source, out.length);
+-                out.putShort(-1);
+-            }
+-        }
+-    }
+-
+-    /**
+-     * Adds a forward reference to this label. This method must be called only
+-     * for a true forward reference, i.e. only if this label is not resolved
+-     * yet. For backward references, the offset of the reference can be, and
+-     * must be, computed and stored directly.
+-     *
+-     * @param sourcePosition    the position of the referencing instruction. This
+-     *                          position will be used to compute the offset of this forward
+-     *                          reference.
+-     * @param referencePosition the position where the offset for this forward
+-     *                          reference must be stored.
+-     */
+-    private void addReference(
+-            final int sourcePosition,
+-            final int referencePosition) {
+-        if (srcAndRefPositions == null) {
+-            srcAndRefPositions = new int[6];
+-        }
+-        if (referenceCount >= srcAndRefPositions.length) {
+-            int[] a = new int[srcAndRefPositions.length + 6];
+-            System.arraycopy(srcAndRefPositions,
+-                    0,
+-                    a,
+-                    0,
+-                    srcAndRefPositions.length);
+-            srcAndRefPositions = a;
+-        }
+-        srcAndRefPositions[referenceCount++] = sourcePosition;
+-        srcAndRefPositions[referenceCount++] = referencePosition;
+-    }
+-
+-    /**
+-     * Resolves all forward references to this label. This method must be called
+-     * when this label is added to the bytecode of the method, i.e. when its
+-     * position becomes known. This method fills in the blanks that where left
+-     * in the bytecode by each forward reference previously added to this label.
+-     *
+-     * @param owner    the code writer that calls this method.
+-     * @param position the position of this label in the bytecode.
+-     * @param data     the bytecode of the method.
+-     * @return <tt>true</tt> if a blank that was left for this label was to
+-     *         small to store the offset. In such a case the corresponding jump
+-     *         instruction is replaced with a pseudo instruction (using unused
+-     *         opcodes) using an unsigned two bytes offset. These pseudo
+-     *         instructions will need to be replaced with true instructions with
+-     *         wider offsets (4 bytes instead of 2). This is done in
+-     *         {@link MethodWriter#resizeInstructions}.
+-     * @throws IllegalArgumentException if this label has already been resolved,
+-     *                                  or if it has not been created by the given code writer.
+-     */
+-    boolean resolve(
+-            final MethodWriter owner,
+-            final int position,
+-            final byte[] data) {
+-        boolean needUpdate = false;
+-        this.status |= RESOLVED;
+-        this.position = position;
+-        int i = 0;
+-        while (i < referenceCount) {
+-            int source = srcAndRefPositions[i++];
+-            int reference = srcAndRefPositions[i++];
+-            int offset;
+-            if (source >= 0) {
+-                offset = position - source;
+-                if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) {
+-                    /*
+-                     * changes the opcode of the jump instruction, in order to
+-                     * be able to find it later (see resizeInstructions in
+-                     * MethodWriter). These temporary opcodes are similar to
+-                     * jump instruction opcodes, except that the 2 bytes offset
+-                     * is unsigned (and can therefore represent values from 0 to
+-                     * 65535, which is sufficient since the size of a method is
+-                     * limited to 65535 bytes).
+-                     */
+-                    int opcode = data[reference - 1] & 0xFF;
+-                    if (opcode <= Opcodes.JSR) {
+-                        // changes IFEQ ... JSR to opcodes 202 to 217
+-                        data[reference - 1] = (byte) (opcode + 49);
+-                    }
+-                    else {
+-                        // changes IFNULL and IFNONNULL to opcodes 218 and 219
+-                        data[reference - 1] = (byte) (opcode + 20);
+-                    }
+-                    needUpdate = true;
+-                }
+-                data[reference++] = (byte) (offset >>> 8);
+-                data[reference] = (byte) offset;
+-            }
+-            else {
+-                offset = position + source + 1;
+-                data[reference++] = (byte) (offset >>> 24);
+-                data[reference++] = (byte) (offset >>> 16);
+-                data[reference++] = (byte) (offset >>> 8);
+-                data[reference] = (byte) offset;
+-            }
+-        }
+-        return needUpdate;
+-    }
+-
+-    /**
+-     * Returns the first label of the series to which this label belongs. For an
+-     * isolated label or for the first label in a series of successive labels,
+-     * this method returns the label itself. For other labels it returns the
+-     * first label of the series.
+-     *
+-     * @return the first label of the series to which this label belongs.
+-     */
+-    Label getFirst() {
+-        return frame == null ? this : frame.owner;
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Overriden Object methods
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Returns a string representation of this label.
+-     *
+-     * @return a string representation of this label.
+-     */
+-    public String toString() {
+-        return "L" + System.identityHashCode(this);
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/MethodAdapter.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/MethodAdapter.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/MethodAdapter.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/MethodAdapter.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,186 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 empty {@link MethodVisitor} that delegates to another
+- * {@link MethodVisitor}. This class can be used as a super class to quickly
+- * implement usefull method adapter classes, just by overriding the necessary
+- * methods.
+- *
+- * @author Eric Bruneton
+- */
+-public class MethodAdapter implements MethodVisitor {
+-
+-    /**
+-     * The {@link MethodVisitor} to which this adapter delegates calls.
+-     */
+-    protected MethodVisitor mv;
+-
+-    /**
+-     * Constructs a new {@link MethodAdapter} object.
+-     *
+-     * @param mv the code visitor to which this adapter must delegate calls.
+-     */
+-    public MethodAdapter(final MethodVisitor mv) {
+-        this.mv = mv;
+-    }
+-
+-    public AnnotationVisitor visitAnnotationDefault() {
+-        return mv.visitAnnotationDefault();
+-    }
+-
+-    public AnnotationVisitor visitAnnotation(
+-            final String desc,
+-            final boolean visible) {
+-        return mv.visitAnnotation(desc, visible);
+-    }
+-
+-    public AnnotationVisitor visitParameterAnnotation(
+-            final int parameter,
+-            final String desc,
+-            final boolean visible) {
+-        return mv.visitParameterAnnotation(parameter, desc, visible);
+-    }
+-
+-    public void visitAttribute(final Attribute attr) {
+-        mv.visitAttribute(attr);
+-    }
+-
+-    public void visitCode() {
+-        mv.visitCode();
+-    }
+-
+-    public void visitFrame(
+-            final int type,
+-            final int nLocal,
+-            final Object[] local,
+-            final int nStack,
+-            final Object[] stack) {
+-        mv.visitFrame(type, nLocal, local, nStack, stack);
+-    }
+-
+-    public void visitInsn(final int opcode) {
+-        mv.visitInsn(opcode);
+-    }
+-
+-    public void visitIntInsn(final int opcode, final int operand) {
+-        mv.visitIntInsn(opcode, operand);
+-    }
+-
+-    public void visitVarInsn(final int opcode, final int var) {
+-        mv.visitVarInsn(opcode, var);
+-    }
+-
+-    public void visitTypeInsn(final int opcode, final String desc) {
+-        mv.visitTypeInsn(opcode, desc);
+-    }
+-
+-    public void visitFieldInsn(
+-            final int opcode,
+-            final String owner,
+-            final String name,
+-            final String desc) {
+-        mv.visitFieldInsn(opcode, owner, name, desc);
+-    }
+-
+-    public void visitMethodInsn(
+-            final int opcode,
+-            final String owner,
+-            final String name,
+-            final String desc) {
+-        mv.visitMethodInsn(opcode, owner, name, desc);
+-    }
+-
+-    public void visitJumpInsn(final int opcode, final Label label) {
+-        mv.visitJumpInsn(opcode, label);
+-    }
+-
+-    public void visitLabel(final Label label) {
+-        mv.visitLabel(label);
+-    }
+-
+-    public void visitLdcInsn(final Object cst) {
+-        mv.visitLdcInsn(cst);
+-    }
+-
+-    public void visitIincInsn(final int var, final int increment) {
+-        mv.visitIincInsn(var, increment);
+-    }
+-
+-    public void visitTableSwitchInsn(
+-            final int min,
+-            final int max,
+-            final Label dflt,
+-            final Label labels[]) {
+-        mv.visitTableSwitchInsn(min, max, dflt, labels);
+-    }
+-
+-    public void visitLookupSwitchInsn(
+-            final Label dflt,
+-            final int keys[],
+-            final Label labels[]) {
+-        mv.visitLookupSwitchInsn(dflt, keys, labels);
+-    }
+-
+-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
+-        mv.visitMultiANewArrayInsn(desc, dims);
+-    }
+-
+-    public void visitTryCatchBlock(
+-            final Label start,
+-            final Label end,
+-            final Label handler,
+-            final String type) {
+-        mv.visitTryCatchBlock(start, end, handler, type);
+-    }
+-
+-    public void visitLocalVariable(
+-            final String name,
+-            final String desc,
+-            final String signature,
+-            final Label start,
+-            final Label end,
+-            final int index) {
+-        mv.visitLocalVariable(name, desc, signature, start, end, index);
+-    }
+-
+-    public void visitLineNumber(final int line, final Label start) {
+-        mv.visitLineNumber(line, start);
+-    }
+-
+-    public void visitMaxs(final int maxStack, final int maxLocals) {
+-        mv.visitMaxs(maxStack, maxLocals);
+-    }
+-
+-    public void visitEnd() {
+-        mv.visitEnd();
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/MethodVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/MethodVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/MethodVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/MethodVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,396 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 interface must be
+- * called in the following order: [ <tt>visitAnnotationDefault</tt> ] (
+- * <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
+- * <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
+- * <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> | <tt>visitTryCatchBlock</tt> |
+- * <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt>)* <tt>visitMaxs</tt> ]
+- * <tt>visitEnd</tt>. In addition, the <tt>visit</tt><i>X</i>Insn</tt>
+- * and <tt>visitLabel</tt> methods must be called in the sequential order of
+- * the bytecode instructions of the visited code, <tt>visitTryCatchBlock</tt>
+- * must be called <i>before</i> the labels passed as arguments have been
+- * visited, and the <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt>
+- * methods must be called <i>after</i> the labels passed as arguments have been
+- * visited.
+- *
+- * @author Eric Bruneton
+- */
+-public interface MethodVisitor {
+-
+-    // -------------------------------------------------------------------------
+-    // Annotations and non standard attributes
+-    // -------------------------------------------------------------------------
+-
+-    /**
+-     * Visits the default value of this annotation interface method.
+-     *
+-     * @return a visitor to the visit the actual default value of this
+-     *         annotation interface method, or <tt>null</tt> if this visitor
+-     *         is not interested in visiting this default value. The 'name'
+-     *         parameters passed to the methods of this annotation visitor are
+-     *         ignored. Moreover, exacly one visit method must be called on this
+-     *         annotation visitor, followed by visitEnd.
+-     */
+-    AnnotationVisitor visitAnnotationDefault();
+-
+-    /**
+-     * Visits an annotation of this method.
+-     *
+-     * @param desc    the class descriptor of the annotation class.
+-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+-     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+-     *         this visitor is not interested in visiting this annotation.
+-     */
+-    AnnotationVisitor visitAnnotation(String desc, boolean visible);
+-
+-    /**
+-     * Visits an annotation of a parameter this method.
+-     *
+-     * @param parameter the parameter index.
+-     * @param desc      the class descriptor of the annotation class.
+-     * @param visible   <tt>true</tt> if the annotation is visible at runtime.
+-     * @return a visitor to visit the annotation values, or <tt>null</tt> if
+-     *         this visitor is not interested in visiting this annotation.
+-     */
+-    AnnotationVisitor visitParameterAnnotation(
+-            int parameter,
+-            String desc,
+-            boolean visible);
+-
+-    /**
+-     * Visits a non standard attribute of this method.
+-     *
+-     * @param attr an attribute.
+-     */
+-    void visitAttribute(Attribute attr);
+-
+-    /**
+-     * Starts the visit of the method's code, if any (i.e. non abstract method).
+-     */
+-    void visitCode();
+-
+-    /**
+-     * Visits the current state of the local variables and operand stack
+-     * elements. This method must(*) be called <i>just before</i> any
+-     * instruction <b>i</b> that follows an unconditionnal branch instruction
+-     * such as GOTO or THROW, that is the target of a jump instruction, or that
+-     * starts an exception handler ast. The visited types must describe the
+-     * values of the local variables and of the operand stack elements <i>just
+-     * before</i> <b>i</b> is executed. <br> <br> (*) this is mandatory only
+-     * for classes whose version is greater than or equal to
+-     * {@link Opcodes#V1_6 V1_6}. <br> <br> Packed frames are basically
+-     * "deltas" from the state of the previous frame (very first frame is
+-     * implicitly defined by the method's parameters and access flags): <ul>
+-     * <li>{@link Opcodes#F_SAME} representing frame with exactly the same
+-     * locals as the previous frame and with the empty stack.</li> <li>{@link Opcodes#F_SAME1}
+-     * representing frame with exactly the same locals as the previous frame and
+-     * with single value on the stack (<code>nStack</code> is 1 and
+-     * <code>stack[0]</code> contains value for the type of the stack item).</li>
+-     * <li>{@link Opcodes#F_APPEND} representing frame with current locals are
+-     * the same as the locals in the previous frame, except that additional
+-     * locals are defined (<code>nLocal</code> is 1, 2 or 3 and
+-     * <code>local</code> elements contains values representing added types).</li>
+-     * <li>{@link Opcodes#F_CHOP} representing frame with current locals are
+-     * the same as the locals in the previous frame, except that the last 1-3
+-     * locals are absent and with the empty stack (<code>nLocals</code> is 1,
+-     * 2 or 3). </li> <li>{@link Opcodes#F_FULL} representing complete frame
+-     * data.</li> </li> </ul>
+-     *
+-     * @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, or type
+-     *               descriptors for array types), 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.
+-     */
+-    void visitFrame(
+-            int type,
+-            int nLocal,
+-            Object[] local,
+-            int nStack,
+-            Object[] 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.
+-     */
+-    void visitInsn(int opcode);
+-
+-    /**
+-     * Visits an instruction with a single int operand.
+-     *
+-     * @param opcode  the opcode of the instruction to be visited. This opcode is
+-     *                either BIPUSH, SIPUSH or NEWARRAY.
+-     * @param operand the operand of the instruction to be visited.<br> When
+-     *                opcode is BIPUSH, operand value should be between Byte.MIN_VALUE
+-     *                and Byte.MAX_VALUE.<br> When opcode is SIPUSH, operand value
+-     *                should be between Short.MIN_VALUE and Short.MAX_VALUE.<br> When
+-     *                opcode is NEWARRAY, operand value should be one of
+-     *                {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
+-     *                {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
+-     *                {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
+-     *                {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
+-     */
+-    void visitIntInsn(int opcode, int 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.
+-     */
+-    void visitVarInsn(int opcode, int var);
+-
+-    /**
+-     * Visits a type instruction. A type instruction is an instruction that
+-     * takes a type descriptor as parameter.
+-     *
+-     * @param opcode the opcode of the type instruction to be visited. This
+-     *               opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
+-     * @param desc   the operand of the instruction to be visited. This operand is
+-     *               must be a fully qualified class name in internal form, or the type
+-     *               descriptor of an array type (see {@link Type Type}).
+-     */
+-    void visitTypeInsn(int opcode, String desc);
+-
+-    /**
+-     * 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}).
+-     */
+-    void visitFieldInsn(int opcode, String owner, String name, String 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}).
+-     */
+-    void visitMethodInsn(int opcode, String owner, String name, String desc);
+-
+-    /**
+-     * 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.
+-     */
+-    void visitJumpInsn(int opcode, Label label);
+-
+-    /**
+-     * Visits a label. A label designates the instruction that will be visited
+-     * just after it.
+-     *
+-     * @param label a {@link Label Label} object.
+-     */
+-    void visitLabel(Label label);
+-
+-    // -------------------------------------------------------------------------
+-    // Special instructions
+-    // -------------------------------------------------------------------------
+-
+-    /**
+-     * Visits a LDC instruction.
+-     *
+-     * @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} (or a {@link Type} for
+-     *            <tt>.class</tt> constants, for classes whose version is 49.0 or
+-     *            more).
+-     */
+-    void visitLdcInsn(Object cst);
+-
+-    /**
+-     * Visits an IINC instruction.
+-     *
+-     * @param var       index of the local variable to be incremented.
+-     * @param increment amount to increment the local variable by.
+-     */
+-    void visitIincInsn(int var, int increment);
+-
+-    /**
+-     * Visits a TABLESWITCH instruction.
+-     *
+-     * @param min    the minimum key value.
+-     * @param max    the maximum key value.
+-     * @param dflt   beginning of the default handler ast.
+-     * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
+-     *               the beginning of the handler ast for the <tt>min + i</tt> key.
+-     */
+-    void visitTableSwitchInsn(int min, int max, Label dflt, Label labels[]);
+-
+-    /**
+-     * Visits a LOOKUPSWITCH instruction.
+-     *
+-     * @param dflt   beginning of the default handler ast.
+-     * @param keys   the values of the keys.
+-     * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
+-     *               the beginning of the handler ast for the <tt>keys[i]</tt> key.
+-     */
+-    void visitLookupSwitchInsn(Label dflt, int keys[], Label 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.
+-     */
+-    void visitMultiANewArrayInsn(String desc, int dims);
+-
+-    // -------------------------------------------------------------------------
+-    // Exceptions table entries, debug information, max stack and max locals
+-    // -------------------------------------------------------------------------
+-
+-    /**
+-     * Visits a try catch ast.
+-     *
+-     * @param start   beginning of the exception handler's scope (inclusive).
+-     * @param end     end of the exception handler's scope (exclusive).
+-     * @param handler beginning of the exception handler's code.
+-     * @param type    internal name of the type of exceptions handled by the
+-     *                handler, or <tt>null</tt> to catch any exceptions (for "finally"
+-     *                blocks).
+-     * @throws IllegalArgumentException if one of the labels has already been
+-     *                                  visited by this visitor (by the {@link #visitLabel visitLabel}
+-     *                                  method).
+-     */
+-    void visitTryCatchBlock(Label start, Label end, Label handler, String type);
+-
+-    /**
+-     * Visits a local variable declaration.
+-     *
+-     * @param name      the name of a local variable.
+-     * @param desc      the type descriptor of this local variable.
+-     * @param signature the type signature of this local variable. May be
+-     *                  <tt>null</tt> if the local variable type does not use generic
+-     *                  types.
+-     * @param start     the first instruction corresponding to the scope of this
+-     *                  local variable (inclusive).
+-     * @param end       the last instruction corresponding to the scope of this local
+-     *                  variable (exclusive).
+-     * @param index     the local variable's index.
+-     * @throws IllegalArgumentException if one of the labels has not already
+-     *                                  been visited by this visitor (by the
+-     *                                  {@link #visitLabel visitLabel} method).
+-     */
+-    void visitLocalVariable(
+-            String name,
+-            String desc,
+-            String signature,
+-            Label start,
+-            Label end,
+-            int index);
+-
+-    /**
+-     * Visits a line number declaration.
+-     *
+-     * @param line  a line number. This number refers to the source file from
+-     *              which the class was compiled.
+-     * @param start the first instruction corresponding to this line number.
+-     * @throws IllegalArgumentException if <tt>start</tt> has not already been
+-     *                                  visited by this visitor (by the {@link #visitLabel visitLabel}
+-     *                                  method).
+-     */
+-    void visitLineNumber(int line, Label 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.
+-     */
+-    void visitMaxs(int maxStack, int 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.
+-     */
+-    void visitEnd();
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/MethodWriter.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/MethodWriter.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/MethodWriter.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/MethodWriter.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,2691 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 implements MethodVisitor {
+-
+-    /**
+-     * Pseudo access flag used to denote constructors.
+-     */
+-    final static int ACC_CONSTRUCTOR = 262144;
+-
+-    /**
+-     * Frame has exactly the same locals as the previous stack map frame and
+-     * number of stack items is zero.
+-     */
+-    final static 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
+-     */
+-    final static int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; // to 127 (40-7f)
+-
+-    /**
+-     * Reserved for future use
+-     */
+-    final static 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;
+-     */
+-    final static 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.
+-     */
+-    final static 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;
+-     */
+-    final static 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.
+-     */
+-    final static int APPEND_FRAME = 252; // to 254 // fc-fe
+-
+-    /**
+-     * Full frame
+-     */
+-    final static 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 final static int FRAMES = 0;
+-
+-    /**
+-     * Indicates that the maximum stack size and number of local variables must
+-     * be automatically computed.
+-     *
+-     * @see #compute
+-     */
+-    private final static int MAXS = 1;
+-
+-    /**
+-     * Indicates that nothing must be automatically computed.
+-     *
+-     * @see #compute
+-     */
+-    private final static int NOTHING = 2;
+-
+-    /**
+-     * Next method writer (see {@link ClassWriter#firstMethod firstMethod}).
+-     */
+-    MethodWriter next;
+-
+-    /**
+-     * The class writer to which this method must be added.
+-     */
+-    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 int name;
+-
+-    /**
+-     * The index of the constant pool item that contains the descriptor of this
+-     * method.
+-     */
+-    private int desc;
+-
+-    /**
+-     * The descriptor of this method.
+-     */
+-    private String descriptor;
+-
+-    /**
+-     * The signature of this method.
+-     */
+-    String signature;
+-
+-    /**
+-     * If not zero, indicates that the code of this method must be copied from
+-     * the ClassReader associated to this writer in <code>cw.cr</code>. More
+-     * precisely, this field gives the index of the first byte to copied from
+-     * <code>cw.cr.b</code>.
+-     */
+-    int classReaderOffset;
+-
+-    /**
+-     * If not zero, indicates that the code of this method must be copied from
+-     * the ClassReader associated to this writer in <code>cw.cr</code>. More
+-     * precisely, this field gives the number of bytes to copied from
+-     * <code>cw.cr.b</code>.
+-     */
+-    int classReaderLength;
+-
+-    /**
+-     * Number of exceptions that can be thrown by this method.
+-     */
+-    int exceptionCount;
+-
+-    /**
+-     * The exceptions that can be thrown by this method. More precisely, this
+-     * array contains the indexes of the constant pool items that contain the
+-     * internal names of these exception classes.
+-     */
+-    int[] exceptions;
+-
+-    /**
+-     * The annotation default attribute of this method. May be <tt>null</tt>.
+-     */
+-    private ByteVector annd;
+-
+-    /**
+-     * The runtime visible annotations of this method. May be <tt>null</tt>.
+-     */
+-    private AnnotationWriter anns;
+-
+-    /**
+-     * The runtime invisible annotations of this method. May be <tt>null</tt>.
+-     */
+-    private AnnotationWriter ianns;
+-
+-    /**
+-     * The runtime visible parameter annotations of this method. May be
+-     * <tt>null</tt>.
+-     */
+-    private AnnotationWriter[] panns;
+-
+-    /**
+-     * The runtime invisible parameter annotations of this method. May be
+-     * <tt>null</tt>.
+-     */
+-    private AnnotationWriter[] ipanns;
+-
+-    /**
+-     * The 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 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;
+-
+-    /**
+-     * Index of the next element to be added in {@link #frame}.
+-     */
+-    private int frameIndex;
+-
+-    /**
+-     * The current stack map frame. The first element contains the offset of the
+-     * instruction to which the frame corresponds, the second element is the
+-     * number of locals and the third one is the number of stack elements. The
+-     * local variables start at index 3 and are followed by the operand stack
+-     * values. In summary frame[0] = offset, frame[1] = nLocal, frame[2] =
+-     * nStack, frame[3] = nLocal. All types are encoded as integers, with the
+-     * same format as the one used in {@link Label}, but limited to BASE types.
+-     */
+-    private int[] frame;
+-
+-    /**
+-     * Number of elements in the exception handler list.
+-     */
+-    private int handlerCount;
+-
+-    /**
+-     * The first element in the exception handler list.
+-     */
+-    private Handler firstHandler;
+-
+-    /**
+-     * The last element in the exception handler list.
+-     */
+-    private Handler lastHandler;
+-
+-    /**
+-     * Number of entries in the LocalVariableTable attribute.
+-     */
+-    private int localVarCount;
+-
+-    /**
+-     * The LocalVariableTable attribute.
+-     */
+-    private ByteVector localVar;
+-
+-    /**
+-     * Number of entries in the LocalVariableTypeTable attribute.
+-     */
+-    private int localVarTypeCount;
+-
+-    /**
+-     * The LocalVariableTypeTable attribute.
+-     */
+-    private ByteVector localVarType;
+-
+-    /**
+-     * Number of entries in the LineNumberTable attribute.
+-     */
+-    private int lineNumberCount;
+-
+-    /**
+-     * The LineNumberTable attribute.
+-     */
+-    private ByteVector lineNumber;
+-
+-    /**
+-     * The non standard attributes of the method's code.
+-     */
+-    private Attribute cattrs;
+-
+-    /**
+-     * Indicates if some jump instructions are too small and need to be resized.
+-     */
+-    private boolean resize;
+-
+-    /**
+-     * Indicates if the instructions contain at least one JSR instruction.
+-     */
+-    private boolean jsr;
+-
+-    // ------------------------------------------------------------------------
+-
+-    /*
+-     * Fields for the control flow graph analysis algorithm (used to compute the
+-     * maximum stack size). A control flow graph contains one node per "basic
+-     * ast", and one edge per "jump" from one basic ast to another. Each
+-     * node (i.e., each basic ast) is represented by the Label object that
+-     * corresponds to the first instruction of this basic ast. 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.
+-     */
+-    private 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
+-     * and starting with the first basic ast.
+-     */
+-    private Label labels;
+-
+-    /**
+-     * The previous basic ast.
+-     */
+-    private Label previousBlock;
+-
+-    /**
+-     * The current basic ast.
+-     */
+-    private Label currentBlock;
+-
+-    /**
+-     * The (relative) stack size after the last visited instruction. This size
+-     * is relative to the beginning of the current basic ast, i.e., the true
+-     * stack size after the last visited instruction is equal to the
+-     * {@link Label#inputStackTop beginStackSize} of the current basic ast
+-     * plus <tt>stackSize</tt>.
+-     */
+-    private int stackSize;
+-
+-    /**
+-     * The (relative) maximum stack size after the last visited instruction.
+-     * This size is relative to the beginning of the current basic ast, i.e.,
+-     * the true maximum stack size after the last visited instruction is equal
+-     * to the {@link Label#inputStackTop beginStackSize} of the current basic
+-     * ast plus <tt>stackSize</tt>.
+-     */
+-    private int maxStackSize;
+-
+-    // ------------------------------------------------------------------------
+-    // Constructor
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Constructs a new {@link MethodWriter}.
+-     *
+-     * @param cw            the class writer in which the method must be added.
+-     * @param access        the method's access flags (see {@link Opcodes}).
+-     * @param name          the method's name.
+-     * @param desc          the method's descriptor (see {@link Type}).
+-     * @param signature     the method's signature. May be <tt>null</tt>.
+-     * @param exceptions    the internal names of the method's exceptions. May be
+-     *                      <tt>null</tt>.
+-     * @param computeMaxs   <tt>true</tt> if the maximum stack size and number
+-     *                      of local variables must be automatically computed.
+-     * @param computeFrames <tt>true</tt> if the stack map tables must be
+-     *                      recomputed from scratch.
+-     */
+-    MethodWriter(
+-            final ClassWriter cw,
+-            final int access,
+-            final String name,
+-            final String desc,
+-            final String signature,
+-            final String[] exceptions,
+-            final boolean computeMaxs,
+-            final boolean computeFrames) {
+-        if (cw.firstMethod == null) {
+-            cw.firstMethod = this;
+-        }
+-        else {
+-            cw.lastMethod.next = this;
+-        }
+-        cw.lastMethod = this;
+-        this.cw = cw;
+-        this.access = access;
+-        this.name = cw.newUTF8(name);
+-        this.desc = cw.newUTF8(desc);
+-        this.descriptor = desc;
+-        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) {
+-            if (computeFrames && name.equals("<init>")) {
+-                this.access |= ACC_CONSTRUCTOR;
+-            }
+-            // updates maxLocals
+-            int size = getArgumentsAndReturnSizes(descriptor) >> 2;
+-            if ((access & Opcodes.ACC_STATIC) != 0) {
+-                --size;
+-            }
+-            maxLocals = size;
+-            // creates and visits the label for the first basic ast
+-            labels = new Label();
+-            labels.status |= Label.PUSHED;
+-            visitLabel(labels);
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Implementation of the MethodVisitor interface
+-    // ------------------------------------------------------------------------
+-
+-    public AnnotationVisitor visitAnnotationDefault() {
+-        annd = new ByteVector();
+-        return new AnnotationWriter(cw, false, annd, null, 0);
+-    }
+-
+-    public AnnotationVisitor visitAnnotation(
+-            final String desc,
+-            final boolean visible) {
+-        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;
+-    }
+-
+-    public AnnotationVisitor visitParameterAnnotation(
+-            final int parameter,
+-            final String desc,
+-            final boolean visible) {
+-        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) {
+-            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;
+-    }
+-
+-    public void visitAttribute(final Attribute attr) {
+-        if (attr.isCodeAttribute()) {
+-            attr.next = cattrs;
+-            cattrs = attr;
+-        }
+-        else {
+-            attr.next = attrs;
+-            attrs = attr;
+-        }
+-    }
+-
+-    public void visitCode() {
+-    }
+-
+-    public void visitFrame(
+-            final int type,
+-            final int nLocal,
+-            final Object[] local,
+-            final int nStack,
+-            final Object[] stack) {
+-        if (compute == FRAMES) {
+-            return;
+-        }
+-
+-        if (type == Opcodes.F_NEW) {
+-            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;
+-            }
+-
+-            switch (type) {
+-                case Opcodes.F_FULL:
+-                    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:
+-                    stackMap.putByte(SAME_FRAME_EXTENDED + nLocal)
+-                            .putShort(delta);
+-                    for (int i = 0; i < nLocal; ++i) {
+-                        writeFrameType(local[i]);
+-                    }
+-                    break;
+-                case Opcodes.F_CHOP:
+-                    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;
+-        }
+-    }
+-
+-    public void visitInsn(final int opcode) {
+-        // adds the instruction to the bytecode of the method
+-        code.putByte(opcode);
+-        // update currentBlock
+-        // Label currentBlock = this.currentBlock;
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(opcode, 0, null, null);
+-            }
+-            else {
+-                // updates current and max stack sizes
+-                int size = stackSize + Frame.SIZE[opcode];
+-                if (size > maxStackSize) {
+-                    maxStackSize = size;
+-                }
+-                stackSize = size;
+-            }
+-            // if opcode == ATHROW or xRETURN, ends current ast (no successor)
+-            if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
+-                    || opcode == Opcodes.ATHROW) {
+-                noSuccessor();
+-            }
+-        }
+-    }
+-
+-    public void visitIntInsn(final int opcode, final int operand) {
+-        // Label currentBlock = this.currentBlock;
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(opcode, operand, null, null);
+-            }
+-            else if (opcode != Opcodes.NEWARRAY) {
+-                // updates current and max stack sizes only for NEWARRAY
+-                // (stack size variation = 0 for BIPUSH or SIPUSH)
+-                int size = stackSize + 1;
+-                if (size > maxStackSize) {
+-                    maxStackSize = size;
+-                }
+-                stackSize = size;
+-            }
+-        }
+-        // adds the instruction to the bytecode of the method
+-        if (opcode == Opcodes.SIPUSH) {
+-            code.put12(opcode, operand);
+-        }
+-        else { // BIPUSH or NEWARRAY
+-            code.put11(opcode, operand);
+-        }
+-    }
+-
+-    public void visitVarInsn(final int opcode, final int var) {
+-        // Label currentBlock = this.currentBlock;
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(opcode, var, null, null);
+-            }
+-            else {
+-                // updates current and max stack sizes
+-                if (opcode == Opcodes.RET) {
+-                    // no stack change, but end of current ast (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());
+-        }
+-    }
+-
+-    public void visitTypeInsn(final int opcode, final String desc) {
+-        Item i = cw.newClassItem(desc);
+-        // 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);
+-    }
+-
+-    public void visitFieldInsn(
+-            final int opcode,
+-            final String owner,
+-            final String name,
+-            final String desc) {
+-        Item i = cw.newFieldItem(owner, name, desc);
+-        // Label currentBlock = this.currentBlock;
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(opcode, 0, cw, i);
+-            }
+-            else {
+-                int size;
+-                // computes the stack size variation
+-                char c = desc.charAt(0);
+-                switch (opcode) {
+-                    case Opcodes.GETSTATIC:
+-                        size = stackSize + (c == 'D' || c == 'J' ? 2 : 1);
+-                        break;
+-                    case Opcodes.PUTSTATIC:
+-                        size = stackSize + (c == 'D' || c == 'J' ? -2 : -1);
+-                        break;
+-                    case Opcodes.GETFIELD:
+-                        size = stackSize + (c == 'D' || c == 'J' ? 1 : 0);
+-                        break;
+-                        // case Constants.PUTFIELD:
+-                    default:
+-                        size = stackSize + (c == 'D' || c == 'J' ? -3 : -2);
+-                        break;
+-                }
+-                // updates current and max stack sizes
+-                if (size > maxStackSize) {
+-                    maxStackSize = size;
+-                }
+-                stackSize = size;
+-            }
+-        }
+-        // adds the instruction to the bytecode of the method
+-        code.put12(opcode, i.index);
+-    }
+-
+-    public void visitMethodInsn(
+-            final int opcode,
+-            final String owner,
+-            final String name,
+-            final String desc) {
+-        boolean itf = opcode == Opcodes.INVOKEINTERFACE;
+-        Item i = cw.newMethodItem(owner, name, desc, itf);
+-        int argSize = i.intVal;
+-        // Label currentBlock = this.currentBlock;
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(opcode, 0, cw, i);
+-            }
+-            else {
+-                /*
+-                 * computes the stack size variation. In order not to recompute
+-                 * several times this variation for the same Item, we use the
+-                 * intVal field of this item to store this variation, once it
+-                 * has been computed. More precisely this intVal field stores
+-                 * the sizes of the arguments and of the return value
+-                 * corresponding to desc.
+-                 */
+-                if (argSize == 0) {
+-                    // the above sizes have not been computed yet,
+-                    // so we compute them...
+-                    argSize = getArgumentsAndReturnSizes(desc);
+-                    // ... and we save them in order
+-                    // not to recompute them in the future
+-                    i.intVal = argSize;
+-                }
+-                int size;
+-                if (opcode == Opcodes.INVOKESTATIC) {
+-                    size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1;
+-                }
+-                else {
+-                    size = stackSize - (argSize >> 2) + (argSize & 0x03);
+-                }
+-                // updates current and max stack sizes
+-                if (size > maxStackSize) {
+-                    maxStackSize = size;
+-                }
+-                stackSize = size;
+-            }
+-        }
+-        // adds the instruction to the bytecode of the method
+-        if (itf) {
+-            if (argSize == 0) {
+-                argSize = getArgumentsAndReturnSizes(desc);
+-                i.intVal = argSize;
+-            }
+-            code.put12(Opcodes.INVOKEINTERFACE, i.index).put11(argSize >> 2, 0);
+-        }
+-        else {
+-            code.put12(opcode, i.index);
+-        }
+-    }
+-
+-    public void visitJumpInsn(final int opcode, final Label label) {
+-        Label nextInsn = null;
+-        // Label currentBlock = this.currentBlock;
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(opcode, 0, null, null);
+-                // 'label' is the target of a jump instruction
+-                label.getFirst().status |= Label.TARGET;
+-                // adds 'label' as a successor of this basic ast
+-                addSuccessor(Edge.NORMAL, label);
+-                if (opcode != Opcodes.GOTO) {
+-                    // creates a Label for the next basic ast
+-                    nextInsn = new Label();
+-                }
+-            }
+-            else {
+-                if (opcode == Opcodes.JSR) {
+-                    jsr = true;
+-                    currentBlock.status |= Label.JSR;
+-                    addSuccessor(stackSize + 1, label);
+-                    // creates a Label for the next basic ast
+-                    nextInsn = new Label();
+-                    /*
+-                     * note that, by construction in this method, a JSR ast
+-                     * has at least two successors in the control flow graph:
+-                     * the first one leads the next instruction after the JSR,
+-                     * while the second one leads to the JSR target.
+-                     */
+-                }
+-                else {
+-                    // updates current stack size (max stack size unchanged
+-                    // because stack size variation always negative in this
+-                    // case)
+-                    stackSize += Frame.SIZE[opcode];
+-                    addSuccessor(stackSize, label);
+-                }
+-            }
+-        }
+-        // adds the instruction to the bytecode of the method
+-        if ((label.status & Label.RESOLVED) != 0
+-                && label.position - code.length < Short.MIN_VALUE) {
+-            /*
+-             * case of a backward jump with an offset < -32768. In this case we
+-             * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
+-             * <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the
+-             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <l'>
+-             * designates the instruction just after the GOTO_W.
+-             */
+-            if (opcode == Opcodes.GOTO) {
+-                code.putByte(200); // GOTO_W
+-            }
+-            else if (opcode == Opcodes.JSR) {
+-                code.putByte(201); // JSR_W
+-            }
+-            else {
+-                // if the IF instruction is transformed into IFNOT GOTO_W the
+-                // next instruction becomes the target of the IFNOT instruction
+-                if (nextInsn != null) {
+-                    nextInsn.status |= Label.TARGET;
+-                }
+-                code.putByte(opcode <= 166
+-                        ? ((opcode + 1) ^ 1) - 1
+-                        : opcode ^ 1);
+-                code.putShort(8); // jump offset
+-                code.putByte(200); // GOTO_W
+-            }
+-            label.put(this, code, code.length - 1, true);
+-        }
+-        else {
+-            /*
+-             * case of a backward jump with an offset >= -32768, or of a forward
+-             * jump with, of course, an unknown offset. In these cases we store
+-             * the offset in 2 bytes (which will be increased in
+-             * resizeInstructions, if needed).
+-             */
+-            code.putByte(opcode);
+-            label.put(this, code, code.length - 1, false);
+-        }
+-        if (currentBlock != null) {
+-            if (nextInsn != null) {
+-                // if the jump instruction is not a GOTO, the next instruction
+-                // is also a successor of this instruction. Calling visitLabel
+-                // adds the label of this next instruction as a successor of the
+-                // current ast, and starts a new basic ast
+-                visitLabel(nextInsn);
+-            }
+-            if (opcode == Opcodes.GOTO) {
+-                noSuccessor();
+-            }
+-        }
+-    }
+-
+-    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 ast
+-                    currentBlock.status |= (label.status & Label.TARGET);
+-                    label.frame = currentBlock.frame;
+-                    return;
+-                }
+-                // ends current ast (with one new successor)
+-                addSuccessor(Edge.NORMAL, label);
+-            }
+-            // begins a new current ast
+-            currentBlock = label;
+-            if (label.frame == null) {
+-                label.frame = new Frame();
+-                label.frame.owner = label;
+-            }
+-            // updates the basic ast 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 ast (with one new successor)
+-                currentBlock.outputStackMax = maxStackSize;
+-                addSuccessor(stackSize, label);
+-            }
+-            // begins a new current ast
+-            currentBlock = label;
+-            // resets the relative current and max stack sizes
+-            stackSize = 0;
+-            maxStackSize = 0;
+-            // updates the basic ast list
+-            if (previousBlock != null) {
+-                previousBlock.successor = label;
+-            }
+-            previousBlock = label;
+-        }
+-    }
+-
+-    public void visitLdcInsn(final Object cst) {
+-        Item i = cw.newConstItem(cst);
+-        // Label currentBlock = this.currentBlock;
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(Opcodes.LDC, 0, cw, i);
+-            }
+-            else {
+-                int size;
+-                // computes the stack size variation
+-                if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
+-                    size = stackSize + 2;
+-                }
+-                else {
+-                    size = stackSize + 1;
+-                }
+-                // updates current and max stack sizes
+-                if (size > maxStackSize) {
+-                    maxStackSize = size;
+-                }
+-                stackSize = size;
+-            }
+-        }
+-        // adds the instruction to the bytecode of the method
+-        int index = i.index;
+-        if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) {
+-            code.put12(20 /* LDC2_W */, index);
+-        }
+-        else if (index >= 256) {
+-            code.put12(19 /* LDC_W */, index);
+-        }
+-        else {
+-            code.put11(Opcodes.LDC, index);
+-        }
+-    }
+-
+-    public void visitIincInsn(final int var, final int increment) {
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(Opcodes.IINC, var, null, null);
+-            }
+-        }
+-        if (compute != NOTHING) {
+-            // updates max locals
+-            int n = var + 1;
+-            if (n > maxLocals) {
+-                maxLocals = n;
+-            }
+-        }
+-        // adds the instruction to the bytecode of the method
+-        if ((var > 255) || (increment > 127) || (increment < -128)) {
+-            code.putByte(196 /* WIDE */)
+-                    .put12(Opcodes.IINC, var)
+-                    .putShort(increment);
+-        }
+-        else {
+-            code.putByte(Opcodes.IINC).put11(var, increment);
+-        }
+-    }
+-
+-    public void visitTableSwitchInsn(
+-            final int min,
+-            final int max,
+-            final Label dflt,
+-            final Label labels[]) {
+-        // adds the instruction to the bytecode of the method
+-        int source = code.length;
+-        code.putByte(Opcodes.TABLESWITCH);
+-        code.length += (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);
+-    }
+-
+-    public void visitLookupSwitchInsn(
+-            final Label dflt,
+-            final int keys[],
+-            final Label labels[]) {
+-        // adds the instruction to the bytecode of the method
+-        int source = code.length;
+-        code.putByte(Opcodes.LOOKUPSWITCH);
+-        code.length += (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 ast 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 ast successors
+-                addSuccessor(stackSize, dflt);
+-                for (int i = 0; i < labels.length; ++i) {
+-                    addSuccessor(stackSize, labels[i]);
+-                }
+-            }
+-            // ends current ast
+-            noSuccessor();
+-        }
+-    }
+-
+-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
+-        Item i = cw.newClassItem(desc);
+-        // Label currentBlock = this.currentBlock;
+-        if (currentBlock != null) {
+-            if (compute == FRAMES) {
+-                currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i);
+-            }
+-            else {
+-                // updates current stack size (max stack size unchanged because
+-                // stack size variation always negative or null)
+-                stackSize += 1 - dims;
+-            }
+-        }
+-        // adds the instruction to the bytecode of the method
+-        code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims);
+-    }
+-
+-    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;
+-    }
+-
+-    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;
+-            }
+-        }
+-    }
+-
+-    public void visitLineNumber(final int line, final Label start) {
+-        if (lineNumber == null) {
+-            lineNumber = new ByteVector();
+-        }
+-        ++lineNumberCount;
+-        lineNumber.putShort(start.position);
+-        lineNumber.putShort(line);
+-    }
+-
+-    public void visitMaxs(final int maxStack, final int maxLocals) {
+-        if (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 ast 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 ast from the list of changed basic blocks
+-                Label l = changed;
+-                changed = changed.next;
+-                l.next = null;
+-                f = l.frame;
+-                // a reacheable jump target must be stored in the stack map
+-                if ((l.status & Label.TARGET) != 0) {
+-                    l.status |= Label.STORE;
+-                }
+-                // all visited labels are reacheable, 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 ast
+-                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;
+-                }
+-            }
+-            this.maxStack = max;
+-
+-            // 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 ast
+-                    Label k = l.successor;
+-                    int start = l.position;
+-                    int end = (k == null ? code.length : k.position) - 1;
+-                    // if non empty basic ast
+-                    if (end >= start) {
+-                        // 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 ast
+-                        startFrame(start, 0, 1);
+-                        frame[frameIndex++] = Frame.OBJECT
+-                                | cw.addType("java/lang/Throwable");
+-                        endFrame();
+-                    }
+-                }
+-                l = l.successor;
+-            }
+-        }
+-        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) {
+-                        // if l is a JSR ast, adds b after the first two edges
+-                        // to preserve the hypothesis about JSR ast successors
+-                        // order (see {@link #visitJumpInsn})
+-                        b.next = l.successors.next.next;
+-                        l.successors.next.next = b;
+-                    }
+-                    else {
+-                        b.next = l.successors;
+-                        l.successors = b;
+-                    }
+-                    // goes to the next label
+-                    l = l.successor;
+-                }
+-                handler = handler.next;
+-            }
+-
+-            if (jsr) {
+-                // completes the control flow graph with the RET successors
+-                /*
+-                 * first step: finds the subroutines. This step determines, for
+-                 * each basic ast, to which subroutine(s) it belongs, and
+-                 * stores this set as a bit set in the {@link Label#status}
+-                 * field. Subroutines are numbered with powers of two, from
+-                 * 0x1000 to 0x80000000 (so there must be at most 20 subroutines
+-                 * in a method).
+-                 */
+-                // finds the basic blocks that belong to the "core" subroutine
+-                int id = 0x1000;
+-                findSubroutine(labels, id);
+-                // 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 does not have an id yet...
+-                        if ((subroutine.status & ~0xFFF) == 0) {
+-                            // ...assigns it a new id and finds its basic blocks
+-                            id = id << 1;
+-                            findSubroutine(subroutine, id);
+-                        }
+-                    }
+-                    l = l.successor;
+-                }
+-                // second step: finds the successors of RET blocks
+-                findSubroutineSuccessors(0x1000, new Label[10], 0);
+-            }
+-
+-            /*
+-             * control flow analysis algorithm: while the ast stack is not
+-             * empty, pop a ast from this stack, update the max stack size,
+-             * compute the true (non relative) begin stack size of the
+-             * successors of this ast, 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 ast stack are the true (non relative) beginning
+-             * stack sizes of these blocks.
+-             */
+-            int max = 0;
+-            Label stack = labels;
+-            while (stack != null) {
+-                // pops a ast from the stack
+-                Label l = stack;
+-                stack = stack.next;
+-                // computes the true (non relative) max stack size of this ast
+-                int start = l.inputStackTop;
+-                int blockMax = start + l.outputStackMax;
+-                // updates the global max stack size
+-                if (blockMax > max) {
+-                    max = blockMax;
+-                }
+-                // analyses the successors of the ast
+-                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 = max;
+-        }
+-        else {
+-            this.maxStack = maxStack;
+-            this.maxLocals = maxLocals;
+-        }
+-    }
+-
+-    public void visitEnd() {
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods: control flow analysis algorithm
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Computes the size of the arguments and of the return value of a method.
+-     *
+-     * @param desc the descriptor of a method.
+-     * @return the size of the arguments of the method (plus one for the
+-     *         implicit this argument), argSize, and the size of its return
+-     *         value, retSize, packed into a single int i =
+-     *         <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal
+-     *         to <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
+-     */
+-    static int getArgumentsAndReturnSizes(final String desc) {
+-        int n = 1;
+-        int c = 1;
+-        while (true) {
+-            char car = desc.charAt(c++);
+-            if (car == ')') {
+-                car = desc.charAt(c);
+-                return n << 2
+-                        | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
+-            }
+-            else if (car == 'L') {
+-                while (desc.charAt(c++) != ';') {
+-                }
+-                n += 1;
+-            }
+-            else if (car == '[') {
+-                while ((car = desc.charAt(c)) == '[') {
+-                    ++c;
+-                }
+-                if (car == 'D' || car == 'J') {
+-                    n -= 1;
+-                }
+-            }
+-            else if (car == 'D' || car == 'J') {
+-                n += 2;
+-            }
+-            else {
+-                n += 1;
+-            }
+-        }
+-    }
+-
+-    /**
+-     * Adds a successor to the {@link #currentBlock currentBlock} ast.
+-     *
+-     * @param info      information about the control flow edge to be added.
+-     * @param successor the successor ast to be added to the current ast.
+-     */
+-    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 ast
+-        b.next = currentBlock.successors;
+-        currentBlock.successors = b;
+-    }
+-
+-    /**
+-     * Ends the current basic ast. This method must be used in the case where
+-     * the current basic ast 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;
+-    }
+-
+-    /**
+-     * Finds the basic blocks that belong to a given subroutine, and marks these
+-     * blocks as belonging to this subroutine (by using {@link Label#status} as
+-     * a bit set (see {@link #visitMaxs}). This recursive method follows the
+-     * control flow graph to find all the blocks that are reachable from the
+-     * given ast WITHOUT following any JSR target.
+-     *
+-     * @param block a ast that belongs to the subroutine
+-     * @param id    the id of this subroutine
+-     */
+-    private void findSubroutine(final Label block, final int id) {
+-        // if 'ast' is already marked as belonging to subroutine 'id', returns
+-        if ((block.status & id) != 0) {
+-            return;
+-        }
+-        // marks 'ast' as belonging to subroutine 'id'
+-        block.status |= id;
+-        // calls this method recursively on each successor, except JSR targets
+-        Edge e = block.successors;
+-        while (e != null) {
+-            // if 'ast' is a JSR ast, then 'ast.successors.next' leads
+-            // to the JSR target (see {@link #visitJumpInsn}) and must therefore
+-            // not be followed
+-            if ((block.status & Label.JSR) == 0 || e != block.successors.next) {
+-                findSubroutine(e.successor, id);
+-            }
+-            e = e.next;
+-        }
+-    }
+-
+-    /**
+-     * Finds the successors of the RET blocks of the specified subroutine, and
+-     * of any nested subroutine it calls.
+-     *
+-     * @param id    id of the subroutine whose RET ast successors must be found.
+-     * @param JSRs  the JSR blocks that were followed to reach this subroutine.
+-     * @param nJSRs number of JSR blocks in the JSRs array.
+-     */
+-    private void findSubroutineSuccessors(
+-            final int id,
+-            final Label[] JSRs,
+-            final int nJSRs) {
+-        // iterates over all the basic blocks...
+-        Label l = labels;
+-        while (l != null) {
+-            // for those that belong to subroutine 'id'...
+-            if ((l.status & id) != 0) {
+-                if ((l.status & Label.JSR) != 0) {
+-                    // finds the subroutine to which 'l' leads by following the
+-                    // second edge of l.successors (see {@link #visitJumpInsn})
+-                    int nId = l.successors.next.successor.status & ~0xFFF;
+-                    if (nId != id) {
+-                        // calls this method recursively with l pushed onto the
+-                        // JSRs stack to find the successors of the RET blocks
+-                        // of this nested subroutine 'nId'
+-                        JSRs[nJSRs] = l;
+-                        findSubroutineSuccessors(nId, JSRs, nJSRs + 1);
+-                    }
+-                }
+-                else if ((l.status & Label.RET) != 0) {
+-                    /*
+-                     * finds the JSR ast in the JSRs stack that corresponds to
+-                     * this RET ast, and updates the successors of this RET
+-                     * ast accordingly. This corresponding JSR is the one that
+-                     * leads to the subroutine to which the RET ast belongs.
+-                     * But the RET ast can belong to several subroutines (if a
+-                     * nested subroutine returns to its parent subroutine
+-                     * implicitely, without a RET). So, in fact, the JSR that
+-                     * corresponds to this RET is the first ast in the JSRs
+-                     * stack, starting from the bottom of the stack, that leads
+-                     * to a subroutine to which the RET ast belongs.
+-                     */
+-                    for (int i = 0; i < nJSRs; ++i) {
+-                        int JSRstatus = JSRs[i].successors.next.successor.status;
+-                        if (((JSRstatus & ~0xFFF) & (l.status & ~0xFFF)) != 0) {
+-                            Edge e = new Edge();
+-                            e.info = l.inputStackTop;
+-                            e.successor = JSRs[i].successors.successor;
+-                            e.next = l.successors;
+-                            l.successors = e;
+-                            break;
+-                        }
+-                    }
+-                }
+-            }
+-            l = l.successor;
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // 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
+-        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();
+-    }
+-
+-    /**
+-     * 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.
+-     */
+-    private void 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;
+-        frameIndex = 3;
+-    }
+-
+-    /**
+-     * Checks if the visit of the current frame {@link #frame} is finished, and
+-     * if yes, write it in the StackMapTable attribute.
+-     */
+-    private void endFrame() {
+-        if (previousFrame != null) { // do not write the first frame
+-            if (stackMap == null) {
+-                stackMap = new ByteVector();
+-            }
+-            writeFrame();
+-            ++frameCount;
+-        }
+-        previousFrame = frame;
+-        frame = null;
+-    }
+-
+-    /**
+-     * Compress and writes the current frame {@link #frame} in the StackMapTable
+-     * attribute.
+-     */
+-    private void writeFrame() {
+-        int clocalsSize = frame[1];
+-        int cstackSize = frame[2];
+-        if ((cw.version & 0xFFFF) < Opcodes.V1_6) {
+-            stackMap.putShort(frame[0]).putShort(clocalsSize);
+-            writeFrameTypes(3, 3 + clocalsSize);
+-            stackMap.putShort(cstackSize);
+-            writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
+-            return;
+-        }
+-        int localsSize = previousFrame[1];
+-        int type = FULL_FRAME;
+-        int k = 0;
+-        int delta;
+-        if (frameCount == 0) {
+-            delta = frame[0];
+-        }
+-        else {
+-            delta = frame[0] - previousFrame[0] - 1;
+-        }
+-        if (cstackSize == 0) {
+-            k = clocalsSize - localsSize;
+-            switch (k) {
+-                case -3:
+-                case -2:
+-                case -1:
+-                    type = CHOP_FRAME;
+-                    localsSize = clocalsSize;
+-                    break;
+-                case 0:
+-                    type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED;
+-                    break;
+-                case 1:
+-                case 2:
+-                case 3:
+-                    type = APPEND_FRAME;
+-                    break;
+-            }
+-        }
+-        else if (clocalsSize == localsSize && cstackSize == 1) {
+-            type = delta < 63
+-                    ? SAME_LOCALS_1_STACK_ITEM_FRAME
+-                    : SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED;
+-        }
+-        if (type != FULL_FRAME) {
+-            // verify if locals are the same
+-            int l = 3;
+-            for (int j = 0; j < localsSize; j++) {
+-                if (frame[l] != previousFrame[l]) {
+-                    type = FULL_FRAME;
+-                    break;
+-                }
+-                l++;
+-            }
+-        }
+-        switch (type) {
+-            case SAME_FRAME:
+-                stackMap.putByte(delta);
+-                break;
+-            case SAME_LOCALS_1_STACK_ITEM_FRAME:
+-                stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta);
+-                writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+-                break;
+-            case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED:
+-                stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED)
+-                        .putShort(delta);
+-                writeFrameTypes(3 + clocalsSize, 4 + clocalsSize);
+-                break;
+-            case SAME_FRAME_EXTENDED:
+-                stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta);
+-                break;
+-            case CHOP_FRAME:
+-                stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+-                break;
+-            case APPEND_FRAME:
+-                stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta);
+-                writeFrameTypes(3 + localsSize, 3 + clocalsSize);
+-                break;
+-                // case FULL_FRAME:
+-            default:
+-                stackMap.putByte(FULL_FRAME)
+-                        .putShort(delta)
+-                        .putShort(clocalsSize);
+-                writeFrameTypes(3, 3 + clocalsSize);
+-                stackMap.putShort(cstackSize);
+-                writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize);
+-        }
+-    }
+-
+-    /**
+-     * Writes some types of the current frame {@link #frame} into the
+-     * StackMapTableAttribute. This method converts types from the format used
+-     * in {@link Label} to the format used in StackMapTable attributes. In
+-     * particular, it converts type table indexes to constant pool indexes.
+-     *
+-     * @param start index of the first type in {@link #frame} to write.
+-     * @param end   index of last type in {@link #frame} to write (exclusive).
+-     */
+-    private void writeFrameTypes(final int start, final int end) {
+-        for (int i = start; i < end; ++i) {
+-            int t = frame[i];
+-            int d = t & Frame.DIM;
+-            if (d == 0) {
+-                int v = t & Frame.BASE_VALUE;
+-                switch (t & Frame.BASE_KIND) {
+-                    case Frame.OBJECT:
+-                        stackMap.putByte(7)
+-                                .putShort(cw.newClass(cw.typeTable[v].strVal1));
+-                        break;
+-                    case Frame.UNINITIALIZED:
+-                        stackMap.putByte(8).putShort(cw.typeTable[v].intVal);
+-                        break;
+-                    default:
+-                        stackMap.putByte(v);
+-                }
+-            }
+-            else {
+-                StringBuffer buf = new StringBuffer();
+-                d >>= 28;
+-                while (d-- > 0) {
+-                    buf.append('[');
+-                }
+-                if ((t & Frame.BASE_KIND) == Frame.OBJECT) {
+-                    buf.append('L');
+-                    buf.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1);
+-                    buf.append(';');
+-                }
+-                else {
+-                    switch (t & 0xF) {
+-                        case 1:
+-                            buf.append('I');
+-                            break;
+-                        case 2:
+-                            buf.append('F');
+-                            break;
+-                        case 3:
+-                            buf.append('D');
+-                            break;
+-                        case 9:
+-                            buf.append('Z');
+-                            break;
+-                        case 10:
+-                            buf.append('B');
+-                            break;
+-                        case 11:
+-                            buf.append('C');
+-                            break;
+-                        case 12:
+-                            buf.append('S');
+-                            break;
+-                        default:
+-                            buf.append('J');
+-                    }
+-                }
+-                stackMap.putByte(7).putShort(cw.newClass(buf.toString()));
+-            }
+-        }
+-    }
+-
+-    private void writeFrameType(final Object type) {
+-        if (type instanceof String) {
+-            stackMap.putByte(7).putShort(cw.newClass((String) type));
+-        }
+-        else if (type instanceof Integer) {
+-            stackMap.putByte(((Integer) type).intValue());
+-        }
+-        else {
+-            stackMap.putByte(8).putShort(((Label) type).position);
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods: dump bytecode array
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Returns the size of the bytecode of this method.
+-     *
+-     * @return the size of the bytecode of this method.
+-     */
+-    final int getSize() {
+-        if (classReaderOffset != 0) {
+-            return 6 + classReaderLength;
+-        }
+-        if (resize) {
+-            // replaces the temporary jump opcodes introduced by Label.resolve.
+-            resizeInstructions();
+-        }
+-        int size = 8;
+-        if (code.length > 0) {
+-            cw.newUTF8("Code");
+-            size += 18 + code.length + 8 * handlerCount;
+-            if (localVar != null) {
+-                cw.newUTF8("LocalVariableTable");
+-                size += 8 + localVar.length;
+-            }
+-            if (localVarType != null) {
+-                cw.newUTF8("LocalVariableTypeTable");
+-                size += 8 + localVarType.length;
+-            }
+-            if (lineNumber != null) {
+-                cw.newUTF8("LineNumberTable");
+-                size += 8 + lineNumber.length;
+-            }
+-            if (stackMap != null) {
+-                boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6;
+-                cw.newUTF8(zip ? "StackMapTable" : "StackMap");
+-                size += 8 + stackMap.length;
+-            }
+-            if (cattrs != null) {
+-                size += cattrs.getSize(cw,
+-                        code.data,
+-                        code.length,
+-                        maxStack,
+-                        maxLocals);
+-            }
+-        }
+-        if (exceptionCount > 0) {
+-            cw.newUTF8("Exceptions");
+-            size += 8 + 2 * exceptionCount;
+-        }
+-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
+-                && (cw.version & 0xffff) < Opcodes.V1_5) {
+-            cw.newUTF8("Synthetic");
+-            size += 6;
+-        }
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            cw.newUTF8("Deprecated");
+-            size += 6;
+-        }
+-        if (signature != null) {
+-            cw.newUTF8("Signature");
+-            cw.newUTF8(signature);
+-            size += 8;
+-        }
+-        if (annd != null) {
+-            cw.newUTF8("AnnotationDefault");
+-            size += 6 + annd.length;
+-        }
+-        if (anns != null) {
+-            cw.newUTF8("RuntimeVisibleAnnotations");
+-            size += 8 + anns.getSize();
+-        }
+-        if (ianns != null) {
+-            cw.newUTF8("RuntimeInvisibleAnnotations");
+-            size += 8 + ianns.getSize();
+-        }
+-        if (panns != null) {
+-            cw.newUTF8("RuntimeVisibleParameterAnnotations");
+-            size += 7 + 2 * panns.length;
+-            for (int i = panns.length - 1; i >= 0; --i) {
+-                size += panns[i] == null ? 0 : panns[i].getSize();
+-            }
+-        }
+-        if (ipanns != null) {
+-            cw.newUTF8("RuntimeInvisibleParameterAnnotations");
+-            size += 7 + 2 * ipanns.length;
+-            for (int i = ipanns.length - 1; i >= 0; --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) {
+-        out.putShort(access).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
+-                && (cw.version & 0xffff) < Opcodes.V1_5) {
+-            ++attributeCount;
+-        }
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            ++attributeCount;
+-        }
+-        if (signature != null) {
+-            ++attributeCount;
+-        }
+-        if (annd != null) {
+-            ++attributeCount;
+-        }
+-        if (anns != null) {
+-            ++attributeCount;
+-        }
+-        if (ianns != null) {
+-            ++attributeCount;
+-        }
+-        if (panns != null) {
+-            ++attributeCount;
+-        }
+-        if (ipanns != null) {
+-            ++attributeCount;
+-        }
+-        if (attrs != null) {
+-            attributeCount += attrs.getCount();
+-        }
+-        out.putShort(attributeCount);
+-        if (code.length > 0) {
+-            int size = 12 + code.length + 8 * handlerCount;
+-            if (localVar != null) {
+-                size += 8 + localVar.length;
+-            }
+-            if (localVarType != null) {
+-                size += 8 + localVarType.length;
+-            }
+-            if (lineNumber != null) {
+-                size += 8 + lineNumber.length;
+-            }
+-            if (stackMap != null) {
+-                size += 8 + stackMap.length;
+-            }
+-            if (cattrs != null) {
+-                size += cattrs.getSize(cw,
+-                        code.data,
+-                        code.length,
+-                        maxStack,
+-                        maxLocals);
+-            }
+-            out.putShort(cw.newUTF8("Code")).putInt(size);
+-            out.putShort(maxStack).putShort(maxLocals);
+-            out.putInt(code.length).putByteArray(code.data, 0, code.length);
+-            out.putShort(handlerCount);
+-            if (handlerCount > 0) {
+-                Handler h = firstHandler;
+-                while (h != null) {
+-                    out.putShort(h.start.position)
+-                            .putShort(h.end.position)
+-                            .putShort(h.handler.position)
+-                            .putShort(h.type);
+-                    h = h.next;
+-                }
+-            }
+-            attributeCount = 0;
+-            if (localVar != null) {
+-                ++attributeCount;
+-            }
+-            if (localVarType != null) {
+-                ++attributeCount;
+-            }
+-            if (lineNumber != null) {
+-                ++attributeCount;
+-            }
+-            if (stackMap != null) {
+-                ++attributeCount;
+-            }
+-            if (cattrs != null) {
+-                attributeCount += cattrs.getCount();
+-            }
+-            out.putShort(attributeCount);
+-            if (localVar != null) {
+-                out.putShort(cw.newUTF8("LocalVariableTable"));
+-                out.putInt(localVar.length + 2).putShort(localVarCount);
+-                out.putByteArray(localVar.data, 0, localVar.length);
+-            }
+-            if (localVarType != null) {
+-                out.putShort(cw.newUTF8("LocalVariableTypeTable"));
+-                out.putInt(localVarType.length + 2).putShort(localVarTypeCount);
+-                out.putByteArray(localVarType.data, 0, localVarType.length);
+-            }
+-            if (lineNumber != null) {
+-                out.putShort(cw.newUTF8("LineNumberTable"));
+-                out.putInt(lineNumber.length + 2).putShort(lineNumberCount);
+-                out.putByteArray(lineNumber.data, 0, lineNumber.length);
+-            }
+-            if (stackMap != null) {
+-                boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6;
+-                out.putShort(cw.newUTF8(zip ? "StackMapTable" : "StackMap"));
+-                out.putInt(stackMap.length + 2).putShort(frameCount);
+-                out.putByteArray(stackMap.data, 0, stackMap.length);
+-            }
+-            if (cattrs != null) {
+-                cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out);
+-            }
+-        }
+-        if (exceptionCount > 0) {
+-            out.putShort(cw.newUTF8("Exceptions"))
+-                    .putInt(2 * exceptionCount + 2);
+-            out.putShort(exceptionCount);
+-            for (int i = 0; i < exceptionCount; ++i) {
+-                out.putShort(exceptions[i]);
+-            }
+-        }
+-        if ((access & Opcodes.ACC_SYNTHETIC) != 0
+-                && (cw.version & 0xffff) < Opcodes.V1_5) {
+-            out.putShort(cw.newUTF8("Synthetic")).putInt(0);
+-        }
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            out.putShort(cw.newUTF8("Deprecated")).putInt(0);
+-        }
+-        if (signature != null) {
+-            out.putShort(cw.newUTF8("Signature"))
+-                    .putInt(2)
+-                    .putShort(cw.newUTF8(signature));
+-        }
+-        if (annd != null) {
+-            out.putShort(cw.newUTF8("AnnotationDefault"));
+-            out.putInt(annd.length);
+-            out.putByteArray(annd.data, 0, annd.length);
+-        }
+-        if (anns != null) {
+-            out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
+-            anns.put(out);
+-        }
+-        if (ianns != null) {
+-            out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
+-            ianns.put(out);
+-        }
+-        if (panns != null) {
+-            out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
+-            AnnotationWriter.put(panns, out);
+-        }
+-        if (ipanns != null) {
+-            out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
+-            AnnotationWriter.put(ipanns, out);
+-        }
+-        if (attrs != null) {
+-            attrs.put(cw, null, 0, -1, -1, out);
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W)
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Resizes and replaces the temporary instructions inserted by
+-     * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
+-     * and instruction addresses consistent. This may require to resize other
+-     * existing instructions, or even to introduce new instructions: for
+-     * example, increasing the size of an instruction by 2 at the middle of a
+-     * method can increases the offset of an IFEQ instruction from 32766 to
+-     * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
+-     * 32765. This, in turn, may require to increase the size of another jump
+-     * instruction, and so on... All these operations are handled automatically
+-     * by this method. <p> <i>This method must be called after all the method
+-     * that is being built has been visited</i>. In particular, the
+-     * {@link Label Label} objects used to construct the method are no longer
+-     * valid after this method has been called.
+-     */
+-    private void resizeInstructions() {
+-        byte[] b = code.data; // bytecode of the method
+-        int u, v, label; // indexes in b
+-        int i, j; // loop indexes
+-        /*
+-         * 1st step: As explained above, resizing an instruction may require to
+-         * resize another one, which may require to resize yet another one, and
+-         * so on. The first step of the algorithm consists in finding all the
+-         * instructions that need to be resized, without modifying the code.
+-         * This is done by the following "fix point" algorithm:
+-         * 
+-         * Parse the code to find the jump instructions whose offset will need
+-         * more than 2 bytes to be stored (the future offset is computed from
+-         * the current offset and from the number of bytes that will be inserted
+-         * or removed between the source and target instructions). For each such
+-         * instruction, adds an entry in (a copy of) the indexes and sizes
+-         * arrays (if this has not already been done in a previous iteration!).
+-         * 
+-         * If at least one entry has been added during the previous step, go
+-         * back to the beginning, otherwise stop.
+-         * 
+-         * In fact the real algorithm is complicated by the fact that the size
+-         * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
+-         * position in the bytecode (because of padding). In order to ensure the
+-         * convergence of the algorithm, the number of bytes to be added or
+-         * removed from these instructions is over estimated during the previous
+-         * loop, and computed exactly only after the loop is finished (this
+-         * requires another pass to parse the bytecode of the method).
+-         */
+-        int[] allIndexes = new int[0]; // copy of indexes
+-        int[] allSizes = new int[0]; // copy of sizes
+-        boolean[] resize; // instructions to be resized
+-        int newOffset; // future offset of a jump instruction
+-
+-        resize = new boolean[code.length];
+-
+-        // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
+-        int state = 3;
+-        do {
+-            if (state == 3) {
+-                state = 2;
+-            }
+-            u = 0;
+-            while (u < b.length) {
+-                int opcode = b[u] & 0xFF; // opcode of current instruction
+-                int insert = 0; // bytes to be added after this instruction
+-
+-                switch (ClassWriter.TYPE[opcode]) {
+-                    case ClassWriter.NOARG_INSN:
+-                    case ClassWriter.IMPLVAR_INSN:
+-                        u += 1;
+-                        break;
+-                    case ClassWriter.LABEL_INSN:
+-                        if (opcode > 201) {
+-                            // converts temporary opcodes 202 to 217, 218 and
+-                            // 219 to IFEQ ... JSR (inclusive), IFNULL and
+-                            // IFNONNULL
+-                            opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+-                            label = u + readUnsignedShort(b, u + 1);
+-                        }
+-                        else {
+-                            label = u + readShort(b, u + 1);
+-                        }
+-                        newOffset = getNewOffset(allIndexes, allSizes, u, label);
+-                        if (newOffset < Short.MIN_VALUE
+-                                || newOffset > Short.MAX_VALUE) {
+-                            if (!resize[u]) {
+-                                if (opcode == Opcodes.GOTO
+-                                        || opcode == Opcodes.JSR) {
+-                                    // two additional bytes will be required to
+-                                    // replace this GOTO or JSR instruction with
+-                                    // a GOTO_W or a JSR_W
+-                                    insert = 2;
+-                                }
+-                                else {
+-                                    // five additional bytes will be required to
+-                                    // replace this IFxxx <l> instruction with
+-                                    // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
+-                                    // is the "opposite" opcode of IFxxx (i.e.,
+-                                    // IFNE for IFEQ) and where <l'> designates
+-                                    // the instruction just after the GOTO_W.
+-                                    insert = 5;
+-                                }
+-                                resize[u] = true;
+-                            }
+-                        }
+-                        u += 3;
+-                        break;
+-                    case ClassWriter.LABELW_INSN:
+-                        u += 5;
+-                        break;
+-                    case ClassWriter.TABL_INSN:
+-                        if (state == 1) {
+-                            // true number of bytes to be added (or removed)
+-                            // from this instruction = (future number of padding
+-                            // bytes - current number of padding byte) -
+-                            // previously over estimated variation =
+-                            // = ((3 - newOffset%4) - (3 - u%4)) - u%4
+-                            // = (-newOffset%4 + u%4) - u%4
+-                            // = -(newOffset & 3)
+-                            newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+-                            insert = -(newOffset & 3);
+-                        }
+-                        else if (!resize[u]) {
+-                            // over estimation of the number of bytes to be
+-                            // added to this instruction = 3 - current number
+-                            // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
+-                            insert = u & 3;
+-                            resize[u] = true;
+-                        }
+-                        // skips instruction
+-                        u = u + 4 - (u & 3);
+-                        u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
+-                        break;
+-                    case ClassWriter.LOOK_INSN:
+-                        if (state == 1) {
+-                            // like TABL_INSN
+-                            newOffset = getNewOffset(allIndexes, allSizes, 0, u);
+-                            insert = -(newOffset & 3);
+-                        }
+-                        else if (!resize[u]) {
+-                            // like TABL_INSN
+-                            insert = u & 3;
+-                            resize[u] = true;
+-                        }
+-                        // skips instruction
+-                        u = u + 4 - (u & 3);
+-                        u += 8 * readInt(b, u + 4) + 8;
+-                        break;
+-                    case ClassWriter.WIDE_INSN:
+-                        opcode = b[u + 1] & 0xFF;
+-                        if (opcode == Opcodes.IINC) {
+-                            u += 6;
+-                        }
+-                        else {
+-                            u += 4;
+-                        }
+-                        break;
+-                    case ClassWriter.VAR_INSN:
+-                    case ClassWriter.SBYTE_INSN:
+-                    case ClassWriter.LDC_INSN:
+-                        u += 2;
+-                        break;
+-                    case ClassWriter.SHORT_INSN:
+-                    case ClassWriter.LDCW_INSN:
+-                    case ClassWriter.FIELDORMETH_INSN:
+-                    case ClassWriter.TYPE_INSN:
+-                    case ClassWriter.IINC_INSN:
+-                        u += 3;
+-                        break;
+-                    case ClassWriter.ITFMETH_INSN:
+-                        u += 5;
+-                        break;
+-                        // case ClassWriter.MANA_INSN:
+-                    default:
+-                        u += 4;
+-                        break;
+-                }
+-                if (insert != 0) {
+-                    // adds a new (u, insert) entry in the allIndexes and
+-                    // allSizes arrays
+-                    int[] newIndexes = new int[allIndexes.length + 1];
+-                    int[] newSizes = new int[allSizes.length + 1];
+-                    System.arraycopy(allIndexes,
+-                            0,
+-                            newIndexes,
+-                            0,
+-                            allIndexes.length);
+-                    System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
+-                    newIndexes[allIndexes.length] = u;
+-                    newSizes[allSizes.length] = insert;
+-                    allIndexes = newIndexes;
+-                    allSizes = newSizes;
+-                    if (insert > 0) {
+-                        state = 3;
+-                    }
+-                }
+-            }
+-            if (state < 3) {
+-                --state;
+-            }
+-        }
+-        while (state != 0);
+-
+-        // 2nd step:
+-        // copies the bytecode of the method into a new bytevector, updates the
+-        // offsets, and inserts (or removes) bytes as requested.
+-
+-        ByteVector newCode = new ByteVector(code.length);
+-
+-        u = 0;
+-        while (u < code.length) {
+-            int opcode = b[u] & 0xFF;
+-            switch (ClassWriter.TYPE[opcode]) {
+-                case ClassWriter.NOARG_INSN:
+-                case ClassWriter.IMPLVAR_INSN:
+-                    newCode.putByte(opcode);
+-                    u += 1;
+-                    break;
+-                case ClassWriter.LABEL_INSN:
+-                    if (opcode > 201) {
+-                        // changes temporary opcodes 202 to 217 (inclusive), 218
+-                        // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+-                        // IFNONNULL
+-                        opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+-                        label = u + readUnsignedShort(b, u + 1);
+-                    }
+-                    else {
+-                        label = u + readShort(b, u + 1);
+-                    }
+-                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
+-                    if (resize[u]) {
+-                        // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+-                        // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
+-                        // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+-                        // and where <l'> designates the instruction just after
+-                        // the GOTO_W.
+-                        if (opcode == Opcodes.GOTO) {
+-                            newCode.putByte(200); // GOTO_W
+-                        }
+-                        else if (opcode == Opcodes.JSR) {
+-                            newCode.putByte(201); // JSR_W
+-                        }
+-                        else {
+-                            newCode.putByte(opcode <= 166
+-                                    ? ((opcode + 1) ^ 1) - 1
+-                                    : opcode ^ 1);
+-                            newCode.putShort(8); // jump offset
+-                            newCode.putByte(200); // GOTO_W
+-                            // newOffset now computed from start of GOTO_W
+-                            newOffset -= 3;
+-                        }
+-                        newCode.putInt(newOffset);
+-                    }
+-                    else {
+-                        newCode.putByte(opcode);
+-                        newCode.putShort(newOffset);
+-                    }
+-                    u += 3;
+-                    break;
+-                case ClassWriter.LABELW_INSN:
+-                    label = u + readInt(b, u + 1);
+-                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
+-                    newCode.putByte(opcode);
+-                    newCode.putInt(newOffset);
+-                    u += 5;
+-                    break;
+-                case ClassWriter.TABL_INSN:
+-                    // skips 0 to 3 padding bytes
+-                    v = u;
+-                    u = u + 4 - (v & 3);
+-                    // reads and copies instruction
+-                    newCode.putByte(Opcodes.TABLESWITCH);
+-                    newCode.length += (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.length += (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:
+-                    newCode.putByteArray(b, u, 5);
+-                    u += 5;
+-                    break;
+-                    // case MANA_INSN:
+-                default:
+-                    newCode.putByteArray(b, u, 4);
+-                    u += 4;
+-                    break;
+-            }
+-        }
+-
+-        // recomputes the stack map frames
+-        if (frameCount > 0) {
+-            if (compute == FRAMES) {
+-                frameCount = 0;
+-                stackMap = null;
+-                previousFrame = null;
+-                frame = null;
+-                Frame f = new Frame();
+-                f.owner = labels;
+-                Type[] args = Type.getArgumentTypes(descriptor);
+-                f.initInputFrame(cw, access, args, maxLocals);
+-                visitFrame(f);
+-                Label l = labels;
+-                while (l != null) {
+-                    /*
+-                     * here we need the original label position. getNewOffset
+-                     * must therefore never have been called for this label.
+-                     */
+-                    u = l.position - 3;
+-                    if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) {
+-                        getNewOffset(allIndexes, allSizes, l);
+-                        visitFrame(l.frame);
+-                    }
+-                    l = l.successor;
+-                }
+-            }
+-            else {
+-                /*
+-                 * Resizing an existing stack map frame table is really hard.
+-                 * Not only the table must be parsed to update the offets, but
+-                 * new frames may be needed for jump instructions that were
+-                 * inserted by this method. And updating the offsets or
+-                 * inserting frames can change the format of the following
+-                 * frames, in case of packed frames. In practice the whole table
+-                 * must be recomputed. For this the frames are marked as
+-                 * potentially invalid. This will cause the whole class to be
+-                 * reread and rewritten with the COMPUTE_FRAMES option (see the
+-                 * ClassWriter.toByteArray method). This is not very efficient
+-                 * but is much easier and requires much less code than any other
+-                 * method I can think of.
+-                 */
+-                cw.invalidFrames = true;
+-            }
+-        }
+-        // updates the exception handler ast labels
+-        Handler h = firstHandler;
+-        while (h != null) {
+-            getNewOffset(allIndexes, allSizes, h.start);
+-            getNewOffset(allIndexes, allSizes, h.end);
+-            getNewOffset(allIndexes, allSizes, h.handler);
+-            h = h.next;
+-        }
+-        // updates the instructions addresses in the
+-        // local var and line number tables
+-        for (i = 0; i < 2; ++i) {
+-            ByteVector bv = i == 0 ? localVar : localVarType;
+-            if (bv != null) {
+-                b = bv.data;
+-                u = 0;
+-                while (u < bv.length) {
+-                    label = readUnsignedShort(b, u);
+-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label);
+-                    writeShort(b, u, newOffset);
+-                    label += readUnsignedShort(b, u + 2);
+-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label)
+-                            - newOffset;
+-                    writeShort(b, u + 2, newOffset);
+-                    u += 10;
+-                }
+-            }
+-        }
+-        if (lineNumber != null) {
+-            b = lineNumber.data;
+-            u = 0;
+-            while (u < lineNumber.length) {
+-                writeShort(b, u, getNewOffset(allIndexes,
+-                        allSizes,
+-                        0,
+-                        readUnsignedShort(b, u)));
+-                u += 4;
+-            }
+-        }
+-        // updates the labels of the other attributes
+-        Attribute attr = cattrs;
+-        while (attr != null) {
+-            Label[] labels = attr.getLabels();
+-            if (labels != null) {
+-                for (i = labels.length - 1; i >= 0; --i) {
+-                    getNewOffset(allIndexes, allSizes, labels[i]);
+-                }
+-            }
+-            attr = attr.next;
+-        }
+-
+-        // replaces old bytecodes with new ones
+-        code = newCode;
+-    }
+-
+-    /**
+-     * Reads an unsigned short value in the given byte array.
+-     *
+-     * @param b     a byte array.
+-     * @param index the start index of the value to be read.
+-     * @return the read value.
+-     */
+-    static int readUnsignedShort(final byte[] b, final int index) {
+-        return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
+-    }
+-
+-    /**
+-     * Reads a signed short value in the given byte array.
+-     *
+-     * @param b     a byte array.
+-     * @param index the start index of the value to be read.
+-     * @return the read value.
+-     */
+-    static short readShort(final byte[] b, final int index) {
+-        return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
+-    }
+-
+-    /**
+-     * Reads a signed int value in the given byte array.
+-     *
+-     * @param b     a byte array.
+-     * @param index the start index of the value to be read.
+-     * @return the read value.
+-     */
+-    static int readInt(final byte[] b, final int index) {
+-        return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
+-                | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
+-    }
+-
+-    /**
+-     * Writes a short value in the given byte array.
+-     *
+-     * @param b     a byte array.
+-     * @param index where the first byte of the short value must be written.
+-     * @param s     the value to be written in the given byte array.
+-     */
+-    static void writeShort(final byte[] b, final int index, final int s) {
+-        b[index] = (byte) (s >>> 8);
+-        b[index + 1] = (byte) s;
+-    }
+-
+-    /**
+-     * Computes the future value of a bytecode offset. <p> Note: it is possible
+-     * to have several entries for the same instruction in the <tt>indexes</tt>
+-     * and <tt>sizes</tt>: two entries (index=a,size=b) and (index=a,size=b')
+-     * are equivalent to a single entry (index=a,size=b+b').
+-     *
+-     * @param indexes current positions of the instructions to be resized. Each
+-     *                instruction must be designated by the index of its <i>last</i>
+-     *                byte, plus one (or, in other words, by the index of the <i>first</i>
+-     *                byte of the <i>next</i> instruction).
+-     * @param sizes   the number of bytes to be <i>added</i> to the above
+-     *                instructions. More precisely, for each i < <tt>len</tt>,
+-     *                <tt>sizes</tt>[i] bytes will be added at the end of the
+-     *                instruction designated by <tt>indexes</tt>[i] or, if
+-     *                <tt>sizes</tt>[i] is negative, the <i>last</i> |<tt>sizes[i]</tt>|
+-     *                bytes of the instruction will be removed (the instruction size
+-     *                <i>must not</i> become negative or null).
+-     * @param begin   index of the first byte of the source instruction.
+-     * @param end     index of the first byte of the target instruction.
+-     * @return the future value of the given bytecode offset.
+-     */
+-    static int getNewOffset(
+-            final int[] indexes,
+-            final int[] sizes,
+-            final int begin,
+-            final int end) {
+-        int offset = end - begin;
+-        for (int i = 0; i < indexes.length; ++i) {
+-            if (begin < indexes[i] && indexes[i] <= end) {
+-                // forward jump
+-                offset += sizes[i];
+-            }
+-            else if (end < indexes[i] && indexes[i] <= begin) {
+-                // backward jump
+-                offset -= sizes[i];
+-            }
+-        }
+-        return offset;
+-    }
+-
+-    /**
+-     * Updates the offset of the given label.
+-     *
+-     * @param indexes current positions of the instructions to be resized. Each
+-     *                instruction must be designated by the index of its <i>last</i>
+-     *                byte, plus one (or, in other words, by the index of the <i>first</i>
+-     *                byte of the <i>next</i> instruction).
+-     * @param sizes   the number of bytes to be <i>added</i> to the above
+-     *                instructions. More precisely, for each i < <tt>len</tt>,
+-     *                <tt>sizes</tt>[i] bytes will be added at the end of the
+-     *                instruction designated by <tt>indexes</tt>[i] or, if
+-     *                <tt>sizes</tt>[i] is negative, the <i>last</i> |<tt>sizes[i]</tt>|
+-     *                bytes of the instruction will be removed (the instruction size
+-     *                <i>must not</i> become negative or null).
+-     * @param label   the label whose offset must be updated.
+-     */
+-    static void getNewOffset(
+-            final int[] indexes,
+-            final int[] sizes,
+-            final Label label) {
+-        if ((label.status & Label.RESIZED) == 0) {
+-            label.position = getNewOffset(indexes, sizes, 0, label.position);
+-            label.status |= Label.RESIZED;
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/Opcodes.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Opcodes.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/Opcodes.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Opcodes.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,341 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 {
+-
+-    // 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;
+-
+-    // access flags
+-
+-    int ACC_PUBLIC = 0x0001; // class, field, method
+-    int ACC_PRIVATE = 0x0002; // class, field, method
+-    int ACC_PROTECTED = 0x0004; // class, field, method
+-    int ACC_STATIC = 0x0008; // field, method
+-    int ACC_FINAL = 0x0010; // class, field, method
+-    int ACC_SUPER = 0x0020; // class
+-    int ACC_SYNCHRONIZED = 0x0020; // method
+-    int ACC_VOLATILE = 0x0040; // field
+-    int ACC_BRIDGE = 0x0040; // method
+-    int ACC_VARARGS = 0x0080; // method
+-    int ACC_TRANSIENT = 0x0080; // field
+-    int ACC_NATIVE = 0x0100; // method
+-    int ACC_INTERFACE = 0x0200; // class
+-    int ACC_ABSTRACT = 0x0400; // class, method
+-    int ACC_STRICT = 0x0800; // method
+-    int ACC_SYNTHETIC = 0x1000; // class, field, method
+-    int ACC_ANNOTATION = 0x2000; // class
+-    int ACC_ENUM = 0x4000; // class(?) field inner
+-
+-    // ASM specific pseudo access flags
+-
+-    int ACC_DEPRECATED = 131072; // 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;
+-
+-    // 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 UNUSED = 186; // NOT VISITED
+-    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-2.0.19/src/main/java/org/mvel2/asm/package.html mvel-2.0.19-gil/src/main/java/org/mvel2/asm/package.html
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/package.html	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/package.html	1970-01-01 01:00:00.000000000 +0100
+@@ -1,87 +0,0 @@
+-<html>
+-<!--
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- *    notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- *    notice, this list of conditions and the following disclaimer in the
+- *    documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- *    contributors may be used to endorse or promote products derived from
+- *    this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+--->
+-<body>
+-Provides a small and fast bytecode manipulation framework.
+-
+-<p>
+-    The <a href="http://www.objectweb.org/asm">ASM</a> framework is organized
+-    around the {@link org.mvel.asm.ClassVisitor ClassVisitor},
+-    {@link org.mvel.asm.FieldVisitor FieldVisitor} and
+-    {@link org.mvel.asm.MethodVisitor MethodVisitor} interfaces, which allow
+-    one to visit the fields and methods of a class, including the bytecode
+-    instructions of each method.
+-
+-<p>
+-    In addition to these main interfaces, ASM provides a {@link
+-    org.mvel.asm.ClassReader ClassReader} class, that can parse an
+-    existing class and make a given visitor visit it. ASM also provides
+-    a {@link org.mvel.asm.ClassWriter ClassWriter} class, which is
+-    a visitor that generates Java class files.
+-
+-<p>
+-    In order to generate a class from scratch, only the {@link
+-    org.mvel.asm.ClassWriter ClassWriter} class is necessary. Indeed,
+-    in order to generate a class, one must just call its visit<i>XXX</i>
+-    methods with the appropriate arguments to generate the desired fields
+-    and methods. See the "helloworld" example in the ASM distribution for
+-    more details about class generation.
+-
+-<p>
+-    In order to modify existing classes, one must use a {@link
+-    org.mvel.asm.ClassReader ClassReader} class to analyze
+-    the original class, a class modifier, and a {@link org.mvel.asm.ClassWriter
+-    ClassWriter} to construct the modified class. The class modifier
+-    is just a {@link org.mvel.asm.ClassVisitor ClassVisitor}
+-    that delegates most of the work to another {@link org.mvel.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, ASM provides the {@link org.mvel.asm.ClassAdapter
+-    ClassAdapter} and {@link org.mvel.asm.MethodAdapter MethodAdapter}
+-    classes, which implement the {@link org.mvel.asm.ClassVisitor ClassVisitor}
+-    and {@link org.mvel.asm.MethodVisitor MethodVisitor} interfaces by
+-    delegating all work to other visitors. See the "adapt" example in the ASM
+-    distribution for more details about class modification.
+-
+-<p>
+-    The size of the core ASM library, <tt>asm.jar</tt>, is only 42KB, which is much
+-    smaller than the size of the
+-    <a href="http://jakarta.apache.org/bcel">BCEL</a> library (504KB), and than the
+-    size of the
+-    <a href="http://serp.sourceforge.net">SERP</a> library (150KB). ASM is also
+-    much faster than these tools. Indeed the overhead of a load time class
+-    transformation process is of the order of 60% with ASM, 700% or more with BCEL,
+-    and 1100% or more with SERP (see the <tt>test/perf</tt> directory in the ASM
+-    distribution)!
+-
+-    @since ASM 1.3
+-</body>
+-</html>
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/signature/package.html mvel-2.0.19-gil/src/main/java/org/mvel2/asm/signature/package.html
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/signature/package.html	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/signature/package.html	1970-01-01 01:00:00.000000000 +0100
+@@ -1,36 +0,0 @@
+-<html>
+-<!--
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 INRIA, France Telecom
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- *    notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- *    notice, this list of conditions and the following disclaimer in the
+- *    documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the copyright holders nor the names of its
+- *    contributors may be used to endorse or promote products derived from
+- *    this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+- * THE POSSIBILITY OF SUCH DAMAGE.
+--->
+-<body>
+-Provides support for type signatures.
+-
+- at since ASM 2.0
+-</body>
+-</html>
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/signature/SignatureReader.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/signature/SignatureReader.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/signature/SignatureReader.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/signature/SignatureReader.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,233 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 <i>ClassSignature</i>, <i>MethodTypeSignature</i>,
+-     *        or <i>FieldTypeSignature</i>.
+-     */
+-    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 <i>ClassSignature</i> (such as the
+-     * <code>signature</code> parameter of the
+-     * {@link org.objectweb.asm.ClassVisitor#visit ClassVisitor.visit} method)
+-     * or a <i>MethodTypeSignature</i> (such as the <code>signature</code>
+-     * parameter of the
+-     * {@link org.objectweb.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());
+-                }
+-
+-                for (;;) {
+-                    if ((c = signature.charAt(pos++)) == ':') {
+-                        pos = parseType(signature, pos, v.visitInterfaceBound());
+-                    } else {
+-                        break;
+-                    }
+-                }
+-            } while (c != '>');
+-        } else {
+-            pos = 0;
+-        }
+-
+-        if (signature.charAt(pos) == '(') {
+-            pos = pos + 1;
+-            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 <i>FieldTypeSignature</i>, such as the
+-     * <code>signature</code> parameter of the
+-     * {@link org.objectweb.asm.ClassVisitor#visitField 
+-     * ClassVisitor.visitField} or {@link 
+-     * org.objectweb.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-2.0.19/src/main/java/org/mvel2/asm/signature/SignatureVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/signature/SignatureVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/signature/SignatureVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/signature/SignatureVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,185 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 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): <ul> <li><i>ClassSignature</i> = (
+- * <tt>visitFormalTypeParameter</tt> 
+- *   <tt>visitClassBound</tt>?
+- * <tt>visitInterfaceBound</tt>* )* ( <tt>visitSuperClass</tt> 
+- *   <tt>visitInterface</tt>* )</li>
+- * <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt> 
+- *   <tt>visitClassBound</tt>?
+- * <tt>visitInterfaceBound</tt>* )* ( <tt>visitParameterType</tt>*
+- * <tt>visitReturnType</tt> 
+- *   <tt>visitExceptionType</tt>* )</li> <li><i>TypeSignature</i> =
+- * <tt>visitBaseType</tt> | <tt>visitTypeVariable</tt> |
+- * <tt>visitArrayType</tt> | (
+- * <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* (
+- * <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )*
+- * <tt>visitEnd</tt> ) )</li> </ul>
+- * 
+- * @author Thomas Hallgren
+- * @author Eric Bruneton
+- */
+-public interface SignatureVisitor {
+-
+-    /**
+-     * Wildcard for an "extends" type argument.
+-     */
+-    char EXTENDS = '+';
+-
+-    /**
+-     * Wildcard for a "super" type argument.
+-     */
+-    char SUPER = '-';
+-
+-    /**
+-     * Wildcard for a normal type argument.
+-     */
+-    char INSTANCEOF = '=';
+-
+-    /**
+-     * Visits a formal type parameter.
+-     * 
+-     * @param name the name of the formal parameter.
+-     */
+-    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.
+-     */
+-    SignatureVisitor visitClassBound();
+-
+-    /**
+-     * Visits an interface bound of the last visited formal type parameter.
+-     * 
+-     * @return a non null visitor to visit the signature of the interface bound.
+-     */
+-    SignatureVisitor visitInterfaceBound();
+-
+-    /**
+-     * Visits the type of the super class.
+-     * 
+-     * @return a non null visitor to visit the signature of the super class
+-     *         type.
+-     */
+-    SignatureVisitor visitSuperclass();
+-
+-    /**
+-     * Visits the type of an interface implemented by the class.
+-     * 
+-     * @return a non null visitor to visit the signature of the interface type.
+-     */
+-    SignatureVisitor visitInterface();
+-
+-    /**
+-     * Visits the type of a method parameter.
+-     * 
+-     * @return a non null visitor to visit the signature of the parameter type.
+-     */
+-    SignatureVisitor visitParameterType();
+-
+-    /**
+-     * Visits the return type of the method.
+-     * 
+-     * @return a non null visitor to visit the signature of the return type.
+-     */
+-    SignatureVisitor visitReturnType();
+-
+-    /**
+-     * Visits the type of a method exception.
+-     * 
+-     * @return a non null visitor to visit the signature of the exception type.
+-     */
+-    SignatureVisitor visitExceptionType();
+-
+-    /**
+-     * Visits a signature corresponding to a primitive type.
+-     * 
+-     * @param descriptor the descriptor of the primitive type, or 'V' for
+-     *        <tt>void</tt>.
+-     */
+-    void visitBaseType(char descriptor);
+-
+-    /**
+-     * Visits a signature corresponding to a type variable.
+-     * 
+-     * @param name the name of the type variable.
+-     */
+-    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.
+-     */
+-    SignatureVisitor visitArrayType();
+-
+-    /**
+-     * Starts the visit of a signature corresponding to a class or interface
+-     * type.
+-     * 
+-     * @param name the internal name of the class or interface.
+-     */
+-    void visitClassType(String name);
+-
+-    /**
+-     * Visits an inner class.
+-     * 
+-     * @param name the local name of the inner class in its enclosing class.
+-     */
+-    void visitInnerClassType(String name);
+-
+-    /**
+-     * Visits an unbounded type argument of the last visited class or inner
+-     * class type.
+-     */
+-    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.
+-     */
+-    SignatureVisitor visitTypeArgument(char wildcard);
+-
+-    /**
+-     * Ends the visit of a signature corresponding to a class or interface type.
+-     */
+-    void visitEnd();
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/signature/SignatureWriter.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/signature/SignatureWriter.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/signature/SignatureWriter.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/signature/SignatureWriter.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,207 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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 signature visitor that generates signatures in string format.
+- * 
+- * @author Thomas Hallgren
+- * @author Eric Bruneton
+- */
+-public class SignatureWriter implements 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() {
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Implementation of the SignatureVisitor interface
+-    // ------------------------------------------------------------------------
+-
+-    public void visitFormalTypeParameter(final String name) {
+-        if (!hasFormals) {
+-            hasFormals = true;
+-            buf.append('<');
+-        }
+-        buf.append(name);
+-        buf.append(':');
+-    }
+-
+-    public SignatureVisitor visitClassBound() {
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitInterfaceBound() {
+-        buf.append(':');
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitSuperclass() {
+-        endFormals();
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitInterface() {
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitParameterType() {
+-        endFormals();
+-        if (!hasParameters) {
+-            hasParameters = true;
+-            buf.append('(');
+-        }
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitReturnType() {
+-        endFormals();
+-        if (!hasParameters) {
+-            buf.append('(');
+-        }
+-        buf.append(')');
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitExceptionType() {
+-        buf.append('^');
+-        return this;
+-    }
+-
+-    public void visitBaseType(final char descriptor) {
+-        buf.append(descriptor);
+-    }
+-
+-    public void visitTypeVariable(final String name) {
+-        buf.append('T');
+-        buf.append(name);
+-        buf.append(';');
+-    }
+-
+-    public SignatureVisitor visitArrayType() {
+-        buf.append('[');
+-        return this;
+-    }
+-
+-    public void visitClassType(final String name) {
+-        buf.append('L');
+-        buf.append(name);
+-        argumentStack *= 2;
+-    }
+-
+-    public void visitInnerClassType(final String name) {
+-        endArguments();
+-        buf.append('.');
+-        buf.append(name);
+-        argumentStack *= 2;
+-    }
+-
+-    public void visitTypeArgument() {
+-        if (argumentStack % 2 == 0) {
+-            ++argumentStack;
+-            buf.append('<');
+-        }
+-        buf.append('*');
+-    }
+-
+-    public SignatureVisitor visitTypeArgument(final char wildcard) {
+-        if (argumentStack % 2 == 0) {
+-            ++argumentStack;
+-            buf.append('<');
+-        }
+-        if (wildcard != '=') {
+-            buf.append(wildcard);
+-        }
+-        return this;
+-    }
+-
+-    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.
+-     */
+-    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-2.0.19/src/main/java/org/mvel2/asm/Type.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Type.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/Type.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/Type.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,815 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.lang.reflect.Constructor;
+-import java.lang.reflect.Method;
+-
+-/**
+- * A Java type. This class can be used to make it easier to manipulate type and
+- * method descriptors.
+- *
+- * @author Eric Bruneton
+- * @author Chris Nokleberg
+- */
+-public class Type {
+-
+-    /**
+-     * The sort of the <tt>void</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int VOID = 0;
+-
+-    /**
+-     * The sort of the <tt>boolean</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int BOOLEAN = 1;
+-
+-    /**
+-     * The sort of the <tt>char</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int CHAR = 2;
+-
+-    /**
+-     * The sort of the <tt>byte</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int BYTE = 3;
+-
+-    /**
+-     * The sort of the <tt>short</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int SHORT = 4;
+-
+-    /**
+-     * The sort of the <tt>int</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int INT = 5;
+-
+-    /**
+-     * The sort of the <tt>float</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int FLOAT = 6;
+-
+-    /**
+-     * The sort of the <tt>long</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int LONG = 7;
+-
+-    /**
+-     * The sort of the <tt>double</tt> type. See {@link #getSort getSort}.
+-     */
+-    public final static int DOUBLE = 8;
+-
+-    /**
+-     * The sort of array reference types. See {@link #getSort getSort}.
+-     */
+-    public final static int ARRAY = 9;
+-
+-    /**
+-     * The sort of object reference type. See {@link #getSort getSort}.
+-     */
+-    public final static int OBJECT = 10;
+-
+-    /**
+-     * The <tt>void</tt> type.
+-     */
+-    public final static Type VOID_TYPE = new Type(VOID);
+-
+-    /**
+-     * The <tt>boolean</tt> type.
+-     */
+-    public final static Type BOOLEAN_TYPE = new Type(BOOLEAN);
+-
+-    /**
+-     * The <tt>char</tt> type.
+-     */
+-    public final static Type CHAR_TYPE = new Type(CHAR);
+-
+-    /**
+-     * The <tt>byte</tt> type.
+-     */
+-    public final static Type BYTE_TYPE = new Type(BYTE);
+-
+-    /**
+-     * The <tt>short</tt> type.
+-     */
+-    public final static Type SHORT_TYPE = new Type(SHORT);
+-
+-    /**
+-     * The <tt>int</tt> type.
+-     */
+-    public final static Type INT_TYPE = new Type(INT);
+-
+-    /**
+-     * The <tt>float</tt> type.
+-     */
+-    public final static Type FLOAT_TYPE = new Type(FLOAT);
+-
+-    /**
+-     * The <tt>long</tt> type.
+-     */
+-    public final static Type LONG_TYPE = new Type(LONG);
+-
+-    /**
+-     * The <tt>double</tt> type.
+-     */
+-    public final static Type DOUBLE_TYPE = new Type(DOUBLE);
+-
+-    // ------------------------------------------------------------------------
+-    // Fields
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * The sort of this Java type.
+-     */
+-    private final int sort;
+-
+-    /**
+-     * A buffer containing the descriptor of this Java type. This field is only
+-     * used for reference types.
+-     */
+-    private char[] buf;
+-
+-    /**
+-     * The offset of the descriptor of this Java type in {@link #buf buf}. This
+-     * field is only used for reference types.
+-     */
+-    private int off;
+-
+-    /**
+-     * The length of the descriptor of this Java type.
+-     */
+-    private int len;
+-
+-    // ------------------------------------------------------------------------
+-    // Constructors
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Constructs a primitive type.
+-     *
+-     * @param sort the sort of the primitive type to be constructed.
+-     */
+-    private Type(final int sort) {
+-        this.sort = sort;
+-        this.len = 1;
+-    }
+-
+-    /**
+-     * Constructs a reference type.
+-     *
+-     * @param sort the sort of the reference type to be constructed.
+-     * @param buf  a buffer containing the descriptor of the previous type.
+-     * @param off  the offset of this descriptor in the previous buffer.
+-     * @param len  the length of this descriptor.
+-     */
+-    private Type(final int sort, final char[] buf, final int off, final int len) {
+-        this.sort = sort;
+-        this.buf = buf;
+-        this.off = off;
+-        this.len = len;
+-    }
+-
+-    /**
+-     * Returns the Java type corresponding to the given type descriptor.
+-     *
+-     * @param typeDescriptor a type descriptor.
+-     * @return the Java type corresponding to the given type descriptor.
+-     */
+-    public static Type getType(final String typeDescriptor) {
+-        return getType(typeDescriptor.toCharArray(), 0);
+-    }
+-
+-    /**
+-     * Returns the Java type corresponding to the given class.
+-     *
+-     * @param c a class.
+-     * @return the Java type corresponding to the given class.
+-     */
+-    public static Type getType(final Class c) {
+-        if (c.isPrimitive()) {
+-            if (c == Integer.TYPE) {
+-                return INT_TYPE;
+-            }
+-            else if (c == Void.TYPE) {
+-                return VOID_TYPE;
+-            }
+-            else if (c == Boolean.TYPE) {
+-                return BOOLEAN_TYPE;
+-            }
+-            else if (c == Byte.TYPE) {
+-                return BYTE_TYPE;
+-            }
+-            else if (c == Character.TYPE) {
+-                return CHAR_TYPE;
+-            }
+-            else if (c == Short.TYPE) {
+-                return SHORT_TYPE;
+-            }
+-            else if (c == Double.TYPE) {
+-                return DOUBLE_TYPE;
+-            }
+-            else if (c == Float.TYPE) {
+-                return FLOAT_TYPE;
+-            }
+-            else /* if (c == Long.TYPE) */ {
+-                return LONG_TYPE;
+-            }
+-        }
+-        else {
+-            return getType(getDescriptor(c));
+-        }
+-    }
+-
+-    /**
+-     * Returns the {@link Type#OBJECT} type for the given internal class name.
+-     * This is a shortcut method for <code>Type.getType("L"+name+";")</code>.
+-     * <i>Note that opposed to {@link Type#getType(String)}, this method takes
+-     * internal class names and not class descriptor.</i>
+-     *
+-     * @param name an internal class name.
+-     * @return the the {@link Type#OBJECT} type for the given class name.
+-     */
+-    public static Type getObjectType(String name) {
+-        int l = name.length();
+-        char[] buf = new char[l + 2];
+-        buf[0] = 'L';
+-        buf[l + 1] = ';';
+-        name.getChars(0, l, buf, 1);
+-        return new Type(OBJECT, buf, 0, l + 2);
+-    }
+-
+-    /**
+-     * Returns the Java types corresponding to the argument types of the given
+-     * method descriptor.
+-     *
+-     * @param methodDescriptor a method descriptor.
+-     * @return the Java types corresponding to the argument types of the given
+-     *         method descriptor.
+-     */
+-    public static Type[] getArgumentTypes(final String methodDescriptor) {
+-        char[] buf = methodDescriptor.toCharArray();
+-        int off = 1;
+-        int size = 0;
+-        while (true) {
+-            char car = buf[off++];
+-            if (car == ')') {
+-                break;
+-            }
+-            else if (car == 'L') {
+-                while (buf[off++] != ';') {
+-                }
+-                ++size;
+-            }
+-            else if (car != '[') {
+-                ++size;
+-            }
+-        }
+-        Type[] args = new Type[size];
+-        off = 1;
+-        size = 0;
+-        while (buf[off] != ')') {
+-            args[size] = getType(buf, off);
+-            off += args[size].len;
+-            size += 1;
+-        }
+-        return args;
+-    }
+-
+-    /**
+-     * Returns the Java types corresponding to the argument types of the given
+-     * method.
+-     *
+-     * @param method a method.
+-     * @return the Java types corresponding to the argument types of the given
+-     *         method.
+-     */
+-    public static Type[] getArgumentTypes(final Method method) {
+-        Class[] classes = method.getParameterTypes();
+-        Type[] types = new Type[classes.length];
+-        for (int i = classes.length - 1; i >= 0; --i) {
+-            types[i] = getType(classes[i]);
+-        }
+-        return types;
+-    }
+-
+-    /**
+-     * Returns the Java type corresponding to the return type of the given
+-     * method descriptor.
+-     *
+-     * @param methodDescriptor a method descriptor.
+-     * @return the Java type corresponding to the return type of the given
+-     *         method descriptor.
+-     */
+-    public static Type getReturnType(final String methodDescriptor) {
+-        char[] buf = methodDescriptor.toCharArray();
+-        return getType(buf, methodDescriptor.indexOf(')') + 1);
+-    }
+-
+-    /**
+-     * Returns the Java type corresponding to the return type of the given
+-     * method.
+-     *
+-     * @param method a method.
+-     * @return the Java type corresponding to the return type of the given
+-     *         method.
+-     */
+-    public static Type getReturnType(final Method method) {
+-        return getType(method.getReturnType());
+-    }
+-
+-    /**
+-     * Returns the Java type corresponding to the given type descriptor.
+-     *
+-     * @param buf a buffer containing a type descriptor.
+-     * @param off the offset of this descriptor in the previous buffer.
+-     * @return the Java type corresponding to the given type descriptor.
+-     */
+-    private static Type getType(final char[] buf, final int off) {
+-        int len;
+-        switch (buf[off]) {
+-            case 'V':
+-                return VOID_TYPE;
+-            case 'Z':
+-                return BOOLEAN_TYPE;
+-            case 'C':
+-                return CHAR_TYPE;
+-            case 'B':
+-                return BYTE_TYPE;
+-            case 'S':
+-                return SHORT_TYPE;
+-            case 'I':
+-                return INT_TYPE;
+-            case 'F':
+-                return FLOAT_TYPE;
+-            case 'J':
+-                return LONG_TYPE;
+-            case 'D':
+-                return DOUBLE_TYPE;
+-            case '[':
+-                len = 1;
+-                while (buf[off + len] == '[') {
+-                    ++len;
+-                }
+-                if (buf[off + len] == 'L') {
+-                    ++len;
+-                    while (buf[off + len] != ';') {
+-                        ++len;
+-                    }
+-                }
+-                return new Type(ARRAY, buf, off, len + 1);
+-                // case 'L':
+-            default:
+-                len = 1;
+-                while (buf[off + len] != ';') {
+-                    ++len;
+-                }
+-                return new Type(OBJECT, buf, off, len + 1);
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Accessors
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Returns the sort of this Java type.
+-     *
+-     * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN},
+-     *         {@link #CHAR CHAR}, {@link #BYTE BYTE}, {@link #SHORT SHORT},
+-     *         {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
+-     *         {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY} or
+-     *         {@link #OBJECT OBJECT}.
+-     */
+-    public int getSort() {
+-        return sort;
+-    }
+-
+-    /**
+-     * Returns the number of dimensions of this array type. This method should
+-     * only be used for an array type.
+-     *
+-     * @return the number of dimensions of this array type.
+-     */
+-    public int getDimensions() {
+-        int i = 1;
+-        while (buf[off + i] == '[') {
+-            ++i;
+-        }
+-        return i;
+-    }
+-
+-    /**
+-     * Returns the type of the elements of this array type. This method should
+-     * only be used for an array type.
+-     *
+-     * @return Returns the type of the elements of this array type.
+-     */
+-    public Type getElementType() {
+-        return getType(buf, off + getDimensions());
+-    }
+-
+-    /**
+-     * Returns the name of the class corresponding to this type.
+-     *
+-     * @return the fully qualified name of the class corresponding to this type.
+-     */
+-    public String getClassName() {
+-        switch (sort) {
+-            case VOID:
+-                return "void";
+-            case BOOLEAN:
+-                return "boolean";
+-            case CHAR:
+-                return "char";
+-            case BYTE:
+-                return "byte";
+-            case SHORT:
+-                return "short";
+-            case INT:
+-                return "int";
+-            case FLOAT:
+-                return "float";
+-            case LONG:
+-                return "long";
+-            case DOUBLE:
+-                return "double";
+-            case ARRAY:
+-                StringBuffer b = new StringBuffer(getElementType().getClassName());
+-                for (int i = getDimensions(); i > 0; --i) {
+-                    b.append("[]");
+-                }
+-                return b.toString();
+-                // case OBJECT:
+-            default:
+-                return new String(buf, off + 1, len - 2).replace('/', '.');
+-        }
+-    }
+-
+-    /**
+-     * Returns the internal name of the class corresponding to this object type.
+-     * The internal name of a class is its fully qualified name, where '.' are
+-     * replaced by '/'. This method should only be used for an object type.
+-     *
+-     * @return the internal name of the class corresponding to this object type.
+-     */
+-    public String getInternalName() {
+-        return new String(buf, off + 1, len - 2);
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Conversion to type descriptors
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Returns the descriptor corresponding to this Java type.
+-     *
+-     * @return the descriptor corresponding to this Java type.
+-     */
+-    public String getDescriptor() {
+-        StringBuffer buf = new StringBuffer();
+-        getDescriptor(buf);
+-        return buf.toString();
+-    }
+-
+-    /**
+-     * Returns the descriptor corresponding to the given argument and return
+-     * types.
+-     *
+-     * @param returnType    the return type of the method.
+-     * @param argumentTypes the argument types of the method.
+-     * @return the descriptor corresponding to the given argument and return
+-     *         types.
+-     */
+-    public static String getMethodDescriptor(
+-            final Type returnType,
+-            final Type[] argumentTypes) {
+-        StringBuffer buf = new StringBuffer();
+-        buf.append('(');
+-        for (int i = 0; i < argumentTypes.length; ++i) {
+-            argumentTypes[i].getDescriptor(buf);
+-        }
+-        buf.append(')');
+-        returnType.getDescriptor(buf);
+-        return buf.toString();
+-    }
+-
+-    /**
+-     * Appends the descriptor corresponding to this Java type to the given
+-     * string buffer.
+-     *
+-     * @param buf the string buffer to which the descriptor must be appended.
+-     */
+-    private void getDescriptor(final StringBuffer buf) {
+-        switch (sort) {
+-            case VOID:
+-                buf.append('V');
+-                return;
+-            case BOOLEAN:
+-                buf.append('Z');
+-                return;
+-            case CHAR:
+-                buf.append('C');
+-                return;
+-            case BYTE:
+-                buf.append('B');
+-                return;
+-            case SHORT:
+-                buf.append('S');
+-                return;
+-            case INT:
+-                buf.append('I');
+-                return;
+-            case FLOAT:
+-                buf.append('F');
+-                return;
+-            case LONG:
+-                buf.append('J');
+-                return;
+-            case DOUBLE:
+-                buf.append('D');
+-                return;
+-                // case ARRAY:
+-                // case OBJECT:
+-            default:
+-                buf.append(this.buf, off, len);
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Direct conversion from classes to type descriptors,
+-    // without intermediate Type objects
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Returns the internal name of the given class. The internal name of a
+-     * class is its fully qualified name, where '.' are replaced by '/'.
+-     *
+-     * @param c an object class.
+-     * @return the internal name of the given class.
+-     */
+-    public static String getInternalName(final Class c) {
+-        return c.getName().replace('.', '/');
+-    }
+-
+-    /**
+-     * Returns the descriptor corresponding to the given Java type.
+-     *
+-     * @param c an object class, a primitive class or an array class.
+-     * @return the descriptor corresponding to the given class.
+-     */
+-    public static String getDescriptor(final Class c) {
+-        StringBuffer buf = new StringBuffer();
+-        getDescriptor(buf, c);
+-        return buf.toString();
+-    }
+-
+-    /**
+-     * Returns the descriptor corresponding to the given constructor.
+-     *
+-     * @param c a {@link Constructor Constructor} object.
+-     * @return the descriptor of the given constructor.
+-     */
+-    public static String getConstructorDescriptor(final Constructor c) {
+-        Class[] parameters = c.getParameterTypes();
+-        StringBuffer buf = new StringBuffer();
+-        buf.append('(');
+-        for (int i = 0; i < parameters.length; ++i) {
+-            getDescriptor(buf, parameters[i]);
+-        }
+-        return buf.append(")V").toString();
+-    }
+-
+-    /**
+-     * Returns the descriptor corresponding to the given method.
+-     *
+-     * @param m a {@link Method Method} object.
+-     * @return the descriptor of the given method.
+-     */
+-    public static String getMethodDescriptor(final Method m) {
+-        Class[] parameters = m.getParameterTypes();
+-        StringBuffer buf = new StringBuffer();
+-        buf.append('(');
+-        for (int i = 0; i < parameters.length; ++i) {
+-            getDescriptor(buf, parameters[i]);
+-        }
+-        buf.append(')');
+-        getDescriptor(buf, m.getReturnType());
+-        return buf.toString();
+-    }
+-
+-    /**
+-     * Appends the descriptor of the given class to the given string buffer.
+-     *
+-     * @param buf the string buffer to which the descriptor must be appended.
+-     * @param c   the class whose descriptor must be computed.
+-     */
+-    private static void getDescriptor(final StringBuffer buf, final Class c) {
+-        Class d = c;
+-        while (true) {
+-            if (d.isPrimitive()) {
+-                char car;
+-                if (d == Integer.TYPE) {
+-                    car = 'I';
+-                }
+-                else if (d == Void.TYPE) {
+-                    car = 'V';
+-                }
+-                else if (d == Boolean.TYPE) {
+-                    car = 'Z';
+-                }
+-                else if (d == Byte.TYPE) {
+-                    car = 'B';
+-                }
+-                else if (d == Character.TYPE) {
+-                    car = 'C';
+-                }
+-                else if (d == Short.TYPE) {
+-                    car = 'S';
+-                }
+-                else if (d == Double.TYPE) {
+-                    car = 'D';
+-                }
+-                else if (d == Float.TYPE) {
+-                    car = 'F';
+-                }
+-                else /* if (d == Long.TYPE) */ {
+-                    car = 'J';
+-                }
+-                buf.append(car);
+-                return;
+-            }
+-            else if (d.isArray()) {
+-                buf.append('[');
+-                d = d.getComponentType();
+-            }
+-            else {
+-                buf.append('L');
+-                String name = d.getName();
+-                int len = name.length();
+-                for (int i = 0; i < len; ++i) {
+-                    char car = name.charAt(i);
+-                    buf.append(car == '.' ? '/' : car);
+-                }
+-                buf.append(';');
+-                return;
+-            }
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Corresponding size and opcodes
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Returns the size of values of this type.
+-     *
+-     * @return the size of values of this type, i.e., 2 for <tt>long</tt> and
+-     *         <tt>double</tt>, and 1 otherwise.
+-     */
+-    public int getSize() {
+-        return sort == LONG || sort == DOUBLE ? 2 : 1;
+-    }
+-
+-    /**
+-     * Returns a JVM instruction opcode adapted to this Java type.
+-     *
+-     * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD,
+-     *               ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL,
+-     *               ISHR, IUSHR, IAND, IOR, IXOR and IRETURN.
+-     * @return an opcode that is similar to the given opcode, but adapted to
+-     *         this Java type. For example, if this type is <tt>float</tt> and
+-     *         <tt>opcode</tt> is IRETURN, this method returns FRETURN.
+-     */
+-    public int getOpcode(final int opcode) {
+-        if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
+-            switch (sort) {
+-                case BOOLEAN:
+-                case BYTE:
+-                    return opcode + 5;
+-                case CHAR:
+-                    return opcode + 6;
+-                case SHORT:
+-                    return opcode + 7;
+-                case INT:
+-                    return opcode;
+-                case FLOAT:
+-                    return opcode + 2;
+-                case LONG:
+-                    return opcode + 1;
+-                case DOUBLE:
+-                    return opcode + 3;
+-                    // case ARRAY:
+-                    // case OBJECT:
+-                default:
+-                    return opcode + 4;
+-            }
+-        }
+-        else {
+-            switch (sort) {
+-                case VOID:
+-                    return opcode + 5;
+-                case BOOLEAN:
+-                case CHAR:
+-                case BYTE:
+-                case SHORT:
+-                case INT:
+-                    return opcode;
+-                case FLOAT:
+-                    return opcode + 2;
+-                case LONG:
+-                    return opcode + 1;
+-                case DOUBLE:
+-                    return opcode + 3;
+-                    // case ARRAY:
+-                    // case OBJECT:
+-                default:
+-                    return opcode + 4;
+-            }
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Equals, hashCode and toString
+-    // ------------------------------------------------------------------------
+-
+-    /**
+-     * Tests if the given object is equal to this type.
+-     *
+-     * @param o the object to be compared to this type.
+-     * @return <tt>true</tt> if the given object is equal to this type.
+-     */
+-    public boolean equals(final Object o) {
+-        if (this == o) {
+-            return true;
+-        }
+-        if (!(o instanceof Type)) {
+-            return false;
+-        }
+-        Type t = (Type) o;
+-        if (sort != t.sort) {
+-            return false;
+-        }
+-        if (sort == Type.OBJECT || sort == Type.ARRAY) {
+-            if (len != t.len) {
+-                return false;
+-            }
+-            for (int i = off, j = t.off, end = i + len; i < end; i++, j++) {
+-                if (buf[i] != t.buf[j]) {
+-                    return false;
+-                }
+-            }
+-        }
+-        return true;
+-    }
+-
+-    /**
+-     * Returns a hash code value for this type.
+-     *
+-     * @return a hash code value for this type.
+-     */
+-    public int hashCode() {
+-        int hc = 13 * sort;
+-        if (sort == Type.OBJECT || sort == Type.ARRAY) {
+-            for (int i = off, end = i + len; i < end; i++) {
+-                hc = 17 * (hc + buf[i]);
+-            }
+-        }
+-        return hc;
+-    }
+-
+-    /**
+-     * Returns a string representation of this type.
+-     *
+-     * @return the descriptor of this type.
+-     */
+-    public String toString() {
+-        return getDescriptor();
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/util/AbstractVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/AbstractVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/util/AbstractVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/AbstractVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,202 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.util;
+-
+-import java.io.PrintWriter;
+-import java.util.ArrayList;
+-import java.util.List;
+-
+-import org.mvel2.asm.Attribute;
+-
+-/**
+- * An abstract visitor.
+- * 
+- * @author Eric Bruneton
+- */
+-public abstract class AbstractVisitor {
+-
+-    /**
+-     * The names of the Java Virtual Machine opcodes.
+-     */
+-    public final static String[] OPCODES;
+-    /**
+-     * Types for <code>operand</code> parameter of the
+-     * {@link org.objectweb.asm.MethodVisitor#visitIntInsn} method when
+-     * <code>opcode</code> is <code>NEWARRAY</code>.
+-     */
+-    public final static String[] TYPES;
+-
+-    static {
+-        String s = "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,BIPUSH,SIPUSH,LDC,,,"
+-                + "ILOAD,LLOAD,FLOAD,DLOAD,ALOAD,,,,,,,,,,,,,,,,,,,,,IALOAD,"
+-                + "LALOAD,FALOAD,DALOAD,AALOAD,BALOAD,CALOAD,SALOAD,ISTORE,"
+-                + "LSTORE,FSTORE,DSTORE,ASTORE,,,,,,,,,,,,,,,,,,,,,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,IINC,I2L,"
+-                + "I2F,I2D,L2I,L2F,L2D,F2I,F2L,F2D,D2I,D2L,D2F,I2B,I2C,I2S,LCMP,"
+-                + "FCMPL,FCMPG,DCMPL,DCMPG,IFEQ,IFNE,IFLT,IFGE,IFGT,IFLE,"
+-                + "IF_ICMPEQ,IF_ICMPNE,IF_ICMPLT,IF_ICMPGE,IF_ICMPGT,IF_ICMPLE,"
+-                + "IF_ACMPEQ,IF_ACMPNE,GOTO,JSR,RET,TABLESWITCH,LOOKUPSWITCH,"
+-                + "IRETURN,LRETURN,FRETURN,DRETURN,ARETURN,RETURN,GETSTATIC,"
+-                + "PUTSTATIC,GETFIELD,PUTFIELD,INVOKEVIRTUAL,INVOKESPECIAL,"
+-                + "INVOKESTATIC,INVOKEINTERFACE,,NEW,NEWARRAY,ANEWARRAY,"
+-                + "ARRAYLENGTH,ATHROW,CHECKCAST,INSTANCEOF,MONITORENTER,"
+-                + "MONITOREXIT,,MULTIANEWARRAY,IFNULL,IFNONNULL,";
+-        OPCODES = new String[200];
+-        int i = 0;
+-        int j = 0;
+-        int l;
+-        while ((l = s.indexOf(',', j)) > 0) {
+-            OPCODES[i++] = j + 1 == l ? null : s.substring(j, l);
+-            j = l + 1;
+-        }
+-
+-        s = "T_BOOLEAN,T_CHAR,T_FLOAT,T_DOUBLE,T_BYTE,T_SHORT,T_INT,T_LONG,";
+-        TYPES = new String[12];
+-        j = 0;
+-        i = 4;
+-        while ((l = s.indexOf(',', j)) > 0) {
+-            TYPES[i++] = s.substring(j, l);
+-            j = l + 1;
+-        }
+-    }
+-
+-    /**
+-     * The text to be printed. Since the code of methods is not necessarily
+-     * visited in sequential order, one method after the other, but can be
+-     * interlaced (some instructions from method one, then some instructions
+-     * from method two, then some instructions from method one again...), it is
+-     * not possible to print the visited instructions directly to a sequential
+-     * stream. A class is therefore printed in a two steps process: a string
+-     * tree is constructed during the visit, and printed to a sequential stream
+-     * at the end of the visit. This string tree is stored in this field, as a
+-     * string list that can contain other string lists, which can themselves
+-     * contain other string lists, and so on.
+-     */
+-    public final List text;
+-
+-    /**
+-     * A buffer that can be used to create strings.
+-     */
+-    protected final StringBuffer buf;
+-
+-    /**
+-     * Constructs a new {@link AbstractVisitor}.
+-     */
+-    protected AbstractVisitor() {
+-        this.text = new ArrayList();
+-        this.buf = new StringBuffer();
+-    }
+-
+-    /**
+-     * Returns the text constructed by this visitor.
+-     * 
+-     * @return the text constructed by this visitor.
+-     */
+-    public List getText() {
+-        return text;
+-    }
+-
+-    /**
+-     * Prints the text constructed by this visitor.
+-     * 
+-     * @param pw the print writer to be used.
+-     */
+-    public void print(final PrintWriter pw) {
+-        printList(pw, text);
+-    }
+-    
+-    /**
+-     * Appends a quoted string to a given buffer.
+-     * 
+-     * @param buf the buffer where the string must be added.
+-     * @param s the string to be added.
+-     */
+-    public static void appendString(final StringBuffer buf, final String s) {
+-        buf.append('\"');
+-        for (int i = 0; i < s.length(); ++i) {
+-            char c = s.charAt(i);
+-            if (c == '\n') {
+-                buf.append("\\n");
+-            } else if (c == '\r') {
+-                buf.append("\\r");
+-            } else if (c == '\\') {
+-                buf.append("\\\\");
+-            } else if (c == '"') {
+-                buf.append("\\\"");
+-            } else if (c < 0x20 || c > 0x7f) {
+-                buf.append("\\u");
+-                if (c < 0x10) {
+-                    buf.append("000");
+-                } else if (c < 0x100) {
+-                    buf.append("00");
+-                } else if (c < 0x1000) {
+-                    buf.append('0');
+-                }
+-                buf.append(Integer.toString(c, 16));
+-            } else {
+-                buf.append(c);
+-            }
+-        }
+-        buf.append('\"');
+-    }
+-
+-    /**
+-     * Prints the given string tree.
+-     * 
+-     * @param pw the writer to be used to print the tree.
+-     * @param l a string tree, i.e., a string list that can contain other string
+-     *        lists, and so on recursively.
+-     */
+-    void printList(final PrintWriter pw, final List l) {
+-        for (int i = 0; i < l.size(); ++i) {
+-            Object o = l.get(i);
+-            if (o instanceof List) {
+-                printList(pw, (List) o);
+-            } else {
+-                pw.print(o.toString());
+-            }
+-        }
+-    }
+-
+-    /**
+-     * Returns the default {@link ASMifiable} prototypes.
+-     * 
+-     * @return the default {@link ASMifiable} prototypes.
+-     */
+-    public static Attribute[] getDefaultAttributes() {
+-        return new Attribute[0];
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/util/Traceable.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/Traceable.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/util/Traceable.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/Traceable.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,52 +0,0 @@
+-/**
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.util;
+-
+-import java.util.Map;
+-
+-/**
+- * An attribute that can print eadable representation of the attribute.
+- * 
+- * Implementation should construct readable output from an attribute data
+- * structures for current attribute state. Such representation could be used in
+- * unit test assertions.
+- * 
+- * @author Eugene Kuleshov
+- */
+-public interface Traceable {
+-
+-    /**
+-     * Build a human readable representation of the attribute.
+-     * 
+-     * @param buf A buffer used for printing Java code.
+-     * @param labelNames map of label instances to their names.
+-     */
+-    void trace(StringBuffer buf, Map labelNames);
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceAbstractVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceAbstractVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceAbstractVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceAbstractVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,179 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.util;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Attribute;
+-
+-/**
+- * An abstract trace visitor.
+- * 
+- * @author Eric Bruneton
+- */
+-public abstract class TraceAbstractVisitor extends AbstractVisitor {
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for internal
+-     * type names in bytecode notation.
+-     */
+-    public final static int INTERNAL_NAME = 0;
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for field
+-     * descriptors, formatted in bytecode notation
+-     */
+-    public final static int FIELD_DESCRIPTOR = 1;
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for field
+-     * signatures, formatted in bytecode notation
+-     */
+-    public final static int FIELD_SIGNATURE = 2;
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for method
+-     * descriptors, formatted in bytecode notation
+-     */
+-    public final static int METHOD_DESCRIPTOR = 3;
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for method
+-     * signatures, formatted in bytecode notation
+-     */
+-    public final static int METHOD_SIGNATURE = 4;
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for class
+-     * signatures, formatted in bytecode notation
+-     */
+-    public final static int CLASS_SIGNATURE = 5;
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for field or
+-     * method return value signatures, formatted in default Java notation
+-     * (non-bytecode)
+-     */
+-    public final static int TYPE_DECLARATION = 6;
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for class
+-     * signatures, formatted in default Java notation (non-bytecode)
+-     */
+-    public final static int CLASS_DECLARATION = 7;
+-
+-    /**
+-     * Constant used in {@link #appendDescriptor appendDescriptor} for method
+-     * parameter signatures, formatted in default Java notation (non-bytecode)
+-     */
+-    public final static int PARAMETERS_DECLARATION = 8;
+-
+-    /**
+-     * Tab for class members.
+-     */
+-    protected String tab = "  ";
+-
+-    /**
+-     * Prints a disassembled view of the given annotation.
+-     * 
+-     * @param desc the class descriptor of the annotation class.
+-     * @param visible <tt>true</tt> if the annotation is visible at runtime.
+-     * @return a visitor to visit the annotation values.
+-     */
+-    public AnnotationVisitor visitAnnotation(
+-        final String desc,
+-        final boolean visible)
+-    {
+-        buf.setLength(0);
+-        buf.append(tab).append('@');
+-        appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        buf.append('(');
+-        text.add(buf.toString());
+-        TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
+-        text.add(tav.getText());
+-        text.add(visible ? ")\n" : ") // invisible\n");
+-        return tav;
+-    }
+-
+-    /**
+-     * Prints a disassembled view of the given attribute.
+-     * 
+-     * @param attr an attribute.
+-     */
+-    public void visitAttribute(final Attribute attr) {
+-        buf.setLength(0);
+-        buf.append(tab).append("ATTRIBUTE ");
+-        appendDescriptor(-1, attr.type);
+-
+-        if (attr instanceof Traceable) {
+-            ((Traceable) attr).trace(buf, null);
+-        } else {
+-            buf.append(" : unknown\n");
+-        }
+-
+-        text.add(buf.toString());
+-    }
+-
+-    /**
+-     * Does nothing.
+-     */
+-    public void visitEnd() {
+-        // does nothing
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods
+-    // ------------------------------------------------------------------------
+-
+-    protected TraceAnnotationVisitor createTraceAnnotationVisitor() {
+-        return new TraceAnnotationVisitor();
+-    }
+-
+-    /**
+-     * Appends an internal name, a type descriptor or a type signature to
+-     * {@link #buf buf}.
+-     * 
+-     * @param type indicates if desc is an internal name, a field descriptor, a
+-     *        method descriptor, a class signature, ...
+-     * @param desc an internal name, type descriptor, or type signature. May be
+-     *        <tt>null</tt>.
+-     */
+-    protected void appendDescriptor(final int type, final String desc) {
+-        if (type == CLASS_SIGNATURE || type == FIELD_SIGNATURE
+-                || type == METHOD_SIGNATURE)
+-        {
+-            if (desc != null) {
+-                buf.append("// signature ").append(desc).append('\n');
+-            }
+-        } else {
+-            buf.append(desc);
+-        }
+-    }
+-
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceAnnotationVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceAnnotationVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceAnnotationVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceAnnotationVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,266 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.util;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Type;
+-
+-/**
+- * An {@link AnnotationVisitor} that prints a disassembled view of the
+- * annotations it visits.
+- * 
+- * @author Eric Bruneton
+- */
+-public class TraceAnnotationVisitor extends TraceAbstractVisitor implements
+-        AnnotationVisitor
+-{
+-
+-    /**
+-     * The {@link AnnotationVisitor} to which this visitor delegates calls. May
+-     * be <tt>null</tt>.
+-     */
+-    protected AnnotationVisitor av;
+-
+-    private int valueNumber = 0;
+-
+-    /**
+-     * Constructs a new {@link TraceAnnotationVisitor}.
+-     */
+-    public TraceAnnotationVisitor() {
+-        // ignore
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Implementation of the AnnotationVisitor interface
+-    // ------------------------------------------------------------------------
+-
+-    public void visit(final String name, final Object value) {
+-        buf.setLength(0);
+-        appendComa(valueNumber++);
+-
+-        if (name != null) {
+-            buf.append(name).append('=');
+-        }
+-
+-        if (value instanceof String) {
+-            visitString((String) value);
+-        } else if (value instanceof Type) {
+-            visitType((Type) value);
+-        } else if (value instanceof Byte) {
+-            visitByte(((Byte) value).byteValue());
+-        } else if (value instanceof Boolean) {
+-            visitBoolean(((Boolean) value).booleanValue());
+-        } else if (value instanceof Short) {
+-            visitShort(((Short) value).shortValue());
+-        } else if (value instanceof Character) {
+-            visitChar(((Character) value).charValue());
+-        } else if (value instanceof Integer) {
+-            visitInt(((Integer) value).intValue());
+-        } else if (value instanceof Float) {
+-            visitFloat(((Float) value).floatValue());
+-        } else if (value instanceof Long) {
+-            visitLong(((Long) value).longValue());
+-        } else if (value instanceof Double) {
+-            visitDouble(((Double) value).doubleValue());
+-        } else if (value.getClass().isArray()) {
+-            buf.append('{');
+-            if (value instanceof byte[]) {
+-                byte[] v = (byte[]) value;
+-                for (int i = 0; i < v.length; i++) {
+-                    appendComa(i);
+-                    visitByte(v[i]);
+-                }
+-            } else if (value instanceof boolean[]) {
+-                boolean[] v = (boolean[]) value;
+-                for (int i = 0; i < v.length; i++) {
+-                    appendComa(i);
+-                    visitBoolean(v[i]);
+-                }
+-            } else if (value instanceof short[]) {
+-                short[] v = (short[]) value;
+-                for (int i = 0; i < v.length; i++) {
+-                    appendComa(i);
+-                    visitShort(v[i]);
+-                }
+-            } else if (value instanceof char[]) {
+-                char[] v = (char[]) value;
+-                for (int i = 0; i < v.length; i++) {
+-                    appendComa(i);
+-                    visitChar(v[i]);
+-                }
+-            } else if (value instanceof int[]) {
+-                int[] v = (int[]) value;
+-                for (int i = 0; i < v.length; i++) {
+-                    appendComa(i);
+-                    visitInt(v[i]);
+-                }
+-            } else if (value instanceof long[]) {
+-                long[] v = (long[]) value;
+-                for (int i = 0; i < v.length; i++) {
+-                    appendComa(i);
+-                    visitLong(v[i]);
+-                }
+-            } else if (value instanceof float[]) {
+-                float[] v = (float[]) value;
+-                for (int i = 0; i < v.length; i++) {
+-                    appendComa(i);
+-                    visitFloat(v[i]);
+-                }
+-            } else if (value instanceof double[]) {
+-                double[] v = (double[]) value;
+-                for (int i = 0; i < v.length; i++) {
+-                    appendComa(i);
+-                    visitDouble(v[i]);
+-                }
+-            }
+-            buf.append('}');
+-        }
+-
+-        text.add(buf.toString());
+-
+-        if (av != null) {
+-            av.visit(name, value);
+-        }
+-    }
+-
+-    private void visitInt(final int value) {
+-        buf.append(value);
+-    }
+-
+-    private void visitLong(final long value) {
+-        buf.append(value).append('L');
+-    }
+-
+-    private void visitFloat(final float value) {
+-        buf.append(value).append('F');
+-    }
+-
+-    private void visitDouble(final double value) {
+-        buf.append(value).append('D');
+-    }
+-
+-    private void visitChar(final char value) {
+-        buf.append("(char)").append((int) value);
+-    }
+-
+-    private void visitShort(final short value) {
+-        buf.append("(short)").append(value);
+-    }
+-
+-    private void visitByte(final byte value) {
+-        buf.append("(byte)").append(value);
+-    }
+-
+-    private void visitBoolean(final boolean value) {
+-        buf.append(value);
+-    }
+-
+-    private void visitString(final String value) {
+-        appendString(buf, value);
+-    }
+-
+-    private void visitType(final Type value) {
+-        buf.append(value.getClassName()).append(".class");
+-    }
+-
+-    public void visitEnum(
+-        final String name,
+-        final String desc,
+-        final String value)
+-    {
+-        buf.setLength(0);
+-        appendComa(valueNumber++);
+-        if (name != null) {
+-            buf.append(name).append('=');
+-        }
+-        appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        buf.append('.').append(value);
+-        text.add(buf.toString());
+-
+-        if (av != null) {
+-            av.visitEnum(name, desc, value);
+-        }
+-    }
+-
+-    public AnnotationVisitor visitAnnotation(
+-        final String name,
+-        final String desc)
+-    {
+-        buf.setLength(0);
+-        appendComa(valueNumber++);
+-        if (name != null) {
+-            buf.append(name).append('=');
+-        }
+-        buf.append('@');
+-        appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        buf.append('(');
+-        text.add(buf.toString());
+-        TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
+-        text.add(tav.getText());
+-        text.add(")");
+-        if (av != null) {
+-            tav.av = av.visitAnnotation(name, desc);
+-        }
+-        return tav;
+-    }
+-
+-    public AnnotationVisitor visitArray(final String name) {
+-        buf.setLength(0);
+-        appendComa(valueNumber++);
+-        if (name != null) {
+-            buf.append(name).append('=');
+-        }
+-        buf.append('{');
+-        text.add(buf.toString());
+-        TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
+-        text.add(tav.getText());
+-        text.add("}");
+-        if (av != null) {
+-            tav.av = av.visitArray(name);
+-        }
+-        return tav;
+-    }
+-
+-    public void visitEnd() {
+-        if (av != null) {
+-            av.visitEnd();
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods
+-    // ------------------------------------------------------------------------
+-
+-    private void appendComa(final int i) {
+-        if (i != 0) {
+-            buf.append(", ");
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceClassVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceClassVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceClassVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceClassVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,523 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.util;
+-
+-import java.io.FileInputStream;
+-import java.io.PrintWriter;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Attribute;
+-import org.mvel2.asm.ClassReader;
+-import org.mvel2.asm.ClassVisitor;
+-import org.mvel2.asm.FieldVisitor;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.signature.SignatureReader;
+-
+-/**
+- * A {@link ClassVisitor} that prints a disassembled view of the classes it
+- * visits. This class visitor can be used alone (see the {@link #main main}
+- * method) to disassemble a class. It can also be used in the middle of class
+- * visitor chain to trace the class that is visited at a given point in this
+- * chain. This may be uselful for debugging purposes. <p> The trace printed when
+- * visiting the <tt>Hello</tt> class is the following: <p> <blockquote>
+- * 
+- * <pre>
+- * // class version 49.0 (49)
+- * // access flags 33
+- * public class Hello {
+- *
+- *  // compiled from: Hello.java
+- *
+- *   // access flags 1
+- *   public &lt;init&gt; ()V
+- *     ALOAD 0
+- *     INVOKESPECIAL java/lang/Object &lt;init&gt; ()V
+- *     RETURN
+- *     MAXSTACK = 1
+- *     MAXLOCALS = 1
+- *
+- *   // access flags 9
+- *   public static main ([Ljava/lang/String;)V
+- *     GETSTATIC java/lang/System out Ljava/io/PrintStream;
+- *     LDC &quot;hello&quot;
+- *     INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V
+- *     RETURN
+- *     MAXSTACK = 2
+- *     MAXLOCALS = 1
+- * }
+- * </pre>
+- * 
+- * </blockquote> where <tt>Hello</tt> is defined by: <p> <blockquote>
+- * 
+- * <pre>
+- * public class Hello {
+- *
+- *     public static void main(String[] args) {
+- *         System.out.println(&quot;hello&quot;);
+- *     }
+- * }
+- * </pre>
+- * 
+- * </blockquote>
+- * 
+- * @author Eric Bruneton
+- * @author Eugene Kuleshov
+- */
+-public class TraceClassVisitor extends TraceAbstractVisitor implements
+-        ClassVisitor
+-{
+-
+-    /**
+-     * The {@link ClassVisitor} to which this visitor delegates calls. May be
+-     * <tt>null</tt>.
+-     */
+-    protected final ClassVisitor cv;
+-
+-    /**
+-     * The print writer to be used to print the class.
+-     */
+-    protected final PrintWriter pw;
+-
+-    /**
+-     * Prints a disassembled view of the given class to the standard output. <p>
+-     * Usage: TraceClassVisitor [-debug] &lt;fully qualified class name or class
+-     * file name &gt;
+-     * 
+-     * @param args the command line arguments.
+-     * 
+-     * @throws Exception if the class cannot be found, or if an IO exception
+-     *         occurs.
+-     */
+-    public static void main(final String[] args) throws Exception {
+-        int i = 0;
+-        int flags = ClassReader.SKIP_DEBUG;
+-
+-        boolean ok = true;
+-        if (args.length < 1 || args.length > 2) {
+-            ok = false;
+-        }
+-        if (ok && args[0].equals("-debug")) {
+-            i = 1;
+-            flags = 0;
+-            if (args.length != 2) {
+-                ok = false;
+-            }
+-        }
+-        if (!ok) {
+-            System.err.println("Prints a disassembled view of the given class.");
+-            System.err.println("Usage: TraceClassVisitor [-debug] "
+-                    + "<fully qualified class name or class file name>");
+-            return;
+-        }
+-        ClassReader cr;
+-        if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1
+-                || args[i].indexOf('/') > -1)
+-        {
+-            cr = new ClassReader(new FileInputStream(args[i]));
+-        } else {
+-            cr = new ClassReader(args[i]);
+-        }
+-        cr.accept(new TraceClassVisitor(new PrintWriter(System.out)),
+-                getDefaultAttributes(),
+-                flags);
+-    }
+-
+-    /**
+-     * Constructs a new {@link TraceClassVisitor}.
+-     * 
+-     * @param pw the print writer to be used to print the class.
+-     */
+-    public TraceClassVisitor(final PrintWriter pw) {
+-        this(null, pw);
+-    }
+-
+-    /**
+-     * Constructs a new {@link TraceClassVisitor}.
+-     * 
+-     * @param cv the {@link ClassVisitor} to which this visitor delegates calls.
+-     *        May be <tt>null</tt>.
+-     * @param pw the print writer to be used to print the class.
+-     */
+-    public TraceClassVisitor(final ClassVisitor cv, final PrintWriter pw) {
+-        this.cv = cv;
+-        this.pw = pw;
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Implementation of the ClassVisitor interface
+-    // ------------------------------------------------------------------------
+-
+-    public void visit(
+-        final int version,
+-        final int access,
+-        final String name,
+-        final String signature,
+-        final String superName,
+-        final String[] interfaces)
+-    {
+-        int major = version & 0xFFFF;
+-        int minor = version >>> 16;
+-        buf.setLength(0);
+-        buf.append("// class version ")
+-                .append(major)
+-                .append('.')
+-                .append(minor)
+-                .append(" (")
+-                .append(version)
+-                .append(")\n");
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            buf.append("// DEPRECATED\n");
+-        }
+-        buf.append("// access flags ").append(access).append('\n');
+-
+-        appendDescriptor(CLASS_SIGNATURE, signature);
+-        if (signature != null) {
+-            TraceSignatureVisitor sv = new TraceSignatureVisitor(access);
+-            SignatureReader r = new SignatureReader(signature);
+-            r.accept(sv);
+-            buf.append("// declaration: ")
+-                    .append(name)
+-                    .append(sv.getDeclaration())
+-                    .append('\n');
+-        }
+-
+-        appendAccess(access & ~Opcodes.ACC_SUPER);
+-        if ((access & Opcodes.ACC_ANNOTATION) != 0) {
+-            buf.append("@interface ");
+-        } else if ((access & Opcodes.ACC_INTERFACE) != 0) {
+-            buf.append("interface ");
+-        } else if ((access & Opcodes.ACC_ENUM) == 0) {
+-            buf.append("class ");
+-        }
+-        appendDescriptor(INTERNAL_NAME, name);
+-
+-        if (superName != null && !superName.equals("java/lang/Object")) {
+-            buf.append(" extends ");
+-            appendDescriptor(INTERNAL_NAME, superName);
+-            buf.append(' ');
+-        }
+-        if (interfaces != null && interfaces.length > 0) {
+-            buf.append(" implements ");
+-            for (int i = 0; i < interfaces.length; ++i) {
+-                appendDescriptor(INTERNAL_NAME, interfaces[i]);
+-                buf.append(' ');
+-            }
+-        }
+-        buf.append(" {\n\n");
+-
+-        text.add(buf.toString());
+-
+-        if (cv != null) {
+-            cv.visit(version, access, name, signature, superName, interfaces);
+-        }
+-    }
+-
+-    public void visitSource(final String file, final String debug) {
+-        buf.setLength(0);
+-        if (file != null) {
+-            buf.append(tab)
+-                    .append("// compiled from: ")
+-                    .append(file)
+-                    .append('\n');
+-        }
+-        if (debug != null) {
+-            buf.append(tab)
+-                    .append("// debug info: ")
+-                    .append(debug)
+-                    .append('\n');
+-        }
+-        if (buf.length() > 0) {
+-            text.add(buf.toString());
+-        }
+-
+-        if (cv != null) {
+-            cv.visitSource(file, debug);
+-        }
+-    }
+-
+-    public void visitOuterClass(
+-        final String owner,
+-        final String name,
+-        final String desc)
+-    {
+-        buf.setLength(0);
+-        buf.append(tab).append("OUTERCLASS ");
+-        appendDescriptor(INTERNAL_NAME, owner);
+-        buf.append(' ');
+-        if (name != null) {
+-            buf.append(name).append(' ');
+-        }
+-        appendDescriptor(METHOD_DESCRIPTOR, desc);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (cv != null) {
+-            cv.visitOuterClass(owner, name, desc);
+-        }
+-    }
+-
+-    public AnnotationVisitor visitAnnotation(
+-        final String desc,
+-        final boolean visible)
+-    {
+-        text.add("\n");
+-        AnnotationVisitor tav = super.visitAnnotation(desc, visible);
+-        if (cv != null) {
+-            ((TraceAnnotationVisitor) tav).av = cv.visitAnnotation(desc,
+-                    visible);
+-        }
+-        return tav;
+-    }
+-
+-    public void visitAttribute(final Attribute attr) {
+-        text.add("\n");
+-        super.visitAttribute(attr);
+-
+-        if (cv != null) {
+-            cv.visitAttribute(attr);
+-        }
+-    }
+-
+-    public void visitInnerClass(
+-        final String name,
+-        final String outerName,
+-        final String innerName,
+-        final int access)
+-    {
+-        buf.setLength(0);
+-        buf.append(tab).append("// access flags ");
+-        buf.append(access & ~Opcodes.ACC_SUPER).append('\n');
+-        buf.append(tab);
+-        appendAccess(access);
+-        buf.append("INNERCLASS ");
+-        appendDescriptor(INTERNAL_NAME, name);
+-        buf.append(' ');
+-        appendDescriptor(INTERNAL_NAME, outerName);
+-        buf.append(' ');
+-        appendDescriptor(INTERNAL_NAME, innerName);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (cv != null) {
+-            cv.visitInnerClass(name, outerName, innerName, access);
+-        }
+-    }
+-
+-    public FieldVisitor visitField(
+-        final int access,
+-        final String name,
+-        final String desc,
+-        final String signature,
+-        final Object value)
+-    {
+-        buf.setLength(0);
+-        buf.append('\n');
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            buf.append(tab).append("// DEPRECATED\n");
+-        }
+-        buf.append(tab).append("// access flags ").append(access).append('\n');
+-        if (signature != null) {
+-            buf.append(tab);
+-            appendDescriptor(FIELD_SIGNATURE, signature);
+-
+-            TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
+-            SignatureReader r = new SignatureReader(signature);
+-            r.acceptType(sv);
+-            buf.append(tab)
+-                    .append("// declaration: ")
+-                    .append(sv.getDeclaration())
+-                    .append('\n');
+-        }
+-
+-        buf.append(tab);
+-        appendAccess(access);
+-
+-        appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        buf.append(' ').append(name);
+-        if (value != null) {
+-            buf.append(" = ");
+-            if (value instanceof String) {
+-                buf.append("\"").append(value).append("\"");
+-            } else {
+-                buf.append(value);
+-            }
+-        }
+-
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        TraceFieldVisitor tav = createTraceFieldVisitor();
+-        text.add(tav.getText());
+-
+-        if (cv != null) {
+-            tav.fv = cv.visitField(access, name, desc, signature, value);
+-        }
+-
+-        return tav;
+-    }
+-
+-    public MethodVisitor visitMethod(
+-        final int access,
+-        final String name,
+-        final String desc,
+-        final String signature,
+-        final String[] exceptions)
+-    {
+-        buf.setLength(0);
+-        buf.append('\n');
+-        if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+-            buf.append(tab).append("// DEPRECATED\n");
+-        }
+-        buf.append(tab).append("// access flags ").append(access).append('\n');
+-
+-        if (signature != null) {
+-            buf.append(tab);
+-            appendDescriptor(METHOD_SIGNATURE, signature);
+-
+-            TraceSignatureVisitor v = new TraceSignatureVisitor(0);
+-            SignatureReader r = new SignatureReader(signature);
+-            r.accept(v);
+-            String genericDecl = v.getDeclaration();
+-            String genericReturn = v.getReturnType();
+-            String genericExceptions = v.getExceptions();
+-
+-            buf.append(tab)
+-                    .append("// declaration: ")
+-                    .append(genericReturn)
+-                    .append(' ')
+-                    .append(name)
+-                    .append(genericDecl);
+-            if (genericExceptions != null) {
+-                buf.append(" throws ").append(genericExceptions);
+-            }
+-            buf.append('\n');
+-        }
+-
+-        buf.append(tab);
+-        appendAccess(access);
+-        if ((access & Opcodes.ACC_NATIVE) != 0) {
+-            buf.append("native ");
+-        }
+-        if ((access & Opcodes.ACC_VARARGS) != 0) {
+-            buf.append("varargs ");
+-        }
+-        if ((access & Opcodes.ACC_BRIDGE) != 0) {
+-            buf.append("bridge ");
+-        }
+-
+-        buf.append(name);
+-        appendDescriptor(METHOD_DESCRIPTOR, desc);
+-        if (exceptions != null && exceptions.length > 0) {
+-            buf.append(" throws ");
+-            for (int i = 0; i < exceptions.length; ++i) {
+-                appendDescriptor(INTERNAL_NAME, exceptions[i]);
+-                buf.append(' ');
+-            }
+-        }
+-
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        TraceMethodVisitor tcv = createTraceMethodVisitor();
+-        text.add(tcv.getText());
+-
+-        if (cv != null) {
+-            tcv.mv = cv.visitMethod(access, name, desc, signature, exceptions);
+-        }
+-
+-        return tcv;
+-    }
+-
+-    public void visitEnd() {
+-        text.add("}\n");
+-
+-        print(pw);
+-        pw.flush();
+-
+-        if (cv != null) {
+-            cv.visitEnd();
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods
+-    // ------------------------------------------------------------------------
+-
+-    protected TraceFieldVisitor createTraceFieldVisitor() {
+-        return new TraceFieldVisitor();
+-    }
+-
+-    protected TraceMethodVisitor createTraceMethodVisitor() {
+-        return new TraceMethodVisitor();
+-    }
+-
+-    /**
+-     * Appends a string representation of the given access modifiers to {@link
+-     * #buf buf}.
+-     * 
+-     * @param access some access modifiers.
+-     */
+-    private void appendAccess(final int access) {
+-        if ((access & Opcodes.ACC_PUBLIC) != 0) {
+-            buf.append("public ");
+-        }
+-        if ((access & Opcodes.ACC_PRIVATE) != 0) {
+-            buf.append("private ");
+-        }
+-        if ((access & Opcodes.ACC_PROTECTED) != 0) {
+-            buf.append("protected ");
+-        }
+-        if ((access & Opcodes.ACC_FINAL) != 0) {
+-            buf.append("final ");
+-        }
+-        if ((access & Opcodes.ACC_STATIC) != 0) {
+-            buf.append("static ");
+-        }
+-        if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
+-            buf.append("synchronized ");
+-        }
+-        if ((access & Opcodes.ACC_VOLATILE) != 0) {
+-            buf.append("volatile ");
+-        }
+-        if ((access & Opcodes.ACC_TRANSIENT) != 0) {
+-            buf.append("transient ");
+-        }
+-        if ((access & Opcodes.ACC_ABSTRACT) != 0) {
+-            buf.append("abstract ");
+-        }
+-        if ((access & Opcodes.ACC_STRICT) != 0) {
+-            buf.append("strictfp ");
+-        }
+-        if ((access & Opcodes.ACC_ENUM) != 0) {
+-            buf.append("enum ");
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceFieldVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceFieldVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceFieldVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceFieldVisitor.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-2005 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.util;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Attribute;
+-import org.mvel2.asm.FieldVisitor;
+-
+-/**
+- * A {@link FieldVisitor} that prints a disassembled view of the fields it
+- * visits.
+- * 
+- * @author Eric Bruneton
+- */
+-public class TraceFieldVisitor extends TraceAbstractVisitor implements
+-        FieldVisitor
+-{
+-
+-    /**
+-     * The {@link FieldVisitor} to which this visitor delegates calls. May be
+-     * <tt>null</tt>.
+-     */
+-    protected FieldVisitor fv;
+-
+-    public AnnotationVisitor visitAnnotation(
+-        final String desc,
+-        final boolean visible)
+-    {
+-        AnnotationVisitor av = super.visitAnnotation(desc, visible);
+-        if (fv != null) {
+-            ((TraceAnnotationVisitor) av).av = fv.visitAnnotation(desc, visible);
+-        }
+-        return av;
+-    }
+-
+-    public void visitAttribute(final Attribute attr) {
+-        super.visitAttribute(attr);
+-
+-        if (fv != null) {
+-            fv.visitAttribute(attr);
+-        }
+-    }
+-
+-    public void visitEnd() {
+-        super.visitEnd();
+-
+-        if (fv != null) {
+-            fv.visitEnd();
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceMethodVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceMethodVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceMethodVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceMethodVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,570 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.util;
+-
+-import org.mvel2.asm.AnnotationVisitor;
+-import org.mvel2.asm.Attribute;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.Type;
+-import org.mvel2.asm.signature.SignatureReader;
+-
+-import java.util.HashMap;
+-
+-/**
+- * A {@link MethodVisitor} that prints a disassembled view of the methods it
+- * visits.
+- * 
+- * @author Eric Bruneton
+- */
+-public class TraceMethodVisitor extends TraceAbstractVisitor implements
+-        MethodVisitor
+-{
+-
+-    /**
+-     * The {@link MethodVisitor} to which this visitor delegates calls. May be
+-     * <tt>null</tt>.
+-     */
+-    protected MethodVisitor mv;
+-
+-    /**
+-     * Tab for bytecode instructions.
+-     */
+-    protected String tab2 = "    ";
+-
+-    /**
+-     * Tab for table and lookup switch instructions.
+-     */
+-    protected String tab3 = "      ";
+-
+-    /**
+-     * Tab for labels.
+-     */
+-    protected String ltab = "   ";
+-
+-    /**
+-     * The label names. This map associate String values to Label keys.
+-     */
+-    protected final HashMap labelNames;
+-
+-    /**
+-     * Constructs a new {@link TraceMethodVisitor}.
+-     */
+-    public TraceMethodVisitor() {
+-        this(null);
+-    }
+-
+-    /**
+-     * Constructs a new {@link TraceMethodVisitor}.
+-     * 
+-     * @param mv the {@link MethodVisitor} to which this visitor delegates
+-     *        calls. May be <tt>null</tt>.
+-     */
+-    public TraceMethodVisitor(final MethodVisitor mv) {
+-        this.labelNames = new HashMap();
+-        this.mv = mv;
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Implementation of the MethodVisitor interface
+-    // ------------------------------------------------------------------------
+-
+-    public AnnotationVisitor visitAnnotation(
+-        final String desc,
+-        final boolean visible)
+-    {
+-        AnnotationVisitor av = super.visitAnnotation(desc, visible);
+-        if (mv != null) {
+-            ((TraceAnnotationVisitor) av).av = mv.visitAnnotation(desc, visible);
+-        }
+-        return av;
+-    }
+-
+-    public void visitAttribute(final Attribute attr) {
+-        buf.setLength(0);
+-        buf.append(tab).append("ATTRIBUTE ");
+-        appendDescriptor(-1, attr.type);
+-
+-        if (attr instanceof Traceable) {
+-            ((Traceable) attr).trace(buf, labelNames);
+-        } else {
+-            buf.append(" : unknown\n");
+-        }
+-
+-        text.add(buf.toString());
+-        if (mv != null) {
+-            mv.visitAttribute(attr);
+-        }
+-    }
+-
+-    public AnnotationVisitor visitAnnotationDefault() {
+-        text.add(tab2 + "default=");
+-        TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
+-        text.add(tav.getText());
+-        text.add("\n");
+-        if (mv != null) {
+-            tav.av = mv.visitAnnotationDefault();
+-        }
+-        return tav;
+-    }
+-
+-    public AnnotationVisitor visitParameterAnnotation(
+-        final int parameter,
+-        final String desc,
+-        final boolean visible)
+-    {
+-        buf.setLength(0);
+-        buf.append(tab2).append('@');
+-        appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        buf.append('(');
+-        text.add(buf.toString());
+-        TraceAnnotationVisitor tav = createTraceAnnotationVisitor();
+-        text.add(tav.getText());
+-        text.add(visible ? ") // parameter " : ") // invisible, parameter ");
+-        text.add(new Integer(parameter));
+-        text.add("\n");
+-        if (mv != null) {
+-            tav.av = mv.visitParameterAnnotation(parameter, desc, visible);
+-        }
+-        return tav;
+-    }
+-
+-    public void visitCode() {
+-        if (mv != null) {
+-            mv.visitCode();
+-        }
+-    }
+-
+-    public void visitFrame(
+-        final int type,
+-        final int nLocal,
+-        final Object[] local,
+-        final int nStack,
+-        final Object[] stack)
+-    {
+-        buf.setLength(0);
+-        buf.append(ltab);
+-        buf.append("FRAME ");
+-        switch (type) {
+-            case Opcodes.F_NEW:
+-            case Opcodes.F_FULL:
+-                buf.append("FULL [");
+-                appendFrameTypes(nLocal, local);
+-                buf.append("] [");
+-                appendFrameTypes(nStack, stack);
+-                buf.append("]");
+-                break;
+-            case Opcodes.F_APPEND:
+-                buf.append("APPEND [");
+-                appendFrameTypes(nLocal, local);
+-                buf.append("]");
+-                break;
+-            case Opcodes.F_CHOP:
+-                buf.append("CHOP ").append(nLocal);
+-                break;
+-            case Opcodes.F_SAME:
+-                buf.append("SAME");
+-                break;
+-            case Opcodes.F_SAME1:
+-                buf.append("SAME1 ");
+-                appendFrameTypes(1, stack);
+-                break;
+-        }
+-        buf.append("\n");
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitFrame(type, nLocal, local, nStack, stack);
+-        }
+-    }
+-
+-    public void visitInsn(final int opcode) {
+-        buf.setLength(0);
+-        buf.append(tab2).append(OPCODES[opcode]).append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitInsn(opcode);
+-        }
+-    }
+-
+-    public void visitIntInsn(final int opcode, final int operand) {
+-        buf.setLength(0);
+-        buf.append(tab2)
+-                .append(OPCODES[opcode])
+-                .append(' ')
+-                .append(opcode == Opcodes.NEWARRAY
+-                        ? TYPES[operand]
+-                        : Integer.toString(operand))
+-                .append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitIntInsn(opcode, operand);
+-        }
+-    }
+-
+-    public void visitVarInsn(final int opcode, final int var) {
+-        buf.setLength(0);
+-        buf.append(tab2)
+-                .append(OPCODES[opcode])
+-                .append(' ')
+-                .append(var)
+-                .append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitVarInsn(opcode, var);
+-        }
+-    }
+-
+-    public void visitTypeInsn(final int opcode, final String desc) {
+-        buf.setLength(0);
+-        buf.append(tab2).append(OPCODES[opcode]).append(' ');
+-        if (desc.startsWith("[")) {
+-            appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        } else {
+-            appendDescriptor(INTERNAL_NAME, desc);
+-        }
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitTypeInsn(opcode, desc);
+-        }
+-    }
+-
+-    public void visitFieldInsn(
+-        final int opcode,
+-        final String owner,
+-        final String name,
+-        final String desc)
+-    {
+-        buf.setLength(0);
+-        buf.append(tab2).append(OPCODES[opcode]).append(' ');
+-        appendDescriptor(INTERNAL_NAME, owner);
+-        buf.append('.').append(name).append(" : ");
+-        appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitFieldInsn(opcode, owner, name, desc);
+-        }
+-    }
+-
+-    public void visitMethodInsn(
+-        final int opcode,
+-        final String owner,
+-        final String name,
+-        final String desc)
+-    {
+-        buf.setLength(0);
+-        buf.append(tab2).append(OPCODES[opcode]).append(' ');
+-        appendDescriptor(INTERNAL_NAME, owner);
+-        buf.append('.').append(name).append(' ');
+-        appendDescriptor(METHOD_DESCRIPTOR, desc);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitMethodInsn(opcode, owner, name, desc);
+-        }
+-    }
+-
+-    public void visitJumpInsn(final int opcode, final Label label) {
+-        buf.setLength(0);
+-        buf.append(tab2).append(OPCODES[opcode]).append(' ');
+-        appendLabel(label);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitJumpInsn(opcode, label);
+-        }
+-    }
+-
+-    public void visitLabel(final Label label) {
+-        buf.setLength(0);
+-        buf.append(ltab);
+-        appendLabel(label);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitLabel(label);
+-        }
+-    }
+-
+-    public void visitLdcInsn(final Object cst) {
+-        buf.setLength(0);
+-        buf.append(tab2).append("LDC ");
+-        if (cst instanceof String) {
+-            AbstractVisitor.appendString(buf, (String) cst);
+-        } else if (cst instanceof Type) {
+-            buf.append(((Type) cst).getDescriptor() + ".class");
+-        } else {
+-            buf.append(cst);
+-        }
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitLdcInsn(cst);
+-        }
+-    }
+-
+-    public void visitIincInsn(final int var, final int increment) {
+-        buf.setLength(0);
+-        buf.append(tab2)
+-                .append("IINC ")
+-                .append(var)
+-                .append(' ')
+-                .append(increment)
+-                .append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitIincInsn(var, increment);
+-        }
+-    }
+-
+-    public void visitTableSwitchInsn(
+-        final int min,
+-        final int max,
+-        final Label dflt,
+-        final Label labels[])
+-    {
+-        buf.setLength(0);
+-        buf.append(tab2).append("TABLESWITCH\n");
+-        for (int i = 0; i < labels.length; ++i) {
+-            buf.append(tab3).append(min + i).append(": ");
+-            appendLabel(labels[i]);
+-            buf.append('\n');
+-        }
+-        buf.append(tab3).append("default: ");
+-        appendLabel(dflt);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitTableSwitchInsn(min, max, dflt, labels);
+-        }
+-    }
+-
+-    public void visitLookupSwitchInsn(
+-        final Label dflt,
+-        final int keys[],
+-        final Label labels[])
+-    {
+-        buf.setLength(0);
+-        buf.append(tab2).append("LOOKUPSWITCH\n");
+-        for (int i = 0; i < labels.length; ++i) {
+-            buf.append(tab3).append(keys[i]).append(": ");
+-            appendLabel(labels[i]);
+-            buf.append('\n');
+-        }
+-        buf.append(tab3).append("default: ");
+-        appendLabel(dflt);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitLookupSwitchInsn(dflt, keys, labels);
+-        }
+-    }
+-
+-    public void visitMultiANewArrayInsn(final String desc, final int dims) {
+-        buf.setLength(0);
+-        buf.append(tab2).append("MULTIANEWARRAY ");
+-        appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        buf.append(' ').append(dims).append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitMultiANewArrayInsn(desc, dims);
+-        }
+-    }
+-
+-    public void visitTryCatchBlock(
+-        final Label start,
+-        final Label end,
+-        final Label handler,
+-        final String type)
+-    {
+-        buf.setLength(0);
+-        buf.append(tab2).append("TRYCATCHBLOCK ");
+-        appendLabel(start);
+-        buf.append(' ');
+-        appendLabel(end);
+-        buf.append(' ');
+-        appendLabel(handler);
+-        buf.append(' ');
+-        appendDescriptor(INTERNAL_NAME, type);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitTryCatchBlock(start, end, handler, type);
+-        }
+-    }
+-
+-    public void visitLocalVariable(
+-        final String name,
+-        final String desc,
+-        final String signature,
+-        final Label start,
+-        final Label end,
+-        final int index)
+-    {
+-        buf.setLength(0);
+-        buf.append(tab2).append("LOCALVARIABLE ").append(name).append(' ');
+-        appendDescriptor(FIELD_DESCRIPTOR, desc);
+-        buf.append(' ');
+-        appendLabel(start);
+-        buf.append(' ');
+-        appendLabel(end);
+-        buf.append(' ').append(index).append('\n');
+-
+-        if (signature != null) {
+-            buf.append(tab2);
+-            appendDescriptor(FIELD_SIGNATURE, signature);
+-
+-            TraceSignatureVisitor sv = new TraceSignatureVisitor(0);
+-            SignatureReader r = new SignatureReader(signature);
+-            r.acceptType(sv);
+-            buf.append(tab2)
+-                    .append("// declaration: ")
+-                    .append(sv.getDeclaration())
+-                    .append('\n');
+-        }
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitLocalVariable(name, desc, signature, start, end, index);
+-        }
+-    }
+-
+-    public void visitLineNumber(final int line, final Label start) {
+-        buf.setLength(0);
+-        buf.append(tab2).append("LINENUMBER ").append(line).append(' ');
+-        appendLabel(start);
+-        buf.append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitLineNumber(line, start);
+-        }
+-    }
+-
+-    public void visitMaxs(final int maxStack, final int maxLocals) {
+-        buf.setLength(0);
+-        buf.append(tab2).append("MAXSTACK = ").append(maxStack).append('\n');
+-        text.add(buf.toString());
+-
+-        buf.setLength(0);
+-        buf.append(tab2).append("MAXLOCALS = ").append(maxLocals).append('\n');
+-        text.add(buf.toString());
+-
+-        if (mv != null) {
+-            mv.visitMaxs(maxStack, maxLocals);
+-        }
+-    }
+-
+-    public void visitEnd() {
+-        super.visitEnd();
+-
+-        if (mv != null) {
+-            mv.visitEnd();
+-        }
+-    }
+-
+-    // ------------------------------------------------------------------------
+-    // Utility methods
+-    // ------------------------------------------------------------------------
+-
+-    private void appendFrameTypes(final int n, final Object[] o) {
+-        for (int i = 0; i < n; ++i) {
+-            if (i > 0) {
+-                buf.append(' ');
+-            }
+-            if (o[i] instanceof String) {
+-                String desc = (String) o[i];
+-                if (desc.startsWith("[")) {
+-                    appendDescriptor(FIELD_DESCRIPTOR, desc);
+-                } else {
+-                    appendDescriptor(INTERNAL_NAME, desc);
+-                }
+-            } else if (o[i] instanceof Integer) {
+-                switch (((Integer) o[i]).intValue()) {
+-                    case 0:
+-                        appendDescriptor(FIELD_DESCRIPTOR, "T");
+-                        break;
+-                    case 1:
+-                        appendDescriptor(FIELD_DESCRIPTOR, "I");
+-                        break;
+-                    case 2:
+-                        appendDescriptor(FIELD_DESCRIPTOR, "F");
+-                        break;
+-                    case 3:
+-                        appendDescriptor(FIELD_DESCRIPTOR, "D");
+-                        break;
+-                    case 4:
+-                        appendDescriptor(FIELD_DESCRIPTOR, "J");
+-                        break;
+-                    case 5:
+-                        appendDescriptor(FIELD_DESCRIPTOR, "N");
+-                        break;
+-                    case 6:
+-                        appendDescriptor(FIELD_DESCRIPTOR, "U");
+-                        break;
+-                }
+-            } else {
+-                appendLabel((Label) o[i]);
+-            }
+-        }
+-    }
+-
+-    /**
+-     * Appends the name of the given label to {@link #buf buf}. Creates a new
+-     * label name if the given label does not yet have one.
+-     * 
+-     * @param l a label.
+-     */
+-    protected void appendLabel(final Label l) {
+-        String name = (String) labelNames.get(l);
+-        if (name == null) {
+-            name = "L" + labelNames.size();
+-            labelNames.put(l, name);
+-        }
+-        buf.append(name);
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceSignatureVisitor.java mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceSignatureVisitor.java
+--- mvel-2.0.19/src/main/java/org/mvel2/asm/util/TraceSignatureVisitor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/asm/util/TraceSignatureVisitor.java	1970-01-01 01:00:00.000000000 +0100
+@@ -1,300 +0,0 @@
+-/***
+- * ASM: a very small and fast Java bytecode manipulation framework
+- * Copyright (c) 2000-2005 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.util;
+-
+-import org.mvel2.asm.Opcodes;
+-import org.mvel2.asm.signature.SignatureVisitor;
+-
+-/**
+- * A {@link SignatureVisitor} that prints a disassembled view of the signature
+- * it visits.
+- * 
+- * @author Eugene Kuleshov
+- * @author Eric Bruneton
+- */
+-public class TraceSignatureVisitor implements SignatureVisitor {
+-
+-    private StringBuffer declaration;
+-
+-    private boolean isInterface;
+-
+-    private boolean seenFormalParameter;
+-
+-    private boolean seenInterfaceBound;
+-
+-    private boolean seenParameter;
+-
+-    private boolean seenInterface;
+-
+-    private StringBuffer returnType;
+-
+-    private StringBuffer exceptions;
+-
+-    /**
+-     * 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;
+-
+-    /**
+-     * Stack used to keep track of array class types. 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 arrayStack;
+-
+-    private String separator = "";
+-
+-    public TraceSignatureVisitor(final int access) {
+-        isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
+-        this.declaration = new StringBuffer();
+-    }
+-
+-    private TraceSignatureVisitor(final StringBuffer buf) {
+-        this.declaration = buf;
+-    }
+-
+-    public void visitFormalTypeParameter(final String name) {
+-        declaration.append(seenFormalParameter ? ", " : "<").append(name);
+-        seenFormalParameter = true;
+-        seenInterfaceBound = false;
+-    }
+-
+-    public SignatureVisitor visitClassBound() {
+-        separator = " extends ";
+-        startType();
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitInterfaceBound() {
+-        separator = seenInterfaceBound ? ", " : " extends ";
+-        seenInterfaceBound = true;
+-        startType();
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitSuperclass() {
+-        endFormals();
+-        separator = " extends ";
+-        startType();
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitInterface() {
+-        separator = seenInterface ? ", " : isInterface
+-                ? " extends "
+-                : " implements ";
+-        seenInterface = true;
+-        startType();
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitParameterType() {
+-        endFormals();
+-        if (!seenParameter) {
+-            seenParameter = true;
+-            declaration.append('(');
+-        } else {
+-            declaration.append(", ");
+-        }
+-        startType();
+-        return this;
+-    }
+-
+-    public SignatureVisitor visitReturnType() {
+-        endFormals();
+-        if (!seenParameter) {
+-            declaration.append('(');
+-        } else {
+-            seenParameter = false;
+-        }
+-        declaration.append(')');
+-        returnType = new StringBuffer();
+-        return new TraceSignatureVisitor(returnType);
+-    }
+-
+-    public SignatureVisitor visitExceptionType() {
+-        if (exceptions == null) {
+-            exceptions = new StringBuffer();
+-        } else {
+-            exceptions.append(", ");
+-        }
+-        // startType();
+-        return new TraceSignatureVisitor(exceptions);
+-    }
+-
+-    public void visitBaseType(final char descriptor) {
+-        switch (descriptor) {
+-            case 'V':
+-                declaration.append("void");
+-                break;
+-            case 'B':
+-                declaration.append("byte");
+-                break;
+-            case 'J':
+-                declaration.append("long");
+-                break;
+-            case 'Z':
+-                declaration.append("boolean");
+-                break;
+-            case 'I':
+-                declaration.append("int");
+-                break;
+-            case 'S':
+-                declaration.append("short");
+-                break;
+-            case 'C':
+-                declaration.append("char");
+-                break;
+-            case 'F':
+-                declaration.append("float");
+-                break;
+-            // case 'D':
+-            default:
+-                declaration.append("double");
+-                break;
+-        }
+-        endType();
+-    }
+-
+-    public void visitTypeVariable(final String name) {
+-        declaration.append(name);
+-        endType();
+-    }
+-
+-    public SignatureVisitor visitArrayType() {
+-        startType();
+-        arrayStack |= 1;
+-        return this;
+-    }
+-
+-    public void visitClassType(final String name) {
+-        if (!"java/lang/Object".equals(name)) {
+-            declaration.append(separator).append(name.replace('/', '.'));
+-        } else {
+-            // Map<java.lang.Object,java.util.List>
+-            // or
+-            // abstract public V get(Object key); (seen in Dictionary.class)
+-            // should have Object
+-            // but java.lang.String extends java.lang.Object is unnecessary
+-            boolean needObjectClass = argumentStack % 2 != 0 || seenParameter;
+-            if (needObjectClass) {
+-                declaration.append(separator).append(name.replace('/', '.'));
+-            }
+-        }
+-        separator = "";
+-        argumentStack *= 2;
+-    }
+-
+-    public void visitInnerClassType(final String name) {
+-        if (argumentStack % 2 != 0) {
+-            declaration.append('>');
+-        }
+-        argumentStack /= 2;
+-        declaration.append('.');
+-        declaration.append(separator).append(name.replace('/', '.'));
+-        separator = "";
+-        argumentStack *= 2;
+-    }
+-
+-    public void visitTypeArgument() {
+-        if (argumentStack % 2 == 0) {
+-            ++argumentStack;
+-            declaration.append('<');
+-        } else {
+-            declaration.append(", ");
+-        }
+-        declaration.append('?');
+-    }
+-
+-    public SignatureVisitor visitTypeArgument(final char tag) {
+-        if (argumentStack % 2 == 0) {
+-            ++argumentStack;
+-            declaration.append('<');
+-        } else {
+-            declaration.append(", ");
+-        }
+-
+-        if (tag == SignatureVisitor.EXTENDS) {
+-            declaration.append("? extends ");
+-        } else if (tag == SignatureVisitor.SUPER) {
+-            declaration.append("? super ");
+-        }
+-
+-        startType();
+-        return this;
+-    }
+-
+-    public void visitEnd() {
+-        if (argumentStack % 2 != 0) {
+-            declaration.append('>');
+-        }
+-        argumentStack /= 2;
+-        endType();
+-    }
+-
+-    public String getDeclaration() {
+-        return declaration.toString();
+-    }
+-
+-    public String getReturnType() {
+-        return returnType == null ? null : returnType.toString();
+-    }
+-
+-    public String getExceptions() {
+-        return exceptions == null ? null : exceptions.toString();
+-    }
+-
+-    // -----------------------------------------------
+-
+-    private void endFormals() {
+-        if (seenFormalParameter) {
+-            declaration.append('>');
+-            seenFormalParameter = false;
+-        }
+-    }
+-
+-    private void startType() {
+-        arrayStack *= 2;
+-    }
+-
+-    private void endType() {
+-        if (arrayStack % 2 != 0) {
+-            while (arrayStack % 2 != 0) {
+-                arrayStack /= 2;
+-                declaration.append("[]");
+-            }
+-        } else {
+-            arrayStack /= 2;
+-        }
+-    }
+-}
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/optimizers/impl/asm/ASMAccessorOptimizer.java mvel-2.0.19-gil/src/main/java/org/mvel2/optimizers/impl/asm/ASMAccessorOptimizer.java
+--- mvel-2.0.19/src/main/java/org/mvel2/optimizers/impl/asm/ASMAccessorOptimizer.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/optimizers/impl/asm/ASMAccessorOptimizer.java	2012-05-26 19:29:36.893461371 +0200
+@@ -18,10 +18,10 @@
+ package org.mvel2.optimizers.impl.asm;
+ 
+ import org.mvel2.*;
+-import org.mvel2.asm.ClassWriter;
+-import org.mvel2.asm.Label;
+-import org.mvel2.asm.MethodVisitor;
+-import org.mvel2.asm.Opcodes;
++import org.objectweb.asm.ClassWriter;
++import org.objectweb.asm.Label;
++import org.objectweb.asm.MethodVisitor;
++import org.objectweb.asm.Opcodes;
+ import org.mvel2.ast.Function;
+ import org.mvel2.ast.TypeDescriptor;
+ import org.mvel2.ast.WithNode;
+@@ -53,8 +53,8 @@
+ import static org.mvel2.DataConversion.convert;
+ import static org.mvel2.MVEL.eval;
+ import static org.mvel2.MVEL.isAdvancedDebugging;
+-import static org.mvel2.asm.Opcodes.*;
+-import static org.mvel2.asm.Type.*;
++import static org.objectweb.asm.Opcodes.*;
++import static org.objectweb.asm.Type.*;
+ import static org.mvel2.ast.TypeDescriptor.getClassReference;
+ import static org.mvel2.integration.GlobalListenerFactory.hasGetListeners;
+ import static org.mvel2.integration.GlobalListenerFactory.notifyGetListeners;
+@@ -648,7 +648,7 @@
+ 
+         mv = cw.visitMethod(ACC_PUBLIC, "getKnownEgressType", "()Ljava/lang/Class;", null, null);
+         mv.visitCode();
+-        mv.visitLdcInsn(org.mvel2.asm.Type.getType(returnType != null ? returnType : Object.class));
++        mv.visitLdcInsn(org.objectweb.asm.Type.getType(returnType != null ? returnType : Object.class));
+         mv.visitInsn(ARETURN);
+ 
+         mv.visitMaxs(1, 1);
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/optimizers/impl/asm/ProducesBytecode.java mvel-2.0.19-gil/src/main/java/org/mvel2/optimizers/impl/asm/ProducesBytecode.java
+--- mvel-2.0.19/src/main/java/org/mvel2/optimizers/impl/asm/ProducesBytecode.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/optimizers/impl/asm/ProducesBytecode.java	2012-05-26 19:29:36.894461371 +0200
+@@ -18,7 +18,7 @@
+ 
+ package org.mvel2.optimizers.impl.asm;
+ 
+-import org.mvel2.asm.MethodVisitor;
++import org.objectweb.asm.MethodVisitor;
+ import org.mvel2.integration.VariableResolverFactory;
+ 
+ /**
+diff -Nru mvel-2.0.19/src/main/java/org/mvel2/optimizers/OptimizerFactory.java mvel-2.0.19-gil/src/main/java/org/mvel2/optimizers/OptimizerFactory.java
+--- mvel-2.0.19/src/main/java/org/mvel2/optimizers/OptimizerFactory.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/main/java/org/mvel2/optimizers/OptimizerFactory.java	2012-05-26 19:29:36.908461371 +0200
+@@ -45,7 +45,7 @@
+          * By default, activate the JIT if ASM is present in the classpath
+          */
+         try {
+-            currentThread().getContextClassLoader().loadClass("org.mvel2.asm.ClassWriter");
++            currentThread().getContextClassLoader().loadClass("org.objectweb.asm.ClassWriter");
+             accessorCompilers.put("ASM", new ASMAccessorOptimizer());
+         }
+ 
+diff -Nru mvel-2.0.19/src/test/java/org/mvel2/tests/core/PropertyHandlerTests.java mvel-2.0.19-gil/src/test/java/org/mvel2/tests/core/PropertyHandlerTests.java
+--- mvel-2.0.19/src/test/java/org/mvel2/tests/core/PropertyHandlerTests.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/test/java/org/mvel2/tests/core/PropertyHandlerTests.java	2012-05-26 19:29:36.954461371 +0200
+@@ -3,8 +3,8 @@
+ import junit.framework.TestCase;
+ import org.mvel2.MVEL;
+ import org.mvel2.PropertyAccessor;
+-import org.mvel2.asm.MethodVisitor;
+-import static org.mvel2.asm.Opcodes.*;
++import org.objectweb.asm.MethodVisitor;
++import static org.objectweb.asm.Opcodes.*;
+ import org.mvel2.integration.*;
+ import org.mvel2.optimizers.OptimizerFactory;
+ import org.mvel2.optimizers.impl.asm.ProducesBytecode;
+diff -Nru mvel-2.0.19/src/test/java/org/mvel2/tests/core/res/SampleBeanAccessor.java mvel-2.0.19-gil/src/test/java/org/mvel2/tests/core/res/SampleBeanAccessor.java
+--- mvel-2.0.19/src/test/java/org/mvel2/tests/core/res/SampleBeanAccessor.java	2010-11-19 20:22:46.000000000 +0100
++++ mvel-2.0.19-gil/src/test/java/org/mvel2/tests/core/res/SampleBeanAccessor.java	2012-05-26 19:29:36.951461371 +0200
+@@ -1,8 +1,8 @@
+ package org.mvel2.tests.core.res;
+ 
+-import org.mvel2.asm.MethodVisitor;
+-import static org.mvel2.asm.Opcodes.CHECKCAST;
+-import static org.mvel2.asm.Opcodes.INVOKEVIRTUAL;
++import org.objectweb.asm.MethodVisitor;
++import static org.objectweb.asm.Opcodes.CHECKCAST;
++import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
+ import org.mvel2.integration.PropertyHandler;
+ import org.mvel2.integration.VariableResolverFactory;
+ import org.mvel2.optimizers.impl.asm.ProducesBytecode;
diff --git a/mvel-script b/mvel-script
new file mode 100644
index 0000000..1d3b2b5
--- /dev/null
+++ b/mvel-script
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# mvel script
+# gil
+
+# Source functions library
+. /usr/share/java-utils/java-functions
+
+# Source system prefs
+if [ -f /etc/mvel.conf ] ; then
+  . /etc/mvel.conf
+fi
+
+# Source user prefs
+if [ -f $HOME/.mvelrc ] ; then
+  . $HOME/.mvelrc
+fi
+
+# Configuration
+MAIN_CLASS=org.mvel2.sh.Main
+BASE_JARS="mvel objectweb-asm/asm objectweb-asm/asm-util"
+
+# Set parameters
+set_jvm
+set_classpath $BASE_JARS
+set_flags $BASE_FLAGS
+set_options $BASE_OPTIONS
+
+# Let's start
+run "$@"
diff --git a/mvel.spec b/mvel.spec
new file mode 100644
index 0000000..3e94bca
--- /dev/null
+++ b/mvel.spec
@@ -0,0 +1,100 @@
+
+Name:          mvel
+Version:       2.0.19
+Release:       1%{?dist}
+Summary:       MVFLEX Expression Language
+Group:         Development/Libraries
+License:       ASL 2.0
+Url:           http://mvel.codehaus.org/
+# git clone git://github.com/mikebrock/mvel.git mvel2-2.0.18
+# cd mvel-2.0.19/ && git archive --format=tar --prefix=mvel2-2.0.19/ mvel2-2.0.19 | xz > ../mvel2-2.0.19.tar.xz
+Source0:       %{name}-%{version}.tar.xz
+Source1:       mvel-script
+Patch0:        mvel-2.0.19-use-system-asm.patch
+# remove tests which require internal objectweb-asm libraries
+Patch1:        mvel-2.0.19-tests.patch
+BuildRequires: java-devel
+BuildRequires: jpackage-utils
+
+BuildRequires: objectweb-asm
+
+# test deps 
+BuildRequires: junit
+BuildRequires: xstream
+
+BuildRequires: maven
+BuildRequires: maven-compiler-plugin
+BuildRequires: maven-install-plugin
+BuildRequires: maven-jar-plugin
+BuildRequires: maven-javadoc-plugin
+BuildRequires: maven-plugin-bundle
+BuildRequires: maven-resources-plugin
+BuildRequires: maven-surefire-plugin
+BuildRequires: maven-surefire-provider-junit4
+
+Requires:      objectweb-asm
+
+Requires:      java
+Requires:      jpackage-utils
+BuildArch:     noarch
+
+%description
+MVEL is a powerful expression language for Java-based applications. It
+provides a plethora of features and is suited for everything from the
+smallest property binding and extraction, to full blown scripts.
+
+%package javadoc
+Group:         Documentation
+Summary:       Javadoc for %{name}
+Requires:      jpackage-utils
+
+%description javadoc
+This package contains javadoc for %{name}.
+
+%prep
+%setup -q
+find . -name "*.jar" -delete
+find . -name "*.class" -delete
+rm ASM-LICENSE.txt
+%patch0 -p1
+%patch1 -p0
+
+sed -i 's/\r//' LICENSE.txt
+
+# fix non ASCII chars
+native2ascii -encoding UTF8 src/main/java/org/mvel2/sh/ShellSession.java src/main/java/org/mvel2/sh/ShellSession.java
+
+%build
+
+mvn-rpmbuild -Dproject.build.sourceEncoding=UTF-8 install javadoc:aggregate
+
+%install
+
+mkdir -p %{buildroot}%{_javadir}
+install -pm 644 target/%{name}2-%{version}.jar %{buildroot}%{_javadir}/%{name}.jar
+
+mkdir -p %{buildroot}%{_mavenpomdir}
+install -pm 644 pom.xml %{buildroot}%{_mavenpomdir}/JPP-%{name}.pom
+%add_maven_depmap JPP-%{name}.pom %{name}.jar
+
+mkdir -p %{buildroot}%{_javadocdir}/%{name}
+cp -rp target/site/api*/* %{buildroot}%{_javadocdir}/%{name}
+
+mkdir -p %{buildroot}%{_bindir}
+install -pm 755 %{SOURCE1} %{buildroot}%{_bindir}/%{name}
+
+%files
+%{_bindir}/%{name}
+%{_javadir}/%{name}*.jar
+%{_mavenpomdir}/JPP-%{name}.pom
+%{_mavendepmapfragdir}/%{name}
+%doc LICENSE.txt
+
+%files javadoc
+%{_javadocdir}/%{name}
+%doc LICENSE.txt
+
+%changelog
+* Sat May 26 2012 gil cattaneo <puntogil at libero.it> 2.0.19-1
+- initial rpm
+
diff --git a/sources b/sources
index e69de29..49ffc81 100644
--- a/sources
+++ b/sources
@@ -0,0 +1 @@
+9fe3e07aebc680950b028089bd263cb2  mvel-2.0.19.tar.xz


More information about the scm-commits mailing list