[janino] 02/05: Imported Upstream version 2.6.1

Damien Raude-Morvan drazzib at alioth.debian.org
Sat Aug 17 13:16:12 UTC 2013


This is an automated email from the git hooks/post-receive script.

drazzib pushed a commit to annotated tag debian/2.6.1-1
in repository janino.

commit 3938a2a06b78dac2a6b55ae4406b7af51f8e97c7
Author: Damien Raude-Morvan <drazzib at drazzib.com>
Date:   Fri Aug 16 10:24:13 2013 +0200

    Imported Upstream version 2.6.1
---
 README.txt                                         |   19 +
 build.properties                                   |   60 -
 build.xml                                          |   99 -
 commons-compiler-jdk-src.zip                       |  Bin 0 -> 27640 bytes
 commons-compiler-jdk.jar                           |  Bin 0 -> 43330 bytes
 commons-compiler-src.zip                           |  Bin 0 -> 42676 bytes
 commons-compiler.jar                               |  Bin 0 -> 29924 bytes
 janino-src.zip                                     |  Bin 0 -> 317584 bytes
 janino.jar                                         |  Bin 0 -> 602320 bytes
 .../new_bsd_license.txt => new_bsd_license.txt     |    2 +-
 src/org/codehaus/janino/Access.java                |   55 -
 src/org/codehaus/janino/AntCompilerAdapter.java    |  186 -
 .../janino/AstCompilationUnitGenerator.java        |   42 -
 src/org/codehaus/janino/ByteArrayClassLoader.java  |  143 -
 .../janino/CachingJavaSourceClassLoader.java       |  225 -
 src/org/codehaus/janino/ClassBodyEvaluator.java    |  495 --
 src/org/codehaus/janino/ClassFileIClass.java       |  449 --
 .../codehaus/janino/ClassLoaderIClassLoader.java   |  108 -
 src/org/codehaus/janino/CodeContext.java           | 1103 ---
 src/org/codehaus/janino/CompileException.java      |   50 -
 src/org/codehaus/janino/Compiler.java              |  846 --
 src/org/codehaus/janino/Cookable.java              |  150 -
 src/org/codehaus/janino/DebuggingInformation.java  |   59 -
 src/org/codehaus/janino/Descriptor.java            |  270 -
 src/org/codehaus/janino/ExpressionEvaluator.java   |  525 --
 src/org/codehaus/janino/FilterWarningHandler.java  |   57 -
 src/org/codehaus/janino/IClass.java                |  819 --
 src/org/codehaus/janino/IClassLoader.java          |  227 -
 src/org/codehaus/janino/Java.java                  | 2924 -------
 src/org/codehaus/janino/JavaSourceClassLoader.java |  412 -
 .../codehaus/janino/JavaSourceIClassLoader.java    |  173 -
 src/org/codehaus/janino/Location.java              |   69 -
 src/org/codehaus/janino/MethodDescriptor.java      |   98 -
 src/org/codehaus/janino/Mod.java                   |  104 -
 src/org/codehaus/janino/Opcode.java                |  612 --
 src/org/codehaus/janino/Parser.java                | 2540 ------
 src/org/codehaus/janino/ReflectionIClass.java      |  314 -
 .../janino/ResourceFinderIClassLoader.java         |   89 -
 src/org/codehaus/janino/Scanner.java               | 1276 ---
 src/org/codehaus/janino/ScriptEvaluator.java       | 1045 ---
 src/org/codehaus/janino/SimpleCompiler.java        |  462 --
 .../codehaus/janino/UnicodeUnescapeException.java  |   45 -
 src/org/codehaus/janino/UnicodeUnescapeReader.java |  136 -
 src/org/codehaus/janino/UnitCompiler.java          | 8378 --------------------
 src/org/codehaus/janino/UnparseVisitor.java        |  775 --
 src/org/codehaus/janino/Visitor.java               |  138 -
 src/org/codehaus/janino/WarningHandler.java        |   42 -
 src/org/codehaus/janino/package.html               |   11 -
 src/org/codehaus/janino/samples/ClassBodyDemo.java |   96 -
 .../janino/samples/DeclarationCounter.java         |   99 -
 src/org/codehaus/janino/samples/DemoBase.java      |  154 -
 .../codehaus/janino/samples/ExpressionDemo.java    |  129 -
 src/org/codehaus/janino/samples/ScriptDemo.java    |  126 -
 src/org/codehaus/janino/samples/ShippingCost.java  |   72 -
 src/org/codehaus/janino/samples/package.html       |    3 -
 src/org/codehaus/janino/tools/Disassembler.java    | 1425 ----
 src/org/codehaus/janino/tools/HprofScrubber.java   |  220 -
 src/org/codehaus/janino/tools/JGrep.java           |  692 --
 src/org/codehaus/janino/tools/package.html         |    3 -
 src/org/codehaus/janino/util/AutoIndentWriter.java |   92 -
 src/org/codehaus/janino/util/Benchmark.java        |  220 -
 src/org/codehaus/janino/util/CausedException.java  |  107 -
 src/org/codehaus/janino/util/ClassFile.java        | 1514 ----
 src/org/codehaus/janino/util/LocatedException.java |   70 -
 src/org/codehaus/janino/util/MultiIterator.java    |  163 -
 src/org/codehaus/janino/util/PrimitiveWrapper.java |   50 -
 src/org/codehaus/janino/util/Producer.java         |   57 -
 .../janino/util/ResourceFinderClassLoader.java     |  120 -
 src/org/codehaus/janino/util/StringPattern.java    |  191 -
 src/org/codehaus/janino/util/TeeReader.java        |   82 -
 src/org/codehaus/janino/util/Traverser.java        |  599 --
 .../janino/util/enumerator/Enumerator.java         |  143 -
 .../util/enumerator/EnumeratorFormatException.java |   45 -
 .../janino/util/enumerator/EnumeratorSet.java      |  324 -
 .../enumerator/EnumeratorSetTypeException.java     |   44 -
 .../codehaus/janino/util/enumerator/package.html   |    3 -
 .../janino/util/iterator/DirectoryIterator.java    |  132 -
 .../janino/util/iterator/EnumerationIterator.java  |   51 -
 .../janino/util/iterator/FilterIterator.java       |   52 -
 .../janino/util/iterator/FilterListIterator.java   |   71 -
 .../janino/util/iterator/IteratorCollection.java   |   82 -
 .../util/iterator/MultiDimensionalIterator.java    |  107 -
 .../janino/util/iterator/ProducerIterator.java     |   75 -
 .../janino/util/iterator/ReverseListIterator.java  |   61 -
 .../janino/util/iterator/TransformingIterator.java |   56 -
 .../janino/util/iterator/TraversingIterator.java   |  100 -
 .../util/iterator/UniterableElementException.java  |   44 -
 src/org/codehaus/janino/util/iterator/package.html |    3 -
 src/org/codehaus/janino/util/package.html          |    3 -
 .../util/resource/DirectoryResourceCreator.java    |   53 -
 .../util/resource/DirectoryResourceFinder.java     |   85 -
 .../janino/util/resource/FileResource.java         |   55 -
 .../janino/util/resource/FileResourceCreator.java  |   62 -
 .../janino/util/resource/FileResourceFinder.java   |   57 -
 .../resource/JarDirectoriesResourceFinder.java     |   80 -
 .../util/resource/LazyMultiResourceFinder.java     |   57 -
 .../janino/util/resource/MapResourceCreator.java   |   71 -
 .../janino/util/resource/MapResourceFinder.java    |   65 -
 .../janino/util/resource/MultiResourceFinder.java  |   64 -
 .../janino/util/resource/PathResourceFinder.java   |  145 -
 .../codehaus/janino/util/resource/Resource.java    |   73 -
 .../janino/util/resource/ResourceCreator.java      |   64 -
 .../janino/util/resource/ResourceFinder.java       |   79 -
 .../util/resource/ZipFileResourceFinder.java       |   71 -
 src/org/codehaus/janino/util/resource/package.html |    6 -
 src/overview.html                                  |    9 -
 106 files changed, 20 insertions(+), 34388 deletions(-)

diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..09c1939
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,19 @@
+Quick start for JANINO users:
+
+(1) Put "commons-compiler.jar" and "janino.jar" on your class path.
+
+(2) If you're using an IDE like ECLIPSE, you can optionally have
+    "commons-compiler-src.zip" as the source attachment of
+    "commons-compiler.jar", and "janino-src.zip" as the source attachment of
+    "janino.jar". That'll get you tooltip JAVADOC and source level debugging
+    into the JANINO libraries.
+
+(3) Use one of the features, e.g. the "expression evaluator", in your program:
+
+        import org.codehaus.janino.*;
+
+        ExpressionEvaluator ee = new ExpressionEvaluator();
+        ee.cook("3 + 4");
+        System.out.println(ee.evaluate(null));
+
+(4) Compile, run, ... be happy!
diff --git a/build.properties b/build.properties
deleted file mode 100644
index 30aa8e5..0000000
--- a/build.properties
+++ /dev/null
@@ -1,60 +0,0 @@
-
-#
-# Janino - An embedded Java[TM] compiler
-#
-# Copyright (c) 2001-2007, Arno Unkrig
-# 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. The name of the author may not be used to endorse or promote
-#       products derived from this software without specific prior
-#       written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-#
-
-# misc
-version = 2.5.15
-
-# directories
-src            = src
-build          = build
-javadoc        = javadoc
-jdk_1_2_2_home = c:/jdk-1.2.2
-
-# files
-ant_jar    = c:/Programme/eclipse-3.3.2/plugins/org.apache.ant_1.7.0.v200706080842/lib/ant.jar
-janino_zip = janino-${version}.zip
-
-# javadoc-related
-jdk_javadoc_local  = c:/j2sdk-1.4.1-doc/docs/api
-jdk_javadoc_remote = http://java.sun.com/j2se/1.4.1/docs/api
-ant_javadoc_local  = ant
-ant_javadoc_remote = http://www.cs.bris.ac.uk/Teaching/Resources/General/ant/docs/manual/api
-javadoc_packages   = \
-	org.codehaus.janino,\
-	org.codehaus.janino.samples,\
-	org.codehaus.janino.tools,\
-	org.codehaus.janino.util,\
-	org.codehaus.janino.util.enumerator,\
-	org.codehaus.janino.util.iterator,\
-	org.codehaus.janino.util.resource
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 5c65f61..0000000
--- a/build.xml
+++ /dev/null
@@ -1,99 +0,0 @@
-<!--
-
-  Janino - An embedded Java[TM] compiler
-
-  Copyright (c) 2001-2007, Arno Unkrig
-  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. The name of the author may not be used to endorse or promote
-        products derived from this software without specific prior
-        written permission.
-
-  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-//-->
-
-<project name="Janino" default="compile" basedir=".">
-	<description>
-		Build file for the Janino project
-    </description>
-
-	<property file="build.properties"/>
-
-	<target name="compile" description="Compile the source">
-		<mkdir dir="build/classes"/>
-
-		<javac
-			fork="yes"
-			executable="${jdk_1_2_2_home}/bin/javac"
-			srcdir="src" excludes="org/codehaus/janino/AstGeneratorVisitor.java"
-			destdir="build/classes"
-			debug="true"
-			debuglevel="source"
-		/>
-	</target>
-
-	<target name="javadoc" description="Build JAVADOC" depends="compile">
-		<mkdir dir="build/javadoc"/>
-		<javadoc
-			header="<a href="http://janino.codehaus.org/">Web Site</a>"
-			splitindex="true"
-			doctitle="Janino ${version}"
-			windowtitle="Janino ${version}"
-			overview="src/overview.html"
-			sourcepath="src"
-			classpath="build/classes;${ant_jar}"
-			destdir="build/javadoc"
-			packagenames="${javadoc_packages}"
-		>
-			<link offline="true" href="${jdk_javadoc_remote}" packagelistloc="${jdk_javadoc_local}"/>
-			<link offline="true" href="${ant_javadoc_remote}" packagelistloc="${ant_javadoc_local}"/>
-		</javadoc>
-	</target>
-
-	<target name="jar" description="Create the janino jar." depends="compile">
-		<mkdir dir="build/lib"/>
-		<jar jarfile="build/lib/janino.jar" basedir="build/classes"/>
-	</target>
- 
-	<target name="dist" description="Generate the distribution" depends="jar, javadoc">
-		<echo level="info">Signing jar: build/lib/janino.jar</echo>
-		<exec executable="jarsigner">
-			<arg value="-keystore"/><arg value="dummy-keystore"/>
-			<arg value="-storepass"/><arg value="storepass"/>
-			<arg value="-keypass"/><arg value="keypass"/>
-			<arg value="build/lib/janino.jar"/>
-			<arg value="dummy"/>
-		</exec>
-
-		<zip destfile="${janino_zip}">
-			<zipfileset file="build/lib/janino.jar" prefix="janino-${version}/lib"/>
-			<zipfileset dir="build/javadoc" prefix="janino-${version}/javadoc"/>
-			<zipfileset dir="src" prefix="janino-${version}/src"/>
-			<zipfileset file="build.*" prefix="janino-${version}"/>
-		</zip>
-	</target>
-
-	<target name="clean" description="Clean built files.">
-		<delete dir="build"/>
-	</target>
-</project>
diff --git a/commons-compiler-jdk-src.zip b/commons-compiler-jdk-src.zip
new file mode 100644
index 0000000..1b583f3
Binary files /dev/null and b/commons-compiler-jdk-src.zip differ
diff --git a/commons-compiler-jdk.jar b/commons-compiler-jdk.jar
new file mode 100644
index 0000000..bb8cbfc
Binary files /dev/null and b/commons-compiler-jdk.jar differ
diff --git a/commons-compiler-src.zip b/commons-compiler-src.zip
new file mode 100644
index 0000000..5f283e8
Binary files /dev/null and b/commons-compiler-src.zip differ
diff --git a/commons-compiler.jar b/commons-compiler.jar
new file mode 100644
index 0000000..39ec753
Binary files /dev/null and b/commons-compiler.jar differ
diff --git a/janino-src.zip b/janino-src.zip
new file mode 100644
index 0000000..a023f67
Binary files /dev/null and b/janino-src.zip differ
diff --git a/janino.jar b/janino.jar
new file mode 100644
index 0000000..c92f477
Binary files /dev/null and b/janino.jar differ
diff --git a/src/org/codehaus/janino/doc-files/new_bsd_license.txt b/new_bsd_license.txt
similarity index 97%
rename from src/org/codehaus/janino/doc-files/new_bsd_license.txt
rename to new_bsd_license.txt
index c39b618..f906e86 100644
--- a/src/org/codehaus/janino/doc-files/new_bsd_license.txt
+++ b/new_bsd_license.txt
@@ -1,6 +1,6 @@
 Janino - An embedded Java[TM] compiler
 
-Copyright (c) 2001-2007, Arno Unkrig
+Copyright (c) 2001-2010, Arno Unkrig
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/src/org/codehaus/janino/Access.java b/src/org/codehaus/janino/Access.java
deleted file mode 100644
index d88d9b7..0000000
--- a/src/org/codehaus/janino/Access.java
+++ /dev/null
@@ -1,55 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import org.codehaus.janino.util.enumerator.Enumerator;
-import org.codehaus.janino.util.enumerator.EnumeratorFormatException;
-
-/**
- * Return value for {@link IClass.IMember#getAccess}.
- * JLS2 6.6
- */
-public final class Access extends Enumerator {
-    public static final Access PRIVATE   = new Access("private");
-    public static final Access PROTECTED = new Access("protected");
-    public static final Access DEFAULT   = new Access("/*default*/");
-    public static final Access PUBLIC    = new Access("public");
-
-    // These MUST be declared exactly like this:
-    private Access(String name) { super(name); }
-    public static Access fromString(String name) throws EnumeratorFormatException {
-        return (Access) Enumerator.fromString(name, Access.class);
-    }
-}
diff --git a/src/org/codehaus/janino/AntCompilerAdapter.java b/src/org/codehaus/janino/AntCompilerAdapter.java
deleted file mode 100644
index f5a6b25..0000000
--- a/src/org/codehaus/janino/AntCompilerAdapter.java
+++ /dev/null
@@ -1,186 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-
-import org.apache.tools.ant.taskdefs.compilers.*;
-import org.apache.tools.ant.types.Path;
-import org.codehaus.janino.util.enumerator.*;
-
-/**
- * A simple {@link org.apache.tools.ant.taskdefs.compilers.CompilerAdapter} for the "ant" tool
- * that silently ignores most of the configuration parameters and attempts to compile all given
- * source files into class files.
- */
-public class AntCompilerAdapter extends DefaultCompilerAdapter {
-
-    /**
-     * Compile all source files in <code>DefaultCompilerAdapter.compileList</code> individually and
-     * write class files in directory <code>DefaultCompilerAdapter.destDir</code>.
-     * <p>
-     * The following fields of {@link DefaultCompilerAdapter} are honored:
-     * <ul>
-     *   <li><code>DefaultCompilerAdapter.compileList</code> - the set of Java<sup>TM</sup> source files to compile
-     *   <li><code>DefaultCompilerAdapter.destDir</code> - where to store the class files
-     *   <li><code>DefaultCompilerAdapter.compileSourcepath</code> - where to look for more Java<sup>TM</sup> source files
-     *   <li><code>DefaultCompilerAdapter.compileClasspath</code> - where to look for required classes
-     *   <li><code>DefaultCompilerAdapter.extdirs</code>
-     *   <li><code>DefaultCompilerAdapter.bootclasspath</code>
-     *   <li><code>DefaultCompilerAdapter.encoding</code> - how the Java<sup>TM</sup> source files are encoded
-     *   <li><code>DefaultCompilerAdapter.verbose</code>
-     *   <li><code>DefaultCompilerAdapter.debug</code>
-     *   <li><code>org.apache.tools.ant.taskdefs.Javac.getDebugLevel()</code>
-     *   <li><code>DefaultCompilerAdapter.src</code>
-     * </ul>
-     * The following fields of {@link DefaultCompilerAdapter} are not honored at this time:
-     * <ul>
-     *   <li><code>DefaultCompilerAdapter.depend</code>
-     *   <li><code>DefaultCompilerAdapter.deprecation</code>
-     *   <li><code>DefaultCompilerAdapter.includeAntRuntime</code>
-     *   <li><code>DefaultCompilerAdapter.includeJavaRuntime</code>
-     *   <li><code>DefaultCompilerAdapter.location</code>
-     *   <li><code>DefaultCompilerAdapter.optimize</code>
-     *   <li><code>DefaultCompilerAdapter.target</code>
-     * </ul>
-     * 
-     * @return "true" on success
-     */
-    public boolean execute() {
-
-        // Convert source files into source file names.
-        File[] sourceFiles = this.compileList;
-
-        // Determine output directory.
-        File destinationDirectory = this.destDir == null ? Compiler.NO_DESTINATION_DIRECTORY : this.destDir;
-
-        // Determine the source path.
-        File[] optionalSourcePath = AntCompilerAdapter.pathToFiles(
-            this.compileSourcepath != null ?
-            this.compileSourcepath :
-            this.src
-        );
-
-        // Determine the class path.
-        File[] classPath = AntCompilerAdapter.pathToFiles(this.compileClasspath, new File[] { new File(".") });
-
-        // Determine the ext dirs.
-        File[] optionalExtDirs = AntCompilerAdapter.pathToFiles(this.extdirs);
-
-        // Determine the boot class path
-        File[] optionalBootClassPath = AntCompilerAdapter.pathToFiles(this.bootclasspath);
-
-        // Determine the encoding.
-        String optionalCharacterEncoding = this.encoding;
-
-        // Determine verbosity.
-        boolean verbose = this.verbose;
-
-        // Determine debugging information.
-        EnumeratorSet debuggingInformation;
-        if (!this.debug) {
-            debuggingInformation = DebuggingInformation.NONE;
-        } else {
-            String debugLevel = this.attributes.getDebugLevel();
-            if (debugLevel == null) {
-                debuggingInformation = DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION;
-            } else {
-                try {
-                    debuggingInformation = new EnumeratorSet(DebuggingInformation.class, debugLevel);
-                } catch (EnumeratorFormatException ex) {
-                    debuggingInformation = DebuggingInformation.NONE;
-                }
-            }
-        }
-
-        // Compile all source files.
-        try {
-            new Compiler(
-                optionalSourcePath,
-                classPath,
-                optionalExtDirs,
-                optionalBootClassPath,
-                destinationDirectory,
-                optionalCharacterEncoding,
-                verbose,
-                debuggingInformation,
-                Compiler.DEFAULT_WARNING_HANDLE_PATTERNS,
-                false                        // rebuild
-            ).compile(sourceFiles);
-        } catch (Scanner.ScanException e) {
-            System.out.println(e.getMessage());
-            return false;
-        } catch (Parser.ParseException e) {
-            System.out.println(e.getMessage());
-            return false;
-        } catch (CompileException e) {
-            System.out.println(e.getMessage());
-            return false;
-        } catch (IOException e) {
-            System.out.println(e.getMessage());
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Convert a {@link org.apache.tools.ant.types.Path} into an array of
-     * {@link File}.
-     * @param path
-     * @return The converted path, or <code>null</code> if <code>path</code> is <code>null</code>
-     */
-    private static File[] pathToFiles(Path path) {
-        if (path == null) return null;
-
-        String[] fileNames = path.list();
-        File[] files = new File[fileNames.length];
-        for (int i = 0; i < fileNames.length; ++i) files[i] = new File(fileNames[i]);
-        return files;
-    }
-
-    /**
-     * Convert a {@link org.apache.tools.ant.types.Path} into an array of
-     * {@link File}.
-     * @param path
-     * @param defaultValue
-     * @return The converted path, or, if <code>path</code> is <code>null</code>, the <code>defaultValue</code>
-     */
-    private static File[] pathToFiles(Path path, File[] defaultValue) {
-        if (path == null) return defaultValue;
-        return AntCompilerAdapter.pathToFiles(path);
-    }
-}
-
-
diff --git a/src/org/codehaus/janino/AstCompilationUnitGenerator.java b/src/org/codehaus/janino/AstCompilationUnitGenerator.java
deleted file mode 100644
index 457e9eb..0000000
--- a/src/org/codehaus/janino/AstCompilationUnitGenerator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-/**
- * @author Eugene Kuleshov
- */
-public interface AstCompilationUnitGenerator {
-    Java.CompilationUnit generate() throws Exception;
-}
diff --git a/src/org/codehaus/janino/ByteArrayClassLoader.java b/src/org/codehaus/janino/ByteArrayClassLoader.java
deleted file mode 100644
index 227fcb9..0000000
--- a/src/org/codehaus/janino/ByteArrayClassLoader.java
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.tools.Disassembler;
-
-/**
- * This {@link ClassLoader} allows for the loading of a set of Java<sup>TM</sup> classes
- * provided in class file format.
- */
-public class ByteArrayClassLoader extends ClassLoader {
-    private static final boolean DEBUG = false;
-
-    /**
-     * The given {@link Map} of classes must not be modified afterwards.
-     * 
-     * @param classes String className => byte[] data
-     */
-    public ByteArrayClassLoader(Map classes) {
-        this.classes = classes;
-    }
-
-    /**
-     * @see #ByteArrayClassLoader(Map)
-     */
-    public ByteArrayClassLoader(Map classes, ClassLoader parent) {
-        super(parent);
-        this.classes = classes;
-    }
-
-    /**
-     * Implements {@link ClassLoader#findClass(String)}.
-     * <p>
-     * Notice that, although nowhere documented, no more than one thread at a time calls this
-     * method, because {@link ClassLoader#loadClass(java.lang.String)} is
-     * <code>synchronized</code>.
-     */
-    protected Class findClass(String name) throws ClassNotFoundException {
-        byte[] data = (byte[]) this.classes.get(name);
-        if (data == null) throw new ClassNotFoundException(name); 
-
-        if (DEBUG) {
-            System.out.println("*** Disassembly of class \"" + name + "\":");
-            try {
-                new Disassembler().disasm(new ByteArrayInputStream(data));
-                System.out.flush();
-            } catch (IOException ex) {
-                throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
-            }
-        }
-
-        // Notice: Not inheriting the protection domain will cause problems with Java Web Start /
-        // JNLP. See
-        //     http://jira.codehaus.org/browse/JANINO-104
-        //     http://www.nabble.com/-Help-jel--java.security.AccessControlException-to13073723.html
-        return super.defineClass(
-            name,                                 // name
-            data, 0, data.length,                 // b, off, len
-            this.getClass().getProtectionDomain() // protectionDomain
-        );
-    }
-
-    /**
-     * An object is regarded equal to <code>this</code> iff
-     * <ul>
-     *   <li>It is also an instance of {@link ByteArrayClassLoader}
-     *   <li>Both have the same parent {@link ClassLoader}
-     *   <li>Exactly the same classes (name, bytecode) were added to both
-     * </ul>
-     * Roughly speaking, equal {@link ByteArrayClassLoader}s will return functionally identical
-     * {@link Class}es on {@link ClassLoader#loadClass(java.lang.String)}.
-     */
-    public boolean equals(Object o) {
-        if (!(o instanceof ByteArrayClassLoader)) return false;
-        if (this == o) return true;
-        ByteArrayClassLoader that = (ByteArrayClassLoader) o;
-
-        {
-            final ClassLoader parentOfThis = this.getParent();
-            final ClassLoader parentOfThat = that.getParent();
-            if (parentOfThis == null ? parentOfThat != null : !parentOfThis.equals(parentOfThat)) return false;
-        }
-
-        if (this.classes.size() != that.classes.size()) return false;
-        for (Iterator it = this.classes.entrySet().iterator(); it.hasNext();) {
-            Map.Entry me = (Map.Entry) it.next();
-            byte[] ba = (byte[]) that.classes.get(me.getKey());
-            if (ba == null) return false; // Key missing in "that".
-            if (!Arrays.equals((byte[]) me.getValue(), ba)) return false; // Byte arrays differ.
-        }
-        return true;
-    }
-    public int hashCode() {
-        int hc = this.getParent().hashCode();
-
-        for (Iterator it = this.classes.entrySet().iterator(); it.hasNext();) {
-            Map.Entry me = (Map.Entry) it.next();
-            hc ^= me.getKey().hashCode();
-            byte[] ba = (byte[]) me.getValue();
-            for (int i = 0; i < ba.length; ++i) {
-                hc = (31 * hc) ^ ba[i];
-            }
-        }
-        return hc;
-    }
-
-    private final Map classes; // String className => byte[] data
-}
diff --git a/src/org/codehaus/janino/CachingJavaSourceClassLoader.java b/src/org/codehaus/janino/CachingJavaSourceClassLoader.java
deleted file mode 100644
index 48a850c..0000000
--- a/src/org/codehaus/janino/CachingJavaSourceClassLoader.java
+++ /dev/null
@@ -1,225 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-import org.codehaus.janino.util.resource.*;
-
-/**
- * A {@link org.codehaus.janino.JavaSourceClassLoader} that uses a
- * resource storage provided by the application to cache compiled
- * classes and thus saving unnecessary recompilations.
- * <p>
- * The application provides access to the resource storeage through a pair of
- * a {@link org.codehaus.janino.util.resource.ResourceFinder} and a
- * {@link org.codehaus.janino.util.resource.ResourceCreator} (see
- * {@link #CachingJavaSourceClassLoader(ClassLoader, ResourceFinder, String, ResourceFinder, ResourceCreator, EnumeratorSet)}.
- * <p>
- * See {@link org.codehaus.janino.JavaSourceClassLoader#main(String[])} for
- * an example how to use this class.
- * <p>
- * <b>Notice:</b> You must NOT rely on that this class stores some particular data in some
- * particular resources through the given <code>classFileCacheResourceFinder/Creator</code>!
- * These serve only as a means for the {@link CachingJavaSourceClassLoader} to persistently
- * cache some data between invocations. In other words: If you want to compile <code>.java</code>
- * files into <code>.class</code> files, then don't use <i>this</i> class but {@link Compiler}
- * instead!
- */
-public class CachingJavaSourceClassLoader extends JavaSourceClassLoader {
-    private final ResourceFinder  classFileCacheResourceFinder;
-    private final ResourceCreator classFileCacheResourceCreator;
-    private final ResourceFinder  sourceFinder;
-
-    /**
-     * See {@link #CachingJavaSourceClassLoader(ClassLoader, ResourceFinder, String, ResourceFinder, ResourceCreator, EnumeratorSet)}.
-     *
-     * @param optionalSourcePath Directories to scan for source files
-     * @param cacheDirectory Directory to use for caching generated class files (see class description)
-     */
-    public CachingJavaSourceClassLoader(
-        ClassLoader   parentClassLoader,
-        File[]        optionalSourcePath,
-        String        optionalCharacterEncoding,
-        File          cacheDirectory,
-        EnumeratorSet debuggingInformation
-    ) {
-        this(
-            parentClassLoader,                            // parentClassLoader
-            (                                             // sourceFinder
-                optionalSourcePath == null ?
-                (ResourceFinder) new DirectoryResourceFinder(new File(".")) :
-                (ResourceFinder) new PathResourceFinder(optionalSourcePath)
-            ),
-            optionalCharacterEncoding,                    // optionalCharacterEncoding
-            new DirectoryResourceFinder(cacheDirectory),  // classFileCacheResourceFinder
-            new DirectoryResourceCreator(cacheDirectory), // classFileCacheResourceCreator
-            debuggingInformation                          // debuggingInformation
-        );
-    }
-
-    /**
-     * Notice that this class is thread-safe if and only if the
-     * <code>classFileCacheResourceCreator</code> stores its data atomically,
-     * i.e. the <code>classFileCacheResourceFinder</code> sees the resource
-     * written by the <code>classFileCacheResourceCreator</code> only after
-     * the {@link OutputStream} is closed.
-     * <p>
-     * In order to make the caching scheme work, both the
-     * <code>classFileCacheResourceFinder</code> and the
-     * <code>sourceFinder</code> must support the {@link org.codehaus.janino.util.resource.Resource#lastModified()}
-     * method, so that the modification time of the source and the class files
-     * can be compared.
-     * 
-     * @param parentClassLoader             Attempt to load classes through this one before looking for source files
-     * @param sourceFinder                  Finds Java<sup>TM</sup> source for class <code>pkg.Cls</code> in resource <code>pkg/Cls.java</code>
-     * @param optionalCharacterEncoding     Encoding of Java<sup>TM</sup> source or <code>null</code> for platform default encoding
-     * @param classFileCacheResourceFinder  Finds precompiled class <code>pkg.Cls</code> in resource <code>pkg/Cls.class</code> (see class description)
-     * @param classFileCacheResourceCreator Stores compiled class <code>pkg.Cls</code> in resource <code>pkg/Cls.class</code> (see class description)
-     * @param debuggingInformation          What debugging information to include into the generated class files
-     */
-    public CachingJavaSourceClassLoader(
-        ClassLoader     parentClassLoader,
-        ResourceFinder  sourceFinder,
-        String          optionalCharacterEncoding,
-        ResourceFinder  classFileCacheResourceFinder,
-        ResourceCreator classFileCacheResourceCreator,
-        EnumeratorSet   debuggingInformation
-    ) {
-        super(parentClassLoader, sourceFinder, optionalCharacterEncoding, debuggingInformation);
-        this.classFileCacheResourceFinder  = classFileCacheResourceFinder;
-        this.classFileCacheResourceCreator = classFileCacheResourceCreator;
-        this.sourceFinder                  = sourceFinder;
-    }
-
-    /**
-     * Override {@link JavaSourceClassLoader#generateBytecodes(String)} to implement
-     * class file caching.
-     *
-     * @return String name => byte[] bytecode, or <code>null</code> if no source code could be found
-     * @throws ClassNotFoundException on compilation problems or class file cache I/O problems
-     */
-    protected Map generateBytecodes(String className) throws ClassNotFoundException {
-
-        // Check whether a class file resource exists in the cache.
-        {
-            Resource classFileResource = this.classFileCacheResourceFinder.findResource(ClassFile.getClassFileResourceName(className));
-            if (classFileResource != null) {
-    
-                // Check whether a source file resource exists.
-                Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
-                if (sourceResource == null) return null;
-    
-                // Check whether the class file is up-to-date.
-                if (sourceResource.lastModified() < classFileResource.lastModified()) {
-
-                    // Yes, it is... read the bytecode from the file and define the class.
-                    byte[] bytecode;
-                    try {
-                        bytecode = CachingJavaSourceClassLoader.readResource(classFileResource);
-                    } catch (IOException ex) {
-                        throw new ClassNotFoundException("Reading class file from \"" + classFileResource + "\"", ex);
-                    }
-                    Map m = new HashMap();
-                    m.put(className, bytecode);
-                    return m;
-                }
-            }
-        }
-
-        // Cache miss... generate the bytecode from source.
-        Map bytecodes = super.generateBytecodes(className);
-        if (bytecodes == null) return null;
-
-        // Write the generated bytecodes to the class file cache.
-        for (Iterator it = bytecodes.entrySet().iterator(); it.hasNext();) {
-            Map.Entry me = (Map.Entry) it.next();
-            String className2 = (String) me.getKey();
-            byte[] bytecode = (byte[]) me.getValue();
-
-            try {
-                CachingJavaSourceClassLoader.writeResource(
-                    this.classFileCacheResourceCreator,
-                    ClassFile.getClassFileResourceName(className2),
-                    bytecode
-                );
-            } catch (IOException ex) {
-                throw new ClassNotFoundException("Writing class file to \"" + ClassFile.getClassFileResourceName(className2) + "\"", ex);
-            }
-        }
-
-        return bytecodes;
-    }
-
-    /**
-     * Read all bytes from the given resource.
-     */
-    private static byte[] readResource(Resource r) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        byte[] buffer = new byte[4096];
-
-        InputStream is = r.open();
-        try {
-            for (;;) {
-                int cnt = is.read(buffer);
-                if (cnt == -1) break;
-                baos.write(buffer, 0, cnt);
-            }
-        } finally {
-            try { is.close(); } catch (IOException ex) {}
-        }
-
-        return baos.toByteArray();
-    }
-
-    /**
-     * Create a resource with the given name and store the data in it.
-     */
-    private static void writeResource(
-        ResourceCreator resourceCreator,
-        String          resourceName,
-        byte[]          data
-    ) throws IOException {
-        OutputStream os = resourceCreator.createResource(resourceName);
-        try {
-            os.write(data);
-        } finally {
-            try { os.close(); } catch (IOException ex) {}
-        }
-    }
-}
diff --git a/src/org/codehaus/janino/ClassBodyEvaluator.java b/src/org/codehaus/janino/ClassBodyEvaluator.java
deleted file mode 100644
index 9ca1cea..0000000
--- a/src/org/codehaus/janino/ClassBodyEvaluator.java
+++ /dev/null
@@ -1,495 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-
-import org.codehaus.janino.Parser.ParseException;
-import org.codehaus.janino.Scanner.ScanException;
-import org.codehaus.janino.util.enumerator.EnumeratorSet;
-
-/**
- * Parses a class body and returns it as a <tt>java.lang.Class</tt> object
- * ready for use with <tt>java.lang.reflect</tt>.
- * <p>
- * Example:
- * <pre>
- *   import java.util.*;
- *
- *   static private int a = 1;
- *   private int b = 2;
- *
- *   public void func(int c, int d) {
- *       return func2(c, d);
- *   }
- *
- *   private static void func2(int e, int f) {
- *       return e * f;
- *   }
- * </pre>
- * <p>
- * The <code>optionalClassLoader</code> serves two purposes:
- * <ul>
- *   <li>It is used to look for classes referenced by the class body.
- *   <li>It is used to load the generated Java<sup>TM</sup> class
- *   into the JVM; directly if it is a subclass of {@link
- *   ByteArrayClassLoader}, or by creation of a temporary
- *   {@link ByteArrayClassLoader} if not.
- * </ul>
- * To set up a {@link ClassBodyEvaluator} object, proceed as follows:
- * <ol>
- *   <li>
- *   Create the {@link ClassBodyEvaluator} using {@link #ClassBodyEvaluator()}
- *   <li>
- *   Configure the {@link ClassBodyEvaluator} by calling any of the following methods:
- *   <ul>
- *      <li>{@link org.codehaus.janino.SimpleCompiler#setParentClassLoader(ClassLoader)}
- *      <li>{@link #setDefaultImports(String[])}
- *   </ul>
- *   <li>
- *   Call any of the {@link org.codehaus.janino.Cookable#cook(Scanner)} methods to scan,
- *   parse, compile and load the class body into the JVM.
- * </ol>
- * Alternatively, a number of "convenience constructors" exist that execute the steps described
- * above instantly.
- * <p>
- * To compile a class body and immediately instantiate an object, one of the
- * {@link #createFastClassBodyEvaluator(Scanner, Class, ClassLoader)} methods can be used.
- * <p>
- * The generated class may optionally extend/implement a given type; the returned instance can
- * safely be type-casted to that <code>optionalBaseType</code>.
- * <p>
- * Example:
- * <pre>
- * public interface Foo {
- *     int bar(int a, int b);
- * }
- * ...
- * Foo f = (Foo) ClassBodyEvaluator.createFastClassBodyEvaluator(
- *     new Scanner(null, new StringReader("public int bar(int a, int b) { return a + b; }")),
- *     Foo.class,                  // Base type to extend/implement
- *     (ClassLoader) null          // Use current thread's context class loader
- * );
- * System.out.println("1 + 2 = " + f.bar(1, 2));
- * </pre>
- * Notice: The <code>optionalBaseType</code> must be accessible from the generated class,
- * i.e. it must either be declared <code>public</code>, or with default accessibility in the
- * same package as the generated class.
- */
-public class ClassBodyEvaluator extends SimpleCompiler {
-    public static final String     DEFAULT_CLASS_NAME = "SC";
-    protected static final Class[] ZERO_CLASSES = new Class[0];
-
-    private String[]               optionalDefaultImports = null;
-    protected String               className = ClassBodyEvaluator.DEFAULT_CLASS_NAME;
-    private Class                  optionalExtendedType = null;
-    private Class[]                implementedTypes = ClassBodyEvaluator.ZERO_CLASSES;
-    private Class                  result = null; // null=uncooked
-
-    /**
-     * Equivalent to<pre>
-     * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
-     * cbe.cook(classBody);</pre>
-     *
-     * @see #ClassBodyEvaluator()
-     * @see Cookable#cook(String)
-     */
-    public ClassBodyEvaluator(
-        String classBody
-    ) throws CompileException, ParseException, ScanException {
-        this.cook(classBody);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
-     * cbe.cook(optionalFileName, is);</pre>
-     *
-     * @see #ClassBodyEvaluator()
-     * @see Cookable#cook(String, InputStream)
-     */
-    public ClassBodyEvaluator(
-        String      optionalFileName,
-        InputStream is
-    ) throws CompileException, ParseException, ScanException, IOException {
-        this.cook(optionalFileName, is);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
-     * cbe.cook(optionalFileName, reader);</pre>
-     *
-     * @see #ClassBodyEvaluator()
-     * @see Cookable#cook(String, Reader)
-     */
-    public ClassBodyEvaluator(
-        String   optionalFileName,
-        Reader   reader
-    ) throws CompileException, ParseException, ScanException, IOException {
-        this.cook(optionalFileName, reader);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
-     * cbe.setParentClassLoader(optionalParentClassLoader);
-     * cbe.cook(scanner);</pre>
-     *
-     * @see #ClassBodyEvaluator()
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(Scanner)
-     */
-    public ClassBodyEvaluator(
-        Scanner     scanner,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, ParseException, ScanException, IOException {
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(scanner);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
-     * cbe.setExtendedType(optionalExtendedType);
-     * cbe.setImplementedTypes(implementedTypes);
-     * cbe.setParentClassLoader(optionalParentClassLoader);
-     * cbe.cook(scanner);</pre>
-     *
-     * @see #ClassBodyEvaluator()
-     * @see #setExtendedType(Class)
-     * @see #setImplementedTypes(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(Scanner)
-     */
-    public ClassBodyEvaluator(
-        Scanner     scanner,
-        Class       optionalExtendedType,
-        Class[]     implementedTypes,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, ParseException, ScanException, IOException {
-        this.setExtendedType(optionalExtendedType);
-        this.setImplementedTypes(implementedTypes);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(scanner);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ClassBodyEvaluator cbe = new ClassBodyEvaluator();
-     * cbe.setClassName(className);
-     * cbe.setExtendedType(optionalExtendedType);
-     * cbe.setImplementedTypes(implementedTypes);
-     * cbe.setParentClassLoader(optionalParentClassLoader);
-     * cbe.cook(scanner);</pre>
-     *
-     * @see #ClassBodyEvaluator()
-     * @see #setClassName(String)
-     * @see #setExtendedType(Class)
-     * @see #setImplementedTypes(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(Scanner)
-     */
-    public ClassBodyEvaluator(
-        Scanner     scanner,
-        String      className,
-        Class       optionalExtendedType,
-        Class[]     implementedTypes,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, ParseException, ScanException, IOException {
-        this.setClassName(className);
-        this.setExtendedType(optionalExtendedType);
-        this.setImplementedTypes(implementedTypes);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(scanner);
-    }
-
-    public ClassBodyEvaluator() {}
-
-    /**
-     * "Default imports" add to the system import "java.lang", i.e. the evaluator may refer to
-     * classes imported by default imports without having to explicitly declare IMPORT statements.
-     * <p>
-     * Notice that JDK 5 "static imports" are also supported, as shown in the following example.
-     * <p>
-     * Example: <pre>
-     *     sc.setDefaultImports(new String[] {
-     *         "java.util.Map",                          // Single type import
-     *         "java.io.*",                              // Type-import-on-demand
-     *         "static java.util.Collections.EMPTY_MAP", // Single static import
-     *         "static java.util.Collections.*",         // Static-import-on-demand
-     *     });</pre>
-     */
-    public void setDefaultImports(String[] optionalDefaultImports) {
-        assertNotCooked();
-        this.optionalDefaultImports = optionalDefaultImports;
-    }
-
-    /**
-     * Set the name of the generated class. Defaults to {@link #DEFAULT_CLASS_NAME}. In most cases,
-     * there is no need to set this name, because the generated class is loaded into its own
-     * {@link java.lang.ClassLoader} where its name cannot collide with classes generated by
-     * other evaluators.
-     * <p>
-     * One reason to use this function is to have a class name in a non-default package, which
-     * can be relevant when types and members with DEFAULT accessibility are accessed.
-     */
-    public void setClassName(String className) {
-        if (className == null) throw new NullPointerException();
-        assertNotCooked();
-        this.className = className;
-    }
-
-    /**
-     * Set a particular superclass that the generated class will extend. If <code>null</code> is
-     * passed, the generated class will extend {@link Object}.
-     * <p>
-     * The common reason to set a base class for an evaluator is that the generated class can
-     * directly access the base superclass's (non-private) members.
-     */
-    public void setExtendedType(Class optionalExtendedType) {
-        assertNotCooked();
-        this.optionalExtendedType = optionalExtendedType;
-    }
-
-    /**
-     * Set a particular set of interfaces that the generated class will implement.
-     */
-    public void setImplementedTypes(Class[] implementedTypes) {
-        if (implementedTypes == null) throw new NullPointerException("Zero implemented types must be specified as \"new Class[0]\", not \"null\"");
-        assertNotCooked();
-        this.implementedTypes = implementedTypes;
-    }
-
-    public void cook(Scanner scanner)
-    throws CompileException, ParseException, ScanException, IOException {
-        this.setUpClassLoaders();
-
-        Java.CompilationUnit compilationUnit = this.makeCompilationUnit(scanner);
-
-        // Add class declaration.
-        Java.ClassDeclaration cd = this.addPackageMemberClassDeclaration(
-            scanner.location(),
-            compilationUnit
-        );
-        
-        // Parse class body declarations (member declarations) until EOF.
-        Parser parser = new Parser(scanner);
-        while (!scanner.peek().isEOF()) {
-            parser.parseClassBodyDeclaration(cd);
-        }
-
-        // Compile and load it.
-        this.result = this.compileToClass(
-            compilationUnit,              // compilationUnit
-            DebuggingInformation.ALL,     // debuggingInformation
-            this.className
-        );
-    }
-
-    /**
-     * Create a {@link Java.CompilationUnit}, set the default imports, and parse the import
-     * declarations.
-     * <p>
-     * If the <code>optionalScanner</code> is given, a sequence of IMPORT directives is parsed
-     * from it and added to the compilation unit.
-     */
-    protected final Java.CompilationUnit makeCompilationUnit(Scanner optionalScanner)
-    throws ParseException, ScanException, IOException {
-        Java.CompilationUnit cu = new Java.CompilationUnit(optionalScanner == null ? null : optionalScanner.getFileName());
-        
-        // Set default imports.
-        if (this.optionalDefaultImports != null) {
-            for (int i = 0; i < this.optionalDefaultImports.length; ++i) {
-                Scanner s = new Scanner(null, new StringReader(this.optionalDefaultImports[i]));
-                cu.addImportDeclaration(new Parser(s).parseImportDeclarationBody());
-                if (!s.peek().isEOF()) throw new ParseException("Unexpected token \"" + s.peek() + "\" in default import", s.location());
-            }
-        }
-
-        // Parse all available IMPORT declarations.
-        if (optionalScanner != null) {
-            Parser parser = new Parser(optionalScanner);
-            while (optionalScanner.peek().isKeyword("import")) {
-                cu.addImportDeclaration(parser.parseImportDeclaration());
-            }
-        }
-
-        return cu;
-    }
-
-    /**
-     * To the given {@link Java.CompilationUnit}, add
-     * <ul>
-     *   <li>A class declaration with the configured name, superclass and interfaces
-     *   <li>A method declaration with the given return type, name, parameter
-     *       names and values and thrown exceptions
-     * </ul>
-     *
-     * @return The created {@link Java.ClassDeclaration} object
-     */
-    protected Java.PackageMemberClassDeclaration addPackageMemberClassDeclaration(
-        Location             location,
-        Java.CompilationUnit compilationUnit
-    ) throws ParseException {
-        String cn = this.className;
-        int idx = cn.lastIndexOf('.');
-        if (idx != -1) {
-            compilationUnit.setPackageDeclaration(new Java.PackageDeclaration(location, cn.substring(0, idx)));
-            cn = cn.substring(idx + 1);
-        }
-        Java.PackageMemberClassDeclaration tlcd = new Java.PackageMemberClassDeclaration(
-            location,                                              // location
-            null,                                                  // optionalDocComment
-            Mod.PUBLIC,                                            // modifiers
-            cn,                                                    // name
-            this.classToType(location, this.optionalExtendedType), // optionalExtendedType
-            this.classesToTypes(location, this.implementedTypes)   // implementedTypes
-        );
-        compilationUnit.addPackageMemberTypeDeclaration(tlcd);
-        return tlcd;
-    }
-
-    /**
-     * Compile the given compilation unit, load all generated classes, and
-     * return the class with the given name. 
-     * @param compilationUnit
-     * @param debuggingInformation TODO
-     * @param newClassName The fully qualified class name
-     * @return The loaded class
-     */
-    protected final Class compileToClass(
-        Java.CompilationUnit compilationUnit,
-        EnumeratorSet        debuggingInformation,
-        String               newClassName
-    ) throws CompileException {
-
-        // Compile and load the compilation unit.
-        ClassLoader cl = this.compileToClassLoader(compilationUnit, debuggingInformation);
-
-        // Find the generated class by name.
-        try {
-            return cl.loadClass(newClassName);
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException("SNO: Generated compilation unit does not declare class \"" + newClassName + "\"");
-        }
-    }
-
-    /**
-     * Returns the loaded {@link Class}.
-     * <p>
-     * This method must only be called after {@link #cook(Scanner)}.
-     * <p>
-     * This method must not be called for instances of derived classes.
-     */
-    public Class getClazz() {
-        if (this.getClass() != ClassBodyEvaluator.class) throw new IllegalStateException("Must not be called on derived instances");
-        if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
-        return this.result;
-    }
-
-    /**
-     * Scans, parses and compiles a class body from the tokens delivered by the the given
-     * {@link Scanner}.
-     * The generated class has the {@link #DEFAULT_CLASS_NAME} and extends the given
-     * <code>optionalBaseType</code> (if that is a class), and implements the given
-     * <code>optionalBaseType</code> (if that is an interface).
-     * <p>
-     * For an explanation of the "fast class body evaluator" concept, see the class description.
-     *
-     * @param scanner                   Source of class body tokens
-     * @param optionalBaseType          Base type to extend/implement
-     * @param optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
-     * @return an object that extends/implements the given <code>optionalBaseType</code>
-     * @see ClassBodyEvaluator
-     */
-    public static Object createFastClassBodyEvaluator(
-        Scanner     scanner,
-        Class       optionalBaseType,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, ParseException, ScanException, IOException {
-        return ClassBodyEvaluator.createFastClassBodyEvaluator(
-            scanner,                               // scanner
-            ClassBodyEvaluator.DEFAULT_CLASS_NAME, // className
-            (                                      // optionalExtendedType
-                optionalBaseType != null && !optionalBaseType.isInterface() ?
-                optionalBaseType : null
-            ),
-            (                                      // implementedTypes
-                optionalBaseType != null && optionalBaseType.isInterface() ?
-                new Class[] { optionalBaseType } : new Class[0]
-            ),
-            optionalParentClassLoader              // optionalParentClassLoader
-        );
-    }
-
-    /**
-     * Scans, parses and compiles a class body from the tokens delivered by the the given
-     * {@link Scanner} with no default imports.
-     * <p>
-     * For an explanation of the "fast class body evaluator" concept, see the class description.
-     * 
-     * @param scanner Source of class body tokens
-     * @param className Name of generated class
-     * @param optionalExtendedType Class to extend
-     * @param implementedTypes Interfaces to implement
-     * @param optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
-     * @return an object that extends the <code>optionalExtendedType</code> and implements the given <code>implementedTypes</code>
-     * @see ClassBodyEvaluator
-     */
-    public static Object createFastClassBodyEvaluator(
-        Scanner     scanner,
-        String      className,
-        Class       optionalExtendedType,
-        Class[]     implementedTypes,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, ParseException, ScanException, IOException {
-        Class c = new ClassBodyEvaluator(
-            scanner,
-            className,
-            optionalExtendedType,
-            implementedTypes,
-            optionalParentClassLoader
-        ).getClazz();
-        try {
-            return c.newInstance();
-        } catch (InstantiationException e) {
-            throw new CompileException("Cannot instantiate abstract class -- one or more method implementations are missing", null);
-        } catch (IllegalAccessException e) {
-            // SNO - type and default constructor of generated class are PUBLIC.
-            throw new RuntimeException(e.toString());
-        }
-    }
-}
diff --git a/src/org/codehaus/janino/ClassFileIClass.java b/src/org/codehaus/janino/ClassFileIClass.java
deleted file mode 100644
index 0365abf..0000000
--- a/src/org/codehaus/janino/ClassFileIClass.java
+++ /dev/null
@@ -1,449 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.util.*;
-
-import org.codehaus.janino.util.ClassFile;
-
-
-/**
- * A wrapper object that turns a {@link ClassFile} object into a
- * {@link IClass}.
- */
-public class ClassFileIClass extends IClass {
-    private static final boolean DEBUG = false;
-
-    private final ClassFile    classFile;
-    private final IClassLoader iClassLoader;
-    private final short        accessFlags;
-
-    private final Map resolvedFields = new HashMap(); // FieldInfo => IField
-
-    /**
-     * @param classFile Source of data
-     * @param iClassLoader {@link IClassLoader} through which to load other classes
-     */
-    public ClassFileIClass(
-        ClassFile    classFile,
-        IClassLoader iClassLoader
-    ) {
-        this.classFile    = classFile;
-        this.iClassLoader = iClassLoader;
-
-        // Determine class access flags.
-        this.accessFlags = classFile.accessFlags;
-    }
-
-    // Implement IClass.
-
-    protected IConstructor[] getDeclaredIConstructors2() {
-        List iConstructors = new ArrayList();
-
-        for (Iterator it = this.classFile.methodInfos.iterator(); it.hasNext();) {
-            ClassFile.MethodInfo mi = (ClassFile.MethodInfo) it.next();
-            IInvocable ii;
-            try {
-                ii = this.resolveMethod(mi);
-            } catch (ClassNotFoundException ex) {
-                throw new RuntimeException(ex.getMessage());
-            }
-            if (ii instanceof IConstructor) iConstructors.add(ii);
-        }
-
-        return (IConstructor[]) iConstructors.toArray(new IConstructor[iConstructors.size()]);
-    }
-
-    protected IMethod[] getDeclaredIMethods2() {
-        List iMethods = new ArrayList();
-
-        for (Iterator it = this.classFile.methodInfos.iterator(); it.hasNext();) {
-            ClassFile.MethodInfo mi = (ClassFile.MethodInfo) it.next();
-
-            // Skip JDK 1.5 synthetic methods (e.g. those generated for
-            // covariant return values).
-            if ((mi.getAccessFlags() & Mod.SYNTHETIC) != 0) continue;
-
-            IInvocable ii;
-            try {
-                ii = this.resolveMethod(mi);
-            } catch (ClassNotFoundException ex) {
-                throw new RuntimeException(ex.getMessage());
-            }
-            if (ii instanceof IMethod) iMethods.add(ii);
-        }
-
-        return (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
-    }
-
-    protected IField[] getDeclaredIFields2() {
-        IField[] ifs = new IClass.IField[this.classFile.fieldInfos.size()];
-        for (int i = 0; i < this.classFile.fieldInfos.size(); ++i) {
-            try {
-                ifs[i] = this.resolveField((ClassFile.FieldInfo) this.classFile.fieldInfos.get(i));
-            } catch (ClassNotFoundException ex) {
-                throw new RuntimeException(ex.getMessage());
-            }
-        }
-        return ifs;
-    }
-
-    protected IClass[] getDeclaredIClasses2() throws CompileException {
-        ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
-        if (ica == null) return new IClass[0];
-
-        List ices = ica.getEntries(); // ClassFile.InnerClassAttribute.Entry
-        List res = new ArrayList(); // IClass
-        for (Iterator it = ices.iterator(); it.hasNext();) {
-            ClassFile.InnerClassesAttribute.Entry e = (ClassFile.InnerClassesAttribute.Entry) it.next();
-            if (e.outerClassInfoIndex == this.classFile.thisClass) {
-                try {
-                    res.add(this.resolveClass(e.innerClassInfoIndex));
-                } catch (ClassNotFoundException ex) {
-                    throw new CompileException(ex.getMessage(), null);
-                }
-            } 
-        }
-        return (IClass[]) res.toArray(new IClass[res.size()]);
-    }
-
-    protected IClass getDeclaringIClass2() throws CompileException {
-        ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
-        if (ica == null) return null;
-
-        List ices = ica.getEntries(); // ClassFile.InnerClassAttribute.Entry
-        for (Iterator it = ices.iterator(); it.hasNext();) {
-            ClassFile.InnerClassesAttribute.Entry e = (ClassFile.InnerClassesAttribute.Entry) it.next();
-            if (e.innerClassInfoIndex == this.classFile.thisClass) {
-                // Is this an anonymous class?
-                if (e.outerClassInfoIndex == 0) return null;
-                try {
-                    return this.resolveClass(e.outerClassInfoIndex);
-                } catch (ClassNotFoundException ex) {
-                    throw new CompileException(ex.getMessage(), null);
-                }
-            } 
-        }
-        return null;
-    }
-
-    protected IClass getOuterIClass2() throws CompileException {
-        ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
-        if (ica == null) return null;
-
-        List ices = ica.getEntries(); // ClassFile.InnerClassAttribute.Entry
-        for (Iterator it = ices.iterator(); it.hasNext();) {
-            ClassFile.InnerClassesAttribute.Entry e = (ClassFile.InnerClassesAttribute.Entry) it.next();
-            if (e.innerClassInfoIndex == this.classFile.thisClass) {
-                if (e.outerClassInfoIndex == 0) {
-
-                    // Anonymous class or local class.
-                    // TODO: Determine enclosing instance of anonymous class or local class
-                    return null;
-                } else  {
-
-                    // Member type.
-                    if ((e.innerClassAccessFlags & Mod.STATIC) != 0) return null;
-                    try {
-                        return this.resolveClass(e.outerClassInfoIndex);
-                    } catch (ClassNotFoundException ex) {
-                        throw new CompileException(ex.getMessage(), null);
-                    }
-                }
-            } 
-        }
-        return null;
-    }
-
-    protected IClass getSuperclass2() throws CompileException {
-        if (this.classFile.superclass == 0) return null;
-        try {
-            return this.resolveClass(this.classFile.superclass);
-        } catch (ClassNotFoundException e) {
-            throw new CompileException(e.getMessage(), null);
-        }
-    }
-
-    public Access getAccess() {
-        return ClassFileIClass.accessFlags2Access(this.accessFlags);
-    }
-
-    public boolean isFinal() {
-        return (this.accessFlags & Mod.FINAL) != 0;
-    }
-
-    protected IClass[] getInterfaces2() throws CompileException {
-        return this.resolveClasses(this.classFile.interfaces);
-    }
-
-    public boolean isAbstract() {
-        return (this.accessFlags & Mod.ABSTRACT) != 0;
-    }
-
-    protected String getDescriptor2() {
-        return Descriptor.fromClassName(this.classFile.getThisClassName());
-    }
-
-    public boolean isInterface() {
-        return (this.accessFlags & Mod.INTERFACE) != 0;
-    }
-
-    public boolean isArray() {
-        return false;
-    }
-
-    public boolean isPrimitive() {
-        return false;
-    }
-
-    public boolean isPrimitiveNumeric() {
-        return false;
-    }
-
-    protected IClass getComponentType2() {
-        return null;
-    }
-
-    public void resolveHalf() throws ClassNotFoundException {
-
-        // Resolve superclass.
-        this.resolveClass(this.classFile.superclass);
-
-        // Resolve interfaces.
-        for (int i = 0; i < this.classFile.interfaces.length; ++i) {
-            this.resolveClass(this.classFile.interfaces[i]);
-        }
-
-        // Resolve constructors and methods.
-        for (int i = 0; i < this.classFile.methodInfos.size(); ++i) {
-            this.resolveMethod((ClassFile.MethodInfo) this.classFile.methodInfos.get(i));
-        }
-
-        // Process fields.
-        for (int i = 0; i < this.classFile.fieldInfos.size(); ++i) {
-            this.resolveField((ClassFile.FieldInfo) this.classFile.fieldInfos.get(i));
-        }
-    }
-
-    public void resolveAllClasses() throws ClassNotFoundException {
-        for (short i = 0; i < this.classFile.constantPool.size(); ++i) {
-            ClassFile.ConstantPoolInfo cpi = this.classFile.getConstantPoolInfo(i);
-            if (cpi instanceof ClassFile.ConstantClassInfo) {
-                this.resolveClass(i);
-            } else
-            if (cpi instanceof ClassFile.ConstantNameAndTypeInfo) {
-                short descriptorIndex = ((ClassFile.ConstantNameAndTypeInfo) cpi).getDescriptorIndex();
-                String descriptor = this.classFile.getConstantUtf8(descriptorIndex);
-                if (descriptor.charAt(0) == '(') {
-                    MethodDescriptor md = new MethodDescriptor(descriptor);
-                    this.resolveClass(md.returnFD);
-                    for (int j = 0; j < md.parameterFDs.length; ++j) this.resolveClass(md.parameterFDs[j]);
-                } else {
-                    this.resolveClass(descriptor);
-                }
-            }
-        }
-    }
-
-    /**
-     * @param index Index of the CONSTANT_Class_info to resolve (JVMS 4.4.1)
-     */
-    private IClass resolveClass(short index) throws ClassNotFoundException {
-        if (ClassFileIClass.DEBUG) System.out.println("index=" + index);
-        return this.resolveClass(Descriptor.fromInternalForm(this.classFile.getConstantClassName(index)));
-    }
-    
-    private IClass resolveClass(String descriptor) throws ClassNotFoundException {
-        if (ClassFileIClass.DEBUG) System.out.println("descriptor=" + descriptor);
-
-        IClass result = (IClass) this.resolvedClasses.get(descriptor);
-        if (result != null) return result;
-        
-        result = this.iClassLoader.loadIClass(descriptor);
-        if (result == null) throw new ClassNotFoundException(descriptor);
-
-        this.resolvedClasses.put(descriptor, result);
-        return result;
-    }
-    private final Map resolvedClasses = new HashMap(); // String descriptor => IClass
-
-    private IClass[] resolveClasses(short[] ifs) throws CompileException {
-        IClass[] result = new IClass[ifs.length];
-        for (int i = 0; i < result.length; ++i) {
-            try {
-                result[i] = this.resolveClass(ifs[i]);
-            } catch (ClassNotFoundException e) {
-                throw new CompileException(e.getMessage(), null);
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Turn a {@link ClassFile.MethodInfo} into an {@link IInvocable}. This includes the checking and the
-     * removal of the magic first parameter of an inner class constructor.
-     *
-     * @param methodInfo
-     * @throws ClassNotFoundException
-     */
-    private IInvocable resolveMethod(final ClassFile.MethodInfo methodInfo) throws ClassNotFoundException {
-        IInvocable result = (IInvocable) this.resolvedMethods.get(methodInfo);
-        if (result != null) return result;
-
-        // Determine method name.
-        final String name = this.classFile.getConstantUtf8(methodInfo.getNameIndex());
-
-        // Determine return type.
-        MethodDescriptor md = new MethodDescriptor(this.classFile.getConstantUtf8(methodInfo.getDescriptorIndex()));
-        final IClass returnType = this.resolveClass(md.returnFD);
-
-        // Determine parameter types.
-        final IClass[] parameterTypes = new IClass[md.parameterFDs.length];
-        for (int i = 0; i < parameterTypes.length; ++i) parameterTypes[i] = this.resolveClass(md.parameterFDs[i]);
-
-        // Determine thrown exceptions.
-        IClass tes[] = null;
-        ClassFile.AttributeInfo[] ais = methodInfo.getAttributes();
-        for (int i = 0; i < ais.length; ++i) {
-            ClassFile.AttributeInfo ai = ais[i];
-            if (ai instanceof ClassFile.ExceptionsAttribute) {
-                short[] teis = ((ClassFile.ExceptionsAttribute) ai).getExceptionIndexes();
-                tes = new IClass[teis.length];
-                for (int j = 0; j < teis.length; ++j) tes[j] = this.resolveClass(teis[j]);
-            }
-        }
-        final IClass thrownExceptions[] = tes == null ? new IClass[0] : tes;
-
-        // Determine access.
-        final Access access = ClassFileIClass.accessFlags2Access(methodInfo.getAccessFlags());
-
-        if (name.equals("<init>")) {
-            result = new IClass.IConstructor() {
-                public IClass[] getParameterTypes() throws CompileException {
-
-                    // Process magic first parameter of inner class constructor.
-                    IClass outerIClass = ClassFileIClass.this.getOuterIClass();
-                    if (outerIClass != null) {
-                        if (parameterTypes.length < 1) throw new RuntimeException("Inner class constructor lacks magic first parameter");
-                        if (parameterTypes[0] != outerIClass) throw new RuntimeException("Magic first parameter of inner class constructor has type \"" + parameterTypes[0].toString() + "\" instead of that of its enclosing instance (\"" + outerIClass.toString() + "\")");
-                        IClass[] tmp = new IClass[parameterTypes.length - 1];
-                        System.arraycopy(parameterTypes, 1, tmp, 0, tmp.length);
-                        return tmp;
-                    }
-
-                    return parameterTypes;
-                }
-                public IClass[] getThrownExceptions() throws CompileException { return thrownExceptions; }
-                public Access getAccess() { return access; }
-            };
-        } else {
-            result = new IClass.IMethod() {
-                public String getName() { return name; }
-                public IClass getReturnType() throws CompileException { return returnType; }
-                public boolean isStatic() { return (methodInfo.getAccessFlags() & Mod.STATIC) != 0; }
-                public boolean isAbstract() { return (methodInfo.getAccessFlags() & Mod.ABSTRACT) != 0; }
-                public IClass[] getParameterTypes() throws CompileException { return parameterTypes; }
-                public IClass[] getThrownExceptions() throws CompileException { return thrownExceptions; }
-                public Access getAccess() { return access; }
-            };
-        }
-        this.resolvedMethods.put(methodInfo, result);
-        return result;
-    }
-    private final Map resolvedMethods = new HashMap(); // MethodInfo => IInvocable
-
-    private IField resolveField(final ClassFile.FieldInfo fieldInfo) throws ClassNotFoundException {
-        IField result = (IField) this.resolvedFields.get(fieldInfo);
-        if (result != null) return result;
-
-        // Determine field name.
-        final String name = this.classFile.getConstantUtf8(fieldInfo.getNameIndex());
-
-        // Determine field type.
-        final String descriptor = this.classFile.getConstantUtf8(fieldInfo.getDescriptorIndex());
-        final IClass type = this.resolveClass(descriptor);
-
-        // Determine optional "constant value" of the field (JLS2 15.28, bullet
-        // 12). If a field has a "ConstantValue" attribute, we assume that it
-        // has a constant value. Notice that this assumption is not always
-        // correct, because typical Java<sup>TM</sup> compilers do not
-        // generate a "ConstantValue" attribute for fields like
-        // "int RED = 0", because "0" is the default value for an integer
-        // field.
-        ClassFile.ConstantValueAttribute cva = null;
-        ClassFile.AttributeInfo[] ais = fieldInfo.getAttributes();
-        for (int i = 0; i < ais.length; ++i) {
-            ClassFile.AttributeInfo ai = ais[i];
-            if (ai instanceof ClassFile.ConstantValueAttribute) {
-                cva = (ClassFile.ConstantValueAttribute) ai;
-                break;
-            }
-        }
-
-        Object ocv = null;
-        if (cva != null) {
-            ClassFile.ConstantPoolInfo cpi = this.classFile.getConstantPoolInfo(cva.getConstantValueIndex());
-            if (cpi instanceof ClassFile.ConstantValuePoolInfo) {
-                ocv = ((ClassFile.ConstantValuePoolInfo) cpi).getValue(this.classFile);
-            } else
-            {
-                throw new RuntimeException("Unexpected constant pool info type \"" + cpi.getClass().getName() + "\"");
-            }
-        }
-        final Object optionalConstantValue = ocv;
-
-        // Determine access.
-        final Access access = ClassFileIClass.accessFlags2Access(fieldInfo.getAccessFlags());
-
-        result = new IField() {
-            public Object  getConstantValue() throws CompileException { return optionalConstantValue; }
-            public String  getName()                                  { return name; }
-            public IClass  getType() throws CompileException          { return type; }
-            public boolean isStatic()                                 { return (fieldInfo.getAccessFlags() & Mod.STATIC) != 0; }
-            public Access  getAccess()                                { return access; }
-        };
-        this.resolvedFields.put(fieldInfo, result);
-        return result;
-    }
-
-    private static Access accessFlags2Access(short accessFlags) {
-        return (
-            (accessFlags & Mod.PUBLIC   ) != 0 ? Access.PUBLIC    :
-            (accessFlags & Mod.PROTECTED) != 0 ? Access.PROTECTED :
-            (accessFlags & Mod.PRIVATE  ) != 0 ? Access.PRIVATE   :
-            Access.DEFAULT
-        );
-    }
-}
diff --git a/src/org/codehaus/janino/ClassLoaderIClassLoader.java b/src/org/codehaus/janino/ClassLoaderIClassLoader.java
deleted file mode 100644
index a02bb07..0000000
--- a/src/org/codehaus/janino/ClassLoaderIClassLoader.java
+++ /dev/null
@@ -1,108 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-/**
- * An {@link IClassLoader} that loads {@link IClass}es through a reflection
- * {@link ClassLoader}.
- */
-public class ClassLoaderIClassLoader extends IClassLoader {
-    private static final boolean DEBUG = false;
-
-    /**
-     * @param classLoader The delegate that loads the classes.
-     */
-    public ClassLoaderIClassLoader(ClassLoader classLoader) {
-        super(
-            null   // optionalParentIClassLoader
-        );
-
-        if (classLoader == null) throw new NullPointerException();
-
-        this.classLoader = classLoader;
-        super.postConstruct();
-    }
-
-    /**
-     * Equivalent to
-     * <pre>
-     *   ClassLoaderIClassLoader(Thread.currentThread().getContextClassLoader())
-     * </pre>
-     */
-    public ClassLoaderIClassLoader() {
-        this(Thread.currentThread().getContextClassLoader());
-    }
-
-    public ClassLoader getClassLoader() {
-        return this.classLoader;
-    }
-
-    /**
-     * Find a new {@link IClass} by descriptor.
-     */
-    protected IClass findIClass(String descriptor) throws ClassNotFoundException {
-
-        //
-        // See also [ 931385 ] Janino 2.0 throwing exception on arrays of java.io.File:
-        //
-        // "ClassLoader.loadClass()" and "Class.forName()" should be identical,
-        // but "ClassLoader.loadClass("[Ljava.lang.Object;")" throws a
-        // ClassNotFoundException under JDK 1.5.0 beta.
-        // Unclear whether this a beta version bug and SUN will fix this in the final
-        // release, but "Class.forName()" seems to work fine in all cases, so we
-        // use that.
-        //
-
-        Class clazz;
-        try {
-//            clazz = this.classLoader.loadClass(className);
-            clazz = Class.forName(Descriptor.toClassName(descriptor), false, this.classLoader);
-        } catch (ClassNotFoundException e) {
-            if (e.getException() == null) {
-                return null;
-            } else
-            {
-                throw e;
-            }
-        }
-        if (ClassLoaderIClassLoader.DEBUG) System.out.println("clazz = " + clazz);
-
-        IClass result = new ReflectionIClass(clazz, this);
-        this.defineIClass(result);
-        return result;
-    }
-
-    private /*final*/ ClassLoader classLoader;
-}
diff --git a/src/org/codehaus/janino/CodeContext.java b/src/org/codehaus/janino/CodeContext.java
deleted file mode 100644
index aab646a..0000000
--- a/src/org/codehaus/janino/CodeContext.java
+++ /dev/null
@@ -1,1103 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import org.codehaus.janino.util.ClassFile;
-
-
-/**
- * The context of the compilation of a function (constructor or method). Manages generation of
- * byte code, the exception table, generation of line number tables, allocation of local variables,
- * determining of stack size and local variable table size and flow analysis.
- */
-public class CodeContext {
-    private static final boolean DEBUG = false;
-
-    private static final int INITIAL_SIZE = 128;
-
-    private /*final*/ ClassFile classFile;
-
-    private short           maxStack;
-    private short           maxLocals;
-    private byte[]          code;
-    private /*final*/ Offset    beginning;
-    private /*final*/ Inserter  end;
-    private Inserter        currentInserter;
-    private /*final*/ List      exceptionTableEntries; // ExceptionTableEntry
-
-    /**
-     * Create an empty "Code" attribute.
-     */
-    public CodeContext(ClassFile classFile) {
-        this.classFile             = classFile;
-
-        this.maxStack              = 0;
-        this.maxLocals             = 0;
-        this.code                  = new byte[CodeContext.INITIAL_SIZE];
-        this.beginning             = new Offset();
-        this.end                   = new Inserter();
-        this.currentInserter       = this.end;
-        this.exceptionTableEntries = new ArrayList();
-
-        this.beginning.offset = 0;
-        this.end.offset = 0;
-        this.beginning.next = this.end;
-        this.end.prev = this.beginning;
-    }
-
-    public ClassFile getClassFile() {
-        return this.classFile;
-    }
-
-    /**
-     * Allocate space for a local variable of the given size (1 or 2)
-     * on the local variable array.
-     *
-     * As a side effect, the "max_locals" field of the "Code" attribute
-     * is updated.
-     *
-     * The only way to deallocate local variables is to
-     * {@link #saveLocalVariables()} and later {@link
-     * #restoreLocalVariables()}.
-     */
-    public short allocateLocalVariable(
-        short size // 1 or 2
-    ) {
-        short res = this.localVariableArrayLength;
-        this.localVariableArrayLength += size;
-        if (this.localVariableArrayLength > this.maxLocals) {
-            this.maxLocals = this.localVariableArrayLength;
-        }
-
-        return res;
-    }
-
-    /**
-     * Remember the current size of the local variables array.
-     */
-    public void saveLocalVariables() {
-        this.savedLocalVariableArrayLengths.push(new Short(this.localVariableArrayLength));
-    }
-
-    /**
-     * Restore the previous size of the local variables array.
-     */
-    public void restoreLocalVariables() {
-        this.localVariableArrayLength = ((Short) this.savedLocalVariableArrayLengths.pop()).shortValue();
-    }
-
-    private static final byte UNEXAMINED = -1;
-    private static final byte INVALID_OFFSET = -2;
-
-    /**
-     * 
-     * @param dos
-     * @param lineNumberTableAttributeNameIndex 0 == don't generate a "LineNumberTable" attribute
-     * @throws IOException
-     */
-    protected void storeCodeAttributeBody(
-        DataOutputStream dos,
-        short            lineNumberTableAttributeNameIndex
-    ) throws IOException {
-        dos.writeShort(this.maxStack);                                // max_stack
-        dos.writeShort(this.maxLocals);                               // max_locals
-        dos.writeInt(this.end.offset);                                // code_length
-        dos.write(this.code, 0, this.end.offset);                     // code
-        dos.writeShort(this.exceptionTableEntries.size());            // exception_table_length
-        for (int i = 0; i < this.exceptionTableEntries.size(); ++i) { // exception_table
-            ExceptionTableEntry exceptionTableEntry = (ExceptionTableEntry) this.exceptionTableEntries.get(i);
-            dos.writeShort(exceptionTableEntry.startPC.offset);
-            dos.writeShort(exceptionTableEntry.endPC.offset);
-            dos.writeShort(exceptionTableEntry.handlerPC.offset);
-            dos.writeShort(exceptionTableEntry.catchType);
-        }
-
-        List attributes = new ArrayList(); // ClassFile.AttributeInfo
-
-        // Add "LineNumberTable" attribute.
-        if (lineNumberTableAttributeNameIndex != 0) {
-            List lnt = new ArrayList();
-            for (Offset o = this.beginning; o != null; o = o.next) {
-                if (o instanceof LineNumberOffset) {
-                    lnt.add(new ClassFile.LineNumberTableAttribute.Entry(o.offset, ((LineNumberOffset) o).lineNumber));
-                }
-            }
-            ClassFile.LineNumberTableAttribute.Entry[] lnte = (ClassFile.LineNumberTableAttribute.Entry[]) lnt.toArray(new ClassFile.LineNumberTableAttribute.Entry[lnt.size()]);
-            attributes.add(new ClassFile.LineNumberTableAttribute(
-                lineNumberTableAttributeNameIndex, // attributeNameIndex
-                lnte                               // lineNumberTableEntries
-            ));
-        }
-
-        dos.writeShort(attributes.size());                         // attributes_count
-        for (Iterator it = attributes.iterator(); it.hasNext();) { // attributes;
-            ClassFile.AttributeInfo attribute = (ClassFile.AttributeInfo) it.next();
-            attribute.store(dos);
-        }
-    }
-
-    /**
-     * Checks the code for consistency; updates the "maxStack" member.
-     *
-     * Notice: On inconsistencies, a "RuntimeException" is thrown (KLUDGE).
-     */
-    public void flowAnalysis(String functionName) {
-        if (CodeContext.DEBUG) { 
-            System.err.println("flowAnalysis(" + functionName + ")"); 
-        }
-        
-        byte[] stackSizes = new byte[this.end.offset];
-        Arrays.fill(stackSizes, CodeContext.UNEXAMINED);
-
-        // Analyze flow from offset zero.
-        this.flowAnalysis(
-            functionName,
-            this.code,       // code
-            this.end.offset, // codeSize
-            0,               // offset
-            0,               // stackSize
-            stackSizes       // stackSizes
-        );
-
-        // Analyze flow from exception handler entry points.
-        int analyzedExceptionHandlers = 0;
-        while (analyzedExceptionHandlers != this.exceptionTableEntries.size()) {
-            for (int i = 0; i < this.exceptionTableEntries.size(); ++i) {
-                ExceptionTableEntry exceptionTableEntry = (ExceptionTableEntry) this.exceptionTableEntries.get(i);
-                if (stackSizes[exceptionTableEntry.startPC.offset] != CodeContext.UNEXAMINED) {
-                    this.flowAnalysis(
-                        functionName,         
-                        this.code,                                          // code
-                        this.end.offset,                                    // codeSize
-                        exceptionTableEntry.handlerPC.offset,               // offset
-                        stackSizes[exceptionTableEntry.startPC.offset] + 1, // stackSize
-                        stackSizes                                          // stackSizes
-                    );
-                    ++analyzedExceptionHandlers;
-                }
-            }
-        }
-
-        // Check results and determine maximum stack size.
-        this.maxStack = 0;
-        for (int i = 0; i < stackSizes.length; ++i) {
-            byte ss = stackSizes[i];
-            if (ss == CodeContext.UNEXAMINED) {
-                if (CodeContext.DEBUG) {
-                    System.out.println(functionName + ": Unexamined code at offset " + i);
-                    return;
-                } else {
-                    throw new RuntimeException(functionName + ": Unexamined code at offset " + i);
-                }
-            }
-            if (ss > this.maxStack) this.maxStack = ss;
-        }
-    }
-
-    private void flowAnalysis(
-        String functionName,
-        byte[] code,      // Bytecode
-        int    codeSize,  // Size
-        int    offset,    // Current PC
-        int    stackSize, // Stack size on entry
-        byte[] stackSizes // Stack sizes in code
-    ) {
-        for (;;) {
-            if (CodeContext.DEBUG) System.out.println("Offset = " + offset + ", stack size = " + stackSize);
-
-            // Check current bytecode offset.
-            if (offset < 0 || offset >= codeSize) throw new RuntimeException(functionName + ": Offset out of range");
-
-            // Have we hit an area that has already been analyzed?
-            byte css = stackSizes[offset];
-            if (css == stackSize) return; // OK.
-            if (css == CodeContext.INVALID_OFFSET) throw new RuntimeException(functionName + ": Invalid offset");
-            if (css != CodeContext.UNEXAMINED) {
-                if (CodeContext.DEBUG) {
-                    System.err.println(functionName + ": Operand stack inconsistent at offset " + offset + ": Previous size " + css + ", now " + stackSize);
-                    return;
-                } else {
-                    throw new RuntimeException(functionName + ": Operand stack inconsistent at offset " + offset + ": Previous size " + css + ", now " + stackSize);
-                }
-            }
-            stackSizes[offset] = (byte) stackSize;
-
-            // Analyze current opcode.
-            byte opcode = code[offset];
-            int operandOffset = offset + 1;
-            short props;
-            if (opcode == Opcode.WIDE) {
-                opcode = code[operandOffset++];
-                props = Opcode.WIDE_OPCODE_PROPERTIES[0xff & opcode];
-            } else {
-                props = Opcode.OPCODE_PROPERTIES[0xff & opcode];
-            }
-            if (props == Opcode.INVALID_OPCODE) throw new RuntimeException(functionName + ": Invalid opcode " + (0xff & opcode) + " at offset " + offset);
-
-            switch (props & Opcode.SD_MASK) {
-
-            case Opcode.SD_M4:
-            case Opcode.SD_M3:
-            case Opcode.SD_M2:
-            case Opcode.SD_M1:
-            case Opcode.SD_P0:
-            case Opcode.SD_P1:
-            case Opcode.SD_P2:
-                stackSize += (props & Opcode.SD_MASK) - Opcode.SD_P0;
-                break;
-
-            case Opcode.SD_0:
-                stackSize = 0;
-                break;
-
-            case Opcode.SD_GETFIELD:
-                --stackSize;
-                /* FALL THROUGH */
-            case Opcode.SD_GETSTATIC:
-                stackSize += this.determineFieldSize((short) (
-                    extract16BitValue(0, operandOffset, code)
-                ));
-                break;
-
-            case Opcode.SD_PUTFIELD:
-                --stackSize;
-                /* FALL THROUGH */
-            case Opcode.SD_PUTSTATIC:
-                stackSize -= this.determineFieldSize((short) (
-                    extract16BitValue(0, operandOffset, code)
-                ));
-                break;
-
-            case Opcode.SD_INVOKEVIRTUAL:
-            case Opcode.SD_INVOKESPECIAL:
-            case Opcode.SD_INVOKEINTERFACE:
-                --stackSize;
-                /* FALL THROUGH */
-            case Opcode.SD_INVOKESTATIC:
-                stackSize -= this.determineArgumentsSize((short) (
-                    extract16BitValue(0, operandOffset, code)
-                ));
-                break;
-
-            case Opcode.SD_MULTIANEWARRAY:
-                stackSize -= code[operandOffset + 2] - 1;
-                break;
-
-            default:
-                throw new RuntimeException(functionName + ": Invalid stack delta");
-            }
-
-            if (stackSize < 0) {
-                String msg = this.classFile.getThisClassName() + '.' + functionName + ": Operand stack underrun at offset " + offset;
-                if (CodeContext.DEBUG) {
-                    System.err.println(msg); 
-                    return;
-                } else {
-                    throw new RuntimeException(msg); 
-                }
-            } 
-
-            if (stackSize > Byte.MAX_VALUE) {
-                String msg = this.classFile.getThisClassName() + '.' + functionName + ": Operand stack overflow at offset " + offset;
-                if (CodeContext.DEBUG) {
-                    System.err.println(msg); 
-                    return;
-                } else {
-                    throw new RuntimeException(msg); 
-                }
-            }
-
-            switch (props & Opcode.OP1_MASK) {
-
-            case 0:
-                ;
-                break;
-
-            case Opcode.OP1_SB:
-            case Opcode.OP1_UB:
-            case Opcode.OP1_CP1:
-            case Opcode.OP1_LV1:
-                ++operandOffset;
-                break;
-
-            case Opcode.OP1_SS:
-            case Opcode.OP1_CP2:
-            case Opcode.OP1_LV2:
-                operandOffset += 2;
-                break;
-
-            case Opcode.OP1_BO2:
-                if (CodeContext.DEBUG) {
-                    System.out.println("Offset = " + offset);
-                    System.out.println("Operand offset = " + operandOffset);
-                    System.out.println(code[operandOffset]);
-                    System.out.println(code[operandOffset + 1]);
-                }
-                this.flowAnalysis(
-                    functionName,
-                    code, codeSize,
-                    extract16BitValue(offset, operandOffset, code),
-                    stackSize,
-                    stackSizes
-                );
-                operandOffset += 2;
-                break;
-
-            case Opcode.OP1_JSR:
-                if (CodeContext.DEBUG) {
-                    System.out.println("Offset = " + offset);
-                    System.out.println("Operand offset = " + operandOffset);
-                    System.out.println(code[operandOffset]);
-                    System.out.println(code[operandOffset + 1]);
-                }
-                int targetOffset = extract16BitValue(offset, operandOffset, code);
-                operandOffset += 2;
-                if (stackSizes[targetOffset] == CodeContext.UNEXAMINED) {
-                    this.flowAnalysis(
-                        functionName,
-                        code, codeSize,
-                        targetOffset,
-                        stackSize + 1,
-                        stackSizes
-                    );
-                }
-                break;
-
-            case Opcode.OP1_BO4:
-                this.flowAnalysis(
-                    functionName,
-                    code, codeSize,
-                    extract32BitValue(offset, operandOffset, code),
-                    stackSize, stackSizes
-                );
-                operandOffset += 4;
-                break;
-
-            case Opcode.OP1_LOOKUPSWITCH:
-                while ((operandOffset & 3) != 0) ++operandOffset;
-                this.flowAnalysis(
-                    functionName,
-                    code, codeSize,
-                    extract32BitValue(offset, operandOffset, code),
-                    stackSize, stackSizes
-                );
-                operandOffset += 4;
-                
-                int npairs = extract32BitValue(0, operandOffset, code);
-                operandOffset += 4;
-                
-                for (int i = 0; i < npairs; ++i) {
-                    operandOffset += 4; //skip match value
-                    this.flowAnalysis(
-                        functionName,
-                        code, codeSize,
-                        extract32BitValue(offset, operandOffset, code),
-                        stackSize, stackSizes
-                    );
-                    operandOffset += 4; //advance over offset
-                }
-                break;
-
-            case Opcode.OP1_TABLESWITCH:
-                while ((operandOffset & 3) != 0) ++operandOffset;
-                this.flowAnalysis(
-                    functionName,
-                    code, codeSize,
-                    extract32BitValue(offset, operandOffset, code),
-                    stackSize, stackSizes
-                );
-                operandOffset += 4;
-                int low = extract32BitValue(offset, operandOffset, code);
-                operandOffset += 4;
-                int hi = extract32BitValue(offset, operandOffset, code);
-                operandOffset += 4;
-                for (int i = low; i <= hi; ++i) {
-                    this.flowAnalysis(
-                        functionName,
-                        code, codeSize,
-                        extract32BitValue(offset, operandOffset, code),
-                        stackSize, stackSizes
-                    );
-                    operandOffset += 4;
-                }
-                break;
-
-            default:
-                throw new RuntimeException(functionName + ": Invalid OP1");
-            }
-
-            switch (props & Opcode.OP2_MASK) {
-
-            case 0:
-                ;
-                break;
-
-            case Opcode.OP2_SB:
-                ++operandOffset;
-                break;
-
-            case Opcode.OP2_SS:
-                operandOffset += 2;
-                break;
-
-            default:
-                throw new RuntimeException(functionName + ": Invalid OP2");
-            }
-
-            switch (props & Opcode.OP3_MASK) {
-
-            case 0:
-                ;
-                break;
-
-            case Opcode.OP3_SB:
-                ++operandOffset;
-                break;
-
-            default:
-                throw new RuntimeException(functionName + ": Invalid OP3");
-            }
-
-            Arrays.fill(stackSizes, offset + 1, operandOffset, CodeContext.INVALID_OFFSET);
-
-            if ((props & Opcode.NO_FALLTHROUGH) != 0) return;
-            offset = operandOffset;
-        }
-    }
-    
-    /**
-     * Extract a 16 bit value at offset in code and add bias to it
-     * @param bias    an int to skew the final result by (useful for calculating relative offsets)
-     * @param offset  the position in the code array to extract the bytes from
-     * @param code    the array of bytes
-     * @return an integer that treats the two bytes at position offset as an UNSIGNED SHORT
-     */
-    private int extract16BitValue(int bias, int offset, byte[] code) {
-        int res = bias + (
-                ((       code[offset  ]) << 8) +
-                ((0xff & code[offset+1])     )
-        );
-        if (CodeContext.DEBUG) {
-            System.out.println("extract16BitValue(bias, offset) = (" + bias +", " + offset + ")");
-            System.out.println("bytes = {" + code[offset] + ", " + code[offset+1] + "}");
-            System.out.println("result = " + res);
-        }
-        return res;
-    }
-    
-    /**
-     * Extract a 32 bit value at offset in code and add bias to it
-     * @param bias    an int to skew the final result by (useful for calculating relative offsets)
-     * @param offset  the position in the code array to extract the bytes from
-     * @param code    the array of bytes
-     * @return the 4 bytes at position offset + bias
-     */
-    private int extract32BitValue(int bias, int offset, byte[] code) {
-        int res = bias + (
-                ((       code[offset  ]) << 24) +
-                ((0xff & code[offset+1]) << 16) +
-                ((0xff & code[offset+2]) <<  8) +
-                ((0xff & code[offset+3])      )
-        );
-        if (CodeContext.DEBUG) {
-            System.out.println("extract32BitValue(bias, offset) = (" + bias +", " + offset + ")");
-            System.out.println(
-                    "bytes = {" + 
-                    code[offset  ] + ", " + 
-                    code[offset+1] + ", " + 
-                    code[offset+2] + ", " + 
-                    code[offset+3] + "}"
-            );
-            System.out.println("result = " + res);
-        }
-        return res;
-    }
-    
-    /**
-     * fixUp() all of the offsets and relocate() all relocatables
-     */
-    public void fixUpAndRelocate() {
-
-        // We do this in a loop to allow relocatables to adjust the size
-        // of things in the byte stream.  It is extremely unlikely, but possible
-        // that a late relocatable will grow the size of the bytecode, and require
-        // an earlier relocatable to switch from 32K mode to 64K mode branching
-        do {
-            fixUp();
-        } while (!relocate());
-    }
-
-    /**
-     * Fix up all offsets.
-     */
-    private void fixUp() {
-        for (Offset o = this.beginning; o != this.end; o = o.next) {
-            if (o instanceof FixUp) ((FixUp) o).fixUp();
-        }
-    }
-
-    /**
-     * Relocate all relocatables and aggregate their response into a single one
-     * @return true if all of them relocated successfully
-     *         false if any of them needed to change size
-     */
-    private boolean relocate() {
-        boolean finished = true;
-        for (int i = 0; i < this.relocatables.size(); ++i) {
-            //do not terminate earlier so that everything gets a chance to grow in the first pass
-            //changes the common case for this to be O(n) instead of O(n**2)
-            boolean part =  ((Relocatable) this.relocatables.get(i)).relocate();
-            finished = finished && part;
-        }
-        return finished;
-    }
-
-    /**
-     * Analyse the descriptor of the Fieldref and return its size.
-     */
-    private int determineFieldSize(short idx) {
-        ClassFile.ConstantFieldrefInfo    cfi   = (ClassFile.ConstantFieldrefInfo)    this.classFile.getConstantPoolInfo(idx);
-        ClassFile.ConstantNameAndTypeInfo cnati = (ClassFile.ConstantNameAndTypeInfo) this.classFile.getConstantPoolInfo(cfi.getNameAndTypeIndex());
-        ClassFile.ConstantUtf8Info        cui   = (ClassFile.ConstantUtf8Info)        this.classFile.getConstantPoolInfo(cnati.getDescriptorIndex());
-        return Descriptor.size(cui.getString());
-    }
-
-    /**
-     * Analyse the descriptor of the Methodref and return the sum of the
-     * arguments' sizes minus the return value's size.
-     */
-    private int determineArgumentsSize(short idx) {
-        ClassFile.ConstantPoolInfo cpi = this.classFile.getConstantPoolInfo(idx);
-        ClassFile.ConstantNameAndTypeInfo nat = (ClassFile.ConstantNameAndTypeInfo) this.classFile.getConstantPoolInfo(
-            cpi instanceof ClassFile.ConstantInterfaceMethodrefInfo ?
-            ((ClassFile.ConstantInterfaceMethodrefInfo) cpi).getNameAndTypeIndex() :
-            ((ClassFile.ConstantMethodrefInfo) cpi).getNameAndTypeIndex()
-        );
-        ClassFile.ConstantUtf8Info cui = (ClassFile.ConstantUtf8Info) this.classFile.getConstantPoolInfo(nat.getDescriptorIndex());
-        String desc = cui.getString();
-
-        if (desc.charAt(0) != '(') throw new RuntimeException("Method descriptor does not start with \"(\"");
-        int i = 1;
-        int res = 0;
-        for (;;) {
-            switch (desc.charAt(i++)) {
-            case ')':
-                return res - Descriptor.size(desc.substring(i));
-            case 'B': case 'C': case 'F': case 'I': case 'S': case 'Z':
-                res += 1;
-                break;
-            case 'D': case 'J':
-                res += 2;
-                break;
-            case '[':
-                res += 1;
-                while (desc.charAt(i) == '[') ++i;
-                if ("BCFISZDJ".indexOf(desc.charAt(i)) != -1) { ++i; break; }
-                if (desc.charAt(i) != 'L') throw new RuntimeException("Invalid char after \"[\"");
-                ++i;
-                while (desc.charAt(i++) != ';');
-                break;
-            case 'L':
-                res += 1;
-                while (desc.charAt(i++) != ';');
-                break;
-            default:
-                throw new RuntimeException("Invalid method descriptor");
-            }
-        }
-    }
-
-    /**
-     * Inserts a sequence of bytes at the current insertion position. Creates
-     * {@link LineNumberOffset}s as necessary.
-     * 
-     * @param lineNumber The line number that corresponds to the byte code, or -1
-     * @param b
-     */
-    public void write(short lineNumber, byte[] b) {
-        if (b.length == 0) return;
-        
-        int ico = this.currentInserter.offset;
-        this.makeSpace(lineNumber, b.length);
-        System.arraycopy(b, 0, this.code, ico, b.length);
-    }
-
-    /**
-     * Inserts a byte at the current insertion position. Creates
-     * {@link LineNumberOffset}s as necessary.
-     * <p>
-     * This method is an optimization to avoid allocating small byte[] and ease
-     * GC load.
-     * 
-     * @param lineNumber The line number that corresponds to the byte code, or -1
-     * @param b1
-     */
-    public void write(short lineNumber, byte b1) {
-        int ico = this.currentInserter.offset;
-        this.makeSpace(lineNumber, 1);
-        this.code[ico] = b1;
-    }
-    
-    /**
-     * Inserts bytes at the current insertion position. Creates
-     * {@link LineNumberOffset}s as necessary.
-     * <p>
-     * This method is an optimization to avoid allocating small byte[] and ease
-     * GC load.
-     * 
-     * @param lineNumber The line number that corresponds to the byte code, or -1
-     * @param b1
-     * @param b2
-     */
-    public void write(short lineNumber, byte b1, byte b2) {
-        int ico = this.currentInserter.offset;
-        this.makeSpace(lineNumber, 2);
-        this.code[ico++] = b1;
-        this.code[ico  ] = b2;
-    }
-    
-    /**
-     * Inserts bytes at the current insertion position. Creates
-     * {@link LineNumberOffset}s as necessary.
-     * <p>
-     * This method is an optimization to avoid allocating small byte[] and ease
-     * GC load.
-     * 
-     * @param lineNumber The line number that corresponds to the byte code, or -1
-     * @param b1
-     * @param b2
-     * @param b3
-     */
-    public void write(short lineNumber, byte b1, byte b2, byte b3) {
-        int ico = this.currentInserter.offset;
-        this.makeSpace(lineNumber, 3);
-        this.code[ico++] = b1;
-        this.code[ico++] = b2;
-        this.code[ico  ] = b3;
-    }
-    
-    /**
-     * Inserts bytes at the current insertion position. Creates
-     * {@link LineNumberOffset}s as necessary.
-     * <p>
-     * This method is an optimization to avoid allocating small byte[] and ease
-     * GC load.
-     * 
-     * @param lineNumber The line number that corresponds to the byte code, or -1
-     * @param b1
-     * @param b2
-     * @param b3
-     * @param b4
-     */
-    public void write(short lineNumber, byte b1, byte b2, byte b3, byte b4) {
-        int ico = this.currentInserter.offset;
-        this.makeSpace(lineNumber, 4);
-        this.code[ico++] = b1;
-        this.code[ico++] = b2;
-        this.code[ico++] = b3;
-        this.code[ico  ] = b4;
-    }
-    
-    /**
-     * Add space for size bytes at current offset. Creates
-     * {@link LineNumberOffset}s as necessary.
-     *  
-     * @param lineNumber The line number that corresponds to the byte code, or -1
-     * @param size       The size in bytes to inject
-     */
-    public void makeSpace(short lineNumber, int size) {
-        if (size == 0) return;
-
-        INSERT_LINE_NUMBER_OFFSET:
-        if (lineNumber != -1) {
-            Offset o;
-            for (o = this.currentInserter.prev; o != this.beginning; o = o.prev) {
-                if (o instanceof LineNumberOffset) {
-                    if (((LineNumberOffset) o).lineNumber == lineNumber) break INSERT_LINE_NUMBER_OFFSET;
-                    break;
-                }
-            }
-            LineNumberOffset lno = new LineNumberOffset(this.currentInserter.offset, lineNumber);
-            lno.prev = this.currentInserter.prev;
-            lno.next = this.currentInserter;
-            this.currentInserter.prev.next = lno;
-            this.currentInserter.prev = lno;
-        }
-
-        int ico = this.currentInserter.offset;
-        if (this.end.offset + size <= this.code.length) {
-            // Optimization to avoid a trivial method call in the common case
-            if(ico != this.end.offset) {
-                System.arraycopy(this.code, ico, this.code, ico + size, this.end.offset - ico);
-            }
-        } else {
-            byte[] oldCode = this.code;
-            //double size to avoid horrible performance, but don't grow over our limit
-            int newSize = Math.max(Math.min(oldCode.length * 2, 0xffff), oldCode.length + size);
-            if (newSize > 0xffff) throw new RuntimeException("Code attribute in class \"" + this.classFile.getThisClassName() + "\" grows beyond 64 KB");
-            this.code = new byte[newSize];
-            System.arraycopy(oldCode, 0, this.code, 0, ico);
-            System.arraycopy(oldCode, ico, this.code, ico + size, this.end.offset - ico);
-        }  
-        Arrays.fill(this.code, ico, ico + size, (byte)0);
-        for (Offset o = this.currentInserter; o != null; o = o.next) o.offset += size;
-    }
-
-    /**
-     * @param lineNumber The line number that corresponds to the byte code, or -1
-     */
-    public void writeShort(short lineNumber, int v) {
-        this.write(lineNumber, (byte) (v >> 8), (byte) v);
-    }
-
-    /**
-     * @param lineNumber The line number that corresponds to the byte code, or -1
-     */
-    public void writeBranch(short lineNumber, int opcode, final Offset dst) {
-        this.relocatables.add(new Branch(opcode, dst));
-        this.write(lineNumber, (byte) opcode, (byte) -1, (byte) -1);
-    }
-
-    private class Branch extends Relocatable {
-        public Branch(int opcode, Offset destination) {
-            this.opcode = opcode;
-            this.source = CodeContext.this.newInserter();
-            this.destination = destination;
-            if (opcode == Opcode.JSR_W || opcode == Opcode.GOTO_W) {
-                //no need to expand wide opcodes
-                this.expanded = true;
-            } else { 
-                this.expanded = false;
-            }
-        }
-        
-        public boolean relocate() {
-            if (this.destination.offset == Offset.UNSET) throw new RuntimeException("Cannot relocate branch to unset destination offset");
-            int offset = this.destination.offset - this.source.offset;
-            
-            if (!this.expanded && (offset > Short.MAX_VALUE || offset < Short.MIN_VALUE)) {
-                //we want to insert the data without skewing our source position,
-                //so we will cache it and then restore it later.
-                int pos = this.source.offset; 
-                CodeContext.this.pushInserter(this.source); {
-                    // promotion to a wide instruction only requires 2 extra bytes 
-                    // everything else requires a new GOTO_W instruction after a negated if
-                    CodeContext.this.makeSpace(
-                        (short) -1, 
-                        this.opcode == Opcode.GOTO ? 2 : this.opcode == Opcode.JSR ? 2 : 5
-                    );
-                } CodeContext.this.popInserter();
-                this.source.offset = pos;
-                this.expanded = true;
-                return false;
-            }
-            
-            final byte[] ba;
-            if (!this.expanded) {
-                //we fit in a 16-bit jump
-                ba = new byte[] { (byte) this.opcode, (byte) (offset >> 8), (byte) offset };
-            } else {
-                if (this.opcode == Opcode.GOTO || this.opcode == Opcode.JSR) {
-                    ba = new byte[] { 
-                        (byte) (this.opcode + 33), // GOTO => GOTO_W; JSR => JSR_W
-                        (byte) (offset >> 24), 
-                        (byte) (offset >> 16), 
-                        (byte) (offset >> 8), 
-                        (byte) offset 
-                    };
-                } else
-                {
-                    //exclude the if-statement from jump target
-                    //if jumping backwards this will increase the jump to go over it
-                    //if jumping forwards this will decrease the jump by it
-                    offset -= 3;
-                            
-                    //  [if cond offset]
-                    //expands to 
-                    //  [if !cond skip_goto]
-                    //  [GOTO_W offset]
-                    ba = new byte[] { 
-                        CodeContext.invertBranchOpcode((byte) this.opcode),
-                        (byte) 0,
-                        (byte) 8, //jump from this instruction past the GOTO_W
-                        (byte) Opcode.GOTO_W, 
-                        (byte) (offset >> 24), 
-                        (byte) (offset >> 16), 
-                        (byte) (offset >> 8), 
-                        (byte) offset 
-                    };
-                }
-            }
-            System.arraycopy(ba, 0, CodeContext.this.code, this.source.offset, ba.length);
-            return true;
-        }
-        
-        private boolean expanded; //marks whether this has been expanded to account for a wide branch
-        private final int opcode;
-        private final Inserter source;
-        private final Offset destination;
-    }
-
-    /**
-     * E.g. {@link Opcode#IFLT} ("less than") inverts to {@link Opcode#IFGE} ("greater than or equal to").
-     */
-    private static byte invertBranchOpcode(byte branchOpcode) {
-        return ((Byte) CodeContext.BRANCH_OPCODE_INVERSION.get(new Byte(branchOpcode))).byteValue();
-    }
-    private static final Map BRANCH_OPCODE_INVERSION = CodeContext.createBranchOpcodeInversion(); // Map<Byte branch-opcode, Byte inverted-branch-opcode>
-    private static Map createBranchOpcodeInversion() {
-        Map m = new HashMap();
-        m.put(new Byte(Opcode.IF_ACMPEQ), new Byte(Opcode.IF_ACMPNE)); 
-        m.put(new Byte(Opcode.IF_ACMPNE), new Byte(Opcode.IF_ACMPEQ)); 
-        m.put(new Byte(Opcode.IF_ICMPEQ), new Byte(Opcode.IF_ICMPNE)); 
-        m.put(new Byte(Opcode.IF_ICMPNE), new Byte(Opcode.IF_ICMPEQ)); 
-        m.put(new Byte(Opcode.IF_ICMPGE), new Byte(Opcode.IF_ICMPLT)); 
-        m.put(new Byte(Opcode.IF_ICMPLT), new Byte(Opcode.IF_ICMPGE)); 
-        m.put(new Byte(Opcode.IF_ICMPGT), new Byte(Opcode.IF_ICMPLE)); 
-        m.put(new Byte(Opcode.IF_ICMPLE), new Byte(Opcode.IF_ICMPGT)); 
-        m.put(new Byte(Opcode.IFEQ),      new Byte(Opcode.IFNE)); 
-        m.put(new Byte(Opcode.IFNE),      new Byte(Opcode.IFEQ)); 
-        m.put(new Byte(Opcode.IFGE),      new Byte(Opcode.IFLT)); 
-        m.put(new Byte(Opcode.IFLT),      new Byte(Opcode.IFGE)); 
-        m.put(new Byte(Opcode.IFGT),      new Byte(Opcode.IFLE)); 
-        m.put(new Byte(Opcode.IFLE),      new Byte(Opcode.IFGT)); 
-        m.put(new Byte(Opcode.IFNULL),    new Byte(Opcode.IFNONNULL)); 
-        m.put(new Byte(Opcode.IFNONNULL), new Byte(Opcode.IFNULL));
-        return Collections.unmodifiableMap(m);
-    }
-
-    public void writeOffset(short lineNumber, Offset src, final Offset dst) {
-        this.relocatables.add(new OffsetBranch(this.newOffset(), src, dst));
-        this.write(lineNumber, (byte) -1, (byte) -1, (byte) -1, (byte) -1);
-    }
-
-    private class OffsetBranch extends Relocatable {
-        public OffsetBranch(Offset where, Offset source, Offset destination) {
-            this.where       = where;
-            this.source      = source;
-            this.destination = destination;
-        }
-        public boolean relocate() {
-            if (
-                this.source.offset == Offset.UNSET ||
-                this.destination.offset == Offset.UNSET
-            ) throw new RuntimeException("Cannot relocate offset branch to unset destination offset");
-            int offset = this.destination.offset - this.source.offset;
-            byte[] ba = new byte[] {
-                (byte) (offset >> 24),
-                (byte) (offset >> 16),
-                (byte) (offset >> 8),
-                (byte) offset
-            };
-            System.arraycopy(ba, 0, CodeContext.this.code, this.where.offset, 4);
-            return true;
-        }
-        private final Offset where, source, destination;
-    }
-
-    public Offset newOffset() {
-        Offset o = new Offset();
-        o.set();
-        return o;
-    }
-
-    /**
-     * Allocate an {@link Inserter}, set it to the current offset, and
-     * insert it before the current offset.
-     *
-     * In clear text, this means that you can continue writing to the
-     * "Code" attribute, then {@link #pushInserter(CodeContext.Inserter)} the
-     * {@link Inserter}, then write again (which inserts bytes into the
-     * "Code" attribute at the previously remembered position), and then
-     * {@link #popInserter()}.
-     */
-    public Inserter newInserter() {
-        Inserter i = new Inserter();
-        i.set();
-        return i;
-    }
-
-    public Inserter currentInserter() {
-        return this.currentInserter;
-    }
-
-    /**
-     * Remember the current {@link Inserter}, then replace it with the
-     * new one.
-     */
-    public void pushInserter(Inserter ins) {
-        if (ins.nextInserter != null) throw new RuntimeException("An Inserter can only be pushed once at a time");
-        ins.nextInserter = this.currentInserter;
-        this.currentInserter = ins;
-    }
-
-    /**
-     * Replace the current {@link Inserter} with the remembered one (see
-     * {@link #pushInserter(CodeContext.Inserter)}).
-     */
-    public void popInserter() {
-        Inserter ni = this.currentInserter.nextInserter;
-        if (ni == null) throw new RuntimeException("Code inserter stack underflow");
-        this.currentInserter.nextInserter = null; // Mark it as "unpushed".
-        this.currentInserter = ni;
-    }
-
-    /**
-     * A class that represents an offset within a "Code" attribute.
-     *
-     * The concept of an "offset" is that if one writes into the middle of
-     * a "Code" attribute, all offsets behind the insertion point are
-     * automatically shifted.
-     */
-    public class Offset {
-        int              offset = Offset.UNSET;
-        Offset             prev = null, next = null;
-        final static int UNSET = -1;
-
-        /**
-         * Set this "Offset" to the offset of the current inserter; insert
-         * this "Offset" before the current inserter.
-         */
-        public void set() {
-            if (this.offset != Offset.UNSET) throw new RuntimeException("Cannot \"set()\" Offset more than once");
-
-            this.offset = CodeContext.this.currentInserter.offset;
-            this.prev = CodeContext.this.currentInserter.prev;
-            this.next = CodeContext.this.currentInserter;
-
-            this.prev.next = this;
-            this.next.prev = this;
-        }
-        public final CodeContext getCodeContext() { return CodeContext.this; }
-
-        public String toString() {
-            return CodeContext.this.classFile.getThisClassName() + ": " + this.offset;
-        }
-    }
-
-    /**
-     * Add another entry to the "exception_table" of this code attribute (see JVMS 4.7.3).
-     * @param startPC
-     * @param endPC
-     * @param handlerPC
-     * @param catchTypeFD
-     */
-    public void addExceptionTableEntry(
-        Offset startPC,
-        Offset endPC,
-        Offset handlerPC,
-        String catchTypeFD // null == "finally" clause
-    ) {
-        this.exceptionTableEntries.add(new ExceptionTableEntry(
-            startPC,
-            endPC,
-            handlerPC,
-            catchTypeFD == null ? (short) 0 : this.classFile.addConstantClassInfo(catchTypeFD)
-        ));
-    }
-
-    /**
-     * Representation of an entry in the "exception_table" of a "Code" attribute (see JVMS
-     * 4.7.3).
-     */
-    private static class ExceptionTableEntry {
-        public ExceptionTableEntry(
-            Offset startPC,
-            Offset endPC,
-            Offset handlerPC,
-            short  catchType
-        ) {
-            this.startPC   = startPC;
-            this.endPC     = endPC;
-            this.handlerPC = handlerPC;
-            this.catchType = catchType;
-        }
-        private final Offset startPC, endPC, handlerPC;
-        private final short  catchType; // 0 == "finally" clause
-    }
-
-    /**
-     * A class that implements an insertion point into a "Code"
-     * attribute.
-     */
-    public class Inserter extends Offset {
-        private Inserter nextInserter = null; // null == not in "currentInserter" stack
-    }
-
-    public class LineNumberOffset extends Offset {
-        private final int lineNumber;
-        public LineNumberOffset(int offset, int lineNumber) {
-            this.lineNumber = lineNumber;
-            this.offset = offset;
-        }
-    }
-
-    private abstract class Relocatable {
-        /**
-         * Relocate this object.
-         * @return true if the relocation succeeded in place
-         *         false if the relocation grew the number of bytes required
-         */
-        public abstract boolean relocate();
-    }
-
-    private short       localVariableArrayLength = 0;
-    private final Stack savedLocalVariableArrayLengths = new Stack();
-    private final List  relocatables = new ArrayList();
-
-    /**
-     * A throw-in interface that marks {@link CodeContext.Offset}s
-     * as "fix-ups": During the execution of
-     * {@link CodeContext#fixUp}, all "fix-ups" are invoked and
-     * can do last touches to the code attribute.
-     * <p>
-     * This is currently used for inserting the "padding bytes" into the
-     * TABLESWITCH and LOOKUPSWITCH instructions.
-     */
-    public interface FixUp {
-        void fixUp();
-    }
-}
diff --git a/src/org/codehaus/janino/CompileException.java b/src/org/codehaus/janino/CompileException.java
deleted file mode 100644
index 8306520..0000000
--- a/src/org/codehaus/janino/CompileException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import org.codehaus.janino.util.*;
-
-/**
- * An exception that reflects an error during compilation.
- */
-public class CompileException extends LocatedException {
-
-    public CompileException(String message, Location optionalLocation) {
-        super(message, optionalLocation);
-    }
-    public CompileException(String message, Location optionalLocation, Throwable cause) {
-        super(message, optionalLocation, cause);
-    }
-}
diff --git a/src/org/codehaus/janino/Compiler.java b/src/org/codehaus/janino/Compiler.java
deleted file mode 100644
index 38104f5..0000000
--- a/src/org/codehaus/janino/Compiler.java
+++ /dev/null
@@ -1,846 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.util.*;
-import java.io.*;
-
-import org.codehaus.janino.Parser.ParseException;
-import org.codehaus.janino.Scanner.ScanException;
-import org.codehaus.janino.UnitCompiler.ErrorHandler;
-import org.codehaus.janino.tools.Disassembler;
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * A simplified substitute for the <tt>javac</tt> tool.
- *
- * Usage:
- * <pre>
- * java org.codehaus.janino.Compiler \
- *           [ -d <i>destination-dir</i> ] \
- *           [ -sourcepath <i>dirlist</i> ] \
- *           [ -classpath <i>dirlist</i> ] \
- *           [ -extdirs <i>dirlist</i> ] \
- *           [ -bootclasspath <i>dirlist</i> ] \
- *           [ -encoding <i>encoding</i> ] \
- *           [ -verbose ] \
- *           [ -g:none ] \
- *           [ -g:{lines,vars,source} ] \
- *           [ -warn:<i>pattern-list</i> ] \
- *           <i>source-file</i> ...
- * java org.codehaus.janino.Compiler -help
- * </pre>
- */
-public class Compiler {
-    private static final boolean DEBUG = false;
-
-    /**
-     * Command line interface.
-     */
-    public static void main(String[] args) {
-        File            destinationDirectory      = Compiler.NO_DESTINATION_DIRECTORY;
-        File[]          optionalSourcePath        = null;
-        File[]          classPath                 = { new File(".") };
-        File[]          optionalExtDirs           = null;
-        File[]          optionalBootClassPath     = null;
-        String          optionalCharacterEncoding = null;
-        boolean         verbose                   = false;
-        EnumeratorSet   debuggingInformation      = DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION;
-        StringPattern[] warningHandlePatterns     = Compiler.DEFAULT_WARNING_HANDLE_PATTERNS;
-        boolean         rebuild                   = false;
-
-        // Process command line options.
-        int i;
-        for (i = 0; i < args.length; ++i) {
-            String arg = args[i];
-            if (arg.charAt(0) != '-') break;
-            if (arg.equals("-d")) {
-                destinationDirectory = new File(args[++i]);
-            } else
-            if (arg.equals("-sourcepath")) {
-                optionalSourcePath = PathResourceFinder.parsePath(args[++i]);
-            } else
-            if (arg.equals("-classpath")) {
-                classPath = PathResourceFinder.parsePath(args[++i]);
-            } else
-            if (arg.equals("-extdirs")) {
-                optionalExtDirs = PathResourceFinder.parsePath(args[++i]);
-            } else
-            if (arg.equals("-bootclasspath")) {
-                optionalBootClassPath = PathResourceFinder.parsePath(args[++i]);
-            } else
-            if (arg.equals("-encoding")) {
-                optionalCharacterEncoding = args[++i];
-            } else
-            if (arg.equals("-verbose")) {
-                verbose = true;
-            } else
-            if (arg.equals("-g")) {
-                debuggingInformation = DebuggingInformation.ALL;
-            } else
-            if (arg.startsWith("-g:")) {
-                try {
-                    debuggingInformation = new EnumeratorSet(DebuggingInformation.class, arg.substring(3));
-                } catch (EnumeratorFormatException ex) {
-                    System.err.println("Invalid debugging option \"" + arg + "\", only \"" + DebuggingInformation.ALL + "\" allowed");
-                    System.exit(1);
-                }
-            } else
-            if (arg.startsWith("-warn:")) {
-                warningHandlePatterns = StringPattern.parseCombinedPattern(arg.substring(6));
-            } else
-            if (arg.equals("-rebuild")) {
-                rebuild = true;
-            } else
-            if (arg.equals("-help")) {
-                for (int j = 0; j < Compiler.USAGE.length; ++j) System.out.println(Compiler.USAGE[j]);
-                System.exit(1);
-            } else {
-                System.err.println("Unrecognized command line option \"" + arg + "\"; try \"-help\".");
-                System.exit(1);
-            }
-        }
-
-        // Get source file names.
-        if (i == args.length) {
-            System.err.println("No source files given on command line; try \"-help\".");
-            System.exit(1);
-        }
-        File[] sourceFiles = new File[args.length - i];
-        for (int j = i; j < args.length; ++j) sourceFiles[j - i] = new File(args[j]);
-
-        // Create the compiler object.
-        final Compiler compiler = new Compiler(
-            optionalSourcePath,
-            classPath,
-            optionalExtDirs,
-            optionalBootClassPath,
-            destinationDirectory,
-            optionalCharacterEncoding,
-            verbose,
-            debuggingInformation,
-            warningHandlePatterns,
-            rebuild
-        );
-
-        // Compile source files.
-        try {
-            compiler.compile(sourceFiles);
-        } catch (Exception e) {
-            System.err.println(e.toString());
-            System.exit(1);
-        }
-    }
-
-    private static final String[] USAGE = {
-        "Usage:",
-        "",
-        "  java " + Compiler.class.getName() + " [ <option> ] ... <source-file> ...",
-        "",
-        "Supported <option>s are:",
-        "  -d <output-dir>           Where to save class files",
-        "  -sourcepath <dirlist>     Where to look for other source files",
-        "  -classpath <dirlist>      Where to look for other class files",
-        "  -extdirs <dirlist>        Where to look for other class files",
-        "  -bootclasspath <dirlist>  Where to look for other class files",
-        "  -encoding <encoding>      Encoding of source files, e.g. \"UTF-8\" or \"ISO-8859-1\"",
-        "  -verbose",
-        "  -g                        Generate all debugging info",
-        "  -g:none                   Generate no debugging info",
-        "  -g:{lines,vars,source}    Generate only some debugging info",
-        "  -warn:<pattern-list>      Issue certain warnings; examples:",
-        "    -warn:*                 Enables all warnings",
-        "    -warn:IASF              Only warn against implicit access to static fields",
-        "    -warn:*-IASF            Enables all warnings, except those against implicit",
-        "                            access to static fields",
-        "    -warn:*-IA*+IASF        Enables all warnings, except those against implicit",
-        "                            accesses, but do warn against implicit access to",
-        "                            static fields",
-        "  -rebuild                  Compile all source files, even if the class files",
-        "                            seems up-to-date",
-        "  -help",
-        "",
-        "The default encoding in this environment is \"" + new InputStreamReader(new ByteArrayInputStream(new byte[0])).getEncoding() + "\".",
-    };
-
-    private /*final*/ ResourceFinder    classFileFinder;
-    public static final ResourceFinder  FIND_NEXT_TO_SOURCE_FILE = null; // Special value for "classFileResourceFinder".
-    private /*final*/ ResourceCreator   classFileCreator;
-    public static final ResourceCreator CREATE_NEXT_TO_SOURCE_FILE = null; // Special value for "classFileResourceCreator".
-    private /*final*/ String            optionalCharacterEncoding;
-    private /*final*/ Benchmark         benchmark;
-    private /*final*/ EnumeratorSet     debuggingInformation;
-    private /*final*/ WarningHandler    optionalWarningHandler;
-    private UnitCompiler.ErrorHandler   optionalCompileErrorHandler = null;
-
-    private /*final*/ IClassLoader iClassLoader;
-    private final ArrayList    parsedCompilationUnits = new ArrayList(); // UnitCompiler
-
-    /**
-     * Initialize a Java<sup>TM</sup> compiler with the given parameters.
-     * <p>
-     * Classes are searched in the following order:
-     * <ul>
-     *   <li>If <code>optionalBootClassPath</code> is <code>null</code>:
-     *   <ul>
-     *     <li>Through the system class loader of the JVM that runs JANINO
-     *   </ul>
-     *   <li>If <code>optionalBootClassPath</code> is not <code>null</code>:
-     *   <ul>
-     *     <li>Through the <code>optionalBootClassPath</code>
-     *   </ul>
-     *   <li>If <code>optionalExtDirs</code> is not <code>null</code>:
-     *   <ul>
-     *     <li>Through the <code>optionalExtDirs</code>
-     *   </ul>
-     *   <li>Through the <code>classPath</code>
-     *   <li>If <code>optionalSourcePath</code> is <code>null</code>:
-     *   <ul>
-     *     <li>Through source files found on the <code>classPath</code>
-     *   </ul>
-     *   <li>If <code>optionalSourcePath</code> is not <code>null</code>:
-     *   <ul>
-     *     <li>Through source files found on the <code>sourcePath</code>
-     *   </ul>
-     * </ul>
-     * <p>
-     * The file name of a class file that represents class "pkg.Example"
-     * is determined as follows:
-     * <ul>
-     *   <li>
-     *   If <code>optionalDestinationDirectory</code> is not {@link #NO_DESTINATION_DIRECTORY}:
-     *   <code><i>optionalDestinationDirectory</i>/pkg/Example.class</code>
-     *   <li>
-     *   If <code>optionalDestinationDirectory</code> is {@link #NO_DESTINATION_DIRECTORY}:
-     *   <code>dir1/dir2/Example.class</code> (Assuming that the file name of the
-     *   source file that declares the class was
-     *   <code>dir1/dir2/Any.java</code>.)
-     * </ul>
-     *
-     * @see #DEFAULT_WARNING_HANDLE_PATTERNS
-     */
-    public Compiler(
-        final File[]    optionalSourcePath,
-        final File[]    classPath,
-        final File[]    optionalExtDirs,
-        final File[]    optionalBootClassPath,
-        final File      destinationDirectory,
-        final String    optionalCharacterEncoding,
-        boolean         verbose,
-        EnumeratorSet   debuggingInformation,
-        StringPattern[] warningHandlePatterns,
-        boolean         rebuild
-    ) {
-        this(
-            new PathResourceFinder(                   // sourceFinder
-                optionalSourcePath == null ? classPath : optionalSourcePath
-            ),
-            Compiler.createJavacLikePathIClassLoader( // iClassLoader
-                optionalBootClassPath,
-                optionalExtDirs,
-                classPath
-            ),
-            (                                         // classFileFinder
-                rebuild ? ResourceFinder.EMPTY_RESOURCE_FINDER :
-                destinationDirectory == Compiler.NO_DESTINATION_DIRECTORY ? Compiler.FIND_NEXT_TO_SOURCE_FILE :
-                new DirectoryResourceFinder(destinationDirectory)
-            ),
-            (                                         // classFileCreator
-                destinationDirectory == Compiler.NO_DESTINATION_DIRECTORY ? Compiler.CREATE_NEXT_TO_SOURCE_FILE :
-                new DirectoryResourceCreator(destinationDirectory)
-            ),
-            optionalCharacterEncoding,                // optionalCharacterEncoding
-            verbose,                                  // verbose
-            debuggingInformation,                     // debuggingInformation
-            new FilterWarningHandler(                 // optionalWarningHandler
-                warningHandlePatterns,
-                new SimpleWarningHandler() // <= Anonymous class here is complicated because the enclosing instance is not fully initialized yet 
-            )
-        );
-
-        this.benchmark.report("*** JANINO - an embedded compiler for the Java(TM) programming language");
-        this.benchmark.report("*** For more information visit http://janino.codehaus.org");
-        this.benchmark.report("Source path",             optionalSourcePath           );
-        this.benchmark.report("Class path",              classPath                    );
-        this.benchmark.report("Ext dirs",                optionalExtDirs              );
-        this.benchmark.report("Boot class path",         optionalBootClassPath        );
-        this.benchmark.report("Destination directory",   destinationDirectory         );
-        this.benchmark.report("Character encoding",      optionalCharacterEncoding    );
-        this.benchmark.report("Verbose",                 new Boolean(verbose)         );
-        this.benchmark.report("Debugging information",   debuggingInformation         );
-        this.benchmark.report("Warning handle patterns", warningHandlePatterns);
-        this.benchmark.report("Rebuild",                 new Boolean(rebuild)         );
-    }
-    public static final File NO_DESTINATION_DIRECTORY = null; // Backwards compatibility -- previously, "null" was officially documented
-    public static class SimpleWarningHandler implements WarningHandler {
-        public void handleWarning(String handle, String message, Location optionalLocation) {
-            StringBuffer sb = new StringBuffer();
-            if (optionalLocation != null) sb.append(optionalLocation).append(": ");
-            sb.append("Warning ").append(handle).append(": ").append(message);
-            System.err.println(sb.toString());
-        }
-    }
-    public static final StringPattern[] DEFAULT_WARNING_HANDLE_PATTERNS = StringPattern.PATTERNS_NONE;
-
-    /**
-     * To mimic the behavior of JAVAC with a missing "-d" command line option,
-     * pass {@link #FIND_NEXT_TO_SOURCE_FILE} as the <code>classFileResourceFinder</code> and
-     * {@link #CREATE_NEXT_TO_SOURCE_FILE} as the <code>classFileResourceCreator</code>.
-     * <p>
-     * If it is impossible to check whether an already-compiled class file
-     * exists, or if you want to enforce recompilation, pass
-     * {@link ResourceFinder#EMPTY_RESOURCE_FINDER} as the
-     * <code>classFileResourceFinder</code>.
-     * 
-     * @param sourceFinder Finds extra Java compilation units that need to be compiled (a.k.a. "sourcepath")
-     * @param iClassLoader loads auxiliary {@link IClass}es; e.g. <code>new ClassLoaderIClassLoader(ClassLoader)</code>
-     * @param classFileFinder Where to look for up-to-date class files that need not be compiled
-     * @param classFileCreator Used to store generated class files
-     * @param optionalCharacterEncoding
-     * @param verbose
-     * @param debuggingInformation a combination of <code>Java.DEBUGGING_...</code>
-     * @param optionalWarningHandler used to issue warnings
-     */
-    public Compiler(
-        ResourceFinder  sourceFinder,
-        IClassLoader    iClassLoader,
-        ResourceFinder  classFileFinder,
-        ResourceCreator classFileCreator,
-        final String    optionalCharacterEncoding,
-        boolean         verbose,
-        EnumeratorSet   debuggingInformation,
-        WarningHandler  optionalWarningHandler
-    ) {
-        this.classFileFinder           = classFileFinder;
-        this.classFileCreator          = classFileCreator;
-        this.optionalCharacterEncoding = optionalCharacterEncoding;
-        this.benchmark                 = new Benchmark(verbose);
-        this.debuggingInformation      = debuggingInformation;
-        this.optionalWarningHandler    = optionalWarningHandler;
-
-        // Set up the IClassLoader.
-        this.iClassLoader = new CompilerIClassLoader(
-            sourceFinder,
-            iClassLoader
-        );
-    }
-
-    /**
-     * Install a custom {@link UnitCompiler.ErrorHandler}. The default
-     * {@link UnitCompiler.ErrorHandler} prints the first 20 compile errors to
-     * {@link System#err} and then throws a {@link CompileException}.
-     * <p>
-     * Passing <code>null</code> restores the default {@link UnitCompiler.ErrorHandler}.
-     * <p>
-     * Notice that scan and parse errors are <i>not</i> redirected to this {@link ErrorHandler},
-     * instead, they cause a {@link ScanException} or a {@link ParseException} to be thrown.
-     * Also, the {@link Compiler} may choose to throw {@link CompileException}s in certain,
-     * fatal compile error situations, even if an {@link ErrorHandler} is installed.
-     * <p>
-     * In other words: In situations where compilation can reasonably continue after a compile
-     * error, the {@link ErrorHandler} is called; all other error conditions cause a
-     * {@link CompileException}, {@link ParseException} or {@link ScanException} to be thrown.
-     */
-    public void setCompileErrorHandler(UnitCompiler.ErrorHandler optionalCompileErrorHandler) {
-        this.optionalCompileErrorHandler = optionalCompileErrorHandler;
-    }
-
-    /**
-     * Create an {@link IClassLoader} that looks for classes in the given "boot class
-     * path", then in the given "extension directories", and then in the given
-     * "class path".
-     * <p>
-     * The default for the <code>optionalBootClassPath</code> is the path defined in
-     * the system property "sun.boot.class.path", and the default for the
-     * <code>optionalExtensionDirs</code> is the path defined in the "java.ext.dirs"
-     * system property.
-     */
-    private static IClassLoader createJavacLikePathIClassLoader(
-        final File[] optionalBootClassPath,
-        final File[] optionalExtDirs,
-        final File[] classPath
-    ) {
-        ResourceFinder bootClassPathResourceFinder = new PathResourceFinder(
-            optionalBootClassPath == null ?
-            PathResourceFinder.parsePath(System.getProperty("sun.boot.class.path")):
-            optionalBootClassPath
-        );
-        ResourceFinder extensionDirectoriesResourceFinder = new JarDirectoriesResourceFinder(
-            optionalExtDirs == null ?
-            PathResourceFinder.parsePath(System.getProperty("java.ext.dirs")):
-            optionalExtDirs
-        );
-        ResourceFinder classPathResourceFinder = new PathResourceFinder(classPath);
-
-        // We can load classes through "ResourceFinderIClassLoader"s, which means
-        // they are read into "ClassFile" objects, or we can load classes through
-        // "ClassLoaderIClassLoader"s, which means they are loaded into the JVM.
-        //
-        // In my environment, the latter is slightly faster. No figures about
-        // resource usage yet.
-        //
-        // In applications where the generated classes are not loaded into the
-        // same JVM instance, we should avoid to use the
-        // ClassLoaderIClassLoader, because that assumes that final fields have
-        // a constant value, even if not compile-time-constant but only
-        // initialization-time constant. The classical example is
-        // "File.separator", which is non-blank final, but not compile-time-
-        // constant.
-        if (true) {
-            IClassLoader icl;
-            icl = new ResourceFinderIClassLoader(bootClassPathResourceFinder, null);
-            icl = new ResourceFinderIClassLoader(extensionDirectoriesResourceFinder, icl);
-            icl = new ResourceFinderIClassLoader(classPathResourceFinder, icl);
-            return icl;
-        } else {
-            ClassLoader cl;
-
-            cl = SimpleCompiler.BOOT_CLASS_LOADER;
-            cl = new ResourceFinderClassLoader(bootClassPathResourceFinder, cl);
-            cl = new ResourceFinderClassLoader(extensionDirectoriesResourceFinder, cl);
-            cl = new ResourceFinderClassLoader(classPathResourceFinder, cl);
-
-            return new ClassLoaderIClassLoader(cl);
-        }
-    }
-
-    /**
-     * Reads a set of Java<sup>TM</sup> compilation units (a.k.a. "source
-     * files") from the file system, compiles them into a set of "class
-     * files" and stores these in the file system. Additional source files are
-     * parsed and compiled on demand through the "source path" set of
-     * directories.
-     * <p>
-     * For example, if the source path comprises the directories "A/B" and "../C",
-     * then the source file for class "com.acme.Main" is searched in
-     * <dl>
-     *   <dd>A/B/com/acme/Main.java
-     *   <dd>../C/com/acme/Main.java
-     * </dl>
-     * Notice that it does make a difference whether you pass multiple source
-     * files to {@link #compile(File[])} or if you invoke
-     * {@link #compile(File[])} multiply: In the former case, the source
-     * files may contain arbitrary references among each other (even circular
-     * ones). In the latter case, only the source files on the source path
-     * may contain circular references, not the <code>sourceFiles</code>.
-     * <p>
-     * This method must be called exactly once after object construction.
-     * <p>
-     * Compile errors are reported as described at
-     * {@link #setCompileErrorHandler(UnitCompiler.ErrorHandler)}.
-     *
-     * @param sourceFiles Contain the compilation units to compile
-     * @return <code>true</code> for backwards compatibility (return value can safely be ignored)
-     * @throws CompileException Fatal compilation error, or the {@link CompileException} thrown be the installed compile error handler
-     * @throws ParseException Parse error
-     * @throws ScanException Scan error
-     * @throws IOException Occurred when reading from the <code>sourceFiles</code>
-     */
-    public boolean compile(File[] sourceFiles)
-    throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
-        this.benchmark.report("Source files", sourceFiles);
-
-        Resource[] sourceFileResources = new Resource[sourceFiles.length];
-        for (int i = 0; i < sourceFiles.length; ++i) sourceFileResources[i] = new FileResource(sourceFiles[i]);
-        this.compile(sourceFileResources);
-        return true;
-    }
-
-    /**
-     * See {@link #compile(File[])}.
-     *
-     * @param sourceResources Contain the compilation units to compile
-     * @return <code>true</code> for backwards compatibility (return value can safely be ignored)
-     */
-    public boolean compile(Resource[] sourceResources)
-    throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
-
-        // Set up the compile error handler as described at "setCompileErrorHandler()".
-        UnitCompiler.ErrorHandler ceh = (
-            this.optionalCompileErrorHandler != null
-            ? this.optionalCompileErrorHandler
-            : new UnitCompiler.ErrorHandler() {
-                int compileErrorCount = 0;
-                public void handleError(String message, Location optionalLocation) throws CompileException {
-                    CompileException ex = new CompileException(message, optionalLocation);
-                    if (++this.compileErrorCount >= 20) throw ex;
-                    System.err.println(ex.getMessage());
-                }
-            }
-        );
-
-        this.benchmark.beginReporting();
-        try {
-
-            // Parse all source files.
-            this.parsedCompilationUnits.clear();
-            for (int i = 0; i < sourceResources.length; ++i) {
-                if (Compiler.DEBUG) System.out.println("Compiling \"" + sourceResources[i] + "\"");
-                this.parsedCompilationUnits.add(new UnitCompiler(this.parseCompilationUnit(
-                    sourceResources[i].getFileName(),                   // fileName
-                    new BufferedInputStream(sourceResources[i].open()), // inputStream
-                    this.optionalCharacterEncoding                      // optionalCharacterEncoding
-                ), this.iClassLoader));
-            }
-    
-            // Compile all parsed compilation units. The vector of parsed CUs may
-            // grow while they are being compiled, but eventually all CUs will
-            // be compiled.
-            for (int i = 0; i < this.parsedCompilationUnits.size(); ++i) {
-                UnitCompiler unitCompiler = (UnitCompiler) this.parsedCompilationUnits.get(i);
-                Java.CompilationUnit cu = unitCompiler.compilationUnit;
-                if (cu.optionalFileName == null) throw new RuntimeException();
-                File sourceFile = new File(cu.optionalFileName);
-
-                unitCompiler.setCompileErrorHandler(ceh);
-                unitCompiler.setWarningHandler(this.optionalWarningHandler);
-
-                this.benchmark.beginReporting("Compiling compilation unit \"" + sourceFile + "\"");
-                ClassFile[] classFiles;
-                try {
-    
-                    // Compile the compilation unit.
-                    classFiles = unitCompiler.compileUnit(this.debuggingInformation);
-                } finally {
-                    this.benchmark.endReporting();
-                }
-    
-                // Store the compiled classes and interfaces into class files.
-                this.benchmark.beginReporting("Storing " + classFiles.length + " class file(s) resulting from compilation unit \"" + sourceFile + "\"");
-                try {
-                    for (int j = 0; j < classFiles.length; ++j) {
-                        this.storeClassFile(classFiles[j], sourceFile);
-                    }
-                } finally {
-                    this.benchmark.endReporting();
-                }
-            }
-        } finally {
-            this.benchmark.endReporting("Compiled " + this.parsedCompilationUnits.size() + " compilation unit(s)");
-        }
-        return true;
-    }
-
-    /**
-     * Read one compilation unit from a file and parse it.
-     * <p>
-     * The <code>inputStream</code> is closed before the method returns.
-     * @return the parsed compilation unit
-     */
-    private Java.CompilationUnit parseCompilationUnit(
-        String      fileName,
-        InputStream inputStream,
-        String      optionalCharacterEncoding
-    ) throws Scanner.ScanException, Parser.ParseException, IOException {
-        try {
-            Scanner scanner = new Scanner(fileName, inputStream, optionalCharacterEncoding);
-            scanner.setWarningHandler(this.optionalWarningHandler);
-            Parser parser = new Parser(scanner);
-            parser.setWarningHandler(this.optionalWarningHandler);
-
-            this.benchmark.beginReporting("Parsing \"" + fileName + "\"");
-            try {
-                return parser.parseCompilationUnit();
-            } finally {
-                this.benchmark.endReporting();
-            }
-        } finally {
-            inputStream.close();
-        }
-    }
-
-    /**
-     * Construct the name of a file that could store the byte code of the class with the given
-     * name.
-     * <p>
-     * If <code>optionalDestinationDirectory</code> is non-null, the returned path is the
-     * <code>optionalDestinationDirectory</code> plus the package of the class (with dots replaced
-     * with file separators) plus the class name plus ".class". Example:
-     * "destdir/pkg1/pkg2/Outer$Inner.class"
-     * <p>
-     * If <code>optionalDestinationDirectory</code> is null, the returned path is the
-     * directory of the <code>sourceFile</code> plus the class name plus ".class". Example:
-     * "srcdir/Outer$Inner.class"
-     * @param className E.g. "pkg1.pkg2.Outer$Inner"
-     * @param sourceFile E.g. "srcdir/Outer.java"
-     * @param optionalDestinationDirectory E.g. "destdir"
-     */
-    public static File getClassFile(String className, File sourceFile, File optionalDestinationDirectory) {
-        if (optionalDestinationDirectory != null) {
-            return new File(optionalDestinationDirectory, ClassFile.getClassFileResourceName(className));
-        } else {
-            int idx = className.lastIndexOf('.');
-            return new File(sourceFile.getParentFile(), ClassFile.getClassFileResourceName(className.substring(idx + 1)));
-        }
-    }
-
-    /**
-     * Store the byte code of this {@link ClassFile} in the file system. Directories are created
-     * as necessary.
-     * @param classFile
-     * @param sourceFile Required to compute class file path if no destination directory given
-     */
-    public void storeClassFile(ClassFile classFile, final File sourceFile) throws IOException {
-        String classFileResourceName = ClassFile.getClassFileResourceName(classFile.getThisClassName());
-
-        // Determine where to create the class file.
-        ResourceCreator rc;
-        if (this.classFileCreator != Compiler.CREATE_NEXT_TO_SOURCE_FILE) {
-            rc = this.classFileCreator;
-        } else {
-
-            // If the JAVAC option "-d" is given, place the class file next
-            // to the source file, irrespective of the package name.
-            rc = new FileResourceCreator() {
-                protected File getFile(String resourceName) {
-                    return new File(
-                        sourceFile.getParentFile(),
-                        resourceName.substring(resourceName.lastIndexOf('/') + 1)
-                    );
-                }
-            };
-        }
-        OutputStream os = rc.createResource(classFileResourceName);
-        try {
-            if (DEBUG) {
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                classFile.store(baos);
-                byte[] ba = baos.toByteArray();
-                System.out.println("*** Disassembly of class \"" + classFile.getThisClassName() + "\":");
-                try {
-                    new Disassembler().disasm(new ByteArrayInputStream(ba));
-                    System.out.flush();
-                } catch (IOException ex) {
-                    throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
-                }
-                os.write(ba);
-            } else
-            {
-                classFile.store(os);
-            }
-        } catch (IOException ex) {
-            try { os.close(); } catch (IOException e) {}
-            os = null;
-            if (!rc.deleteResource(classFileResourceName)) throw new IOException("Could not delete incompletely written class file \"" + classFileResourceName + "\"");
-            throw ex;
-        } finally {
-            if (os != null) try { os.close(); } catch (IOException e) {}
-        }
-    }
-
-    /**
-     * A specialized {@link IClassLoader} that loads {@link IClass}es from the following
-     * sources:
-     * <ol>
-     *   <li>An already-parsed compilation unit
-     *   <li>A class file in the output directory (if existant and younger than source file)
-     *   <li>A source file in any of the source path directories
-     *   <li>The parent class loader
-     * </ol>
-     * Notice that the {@link CompilerIClassLoader} is an inner class of {@link Compiler} and
-     * heavily uses {@link Compiler}'s members.
-     */
-    private class CompilerIClassLoader extends IClassLoader {
-        private final ResourceFinder sourceFinder;
-
-        /**
-         * @param sourceFinder Where to look for source files
-         * @param optionalParentIClassLoader {@link IClassLoader} through which {@link IClass}es are to be loaded
-         */
-        public CompilerIClassLoader(
-            ResourceFinder sourceFinder,
-            IClassLoader   optionalParentIClassLoader
-        ) {
-            super(optionalParentIClassLoader);
-            this.sourceFinder = sourceFinder;
-            super.postConstruct();
-        }
-
-        /**
-         * @param type field descriptor of the {@IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
-         * @return <code>null</code> if a the type could not be found
-         * @throws ClassNotFoundException if an exception was raised while loading the {@link IClass}
-         */
-        protected IClass findIClass(final String type) throws ClassNotFoundException {
-            if (Compiler.DEBUG) System.out.println("type = " + type);
-
-            // Determine the class name.
-            String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
-            if (Compiler.DEBUG) System.out.println("2 className = \"" + className + "\"");
-
-            // Do not attempt to load classes from package "java".
-            if (className.startsWith("java.")) return null;
-
-            // Determine the name of the top-level class.
-            String topLevelClassName;
-            {
-                int idx = className.indexOf('$');
-                topLevelClassName = idx == -1 ? className : className.substring(0, idx);
-            }
-
-            // Check the already-parsed compilation units.
-            for (int i = 0; i < Compiler.this.parsedCompilationUnits.size(); ++i) {
-                UnitCompiler uc = (UnitCompiler) Compiler.this.parsedCompilationUnits.get(i);
-                IClass res = uc.findClass(topLevelClassName);
-                if (res != null) {
-                    if (!className.equals(topLevelClassName)) {
-                        res = uc.findClass(className);
-                        if (res == null) return null;
-                    }
-                    this.defineIClass(res);
-                    return res;
-                } 
-            }
-
-            // Search source path for uncompiled class.
-            final Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
-            if (sourceResource == null) return null;
-
-            // Find an existing class file.
-            Resource classFileResource;
-            if (Compiler.this.classFileFinder != Compiler.FIND_NEXT_TO_SOURCE_FILE) {
-                classFileResource = Compiler.this.classFileFinder.findResource(ClassFile.getClassFileResourceName(className));
-            } else {
-                if (!(sourceResource instanceof FileResource)) return null;
-                File classFile = new File(
-                    ((FileResource) sourceResource).getFile().getParentFile(),
-                    ClassFile.getClassFileResourceName(className.substring(className.lastIndexOf('.') + 1))
-                );
-                classFileResource = classFile.exists() ? new FileResource(classFile) : null;
-            }
-
-            // Compare source modification time against class file modification time.
-            if (classFileResource != null && sourceResource.lastModified() <= classFileResource.lastModified()) {
-
-                // The class file is up-to-date; load it.
-                return this.defineIClassFromClassFileResource(classFileResource);
-            } else {
-
-                // Source file not yet compiled or younger than class file.
-                return this.defineIClassFromSourceResource(sourceResource, className);
-            }
-        }
-
-        /**
-         * Parse the compilation unit stored in the given <code>sourceResource</code>, remember it in
-         * <code>Compiler.this.parsedCompilationUnits</code> (it may declare other classes that
-         * are needed later), find the declaration of the type with the given
-         * <code>className</code>, and define it in the {@link IClassLoader}.
-         * <p>
-         * Notice that the CU is not compiled here!
-         */
-        private IClass defineIClassFromSourceResource(
-            Resource sourceResource,
-            String                  className
-        ) throws ClassNotFoundException {
-
-            // Parse the source file.
-            UnitCompiler uc;
-            try {
-                Java.CompilationUnit cu = Compiler.this.parseCompilationUnit(
-                    sourceResource.getFileName(),                   // fileName
-                    new BufferedInputStream(sourceResource.open()), // inputStream
-                    Compiler.this.optionalCharacterEncoding         // optionalCharacterEncoding
-                );
-                uc = new UnitCompiler(cu, Compiler.this.iClassLoader);
-            } catch (IOException ex) {
-                throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
-            } catch (Parser.ParseException ex) {
-                throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
-            } catch (Scanner.ScanException ex) {
-                throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
-            } catch (CompileException ex) {
-                throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", ex);
-            }
-
-            // Remember compilation unit for later compilation.
-            Compiler.this.parsedCompilationUnits.add(uc);
-
-            // Define the class.
-            IClass res = uc.findClass(className);
-            if (res == null) {
-
-                // This is a really complicated case: We may find a source file on the source
-                // path that seemingly contains the declaration of the class we are looking
-                // for, but doesn't. This is possible if the underlying file system has
-                // case-insensitive file names and/or file names that are limited in length
-                // (e.g. DOS 8.3).
-                return null;
-            }
-            this.defineIClass(res);
-            return res;
-        }
-
-        /**
-         * Open the given <code>classFileResource</code>, read its contents, define it in the
-         * {@link IClassLoader}, and resolve it (this step may involve loading more classes).
-         */
-        private IClass defineIClassFromClassFileResource(Resource classFileResource) throws ClassNotFoundException {
-            Compiler.this.benchmark.beginReporting("Loading class file \"" + classFileResource.getFileName() + "\"");
-            try {
-                InputStream is = null;
-                ClassFile cf;
-                try {
-                    is = classFileResource.open();
-					cf = new ClassFile(new BufferedInputStream(is));
-                } catch (IOException ex) {
-                    throw new ClassNotFoundException("Opening class file resource \"" + classFileResource + "\"", ex);
-                } finally {
-                    if (is != null) try { is.close(); } catch (IOException e) {}
-                }
-                ClassFileIClass result = new ClassFileIClass(
-                    cf,                       // classFile
-                    CompilerIClassLoader.this // iClassLoader
-                );
-
-                // Important: We must FIRST call "defineIClass()" so that the
-                // new IClass is known to the IClassLoader, and THEN
-                // "resolveAllClasses()", because otherwise endless recursion could
-                // occur.
-                this.defineIClass(result);
-                result.resolveAllClasses();
-
-                return result;
-            } finally {
-                Compiler.this.benchmark.endReporting();
-            }
-        }
-    }
-}
-
-
diff --git a/src/org/codehaus/janino/Cookable.java b/src/org/codehaus/janino/Cookable.java
deleted file mode 100644
index 16ff334..0000000
--- a/src/org/codehaus/janino/Cookable.java
+++ /dev/null
@@ -1,150 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-
-/**
- * "Cooking" means scanning a sequence of Java<sup>TM</sup> tokens with a {@link
- * org.codehaus.janino.Scanner} and turning them into some artifact. For example, if you cook a
- * {@link ClassBodyEvaluator}, then the tokens are interpreted as a class body and compiled into
- * a {@link Class} which is accessible through {@link ClassBodyEvaluator#getClazz()}.
- * <p>
- * This class declares numerous <code>cook*()</code> methods
- * that use a {@link java.lang.String}, a {@link java.io.File}, an {@link java.io.InputStream} or
- * a {@link java.io.Reader} as the source of characters for scanning.
- * <p>
- * The <code>cook*()</code> methods eventually invoke the abstract {@link #cook(Scanner)}
- * method with a correctly configured {@link org.codehaus.janino.Scanner}.
- */
-public abstract class Cookable {
-
-    /**
-     * To be implemented by the derived classes.
-     */
-    public abstract void cook(Scanner scanner)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException;
-
-    // The "cook()" method family.
-
-    public final void cook(Reader r)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cook(null, r);
-    }
-
-    /**
-     * @param optionalFileName Used when reporting errors and warnings.
-     */
-    public final void cook(String optionalFileName, Reader r)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cook(new Scanner(optionalFileName, r));
-    }
-
-    /**
-     * Cook tokens from an {@link InputStream}, encoded in the "platform default encoding".
-     */
-    public final void cook(InputStream is)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cook(null, is);
-    }
-
-    /**
-     * Cook tokens from an {@link InputStream}, encoded in the "platform default encoding".
-     *
-     * @param optionalFileName Used when reporting errors and warnings.
-     */
-    public final void cook(String optionalFileName, InputStream is)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cook(optionalFileName, is, null);
-    }
-    public final void cook(InputStream is, String optionalEncoding)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cook(new Scanner(null, is, optionalEncoding));
-    }
-
-    /**
-     * @param optionalFileName Used when reporting errors and warnings.
-     */
-    public final void cook(String optionalFileName, InputStream is, String optionalEncoding)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cook(new Scanner(optionalFileName, is, optionalEncoding));
-    }
-
-    /**
-     * Cook tokens from a {@link java.lang.String}.
-     * <p>
-     * <b>Notice:</b> If you pass a string literal, be sure to escape all Java<sup>TM</sup> special
-     * characters, especially backslashes.
-     */
-    public final void cook(String s)
-    throws CompileException, Parser.ParseException, Scanner.ScanException {
-        try {
-            this.cook(new StringReader(s));
-        } catch (IOException ex) {
-            throw new RuntimeException("SNO: IOException despite StringReader");
-        }
-    }
-
-    /**
-     * Cook tokens from the given {@link File}, encoded in the "platform default encoding".
-     */
-    public final void cookFile(File file)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cookFile(file, null);
-    }
-    public final void cookFile(File file, String optionalEncoding)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        InputStream is = new FileInputStream(file);
-        try {
-            this.cook(new Scanner(file.getAbsolutePath(), is, optionalEncoding));
-            is.close();
-            is = null;
-        } finally {
-            if (is != null) try { is.close(); } catch (IOException ex) {}
-        }
-    }
-
-    /**
-     * Cook tokens from the named file, encoded in the "platform default encoding".
-     */
-    public final void cookFile(String fileName)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cookFile(fileName, null);
-    }
-    public final void cookFile(String fileName, String optionalEncoding)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cookFile(new File(fileName), optionalEncoding);
-    }
-}
diff --git a/src/org/codehaus/janino/DebuggingInformation.java b/src/org/codehaus/janino/DebuggingInformation.java
deleted file mode 100644
index 1232292..0000000
--- a/src/org/codehaus/janino/DebuggingInformation.java
+++ /dev/null
@@ -1,59 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import org.codehaus.janino.util.enumerator.*;
-
-public class DebuggingInformation extends Enumerator {
-    public static final DebuggingInformation SOURCE = new DebuggingInformation("source");
-    public static final DebuggingInformation LINES  = new DebuggingInformation("lines");
-    public static final DebuggingInformation VARS   = new DebuggingInformation("vars");
-
-    public static final EnumeratorSet NONE = new EnumeratorSet(DebuggingInformation.class      ).setName("none");
-    public static final EnumeratorSet ALL  = new EnumeratorSet(DebuggingInformation.class, true).setName("all");
-
-    public static final EnumeratorSet DEFAULT_DEBUGGING_INFORMATION = (
-        new EnumeratorSet(DebuggingInformation.class)
-        .add(DebuggingInformation.LINES)
-        .add(DebuggingInformation.SOURCE)
-    );
-
-    private DebuggingInformation(String name) {
-        super(name);
-    }
-    public static DebuggingInformation fromString(String name) throws EnumeratorFormatException {
-        return (DebuggingInformation) Enumerator.fromString(name, DebuggingInformation.class);
-    }
-}
diff --git a/src/org/codehaus/janino/Descriptor.java b/src/org/codehaus/janino/Descriptor.java
deleted file mode 100644
index 25aef18..0000000
--- a/src/org/codehaus/janino/Descriptor.java
+++ /dev/null
@@ -1,270 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * Helper class that defines useful methods for handling "field descriptors"
- * (JVMS 4.3.2) and "method descriptors" (JVMS 4.3.3).<p>
- * Typical descriptors are:
- * <ul>
- *   <li><code>I</code> Integer
- *   <li><code>[I</code> Array of integer
- *   <li><code>Lpkg1/pkg2/Cls;</code> Class
- *   <li><code>Lpkg1/pkg2/Outer$Inner;</code> Member class
- * </ul>
- */
-public class Descriptor {
-    public static boolean isReference(String d) {
-        return d.length() > 1;
-    }
-    public static boolean isClassOrInterfaceReference(String d) {
-        return d.charAt(0) == 'L';
-    }
-    public static boolean isArrayReference(String d) {
-        return d.charAt(0) == '[';
-    }
-    public static String getComponentDescriptor(String d) {
-        if (d.charAt(0) != '[') throw new RuntimeException("Cannot determine component descriptor from non-array descriptor \"" + d + "\"");
-        return d.substring(1);
-    }
-    public static short size(String d) {
-        if (d.equals(Descriptor.VOID_)) return 0;
-        if (Descriptor.hasSize1(d)) return 1;
-        if (Descriptor.hasSize2(d)) return 2;
-        throw new RuntimeException("No size defined for type \"" + Descriptor.toString(d) + "\"");
-    }
-    public static boolean hasSize1(String d) {
-        if (d.length() == 1) return "BCFISZ".indexOf(d) != -1;
-        return Descriptor.isReference(d);
-    }
-    public static boolean hasSize2(String d) {
-        return d.equals(Descriptor.LONG_) || d.equals(Descriptor.DOUBLE_);
-    }
-
-    // Pretty-print.
-    public static String toString(String d) {
-        int idx = 0;
-        StringBuffer sb = new StringBuffer();
-        if (d.charAt(0) == '(') {
-            ++idx;
-            sb.append("(");
-            while (idx < d.length() && d.charAt(idx) != ')') {
-                if (idx != 1) sb.append(", ");
-                idx = Descriptor.toString(d, idx, sb);
-            }
-            if (idx >= d.length()) throw new RuntimeException("Invalid descriptor \"" + d + "\"");
-            sb.append(") => ");
-            ++idx;
-        }
-        Descriptor.toString(d, idx, sb);
-        return sb.toString();
-    }
-    private static int toString(String d, int idx, StringBuffer sb) {
-        int dimensions = 0;
-        while (idx < d.length() && d.charAt(idx) == '[') {
-            ++dimensions;
-            ++idx;
-        }
-        if (idx >= d.length()) throw new RuntimeException("Invalid descriptor \"" + d + "\"");
-        switch (d.charAt(idx)) {
-        case 'L':
-            {
-                int idx2 = d.indexOf(';', idx);
-                if (idx2 == -1) throw new RuntimeException("Invalid descriptor \"" + d + "\"");
-                sb.append(d.substring(idx + 1, idx2).replace('/', '.'));
-                idx = idx2;
-            }
-            break;
-        case 'V': sb.append("void");    break;
-        case 'B': sb.append("byte");    break;
-        case 'C': sb.append("char");    break;
-        case 'D': sb.append("double");  break;
-        case 'F': sb.append("float");   break;
-        case 'I': sb.append("int");     break;
-        case 'J': sb.append("long");    break;
-        case 'S': sb.append("short");   break;
-        case 'Z': sb.append("boolean"); break;
-        default:
-            throw new RuntimeException("Invalid descriptor \"" + d + "\"");
-        }
-        for (; dimensions > 0; --dimensions) sb.append("[]");
-        return idx + 1;
-    }
-
-    /**
-     * Convert a class name as defined by "Class.getName()" into a
-     * descriptor.
-     */
-    public static String fromClassName(String className) {
-        String res = (String)Descriptor.classNameToDescriptor.get(className);
-        if(res != null) { return res; }
-        if (className.startsWith("[")) return className.replace('.', '/');
-        return 'L' + className.replace('.', '/') + ';';
-    }
-
-    /**
-     * Convert a class name in the "internal form" as described in JVMS 4.2 into a descriptor.
-     * <p>
-     * Also implement the encoding of array types as described in JVMS 4.4.1.
-     */
-    public static String fromInternalForm(String internalForm) {
-        if (internalForm.charAt(0) == '[') return internalForm;
-        return 'L' + internalForm + ';';
-    }
-
-    /**
-     * Convert a field descriptor into a class name as defined by {@link
-     * Class#getName()}.
-     */
-    public static String toClassName(String d) {
-        String res = (String)Descriptor.descriptorToClassName.get(d);
-        if(res != null) { return res; }
-        
-        char firstChar = d.charAt(0);
-        if (firstChar == 'L' && d.endsWith(";")) {
-            // Class or interface -- convert "Ljava/lang/String;" to "java.lang.String".
-            return d.substring(1, d.length() - 1).replace('/', '.');
-        } 
-        if (firstChar == '[') {
-            // Array type -- convert "[Ljava/lang/String;" to "[Ljava.lang.String;".
-            return d.replace('/', '.');
-        } 
-        throw new RuntimeException("(Invalid field descriptor \"" + d + "\")");
-    }
-
-    /**
-     * Convert a descriptor into the "internal form" as defined by JVMS 4.2.
-     */
-    public static String toInternalForm(String d) {
-        if (d.charAt(0) != 'L') throw new RuntimeException("Attempt to convert non-class descriptor \"" + d + "\" into internal form");
-        return d.substring(1, d.length() - 1);
-    }
-
-    public static boolean isPrimitive(String d) {
-        return d.length() == 1 && "VBCDFIJSZ".indexOf(d.charAt(0)) != -1;
-    }
-
-    public static boolean isPrimitiveNumeric(String d) {
-        return d.length() == 1 && "BDFIJSC".indexOf(d.charAt(0)) != -1;
-    }
-
-    /**
-     * Returns the package name of a class or interface reference descriptor,
-     * or <code>null</code> if the class or interface is declared in the
-     * default package.
-     */
-    public static String getPackageName(String d) {
-        if (d.charAt(0) != 'L') throw new RuntimeException("Attempt to get package name of non-class descriptor \"" + d + "\"");
-        int idx = d.lastIndexOf('/');
-        return idx == -1 ? null : d.substring(1, idx).replace('/', '.');
-    }
-
-    /**
-     * Check whether two reference types are declared in the same package.
-     */
-    public static boolean areInSamePackage(String d1, String d2) {
-        String packageName1 = Descriptor.getPackageName(d1);
-        String packageName2 = Descriptor.getPackageName(d2);
-        return packageName1 == null ? packageName2 == null : packageName1.equals(packageName2);
-    }
-
-    public final static String VOID_             = "V";
-    public final static String BYTE_             = "B";
-    public final static String CHAR_             = "C";
-    public final static String DOUBLE_           = "D";
-    public final static String FLOAT_            = "F";
-    public final static String INT_              = "I";
-    public final static String LONG_             = "J";
-    public final static String SHORT_            = "S";
-    public final static String BOOLEAN_          = "Z";
-    public final static String OBJECT            = "Ljava/lang/Object;";
-    public final static String STRING            = "Ljava/lang/String;";
-    public final static String STRING_BUFFER     = "Ljava/lang/StringBuffer;";
-    public final static String STRING_BUILDER    = "Ljava/lang/StringBuilder;"; // Since 1.5!
-    public final static String CLASS             = "Ljava/lang/Class;";
-    public final static String THROWABLE         = "Ljava/lang/Throwable;";
-    public final static String RUNTIME_EXCEPTION = "Ljava/lang/RuntimeException;";
-    public final static String ERROR             = "Ljava/lang/Error;";
-    public final static String CLONEABLE         = "Ljava/lang/Cloneable;";
-    public final static String SERIALIZABLE      = "Ljava/io/Serializable;";
-    public final static String BOOLEAN           = "Ljava/lang/Boolean;";
-    public final static String BYTE              = "Ljava/lang/Byte;";
-    public final static String CHARACTER         = "Ljava/lang/Character;";
-    public final static String SHORT             = "Ljava/lang/Short;";
-    public final static String INTEGER           = "Ljava/lang/Integer;";
-    public final static String LONG              = "Ljava/lang/Long;";
-    public final static String FLOAT             = "Ljava/lang/Float;";
-    public final static String DOUBLE            = "Ljava/lang/Double;";
-    private final static Map classNameToDescriptor = new HashMap();
-    private final static Map descriptorToClassName = new HashMap();
-    static {
-        descriptorToClassName.put(Descriptor.VOID_,             "void");
-        descriptorToClassName.put(Descriptor.BYTE_,             "byte");
-        descriptorToClassName.put(Descriptor.CHAR_,             "char");
-        descriptorToClassName.put(Descriptor.DOUBLE_,           "double");
-        descriptorToClassName.put(Descriptor.FLOAT_,            "float");
-        descriptorToClassName.put(Descriptor.INT_,              "int");
-        descriptorToClassName.put(Descriptor.LONG_,             "long");
-        descriptorToClassName.put(Descriptor.SHORT_,            "short");
-        descriptorToClassName.put(Descriptor.BOOLEAN_,          "boolean");
-        descriptorToClassName.put(Descriptor.OBJECT,            "java.lang.Object");
-        descriptorToClassName.put(Descriptor.STRING,            "java.lang.String");
-        descriptorToClassName.put(Descriptor.STRING_BUFFER,     "java.lang.StringBuffer");
-        descriptorToClassName.put(Descriptor.STRING_BUILDER,    "java.lang.StringBuilder");
-        descriptorToClassName.put(Descriptor.CLASS,             "java.lang.Class");
-        descriptorToClassName.put(Descriptor.THROWABLE,         "java.lang.Throwable");
-        descriptorToClassName.put(Descriptor.RUNTIME_EXCEPTION, "java.lang.RuntimeException");
-        descriptorToClassName.put(Descriptor.ERROR,             "java.lang.Error");
-        descriptorToClassName.put(Descriptor.CLONEABLE,         "java.lang.Cloneable");
-        descriptorToClassName.put(Descriptor.SERIALIZABLE,      "java.io.Serializable");
-        descriptorToClassName.put(Descriptor.BOOLEAN,           "java.lang.Boolean");
-        descriptorToClassName.put(Descriptor.BYTE,              "java.lang.Byte");
-        descriptorToClassName.put(Descriptor.CHARACTER,         "java.lang.Character");
-        descriptorToClassName.put(Descriptor.SHORT,             "java.lang.Short");
-        descriptorToClassName.put(Descriptor.INTEGER,           "java.lang.Integer");
-        descriptorToClassName.put(Descriptor.LONG,              "java.lang.Long");
-        descriptorToClassName.put(Descriptor.FLOAT,             "java.lang.Float");
-        descriptorToClassName.put(Descriptor.DOUBLE,            "java.lang.Double");
-        
-        for(Iterator it = descriptorToClassName.entrySet().iterator(); it.hasNext();) {
-            Map.Entry e = (Map.Entry) it.next();
-            classNameToDescriptor.put(e.getValue(), e.getKey());
-        }
-    }
-}
diff --git a/src/org/codehaus/janino/ExpressionEvaluator.java b/src/org/codehaus/janino/ExpressionEvaluator.java
deleted file mode 100644
index fa256ba..0000000
--- a/src/org/codehaus/janino/ExpressionEvaluator.java
+++ /dev/null
@@ -1,525 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.Java.AmbiguousName;
-import org.codehaus.janino.Java.Rvalue;
-import org.codehaus.janino.Parser.ParseException;
-import org.codehaus.janino.Scanner.ScanException;
-import org.codehaus.janino.Visitor.RvalueVisitor;
-import org.codehaus.janino.util.PrimitiveWrapper;
-import org.codehaus.janino.util.Traverser;
-
-/**
- * An engine that evaluates expressions in Java<sup>TM</sup> bytecode.
- * <p>
- * The syntax of the expression to compile is that of a Java<sup>TM</sup> expression, as defined
- * in the <a href="http://java.sun.com/docs/books/jls/second_edition">Java Language Specification,
- * 2nd edition</a>, section
- * <a href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#44393">15</a>.
- * Notice that a Java<sup>TM</sup> expression does not have a concluding semicolon.
- * <p>
- * Example:<pre>
- *   a + 7 * b</pre>
- * (Notice that this expression refers to two parameters "a" and "b", as explained below.)
- * <p>
- * The expression may optionally be preceeded with a sequence of import directives like
- * <pre>
- *   import java.text.*;
- *   new DecimalFormat("####,###.##").format(10200020.345345)
- * </pre>
- * (Notice that the import directive is concluded with a semicolon, while the expression is not.)
- * This feature is not available if you compile many expressions at a time (see below).
- * <p>
- * The expression evaluator is implemented by creating and compiling a temporary compilation unit
- * defining one class with one static method with one RETURN statement.
- * <p>
- * To set up an {@link ExpressionEvaluator} object, proceed as follows:
- * <ol>
- *   <li>
- *   Create the {@link ExpressionEvaluator} using {@link #ExpressionEvaluator()}
- *   <li>
- *   Configure the {@link ExpressionEvaluator} by calling any of the following methods:
- *   <ul>
- *      <li>{@link #setExpressionType(Class)}
- *      <li>{@link org.codehaus.janino.ScriptEvaluator#setParameters(String[], Class[])}
- *      <li>{@link org.codehaus.janino.ScriptEvaluator#setThrownExceptions(Class[])}
- *      <li>{@link org.codehaus.janino.SimpleCompiler#setParentClassLoader(ClassLoader)}
- *      <li>{@link org.codehaus.janino.ClassBodyEvaluator#setDefaultImports(String[])}
- *   </ul>
- *   <li>
- *   Call any of the {@link org.codehaus.janino.Cookable#cook(Scanner)} methods to scan,
- *   parse, compile and load the expression into the JVM.
- * </ol>
- * After the {@link ExpressionEvaluator} object is set up, the expression can be evaluated as
- * often with different parameter values (see {@link #evaluate(Object[])}). This evaluation is
- * very fast, compared to the compilation.
- * <p>
- * Less common methods exist that allow for the specification of the name of the generated class,
- * the class it extends, the interfaces it implements, the name of the method that executes the
- * expression, the exceptions that this method (i.e. the expression) is allowed to throw, and the
- * {@link ClassLoader} that is used to define the generated class and to load classes referenced by
- * the expression.
- * <p>
- * Alternatively, a number of "convenience constructors" exist that execute the steps described
- * above instantly.
- * <p>
- * If you want to compile many expressions at the same time, you have the option to cook an
- * <i>array</i> of expressions in one {@link ExpressionEvaluator} by using the following methods:
- * <ul>
- *   <li>{@link #setMethodNames(String[])}
- *   <li>{@link #setParameters(String[][], Class[][])}
- *   <li>{@link #setExpressionTypes(Class[])}
- *   <li>{@link #setStaticMethod(boolean[])}
- *   <li>{@link #setThrownExceptions(Class[][])}
- *   <li>{@link #cook(Scanner[])}
- *   <li>{@link #evaluate(int, Object[])}
- * </ul>
- * Notice that these methods have array parameters in contrast to their one-expression brethren.
- * <p>
- * Notice that for <i>functionally</i> identical {@link ExpressionEvaluator}s,
- * {@link java.lang.Object#equals(java.lang.Object)} will return <code>true</code>. E.g. "a+b" and
- * "c + d" are functionally identical if "a" and "c" have the same type, and so do "b" and "d".
- * <p>
- * If the parameter and return types of the expression are known at compile time, then a "fast"
- * expression evaluator can be instantiated through
- * {@link #createFastExpressionEvaluator(String, Class, String[], ClassLoader)}. Expression
- * evaluation is faster than through {@link #evaluate(Object[])}, because it is not done through
- * reflection but through direct method invocation.
- * <p>
- * Example:
- * <pre>
- * public interface Foo {
- *     int bar(int a, int b);
- * }
- * ...
- * Foo f = (Foo) ExpressionEvaluator.createFastExpressionEvaluator(
- *     "a + b",                    // expression to evaluate
- *     Foo.class,                  // interface that describes the expression's signature
- *     new String[] { "a", "b" },  // the parameters' names
- *     (ClassLoader) null          // Use current thread's context class loader
- * );
- * System.out.println("1 + 2 = " + f.bar(1, 2)); // Evaluate the expression
- * </pre>
- * Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
- * or with package scope in the root package (i.e. "no" package).
- * <p>
- * On my system (Intel P4, 2 GHz, MS Windows XP, JDK 1.4.1), expression "x + 1"
- * evaluates as follows:
- * <table>
- *   <tr><td></td><th>Server JVM</th><th>Client JVM</th></td></tr>
- *   <tr><td>Normal EE</td><td>23.7 ns</td><td>64.0 ns</td></tr>
- *   <tr><td>Fast EE</td><td>31.2 ns</td><td>42.2 ns</td></tr>
- * </table>
- * (How can it be that interface method invocation is slower than reflection for
- * the server JVM?)
- * <p>
- * The expression may refer to a set of parameters with the given
- * <code>parameterNames</code> and <code>parameterTypes</code>.
- * <p>
- * <code>parameterNames</code> and <code>parameterTypes</code> must have the
- * same number of elements.
- * <p>
- * The parameters and/or the return value can be of primitive type, e.g.
- * {@link Double#TYPE}.
- * <p>
- * The <code>optionalClassLoader</code> serves two purposes:
- * <ul>
- *   <li>It is used to look for classes referenced by the script.
- *   <li>It is used to load the generated Java<sup>TM</sup> class
- *   into the JVM; directly if it is a subclass of {@link
- *   ByteArrayClassLoader}, or by creation of a temporary
- *   {@link ByteArrayClassLoader} if not.
- * </ul>
- * If the <code>optionalClassLoader</code> is <code>null</code>, then the
- * current thread's context class loader is used.
- * <p>
- * A number of constructors exist that provide useful default values for
- * the various parameters, or parse their script from a {@link String}
- * instead of a {@link Scanner}. (You hardly want to use a scanner other than
- * the default scanner.)
- * <p>
- * If the type of the expression is not fixed, you can pass a <code>null</code>
- * <code>optionalExpressionType<code> argument; in this case, references are
- * returned as {@link Object}s, and primitive values are wrapped in their
- * wrapper classes.
- * <p>
- * If <code>optionalExpressionType</code> is {@link Void#TYPE}, then the
- * expression must be an invocation of a <code>void</code> method.
- */
-public class ExpressionEvaluator extends ScriptEvaluator {
-    public static final Class ANY_TYPE = null;
-
-    private Class[] optionalExpressionTypes = null;
-
-    /**
-     * Equivalent to<pre>
-     * ExpressionEvaluator ee = new ExpressionEvaluator();
-     * ee.setExpressionType(expressionType);
-     * ee.setParameters(parameterNames, parameterTypes);
-     * ee.cook(expression);</pre>
-     *
-     * @see #ExpressionEvaluator()
-     * @see ExpressionEvaluator#setExpressionType(Class)
-     * @see ScriptEvaluator#setParameters(String[], Class[])
-     * @see Cookable#cook(String)
-     */
-    public ExpressionEvaluator(
-        String   expression,
-        Class    expressionType,
-        String[] parameterNames,
-        Class[]  parameterTypes
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        this.setExpressionType(expressionType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.cook(expression);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ExpressionEvaluator ee = new ExpressionEvaluator();
-     * ee.setExpressionType(expressionType);
-     * ee.setParameters(parameterNames, parameterTypes);
-     * ee.setThrownExceptions(thrownExceptions);
-     * ee.setParentClassLoader(optionalParentClassLoader);
-     * ee.cook(expression);</pre>
-     *
-     * @see #ExpressionEvaluator()
-     * @see ExpressionEvaluator#setExpressionType(Class)
-     * @see ScriptEvaluator#setParameters(String[], Class[])
-     * @see ScriptEvaluator#setThrownExceptions(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(String)
-     */
-    public ExpressionEvaluator(
-        String      expression,
-        Class       expressionType,
-        String[]    parameterNames,
-        Class[]     parameterTypes,
-        Class[]     thrownExceptions,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        this.setExpressionType(expressionType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(expression);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ExpressionEvaluator ee = new ExpressionEvaluator();
-     * ee.setExpressionType(expressionType);
-     * ee.setParameters(parameterNames, parameterTypes);
-     * ee.setThrownExceptions(thrownExceptions);
-     * ee.setExtendedType(optionalExtendedType);
-     * ee.setImplementedTypes(implementedTypes);
-     * ee.setParentClassLoader(optionalParentClassLoader);
-     * ee.cook(expression);</pre>
-     *
-     * @see #ExpressionEvaluator()
-     * @see ExpressionEvaluator#setExpressionType(Class)
-     * @see ScriptEvaluator#setParameters(String[], Class[])
-     * @see ScriptEvaluator#setThrownExceptions(Class[])
-     * @see ClassBodyEvaluator#setExtendedType(Class)
-     * @see ClassBodyEvaluator#setImplementedTypes(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(String)
-     */
-    public ExpressionEvaluator(
-        String      expression,
-        Class       expressionType,
-        String[]    parameterNames,
-        Class[]     parameterTypes,
-        Class[]     thrownExceptions,
-        Class       optionalExtendedType,
-        Class[]     implementedTypes,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        this.setExpressionType(expressionType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.setExtendedType(optionalExtendedType);
-        this.setImplementedTypes(implementedTypes);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(expression);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ExpressionEvaluator ee = new ExpressionEvaluator();
-     * ee.setClassName(className);
-     * ee.setExtendedType(optionalExtendedType);
-     * ee.setImplementedTypes(implementedTypes);
-     * ee.setStaticMethod(staticMethod);
-     * ee.setExpressionType(expressionType);
-     * ee.setMethodName(methodName);
-     * ee.setParameters(parameterNames, parameterTypes);
-     * ee.setThrownExceptions(thrownExceptions);
-     * ee.setParentClassLoader(optionalParentClassLoader);
-     * ee.cook(scanner);
-     *
-     * @see #ExpressionEvaluator()
-     * @see ClassBodyEvaluator#setClassName(String)
-     * @see ClassBodyEvaluator#setExtendedType(Class)
-     * @see ClassBodyEvaluator#setImplementedTypes(Class[])
-     * @see ScriptEvaluator#setStaticMethod(boolean)
-     * @see ExpressionEvaluator#setExpressionType(Class)
-     * @see ScriptEvaluator#setMethodName(String)
-     * @see ScriptEvaluator#setParameters(String[], Class[])
-     * @see ScriptEvaluator#setThrownExceptions(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(Scanner)
-     */
-    public ExpressionEvaluator(
-        Scanner     scanner,
-        String      className,
-        Class       optionalExtendedType,
-        Class[]     implementedTypes,
-        boolean     staticMethod,
-        Class       expressionType,
-        String      methodName,
-        String[]    parameterNames,
-        Class[]     parameterTypes,
-        Class[]     thrownExceptions,
-        ClassLoader optionalParentClassLoader
-    ) throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
-        this.setClassName(className);
-        this.setExtendedType(optionalExtendedType);
-        this.setImplementedTypes(implementedTypes);
-        this.setStaticMethod(staticMethod);
-        this.setExpressionType(expressionType);
-        this.setMethodName(methodName);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(scanner);
-    }
-
-    public ExpressionEvaluator() {}
-
-    /**
-     * Define the type of the expression. The special type {@link #ANY_TYPE} allows the expression
-     * to return any type (primitive or reference).
-     * <p>
-     * Defaults to {@link #ANY_TYPE}.
-     */
-    public void setExpressionType(Class expressionType) {
-        this.setExpressionTypes(new Class[] { expressionType });
-    }
-
-    public void setExpressionTypes(Class[] expressionTypes) {
-        assertNotCooked();
-        this.optionalExpressionTypes = expressionTypes;
-
-        Class[] returnTypes = new Class[expressionTypes.length];
-        for (int i = 0; i < returnTypes.length; ++i) {
-            Class et = expressionTypes[i];
-            returnTypes[i] = et == ANY_TYPE ? Object.class : et;
-        }
-        super.setReturnTypes(returnTypes);
-    }
-
-    protected Class getDefaultReturnType() {
-        return Object.class;
-    }
-
-    protected Java.Block makeBlock(int idx, Scanner scanner) throws ParseException, ScanException, IOException {
-        Java.Block block = new Java.Block(scanner.location());
-
-        Parser parser = new Parser(scanner);
-
-        // Parse the expression.
-        Rvalue value = parser.parseExpression().toRvalueOrPE();
-
-        Class et = this.optionalExpressionTypes == null ? ANY_TYPE : this.optionalExpressionTypes[idx];
-        if (et == void.class) {
-
-            // ExpressionEvaluator with an expression type "void" is a simple expression statement.
-            block.addStatement(new Java.ExpressionStatement(value));
-        } else {
-
-            // Special case: Expression type "ANY_TYPE" means return type "Object" and automatic
-            // wrapping of primitive types.
-            if (et == ANY_TYPE) {
-                value = new Java.MethodInvocation(
-                    scanner.location(),         // location
-                    new Java.ReferenceType(     // optionalTarget
-                        scanner.location(),                                                      // location
-                        new String[] { "org", "codehaus", "janino", "util", "PrimitiveWrapper" } // identifiers
-                    ),
-                    "wrap",                     // methodName
-                    new Java.Rvalue[] { value } // arguments
-                );
-
-                // Make sure "PrimitiveWrapper" is compiled.
-                PrimitiveWrapper.wrap(99);
-
-                // Add "PrimitiveWrapper" as an auxiliary class.
-                this.classToType(null, PrimitiveWrapper.class);
-            }
-
-            // Add a return statement.
-            block.addStatement(new Java.ReturnStatement(scanner.location(), value));
-        }
-        if (!scanner.peek().isEOF()) throw new Parser.ParseException("Unexpected token \"" + scanner.peek() + "\"", scanner.location());
-
-        return block;
-    }
-
-    /**
-     * Creates a "fast expression evaluator" from the given {@link java.lang.String}
-     * <code>expression</code>, generating a class with the {@link #DEFAULT_CLASS_NAME} that
-     * extends {@link Object}.
-     * <p>
-     * See the class description for an explanation of the "fast expression evaluator" concept.
-     *
-     * @see #createFastExpressionEvaluator(Scanner, String[], String, Class, Class, String[], ClassLoader)
-     * @see ExpressionEvaluator
-     */
-    public static Object createFastExpressionEvaluator(
-        String      expression,
-        Class       interfaceToImplement,
-        String[]    parameterNames,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        ExpressionEvaluator ee = new ExpressionEvaluator();
-        ee.setParentClassLoader(optionalParentClassLoader);
-        return ScriptEvaluator.createFastEvaluator(ee, expression, parameterNames, interfaceToImplement);
-    }
-
-    /**
-     * Creates a "fast expression evaluator" from the given {@link Scanner} with no default
-     * imports.
-     * <p>
-     * See the class description for an explanation of the "fast expression evaluator" concept.
-     *
-     * @see #createFastExpressionEvaluator(Scanner, String[], String, Class, Class, String[], ClassLoader)
-     * @see ExpressionEvaluator
-     */
-    public static Object createFastExpressionEvaluator(
-        Scanner     scanner,
-        String      className,
-        Class       optionalExtendedType,
-        Class       interfaceToImplement,
-        String[]    parameterNames,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        ExpressionEvaluator ee = new ExpressionEvaluator();
-        ee.setClassName(className);
-        ee.setExtendedType(optionalExtendedType);
-        ee.setParentClassLoader(optionalParentClassLoader);
-        return ScriptEvaluator.createFastEvaluator(ee, scanner, parameterNames, interfaceToImplement);
-    }
-
-    /**
-     * Creates a "fast expression evaluator".
-     * <p>
-     * See the class description for an explanation of the "fast expression evaluator" concept.
-     * <p> 
-     * Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
-     * or with package scope in the same package as <code>className</code>.
-     * 
-     * @param scanner                   Source of expression tokens
-     * @param optionalDefaultImports    Default imports, e.g. <code>{ "java.util.Map", "java.io.*" }</code>
-     * @param className                 Name of generated class
-     * @param optionalExtendedType      Class to extend
-     * @param interfaceToImplement      Must declare exactly the one method that defines the expression's signature
-     * @param parameterNames            The expression references the parameters through these names
-     * @param optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
-     * @return an object that implements the given interface and extends the <code>optionalExtendedType</code>
-     * @see ExpressionEvaluator
-     */
-    public static Object createFastExpressionEvaluator(
-        Scanner     scanner,
-        String[]    optionalDefaultImports,
-        String      className,
-        Class       optionalExtendedType,
-        Class       interfaceToImplement,
-        String[]    parameterNames,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        ExpressionEvaluator ee = new ExpressionEvaluator();
-        ee.setClassName(className);
-        ee.setExtendedType(optionalExtendedType);
-        ee.setDefaultImports(optionalDefaultImports);
-        ee.setParentClassLoader(optionalParentClassLoader);
-        return ScriptEvaluator.createFastEvaluator(ee, scanner, parameterNames, interfaceToImplement);
-    }
-
-    /**
-     * Guess the names of the parameters used in the given expression. The strategy is to look
-     * at all "ambiguous names" in the expression (e.g. in "a.b.c.d()", the ambiguous name
-     * is "a.b.c"), and then at the first components of the ambiguous name.
-     * <ul>
-     *   <li>If any component starts with an upper-case letter, then ambiguous name is assumed to
-     *       be a type name.
-     *   <li>Otherwise, it is assumed to be a parameter name.
-     * </ul>
-     *
-     * @see Scanner#Scanner(String, Reader)
-     */
-    public static String[] guessParameterNames(Scanner scanner) throws ParseException, ScanException, IOException {
-        Parser parser = new Parser(scanner);
-
-        // Eat optional leading import declarations.
-        while (scanner.peek().isKeyword("import")) parser.parseImportDeclaration();
-
-        // Parse the expression.
-        Rvalue rvalue = parser.parseExpression().toRvalueOrPE();
-        if (!scanner.peek().isEOF()) throw new Parser.ParseException("Unexpected token \"" + scanner.peek() + "\"", scanner.location());
-
-        // Traverse the expression for ambiguous names and guess which of them are parameter names.
-        final Set parameterNames = new HashSet();
-        rvalue.accept((RvalueVisitor) new Traverser() {
-            public void traverseAmbiguousName(AmbiguousName an) {
-
-                // If any of the components starts with an upper-case letter, then the ambiguous
-                // name is most probably a type name, e.g. "System.out" or "java.lang.System.out".
-                for (int i = 0; i < an.identifiers.length; ++i) {
-                    if (Character.isUpperCase(an.identifiers[i].charAt(0))) return;
-                }
-
-                // It's most probably a parameter name (although it could be a field name as well).
-                parameterNames.add(an.identifiers[0]);
-            }
-        }.comprehensiveVisitor());
-
-        return (String[]) parameterNames.toArray(new String[parameterNames.size()]);
-    }
-}
diff --git a/src/org/codehaus/janino/FilterWarningHandler.java b/src/org/codehaus/janino/FilterWarningHandler.java
deleted file mode 100644
index 0ec6d3c..0000000
--- a/src/org/codehaus/janino/FilterWarningHandler.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import org.codehaus.janino.util.StringPattern;
-
-public class FilterWarningHandler implements WarningHandler {
-    private final StringPattern[] handlePatterns;
-    private final WarningHandler  delegate;
-
-    /**
-     * Popular values for the <code>handlePatterns</code> parameter are
-     * {@link StringPattern#PATTERNS_ALL} and {@link StringPattern#PATTERNS_NONE}.
-     */
-    public FilterWarningHandler(StringPattern[] handlePatterns, WarningHandler delegate) {
-        this.handlePatterns = handlePatterns;
-        this.delegate = delegate;
-    }
-
-    public void handleWarning(String handle, String message, Location optionalLocation) {
-        if (StringPattern.matches(this.handlePatterns, handle)) {
-            this.delegate.handleWarning(handle, message, optionalLocation);
-        }
-    }
-}
diff --git a/src/org/codehaus/janino/IClass.java b/src/org/codehaus/janino/IClass.java
deleted file mode 100644
index 9bfbd2f..0000000
--- a/src/org/codehaus/janino/IClass.java
+++ /dev/null
@@ -1,819 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.util.*;
-
-/**
- * A simplified equivalent to "java.lang.reflect".
- */
-public abstract class IClass {
-    private static final boolean DEBUG = false;
-
-    public static final IClass VOID    = new PrimitiveIClass(Descriptor.VOID_);
-    public static final IClass BYTE    = new PrimitiveIClass(Descriptor.BYTE_);
-    public static final IClass CHAR    = new PrimitiveIClass(Descriptor.CHAR_);
-    public static final IClass DOUBLE  = new PrimitiveIClass(Descriptor.DOUBLE_);
-    public static final IClass FLOAT   = new PrimitiveIClass(Descriptor.FLOAT_);
-    public static final IClass INT     = new PrimitiveIClass(Descriptor.INT_);
-    public static final IClass LONG    = new PrimitiveIClass(Descriptor.LONG_);
-    public static final IClass SHORT   = new PrimitiveIClass(Descriptor.SHORT_);
-    public static final IClass BOOLEAN = new PrimitiveIClass(Descriptor.BOOLEAN_);
-
-    private static class PrimitiveIClass extends IClass {
-        private final String fieldDescriptor;
-
-        public PrimitiveIClass(String fieldDescriptor) {
-            this.fieldDescriptor = fieldDescriptor;
-        }
-        protected IClass         getComponentType2()         { return null; }
-        protected IClass[]       getDeclaredIClasses2()      { return new IClass[0]; }
-        protected IConstructor[] getDeclaredIConstructors2() { return new IConstructor[0]; }
-        protected IField[]       getDeclaredIFields2()       { return new IField[0]; }
-        protected IMethod[]      getDeclaredIMethods2()      { return new IMethod[0]; }
-        protected IClass         getDeclaringIClass2()       { return null; }
-        protected String         getDescriptor2()            { return this.fieldDescriptor; }
-        protected IClass[]       getInterfaces2()            { return new IClass[0]; }
-        protected IClass         getOuterIClass2()           { return null; }
-        protected IClass         getSuperclass2()            { return null; }
-        public boolean           isAbstract()                { return false; }
-        public boolean           isArray()                   { return false; }
-        public boolean           isFinal()                   { return true; }
-        public boolean           isInterface()               { return false; }
-        public boolean           isPrimitive()               { return true; }
-        public boolean           isPrimitiveNumeric()        { return Descriptor.isPrimitiveNumeric(this.fieldDescriptor); }
-        public Access            getAccess()                 { return Access.PUBLIC; }
-    }
-
-    /**
-     * Returns all the constructors declared by the class represented by the
-     * type. If the class has a default constructor, it is included.
-     * <p>
-     * Returns an array with zero elements for an interface, array, primitive type or
-     * "void".
-     */
-    public final IConstructor[] getDeclaredIConstructors() {
-        if (this.declaredIConstructors == null) {
-            this.declaredIConstructors = this.getDeclaredIConstructors2();
-        }
-        return this.declaredIConstructors;
-    }
-    private IConstructor[] declaredIConstructors = null;
-    protected abstract IConstructor[] getDeclaredIConstructors2();
-
-    /**
-     * Returns the methods of the class or interface (but not inherited
-     * methods).<br>
-     * Returns an empty array for an array, primitive type or "void".
-     */
-    public final IMethod[] getDeclaredIMethods() {
-        if (this.declaredIMethods == null) {
-            this.declaredIMethods = this.getDeclaredIMethods2();
-        }
-        return this.declaredIMethods;
-    }
-    protected IMethod[] declaredIMethods = null;
-    protected abstract IMethod[] getDeclaredIMethods2();
-
-    /**
-     * Returns all methods with the given name declared in the class or
-     * interface (but not inherited methods).<br>
-     * Returns an empty array if no methods with that name are declared.
-     * 
-     * @return an array of {@link IMethod}s that must not be modified
-     */
-    public final IMethod[] getDeclaredIMethods(String methodName) {
-        if (this.declaredIMethodCache == null) {
-            Map m = new HashMap();
-
-            // Fill the map with "IMethod"s and "List"s.
-            IMethod[] dims = this.getDeclaredIMethods();
-            for (int i = 0; i < dims.length; i++) {
-                IMethod dim = dims[i];
-                String mn = dim.getName();
-                Object o = m.get(mn);
-                if (o == null) {
-                    m.put(mn, dim);
-                } else
-                if (o instanceof IMethod) {
-                    List l = new ArrayList();
-                    l.add(o);
-                    l.add(dim);
-                    m.put(mn, l);
-                } else {
-                    ((List) o).add(dim);
-                }
-            }
-
-            // Convert "IMethod"s and "List"s to "IMethod[]"s.
-            for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
-                Map.Entry me = (Map.Entry) it.next();
-                Object v = me.getValue();
-                if (v instanceof IMethod) {
-                    me.setValue(new IMethod[] { (IMethod) v });
-                } else {
-                    List l = (List) v;
-                    me.setValue(l.toArray(new IMethod[l.size()]));
-                }
-            }
-            this.declaredIMethodCache = m;
-        }
-        
-        IMethod[] methods = (IMethod[]) this.declaredIMethodCache.get(methodName);
-        return methods == null ? IClass.NO_IMETHODS : methods;
-    }
-    /*package*/ Map declaredIMethodCache = null; // String methodName => IMethod[]
-
-    /**
-     * Returns all methods declared in the class or interface, its superclasses and its
-     * superinterfaces.<br>
-     * For overridden methods, only the last non-abstract implementation is returned.
-     * 
-     * @return an array of {@link IMethod}s that must not be modified
-     */
-    public final IMethod[] getIMethods() throws CompileException {
-        if (this.iMethodCache == null) {
-            Map m = new HashMap();
-            this.getIMethods(m);
-            Collection iMethods = m.values();
-            this.iMethodCache = (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
-        }
-        return this.iMethodCache;
-    }
-    /*package*/ IMethod[] iMethodCache = null;
-    private void getIMethods(Map result) throws CompileException {
-        IMethod[] ms = this.getDeclaredIMethods();
-        for (int i = 0; i < ms.length; ++i) {
-            IMethod m = ms[i];
-            String key = m.getName() + m.getDescriptor();
-            IMethod m2 = (IMethod) result.get(key);
-            if (m2 == null || m2.isAbstract()) result.put(key, m);
-        }
-        {
-            IClass sc = this.getSuperclass();
-            if (sc != null) sc.getIMethods(result);
-        }
-        {
-            IClass[] iis = this.getInterfaces();
-            for (int i = 0; i < iis.length; ++i) iis[i].getIMethods(result);
-        }
-    }
-
-    public static final IMethod[] NO_IMETHODS = new IMethod[0];
-
-    public final boolean hasIMethod(String methodName, IClass[] parameterTypes) throws CompileException {
-        IMethod[] ims = this.getDeclaredIMethods(methodName);
-        for (int i = 0; i < ims.length; ++i) {
-            IClass[] pts = ims[i].getParameterTypes();
-            if (Arrays.equals(pts, parameterTypes)) return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns the fields of a class or interface (but not inherited
-     * fields).<br>
-     * Returns an empty array for an array, primitive type or "void".
-     */
-    public final IField[] getDeclaredIFields() {
-        if (this.declaredIFields == null) {
-            this.declaredIFields = this.getDeclaredIFields2();
-        }
-        return this.declaredIFields;
-    }
-    public final IField getDeclaredIField(String name) {
-        if(this.declaredIFieldsCache == null) {
-            IField[] fields = getDeclaredIFields();
-            Map m = new HashMap();
-            for(int i = 0; i < fields.length; ++i) {
-                m.put(fields[i].getName(), fields[i]);
-            }
-            this.declaredIFieldsCache = m;
-        }
-        return (IField) this.declaredIFieldsCache.get(name);
-    }
-    
-    protected void clearIFieldCaches() {
-        this.declaredIFields = null;
-        this.declaredIFieldsCache = null;
-    }
-        
-    private Map declaredIFieldsCache = null; // String name => IField
-    private IField[] declaredIFields = null;
-    protected abstract IField[] getDeclaredIFields2();
-
-    /**
-     * Returns the synthetic fields of an anonymous or local class, in
-     * the order in which they are passed to all constructors.
-     */
-    public IField[] getSyntheticIFields() {
-        return new IField[0];
-    }
-
-    /**
-     * Returns the classes and interfaces declared as members of the class
-     * (but not inherited classes and interfaces).<br>
-     * Returns an empty array for an array, primitive type or "void".
-     */
-    public final IClass[] getDeclaredIClasses() throws CompileException {
-        if (this.declaredIClasses == null) {
-            this.declaredIClasses = this.getDeclaredIClasses2();
-        }
-        return this.declaredIClasses;
-    }
-    private IClass[] declaredIClasses = null;
-    protected abstract IClass[] getDeclaredIClasses2() throws CompileException;
-
-    /**
-     * If this class is a member class, return the declaring class, otherwise return
-     * <code>null</code>.
-     */
-    public final IClass getDeclaringIClass() throws CompileException {
-        if (!this.declaringIClassIsCached) {
-            this.declaringIClass = this.getDeclaringIClass2();
-            this.declaringIClassIsCached = true;
-        }
-        return this.declaringIClass;
-    }
-    private boolean declaringIClassIsCached = false;
-    private IClass declaringIClass = null;
-    protected abstract IClass getDeclaringIClass2() throws CompileException;
-
-    /**
-     * The following types have an "outer class":
-     * <ul>
-     *   <li>Anonymous classes declared in a non-static method of a class
-     *   <li>Local classes declared in a non-static method of a class
-     *   <li>Non-static member classes
-     * </ul>
-     */
-    public final IClass getOuterIClass() throws CompileException {
-        if (!this.outerIClassIsCached) {
-            this.outerIClass = this.getOuterIClass2();
-            this.outerIClassIsCached = true;
-        }
-        return this.outerIClass;
-    }
-    private boolean outerIClassIsCached = false;
-    private IClass outerIClass = null;
-    protected abstract IClass getOuterIClass2() throws CompileException;
-
-    /**
-     * Returns the superclass of the class.<br>
-     * Returns "null" for class "Object", interfaces, arrays, primitive types
-     * and "void".
-     */
-    public final IClass getSuperclass() throws CompileException {
-        if (!this.superclassIsCached) {
-            this.superclass = this.getSuperclass2();
-            this.superclassIsCached = true;
-            if (this.superclass != null && this.superclass.isSubclassOf(this)) throw new CompileException("Class circularity detected for \"" + Descriptor.toClassName(this.getDescriptor()) + "\"", null);
-        }
-        return this.superclass;
-    }
-    private boolean superclassIsCached = false;
-    private IClass superclass = null;
-    protected abstract IClass getSuperclass2() throws CompileException;
-
-    public abstract Access getAccess();
-
-    /**
-     * Whether subclassing is allowed (JVMS 4.1 access_flags)
-     * @return <code>true</code> if subclassing is prohibited
-     */
-    public abstract boolean isFinal();
-
-    /**
-     * Returns the interfaces implemented by the class.<br>
-     * Returns the superinterfaces of the interface.<br>
-     * Returns "Cloneable" and "Serializable" for arrays.<br>
-     * Returns an empty array for primitive types and "void".
-     */
-    public final IClass[] getInterfaces() throws CompileException {
-        if (this.interfaces == null) {
-            this.interfaces = this.getInterfaces2();
-            for (int i = 0; i < this.interfaces.length; ++i) {
-                if (this.interfaces[i].implementsInterface(this)) throw new CompileException("Interface circularity detected for \"" + Descriptor.toClassName(this.getDescriptor()) + "\"", null);
-            }
-        }
-        return this.interfaces;
-    }
-    private IClass[] interfaces = null;
-    protected abstract IClass[] getInterfaces2() throws CompileException;
-
-    /**
-     * Whether the class may be instantiated (JVMS 4.1 access_flags)
-     * @return <code>true</code> if instantiation is prohibited
-     */
-    public abstract boolean isAbstract();
-
-    /**
-     * Returns the field descriptor for the type as defined by JVMS 4.3.2.
-     */
-    public final String getDescriptor() {
-        if (this.descriptor == null) {
-            this.descriptor = this.getDescriptor2();
-        }
-        return this.descriptor;
-    }
-    private String descriptor = null;
-    protected abstract String getDescriptor2();
-
-    /**
-     * Convenience method that determines the field descriptors of an array of {@link IClass}es.
-     * @see #getDescriptor()
-     */
-    public static String[] getDescriptors(IClass[] iClasses) {
-        String[] descriptors = new String[iClasses.length];
-        for (int i = 0; i < iClasses.length; ++i) descriptors[i] = iClasses[i].getDescriptor();
-        return descriptors;
-    }
-
-    /**
-     * Returns "true" if this type represents an interface.
-     */
-    public abstract boolean isInterface();
-
-    /**
-     * Returns "true" if this type represents an array.
-     */
-    public abstract boolean isArray();
-
-    /**
-     * Returns "true" if this type represents a primitive type or "void".
-     */
-    public abstract boolean isPrimitive();
-
-    /**
-     * Returns "true" if this type represents "byte", "short", "int", "long",
-     * "char", "float" or "double".
-     */
-    public abstract boolean isPrimitiveNumeric();
-
-    /**
-     * Returns the component type of the array.<br>
-     * Returns "null" for classes, interfaces, primitive types and "void".
-     */
-    public final IClass getComponentType() {
-        if (!this.componentTypeIsCached) {
-            this.componentType = this.getComponentType2();
-            this.componentTypeIsCached = true;
-        }
-        return this.componentType;
-    }
-    private boolean componentTypeIsCached = false;
-    private IClass componentType = null;
-    protected abstract IClass getComponentType2();
-
-    /**
-     * Returns a string representation for this object.
-     */
-    public String toString() { return Descriptor.toClassName(this.getDescriptor()); }
-
-    /**
-     * Determine if "this" is assignable from "that". This is true if "this"
-     * is identical with "that" (JLS2 5.1.1), or if "that" is
-     * widening-primitive-convertible to "this" (JLS2 5.1.2), or if "that" is
-     * widening-reference-convertible to "this" (JLS2 5.1.4).
-     */
-    public boolean isAssignableFrom(IClass that) throws CompileException {
-
-        // Identity conversion, JLS2 5.1.1
-        if (this == that) return true;
-
-        // Widening primitive conversion, JLS2 5.1.2
-        {
-            String ds = that.getDescriptor() + this.getDescriptor();
-            if (ds.length() == 2 && IClass.PRIMITIVE_WIDENING_CONVERSIONS.contains(ds)) return true;
-        }
-
-        // Widening reference conversion, JLS2 5.1.4
-        {
-
-            // JLS 5.1.4.1: Target type is superclass of source class type.
-            if (that.isSubclassOf(this)) return true;
-    
-            // JLS 5.1.4.2: Source class type implements target interface type.
-            // JLS 5.1.4.4: Source interface type implements target interface type.
-            if (that.implementsInterface(this)) return true;
-    
-            // JLS 5.1.4.3 Convert "null" literal to any reference type.
-            if (that == IClass.VOID && !this.isPrimitive()) return true;
-    
-            // JLS 5.1.4.5: From any interface to type "Object".
-            if (that.isInterface() && this.getDescriptor().equals(Descriptor.OBJECT)) return true;
-    
-            if (that.isArray()) {
-    
-                // JLS 5.1.4.6: From any array type to type "Object".
-                if (this.getDescriptor().equals(Descriptor.OBJECT)) return true;
-    
-                // JLS 5.1.4.7: From any array type to type "Cloneable".
-                if (this.getDescriptor().equals(Descriptor.CLONEABLE)) return true;
-    
-                // JLS 5.1.4.8: From any array type to type "java.io.Serializable".
-                if (this.getDescriptor().equals(Descriptor.SERIALIZABLE)) return true;
-    
-                // JLS 5.1.4.9: From SC[] to TC[] while SC if widening reference convertible to TC.
-                if (this.isArray()) {
-                    IClass thisCT = this.getComponentType();
-                    IClass thatCT = that.getComponentType();
-                    if (!thisCT.isPrimitive() && thisCT.isAssignableFrom(thatCT)) return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private static final Set PRIMITIVE_WIDENING_CONVERSIONS = new HashSet();
-    static {
-        String[] pwcs = new String[] {
-            Descriptor.BYTE_  + Descriptor.SHORT_,
-
-            Descriptor.BYTE_  + Descriptor.INT_,
-            Descriptor.SHORT_ + Descriptor.INT_,
-            Descriptor.CHAR_  + Descriptor.INT_,
-    
-            Descriptor.BYTE_  + Descriptor.LONG_,
-            Descriptor.SHORT_ + Descriptor.LONG_,
-            Descriptor.CHAR_  + Descriptor.LONG_,
-            Descriptor.INT_   + Descriptor.LONG_,
-    
-            Descriptor.BYTE_  + Descriptor.FLOAT_,
-            Descriptor.SHORT_ + Descriptor.FLOAT_,
-            Descriptor.CHAR_  + Descriptor.FLOAT_,
-            Descriptor.INT_   + Descriptor.FLOAT_,
-    
-            Descriptor.LONG_  + Descriptor.FLOAT_,
-    
-            Descriptor.BYTE_  + Descriptor.DOUBLE_,
-            Descriptor.SHORT_ + Descriptor.DOUBLE_,
-            Descriptor.CHAR_  + Descriptor.DOUBLE_,
-            Descriptor.INT_   + Descriptor.DOUBLE_,
-    
-            Descriptor.LONG_  + Descriptor.DOUBLE_,
-    
-            Descriptor.FLOAT_ + Descriptor.DOUBLE_,
-        };
-        for (int i = 0; i < pwcs.length; ++i) IClass.PRIMITIVE_WIDENING_CONVERSIONS.add(pwcs[i]);
-    }
-
-    /**
-     * Returns <code>true</code> if this class is an immediate or non-immediate
-     * subclass of <code>that</code> class.
-     */
-    public boolean isSubclassOf(IClass that) throws CompileException {
-        for (IClass sc = this.getSuperclass(); sc != null; sc = sc.getSuperclass()) {
-            if (sc == that) return true;
-        }
-        return false;
-    }
-
-    /**
-     * If <code>this</code> represents a class: Return <code>true</code> if this class
-     * directly or indirectly implements <code>that</code> interface.
-     * <p>
-     * If <code>this</code> represents an interface: Return <code>true</code> if this
-     * interface directly or indirectly extends <code>that</code> interface.
-     */
-    public boolean implementsInterface(IClass that) throws CompileException {
-        for (IClass c = this; c != null; c = c.getSuperclass()) {
-            IClass[] tis = c.getInterfaces();
-            for (int i = 0; i < tis.length; ++i) {
-                IClass ti = tis[i];
-                if (ti == that || ti.implementsInterface(that)) return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Get an {@link IClass} that represents an n-dimensional array of this type.
-     *
-     * @param n dimension count
-     * @param objectType Required because the superclass of an array class is {@link Object} by definition
-     */
-    public IClass getArrayIClass(int n, IClass objectType) {
-        IClass result = this;
-        for (int i = 0; i < n; ++i) result = result.getArrayIClass(objectType);
-        return result;
-    }
-
-    /**
-     * Get an {@link IClass} that represents an array of this type.
-     *
-     * @param objectType Required because the superclass of an array class is {@link Object} by definition
-     */
-    public IClass getArrayIClass(IClass objectType) {
-        if (this.arrayIClass == null) this.arrayIClass = this.getArrayIClass2(objectType);
-        return this.arrayIClass;
-    }
-    private IClass arrayIClass = null;
-
-    private IClass getArrayIClass2(final IClass objectType) {
-        final IClass componentType = this;
-        return new IClass() {
-            public IClass.IConstructor[] getDeclaredIConstructors2() { return new IClass.IConstructor[0]; }
-
-            // Special trickery #17: Arrays override "Object.clone()", but without "throws
-            // CloneNotSupportedException"!
-            public IClass.IMethod[]      getDeclaredIMethods2() {
-                return new IClass.IMethod[] {
-                    new IMethod() {
-                        public String   getName() { return "clone"; }
-                        public IClass   getReturnType() { return objectType /*ot*/; }
-                        public boolean  isAbstract() { return false; }
-                        public boolean  isStatic() { return false; }
-                        public Access   getAccess() { return Access.PUBLIC; }
-                        public IClass[] getParameterTypes() { return new IClass[0]; }
-                        public IClass[] getThrownExceptions() { return new IClass[0]; }
-                    }
-                };
-            }
-            public IClass.IField[]       getDeclaredIFields2() { return new IClass.IField[0]; }
-            public IClass[]              getDeclaredIClasses2() { return new IClass[0]; }
-            public IClass                getDeclaringIClass2() { return null; }
-            public IClass                getOuterIClass2() { return null; }
-            public IClass                getSuperclass2() { return objectType; }
-            public IClass[]              getInterfaces2() { return new IClass[0]; }
-            public String                getDescriptor2() { return '[' + componentType.getDescriptor(); }
-            public Access                getAccess() { return componentType.getAccess(); }
-            public boolean               isFinal() { return true; }
-            public boolean               isInterface() { return false; }
-            public boolean               isAbstract() { return false; }
-            public boolean               isArray() { return true; }
-            public boolean               isPrimitive() { return false; }
-            public boolean               isPrimitiveNumeric() { return false; }
-            public IClass                getComponentType2() { return componentType; }
-
-            public String toString() { return componentType.toString() + "[]"; }
-        };
-    }
-
-    /**
-     * If <code>optionalName</code> is <code>null</code>, find all {@link IClass}es visible in the
-     * scope of the current class.
-     * <p>
-     * If <code>optionalName</code> is not <code>null</code>, find the member {@link IClass}es
-     * that has the given name. If the name is ambiguous (i.e. if more than one superclass,
-     * interface of enclosing type declares a type with that name), then the size of the
-     * returned array is greater than one.
-     * <p>
-     * Examines superclasses, interfaces and enclosing type declarations.
-     * @return an array of {@link IClass}es in unspecified order, possibly of length zero
-     */
-    IClass[] findMemberType(String optionalName) throws CompileException {
-        IClass[] res = (IClass[]) this.memberTypeCache.get(optionalName);
-        if (res == null) {
-
-            // Notice: A type may be added multiply to the result set because we are in its scope
-            // multiply. E.g. the type is a member of a superclass AND a member of an enclosing type.
-            Set s = new HashSet(); // IClass
-            this.findMemberType(optionalName, s);
-            res = s.isEmpty() ? IClass.ZERO_ICLASSES : (IClass[]) s.toArray(new IClass[s.size()]);
-    
-            this.memberTypeCache.put(optionalName, res);
-        }
-
-        return res;
-    }
-    private final Map memberTypeCache = new HashMap(); // String name => IClass[]
-    private static final IClass[] ZERO_ICLASSES = new IClass[0];
-    private void findMemberType(String optionalName, Collection result) throws CompileException {
-
-        // Search for a type with the given name in the current class.
-        IClass[] memberTypes = this.getDeclaredIClasses();
-        if (optionalName == null) {
-            result.addAll(Arrays.asList(memberTypes));
-        } else {
-            String memberDescriptor = Descriptor.fromClassName(Descriptor.toClassName(this.getDescriptor()) + '$' + optionalName);
-            for (int i = 0; i < memberTypes.length; ++i) {
-                final IClass mt = memberTypes[i];
-                if (mt.getDescriptor().equals(memberDescriptor)) {
-                    result.add(mt);
-                    return;
-                } 
-            }
-        }
-        
-        // Examine superclass.
-        {
-            IClass superclass = this.getSuperclass();
-            if (superclass != null) superclass.findMemberType(optionalName, result); 
-        }
-        
-        // Examine interfaces.
-        {
-            IClass[] ifs = this.getInterfaces();
-            for (int i = 0; i < ifs.length; ++i) ifs[i].findMemberType(optionalName, result);
-        }
-
-        // Examine enclosing type declarations.
-        {
-            IClass declaringIClass = this.getDeclaringIClass();
-            IClass outerIClass = this.getOuterIClass();
-            if (declaringIClass != null) {
-                declaringIClass.findMemberType(optionalName, result);
-            }
-            if (outerIClass != null && outerIClass != declaringIClass) {
-                outerIClass.findMemberType(optionalName, result);
-            }
-        }
-    }
-
-    public interface IMember {
-
-        /**
-         * @return One of {@link Access#PRIVATE}, {@link Access#PROTECTED},
-         * {@link Access#DEFAULT} and {@link Access#PUBLIC}.
-         */
-        Access getAccess();
-
-        /**
-         * Returns the {@link IClass} that declares this {@link IClass.IMember}.
-         */
-        IClass getDeclaringIClass();
-    }
-
-    public abstract class IInvocable implements IMember {
-
-        // Implement IMember.
-        public abstract Access   getAccess();
-        public IClass            getDeclaringIClass() { return IClass.this; }
-        public abstract IClass[] getParameterTypes() throws CompileException;
-        public abstract String   getDescriptor() throws CompileException;
-        public abstract IClass[] getThrownExceptions() throws CompileException;
-
-        public boolean isMoreSpecificThan(IInvocable that) throws CompileException {
-            if (IClass.DEBUG) System.out.print("\"" + this + "\".isMoreSpecificThan(\"" + that + "\") => ");
-
-            // The following case is tricky: JLS2 says that the invocation is AMBIGUOUS, but only
-            // JAVAC 1.2 issues an error; JAVAC 1.4.1, 1.5.0 and 1.6.0 obviously ignore the declaring
-            // type and invoke "A.meth(String)".
-            // JLS3 is not clear about this. For compatibility with JAVA 1.4.1, 1.5.0 and 1.6.0,
-            // JANINO also ignores the declaring type.
-            //
-            // See also JANINO-79 and JLS2Tests / 15.12.2.2
-            if (false) {
-                if (!that.getDeclaringIClass().isAssignableFrom(this.getDeclaringIClass())) {
-                    if (IClass.DEBUG) System.out.println("falsE");
-                    return false;
-                }
-            }
-
-            IClass[] thisParameterTypes = this.getParameterTypes();
-            IClass[] thatParameterTypes = that.getParameterTypes();
-            int i;
-            for (i = 0; i < thisParameterTypes.length; ++i) {
-                if (!thatParameterTypes[i].isAssignableFrom(thisParameterTypes[i])) {
-                    if (IClass.DEBUG) System.out.println("false");
-                    return false;
-                }
-            }
-            if (IClass.DEBUG) System.out.println("true");
-            return !Arrays.equals(thisParameterTypes, thatParameterTypes);
-        }
-        public boolean isLessSpecificThan(IInvocable that) throws CompileException {
-            return that.isMoreSpecificThan(this);
-        }
-        public abstract String toString();
-    }
-    public abstract class IConstructor extends IInvocable {
-
-        /**
-         * Opposed to {@link java.lang.reflect.Constructor#getParameterTypes()}, the
-         * return value of this method does not include the optionally leading "synthetic
-         * parameters".
-         */
-        public abstract IClass[] getParameterTypes() throws CompileException;
-
-        /**
-         * Opposed to {@link #getParameterTypes()}, the method descriptor returned by this
-         * method does include the optionally leading synthetic parameters.
-         */
-        public String getDescriptor() throws CompileException {
-            IClass[] parameterTypes = this.getParameterTypes();
-
-            IClass outerIClass = IClass.this.getOuterIClass();
-            if (outerIClass != null) {
-                IClass[] tmp = new IClass[parameterTypes.length + 1];
-                tmp[0] = outerIClass;
-                System.arraycopy(parameterTypes, 0, tmp, 1, parameterTypes.length);
-                parameterTypes = tmp;
-            }
-
-            return new MethodDescriptor(IClass.getDescriptors(parameterTypes), Descriptor.VOID_).toString();
-        }
-        public String toString() {
-            StringBuffer sb = new StringBuffer(this.getDeclaringIClass().toString());
-            sb.append('(');
-            try {
-                IClass[] parameterTypes = this.getParameterTypes();
-                for (int i = 0; i < parameterTypes.length; ++i) {
-                    if (i > 0) sb.append(", ");
-                    sb.append(parameterTypes[i].toString());
-                }
-            } catch (CompileException ex) {
-                sb.append("<invalid type>");
-            }
-            sb.append(')');
-            return sb.toString();
-        }
-    }
-    public abstract class IMethod extends IInvocable {
-        public abstract boolean isStatic();
-        public abstract boolean isAbstract();
-        public abstract IClass  getReturnType() throws CompileException;
-        public abstract String  getName();
-        public String getDescriptor() throws CompileException {
-            return new MethodDescriptor(
-                IClass.getDescriptors(this.getParameterTypes()),
-                this.getReturnType().getDescriptor()
-            ).toString();
-        }
-        public String toString() {
-            StringBuffer sb = new StringBuffer();
-            try {
-                sb.append(this.getReturnType().toString());
-            } catch (CompileException ex) {
-                sb.append("<invalid type>");
-            }
-            sb.append(' ');
-            sb.append(this.getDeclaringIClass().toString());
-            sb.append('.');
-            sb.append(this.getName());
-            sb.append('(');
-            try {
-                IClass[] parameterTypes = this.getParameterTypes();
-                for (int i = 0; i < parameterTypes.length; ++i) {
-                    if (i > 0) sb.append(", ");
-                    sb.append(parameterTypes[i].toString());
-                }
-            } catch (CompileException ex) {
-                sb.append("<invalid type>");
-            }
-            sb.append(')');
-            try {
-                IClass[] tes = this.getThrownExceptions();
-                if (tes.length > 0) {
-                    sb.append(" throws ").append(tes[0]);
-                    for (int i = 1; i < tes.length; ++i) sb.append(", ").append(tes[i]);
-                }
-            } catch (CompileException ex) {
-                sb.append("<invalid thrown exception type>");
-            }
-            return sb.toString();
-        }
-    }
-    public abstract class IField implements IMember {
-
-        // Implement IMember.
-        public abstract Access  getAccess();
-        public IClass           getDeclaringIClass() { return IClass.this; }
-
-        public abstract boolean isStatic();
-        public abstract IClass  getType() throws CompileException;
-        public abstract String  getName();
-        public String           getDescriptor() throws CompileException { return this.getType().getDescriptor(); }
-
-        /**
-         * Returns the value of the field if it is a compile-time constant
-         * value, i.e. the field is FINAL and its initializer is a constant
-         * expression (JLS2 15.28, bullet 12).
-         */
-        public abstract Object  getConstantValue() throws CompileException;
-        public String           toString() { return this.getDeclaringIClass().toString() + "." + this.getName(); }
-    }
-}
diff --git a/src/org/codehaus/janino/IClassLoader.java b/src/org/codehaus/janino/IClassLoader.java
deleted file mode 100644
index 9f7df5e..0000000
--- a/src/org/codehaus/janino/IClassLoader.java
+++ /dev/null
@@ -1,227 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.util.*;
-
-/**
- * Loads an {@link IClass} by type name.
- */
-public abstract class IClassLoader {
-    private static final boolean DEBUG = false;
-
-    public IClass OBJECT;
-    public IClass STRING;
-    public IClass CLASS;
-    public IClass THROWABLE;
-    public IClass RUNTIME_EXCEPTION;
-    public IClass ERROR;
-    public IClass CLONEABLE;
-    public IClass SERIALIZABLE;
-    public IClass BOOLEAN;
-    public IClass BYTE;
-    public IClass CHARACTER;
-    public IClass SHORT;
-    public IClass INTEGER;
-    public IClass LONG;
-    public IClass FLOAT;
-    public IClass DOUBLE;
-
-    public IClassLoader(IClassLoader optionalParentIClassLoader) {
-        this.optionalParentIClassLoader = optionalParentIClassLoader;
-    }
-
-    /**
-     * This method must be called by the constructor of the directly derived
-     * class. (The reason being is that this method invokes abstract
-     * {@link #loadIClass(String)} which will not work until the implementing
-     * class is constructed.)
-     */
-    protected final void postConstruct() {
-        try {
-            this.OBJECT            = this.loadIClass(Descriptor.OBJECT);
-            this.STRING            = this.loadIClass(Descriptor.STRING);
-            this.CLASS             = this.loadIClass(Descriptor.CLASS);
-            this.THROWABLE         = this.loadIClass(Descriptor.THROWABLE);
-            this.RUNTIME_EXCEPTION = this.loadIClass(Descriptor.RUNTIME_EXCEPTION);
-            this.ERROR             = this.loadIClass(Descriptor.ERROR);
-            this.CLONEABLE         = this.loadIClass(Descriptor.CLONEABLE);
-            this.SERIALIZABLE      = this.loadIClass(Descriptor.SERIALIZABLE);
-            this.BOOLEAN           = this.loadIClass(Descriptor.BOOLEAN);
-            this.BYTE              = this.loadIClass(Descriptor.BYTE);
-            this.CHARACTER         = this.loadIClass(Descriptor.CHARACTER);
-            this.SHORT             = this.loadIClass(Descriptor.SHORT);
-            this.INTEGER           = this.loadIClass(Descriptor.INTEGER);
-            this.LONG              = this.loadIClass(Descriptor.LONG);
-            this.FLOAT             = this.loadIClass(Descriptor.FLOAT);
-            this.DOUBLE            = this.loadIClass(Descriptor.DOUBLE);
-        } catch (ClassNotFoundException e) {
-            throw new RuntimeException("Cannot load simple types");
-        }
-    }
-
-    /**
-     * Get an {@link IClass} by field descriptor.
-     *
-     * @return <code>null</code> if an {@link IClass} could not be loaded
-     * @throws {@link ClassNotFoundException} if an exception was raised while loading the {@link IClass}
-     */
-    public final IClass loadIClass(String fieldDescriptor) throws ClassNotFoundException {
-        if (IClassLoader.DEBUG) System.out.println(this + ": Load type \"" + fieldDescriptor + "\"");
-
-        if (Descriptor.isPrimitive(fieldDescriptor)) {
-            return (
-                fieldDescriptor.equals(Descriptor.VOID_   ) ? IClass.VOID    :
-                fieldDescriptor.equals(Descriptor.BYTE_   ) ? IClass.BYTE    :
-                fieldDescriptor.equals(Descriptor.CHAR_   ) ? IClass.CHAR    :
-                fieldDescriptor.equals(Descriptor.DOUBLE_ ) ? IClass.DOUBLE  :
-                fieldDescriptor.equals(Descriptor.FLOAT_  ) ? IClass.FLOAT   :
-                fieldDescriptor.equals(Descriptor.INT_    ) ? IClass.INT     :
-                fieldDescriptor.equals(Descriptor.LONG_   ) ? IClass.LONG    :
-                fieldDescriptor.equals(Descriptor.SHORT_  ) ? IClass.SHORT   :
-                fieldDescriptor.equals(Descriptor.BOOLEAN_) ? IClass.BOOLEAN :
-                null
-            );
-        }
-
-        // Ask parent IClassLoader first.
-        if (this.optionalParentIClassLoader != null) {
-            IClass res = this.optionalParentIClassLoader.loadIClass(fieldDescriptor);
-            if (res != null) return res;
-        }
-
-        // We need to synchronize here because "unloadableIClasses" and
-        // "loadedIClasses" are unsynchronized containers.
-        IClass result;
-        synchronized (this) {
-
-            // Class could not be loaded before?
-            if (this.unloadableIClasses.contains(fieldDescriptor)) return null;
-
-            // Class already loaded?
-            result = (IClass) this.loadedIClasses.get(fieldDescriptor);
-            if (result != null) return result;
-
-            // Special handling for array types.
-            if (Descriptor.isArrayReference(fieldDescriptor)) {
-
-                // Load the component type.
-                IClass componentIClass = this.loadIClass(
-                    Descriptor.getComponentDescriptor(fieldDescriptor)
-                );
-                if (componentIClass == null) return null;
-
-                // Now get and define the array type.
-                IClass arrayIClass = componentIClass.getArrayIClass(this.OBJECT);
-                this.loadedIClasses.put(fieldDescriptor, arrayIClass);
-                return arrayIClass;
-            }
-
-            // Load the class through the {@link #findIClass(String)} method implemented by the
-            // derived class.
-            if (IClassLoader.DEBUG) System.out.println("call IClassLoader.findIClass(\"" + fieldDescriptor + "\")");
-            result = this.findIClass(fieldDescriptor);
-            if (result == null) {
-                this.unloadableIClasses.add(fieldDescriptor);
-                return null;
-            }
-        }
-
-        if (!result.getDescriptor().equalsIgnoreCase(fieldDescriptor)) throw new RuntimeException("\"findIClass()\" returned \"" + result.getDescriptor() + "\" instead of \"" + fieldDescriptor + "\"");
-
-        if (IClassLoader.DEBUG) System.out.println(this + ": Loaded type \"" + fieldDescriptor + "\" as " + result);
-
-        return result;
-    }
-
-    /**
-     * Find a new {@link IClass} by descriptor; return <code>null</code> if a class
-     * for that <code>descriptor</code> could not be found.
-     * <p>
-     * Similar {@link java.lang.ClassLoader#findClass(java.lang.String)}, this method
-     * must
-     * <ul>
-     *   <li>Get an {@link IClass} object from somewhere for the given type
-     *   <li>Call {@link #defineIClass(IClass)} with that {@link IClass} object as
-     *       the argument
-     *   <li>Return the {@link IClass} object
-     * </ul>
-     * <p>
-     * The format of a <code>descriptor</code> is defined in JVMS 4.3.2. Typical
-     * descriptors are:
-     * <ul>
-     *   <li><code>I</code> (Integer)
-     *   <li><code>Lpkg1/pkg2/Cls;</code> (Class declared in package)
-     *   <li><code>Lpkg1/pkg2/Outer$Inner;</code> Member class
-     * </ul>
-     * Notice that this method is never called for array types.
-     * <p>
-     * Notice that this method is never called from more than one thread at a time.
-     * In other words, implementations of this method need not be synchronized.
-     *
-     * @return <code>null</code> if a class with that descriptor could not be found
-     * @throws ClassNotFoundException if an exception was raised while loading the class
-     */
-    protected abstract IClass findIClass(String descriptor) throws ClassNotFoundException;
-
-    /**
-     * Define an {@link IClass} in the context of this {@link IClassLoader}.
-     * If an {@link IClass} with that descriptor already exists, a
-     * {@link RuntimeException} is thrown.
-     * <p>
-     * This method should only be called from an implementation of
-     * {@link #findIClass(String)}.
-     * 
-     * @throws RuntimeException A different {@link IClass} object is already defined for this type
-     */
-    protected final void defineIClass(IClass iClass) {
-        String descriptor = iClass.getDescriptor();
-
-        // Already defined?
-        IClass loadedIClass = (IClass) this.loadedIClasses.get(descriptor);
-        if (loadedIClass != null) {
-            if (loadedIClass == iClass) return;
-            throw new RuntimeException("Non-identical definition of IClass \"" + descriptor + "\"");
-        }
-
-        // Define.
-        this.loadedIClasses.put(descriptor, iClass);
-        if (IClassLoader.DEBUG) System.out.println(this + ": Defined type \"" + descriptor + "\"");
-    }
-
-    private final IClassLoader optionalParentIClassLoader;
-    private final Map          loadedIClasses = new HashMap(); // String descriptor => IClass
-    private final Set          unloadableIClasses = new HashSet(); // String descriptor
-}
diff --git a/src/org/codehaus/janino/Java.java b/src/org/codehaus/janino/Java.java
deleted file mode 100644
index f2a7aa7..0000000
--- a/src/org/codehaus/janino/Java.java
+++ /dev/null
@@ -1,2924 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.codehaus.janino.util.Traverser;
-import org.codehaus.janino.util.iterator.ReverseListIterator;
-
-
-/**
- * This wrapper class defines classes that represent the elements of the
- * Java<sup>TM</sup> programming language.
- * <p>
- * Notices:
- * <ul>
- *   <li>"JLS1" refers to <a href="http://java.sun.com/docs/books/jls/first_edition/html/index.html">"The Java<sup>TM</sup> Language Specification, First Edition"</a>.
- *   <li>"JLS" or "JLS2" refers to <a href="http://java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html">"The Java<sup>TM</sup> Language Specification, Second Edition"</a>.
- * </ul>
- */
-
-public class Java {
-    private Java() {} // Don't instantiate me.
-
-    public interface Scope {
-        public Scope getEnclosingScope();
-    }
-
-    /**
-     * This interface is implemented by objects which are associated with a
-     * location in the source code.
-     */
-    public interface Locatable {
-        public Location getLocation();
-
-        /**
-         * Throw a {@link Parser.ParseException} with the given message and this
-         * object's location.
-         * 
-         * @param message The message to report
-         */
-        public void throwParseException(String message) throws Parser.ParseException;
-    }
-    public static abstract class Located implements Locatable {
-        private final Location location;
-
-        protected Located(Location location) {
-            this.location = location;
-        }
-
-        // Implement "Locatable".
-
-        public Location getLocation() { return this.location; }
-        public void throwParseException(String message) throws Parser.ParseException {
-            throw new Parser.ParseException(message, this.location);
-        }
-    }
-
-    /**
-     * Holds the result of {@link Parser#parseCompilationUnit}.
-     */
-    public static final class CompilationUnit implements Scope {
-        public /*final*/          String optionalFileName;
-        public PackageDeclaration optionalPackageDeclaration    = null;
-        public final List         importDeclarations            = new ArrayList(); // ImportDeclaration
-        public final List         packageMemberTypeDeclarations = new ArrayList(); // PackageMemberTypeDeclaration
-
-        public CompilationUnit(String optionalFileName) {
-            this.optionalFileName = optionalFileName;
-        }
-
-        // Implement "Scope".
-        public Scope getEnclosingScope() { throw new RuntimeException("A compilation unit has no enclosing scope"); }
-
-        public void setPackageDeclaration(PackageDeclaration packageDeclaration) {
-            if (this.optionalPackageDeclaration != null) throw new RuntimeException("Re-setting package declaration");
-            this.optionalPackageDeclaration = packageDeclaration;
-        }
-
-        public void addImportDeclaration(CompilationUnit.ImportDeclaration id) {
-
-            // Conflicting imports are checked in UnitCompiler, not here.
-            this.importDeclarations.add(id);
-        }
-
-        public void addPackageMemberTypeDeclaration(PackageMemberTypeDeclaration pmtd) {
-            this.packageMemberTypeDeclarations.add(pmtd);
-            pmtd.setDeclaringCompilationUnit(this);
-        }
-
-        /**
-         * Get all classes and interfaces declared in this compilation unit.
-         */
-        public PackageMemberTypeDeclaration[] getPackageMemberTypeDeclarations() {
-            return (PackageMemberTypeDeclaration[]) this.packageMemberTypeDeclarations.toArray(new PackageMemberTypeDeclaration[this.packageMemberTypeDeclarations.size()]);
-        }
-
-        /**
-         * Return the package member class or interface declared with the given name.
-         * @param name Declared (i.e. not the fully qualified) name
-         * @return <code>null</code> if a package member type with that name is not declared in this compilation unit
-         */
-        public PackageMemberTypeDeclaration getPackageMemberTypeDeclaration(String name) {
-            for (Iterator it = this.packageMemberTypeDeclarations.iterator(); it.hasNext();) {
-                PackageMemberTypeDeclaration pmtd = (PackageMemberTypeDeclaration) it.next();
-                if (pmtd.getName().equals(name)) return pmtd;
-            }
-            return null;
-        }
-
-        /**
-         * Represents a single type import declaration like<pre>
-         *     import java.util.Map;</pre>
-         */
-        public static class SingleTypeImportDeclaration extends ImportDeclaration {
-            public final String[] identifiers;
-        
-            public SingleTypeImportDeclaration(Location location, String[] identifiers) {
-                super(location);
-                this.identifiers = identifiers;
-            }
-            public final void accept(Visitor.ImportVisitor visitor) { visitor.visitSingleTypeImportDeclaration(this); }
-            public String toString() {
-                return "import " + Java.join(this.identifiers, ".") + ';';
-            }
-        }
-
-        /**
-         * Represents a type-import-on-demand declaration like<pre>
-         *     import java.util.*;</pre>
-         */
-        public static class TypeImportOnDemandDeclaration extends ImportDeclaration {
-            public final String[] identifiers;
-        
-            public TypeImportOnDemandDeclaration(Location location, String[] identifiers) {
-                super(location);
-                this.identifiers = identifiers;
-            }
-            public final void accept(Visitor.ImportVisitor visitor) { visitor.visitTypeImportOnDemandDeclaration(this); }
-            public String toString() {
-                return "import " + Java.join(this.identifiers, ".") + ".*;";
-            }
-        }
-
-        /**
-         * Represents a single static import declaration like<pre>
-         *     import java.util.Collections.EMPTY_MAP;</pre>
-         */
-        public static class SingleStaticImportDeclaration extends ImportDeclaration {
-            public final String[] identifiers;
-            
-            public SingleStaticImportDeclaration(Location location, String[] identifiers) {
-                super(location);
-                this.identifiers = identifiers;
-            }
-            public final void accept(Visitor.ImportVisitor visitor) { visitor.visitSingleStaticImportDeclaration(this); }
-        }
-        
-        /**
-         * Represents a static-import-on-demand declaration like<pre>
-         *     import java.util.Collections.*;</pre>
-         */
-        public static class StaticImportOnDemandDeclaration extends ImportDeclaration {
-            public final String[] identifiers;
-            
-            public StaticImportOnDemandDeclaration(Location location, String[] identifiers) {
-                super(location);
-                this.identifiers = identifiers;
-            }
-            public final void accept(Visitor.ImportVisitor visitor) { visitor.visitStaticImportOnDemandDeclaration(this); }
-        }
-        
-        public abstract static class ImportDeclaration extends Java.Located {
-            public ImportDeclaration(Location location) {
-                super(location);
-            }
-            public abstract void accept(Visitor.ImportVisitor visitor);
-        }
-    }
-
-    /**
-     * Represents a package declaration like<pre>
-     *     package com.acme.tools;</pre>
-     */
-    public static class PackageDeclaration extends Located {
-        public final String packageName;
-
-        public PackageDeclaration(Location location, String packageName) {
-            super(location);
-            this.packageName = packageName;
-        }
-    }
-
-    public interface TypeDeclaration extends Locatable, Scope {
-
-        /**
-         * Return the member type with the given name.
-         * @return <code>null</code> if a member type with that name is not declared
-         */
-        MemberTypeDeclaration getMemberTypeDeclaration(String name);
-
-        /**
-         * Determine the effective class name, e.g. "pkg.Outer$Inner".
-         */
-        String getClassName();
-
-        /**
-         * Creates a unique name for a local class or interface.
-         */
-        String createLocalTypeName(String localTypeName);
-
-        /**
-         * Creates a unique name for an anonymous class.
-         */
-        String createAnonymousClassName();
-
-        void accept(Visitor.TypeDeclarationVisitor visitor);
-    }
-
-    public interface DocCommentable {
-
-        /**
-         * Returns the doc comment of the object or <code>null</code>.
-         */
-        public String getDocComment();
-
-        /**
-         * Returns <code>true</code> if the object has a doc comment and
-         * the <code>&#64#deprecated</code> tag appears in the doc
-         * comment.
-         */
-        public boolean hasDeprecatedDocTag();
-    }
-
-    /**
-     * Represents a class or interface declaration on compilation unit level. These are called
-     * "package member types" because they are immediate members of a package, e.g.
-     * "java.lang.String".
-     */
-    public interface PackageMemberTypeDeclaration extends NamedTypeDeclaration {
-        void setDeclaringCompilationUnit(CompilationUnit declaringCompilationUnit);
-        CompilationUnit getDeclaringCompilationUnit();
-    }
-
-    /**
-     * Represents a class or interface declaration where the immediately enclosing scope is
-     * another class or interface declaration.
-     */
-    public interface MemberTypeDeclaration extends NamedTypeDeclaration, TypeBodyDeclaration {
-    }
-
-    /**
-     * Represents the declaration of a class or an interface that has a name. (All type
-     * declarations are named, except for anonymous classes.)
-     */
-    public interface NamedTypeDeclaration extends TypeDeclaration {
-
-        /**
-         * Returns the declared (not the fully qualified) name of the class or interface.
-         */
-        public String getName();
-    }
-
-    /**
-     * Represents the declaration of an inner class, i.e. a class that exists in the context of
-     * zero or more "enclosing instances". These are anonymous classes, local classes and member
-     * classes.
-     */
-    interface InnerClassDeclaration extends TypeDeclaration {
-
-        /**
-         * Inner classes have zero or more synthetic fields that hold references to their enclosing
-         * context:
-         * <dl>
-         *   <dt><code>this$<i>n</i></code></dt>
-         *   <dd>
-         *     (Mandatory for non-private non-static member classes; optional for private non-static
-         *     member classes, local classes in non-static context, and anonymous classes in
-         *     non-static context; forbidden for static member classes, local classes in static
-         *     context, and anonymous classes in static context)
-         *     Holds a reference to the immediately enclosing instance. <code><i>n</i></code> is
-         *     N-1 for the Nth nesting level; e.g. the public non-static member class of a
-         *     package member class has a synthetic field <code>this$0</code>.
-         *   </dd>
-         *   <dt><code>val$<i>local-variable-name</i></code></dt>
-         *   <dd>
-         *     (Allowed for local classes and anonymous classes; forbidden for member classes)
-         *     Hold copies of <code>final</code> local variables of the defining context.
-         *   </dd>
-         * </dl>
-         * Notice that these fields are not included in the {@link IClass.IField} array returned
-         * by {@link IClass#getDeclaredIFields()}.
-         * <p>
-         * If a synthetic field with the same name exists already, then it must have the same
-         * type and the redefinition is ignored.
-         * @param iField
-         */
-        void defineSyntheticField(IClass.IField iField) throws CompileException;
-    }
-
-    public abstract static class AbstractTypeDeclaration implements TypeDeclaration {
-        private final Location location;
-        public final short     modifiers;
-        public final List      declaredMethods              = new ArrayList(); // MethodDeclarator
-        public final List      declaredClassesAndInterfaces = new ArrayList(); // MemberTypeDeclaration
-        private Scope          enclosingScope = null;
-
-        /*package*/ IClass resolvedType = null;
-
-        public AbstractTypeDeclaration(
-            Location location,
-            short    modifiers
-        ) {
-            this.location  = location;
-            this.modifiers = modifiers;
-        }
-
-        public void setEnclosingScope(Scope enclosingScope) {
-            if (this.enclosingScope != null && enclosingScope != this.enclosingScope) throw new RuntimeException("Enclosing scope is already set for type declaration \"" + this.toString() + "\" at " + this.getLocation());
-            this.enclosingScope = enclosingScope;
-        }
-        public Scope getEnclosingScope() {
-            return this.enclosingScope;
-        }
-
-        public void addDeclaredMethod(MethodDeclarator method) {
-            this.declaredMethods.add(method);
-            method.setDeclaringType(this);
-        }
-
-        public void invalidateMethodCaches() {
-            if (this.resolvedType != null) {
-                this.resolvedType.declaredIMethods = null;
-                this.resolvedType.declaredIMethodCache = null;
-            }
-        }
-
-        // Implement TypeDeclaration.
-        public void addMemberTypeDeclaration(MemberTypeDeclaration mcoid) {
-            this.declaredClassesAndInterfaces.add(mcoid);
-            mcoid.setDeclaringType(this);
-        }
-        public Collection getMemberTypeDeclarations() {
-            return this.declaredClassesAndInterfaces;
-        }
-        public MemberTypeDeclaration getMemberTypeDeclaration(String name) {
-            for (Iterator it = this.declaredClassesAndInterfaces.iterator(); it.hasNext();) {
-                MemberTypeDeclaration mtd = (MemberTypeDeclaration) it.next();
-                if (mtd.getName().equals(name)) return mtd;
-            }
-            return null;
-        }
-        public MethodDeclarator getMethodDeclaration(String name) {
-            for (Iterator it = this.declaredMethods.iterator(); it.hasNext();) {
-                MethodDeclarator md = (MethodDeclarator) it.next();
-                if (md.name.equals(name)) return md;
-            }
-            return null;
-        }
-        public String createLocalTypeName(String localTypeName) {
-            return (
-                this.getClassName()
-                + '$'
-                + ++this.localClassCount
-                + '$'
-                + localTypeName
-            );
-        }
-        public String createAnonymousClassName() {
-            return (
-                this.getClassName()
-                + '$'
-                + ++this.anonymousClassCount
-            );
-        }
-
-        // Implement "Locatable".
-        public Location getLocation() { return this.location; }
-        public void throwParseException(String message) throws Parser.ParseException {
-            throw new Parser.ParseException(message, this.location);
-        }
-
-        abstract public String toString();
-
-        public int anonymousClassCount = 0; // For naming anonymous classes.
-        public int localClassCount = 0;     // For naming local classes.
-    }
-
-    public abstract static class ClassDeclaration extends AbstractTypeDeclaration {
-        public final List constructors = new ArrayList(); // ConstructorDeclarator
-        public final List variableDeclaratorsAndInitializers = new ArrayList(); // TypeBodyDeclaration
-
-        public ClassDeclaration(
-            Location location,
-            short    modifiers
-        ) {
-            super(location, modifiers);
-        }
-
-        public void addConstructor(ConstructorDeclarator cd) {
-            this.constructors.add(cd);
-            cd.setDeclaringType(this);
-        }
-        public void addVariableDeclaratorOrInitializer(TypeBodyDeclaration tbd) {
-            this.variableDeclaratorsAndInitializers.add(tbd);
-            tbd.setDeclaringType(this);
-
-            // Clear resolved type cache.
-            if (this.resolvedType != null) this.resolvedType.clearIFieldCaches();
-        }
-
-        // Compile time members.
-
-        // Implement InnerClassDeclaration.
-        public void defineSyntheticField(IClass.IField iField) throws CompileException {
-            if (!(this instanceof InnerClassDeclaration)) throw new RuntimeException();
-
-            IClass.IField if2 = (IClass.IField) this.syntheticFields.get(iField.getName());
-            if (if2 != null) {
-                if (iField.getType() != if2.getType()) throw new RuntimeException();
-                return;
-            }
-            this.syntheticFields.put(iField.getName(), iField);
-        }
-
-        /**
-         * Return the declared constructors, or the default constructor.
-         */
-        ConstructorDeclarator[] getConstructors() {
-            if (this.constructors.isEmpty()) {
-                ConstructorDeclarator defaultConstructor = new ConstructorDeclarator(
-                    this.getLocation(),                        // location
-                    null,                                      // optionalDocComment
-                    Mod.PUBLIC,                                // modifiers
-                    new FunctionDeclarator.FormalParameter[0], // formalParameters
-                    new Type[0],                               // thrownExceptions
-                    null,                                      // optionalExplicitConstructorInvocation
-                    new Block(this.getLocation())              // optionalBody
-                );
-                defaultConstructor.setDeclaringType(this);
-                return new ConstructorDeclarator[] { defaultConstructor };
-            }
-
-            return (ConstructorDeclarator[]) this.constructors.toArray(new ConstructorDeclarator[this.constructors.size()]);
-        }
-
-        // All field names start with "this$" or "val$".
-        final SortedMap syntheticFields = new TreeMap(); // String name => IClass.IField
-    }
-
-    public static final class AnonymousClassDeclaration extends ClassDeclaration implements InnerClassDeclaration {
-        public final Type baseType;  // Base class or interface
-
-        public AnonymousClassDeclaration(
-            Location location,
-            Type     baseType
-        ) {
-            super(
-                location,                         // location
-                (short) (Mod.PRIVATE | Mod.FINAL) // modifiers
-            );
-            (this.baseType = baseType).setEnclosingScope(new EnclosingScopeOfTypeDeclaration(this));
-        }
-
-        public final void accept(Visitor.TypeDeclarationVisitor visitor) {
-            visitor.visitAnonymousClassDeclaration(this);
-        }
-
-        // Implement TypeDeclaration.
-        public String getClassName() {
-            if (this.myName == null) {
-                Scope s = this.getEnclosingScope();
-                for (; !(s instanceof TypeDeclaration); s = s.getEnclosingScope());
-                this.myName = ((TypeDeclaration) s).createAnonymousClassName();
-            }
-            return this.myName;
-        }
-        private String myName = null;
-        public String toString() { return this.getClassName(); }
-    }
-
-    public abstract static class NamedClassDeclaration extends ClassDeclaration implements NamedTypeDeclaration, DocCommentable {
-        private final String optionalDocComment;
-        public final String  name;
-        public final Type    optionalExtendedType;
-        public final Type[]  implementedTypes;
-
-        public NamedClassDeclaration(
-            Location location,
-            String   optionalDocComment,
-            short    modifiers,
-            String   name,
-            Type     optionalExtendedType,
-            Type[]   implementedTypes
-        ) {
-            super(location, modifiers);
-            this.optionalDocComment   = optionalDocComment;
-            this.name                 = name;
-            this.optionalExtendedType = optionalExtendedType;
-            if (optionalExtendedType != null) optionalExtendedType.setEnclosingScope(new EnclosingScopeOfTypeDeclaration(this));
-            this.implementedTypes     = implementedTypes;
-            for (int i = 0; i < implementedTypes.length; ++i) implementedTypes[i].setEnclosingScope(new EnclosingScopeOfTypeDeclaration(this));
-        }
-
-        public String toString() { return this.name; }
-
-        // Implement NamedTypeDeclaration.
-        public String getName() { return this.name; }
-
-        // Implement DocCommentable.
-        public String getDocComment() { return this.optionalDocComment; }
-        public boolean hasDeprecatedDocTag() { return this.optionalDocComment != null && this.optionalDocComment.indexOf("@deprecated") != -1; }
-    }
-
-    /**
-     * Lazily determines and returns the enclosing
-     * {@link org.codehaus.janino.Java.Scope} of the given
-     * {@link org.codehaus.janino.Java.TypeDeclaration}.
-     */
-    public static final class EnclosingScopeOfTypeDeclaration implements Scope {
-        public final TypeDeclaration typeDeclaration;
-        public EnclosingScopeOfTypeDeclaration(TypeDeclaration typeDeclaration) {
-            this.typeDeclaration = typeDeclaration;
-        }
-        public Scope getEnclosingScope() { return this.typeDeclaration.getEnclosingScope(); }
-    }
-
-    public static final class MemberClassDeclaration extends NamedClassDeclaration implements MemberTypeDeclaration, InnerClassDeclaration {
-        public MemberClassDeclaration(
-            Location             location,
-            String               optionalDocComment,
-            short                modifiers,
-            String               name,
-            Type                 optionalExtendedType,
-            Type[]               implementedTypes
-        ) {
-            super(
-                location,              // location
-                optionalDocComment,    // optionalDocComment
-                modifiers,             // modifiers
-                name,                  // name
-                optionalExtendedType,  // optionalExtendedType
-                implementedTypes       // implementedTypes
-            );
-        }
-
-        // Implement TypeBodyDeclaration.
-        public void setDeclaringType(TypeDeclaration declaringType) {
-            this.setEnclosingScope(declaringType);
-        }
-        public TypeDeclaration getDeclaringType() {
-            return (TypeDeclaration) this.getEnclosingScope();
-        }
-        public boolean isStatic() {
-            return (this.modifiers & Mod.STATIC) != 0;
-        }
-
-        // Implement TypeDeclaration.
-        public String getClassName() {
-            return (
-                this.getDeclaringType().getClassName()
-                + '$'
-                + this.getName()
-            );
-        }
-
-        public void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitMemberClassDeclaration(this); }
-        public void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitMemberClassDeclaration(this); }
-    }
-
-    public static final class LocalClassDeclaration extends NamedClassDeclaration implements InnerClassDeclaration {
-        public LocalClassDeclaration(
-            Location location,
-            String   optionalDocComment,
-            short    modifiers,
-            String   name,
-            Type     optionalExtendedType,
-            Type[]   implementedTypes
-        ) {
-            super(
-                location,               // location
-                optionalDocComment,     // optionalDocComment
-                modifiers,              // modifiers
-                name,                   // name
-                optionalExtendedType,   // optionalExtendedType
-                implementedTypes        // implementedTypes
-            );
-        }
-
-        // Implement ClassDeclaration.
-        protected IClass getOuterIClass2() {
-            Scope s = this.getEnclosingScope();
-            for (; !(s instanceof FunctionDeclarator); s = s.getEnclosingScope());
-            boolean isStaticMethod = (s instanceof MethodDeclarator) && (((FunctionDeclarator) s).modifiers & Mod.STATIC) != 0;
-            for (; !(s instanceof TypeDeclaration); s = s.getEnclosingScope());
-            TypeDeclaration immediatelyEnclosingTypeDeclaration = (TypeDeclaration) s;
-            return (
-                immediatelyEnclosingTypeDeclaration instanceof ClassDeclaration &&
-                !isStaticMethod
-            ) ? (IClass) immediatelyEnclosingTypeDeclaration : null;
-        }
-
-        // Implement TypeDeclaration.
-        public String getClassName() {
-            for (Scope s = this.getEnclosingScope();; s = s.getEnclosingScope()) {
-                if (s instanceof Java.TypeDeclaration) return ((Java.TypeDeclaration) s).getClassName() + '$' + this.name;
-            }
-        }
-
-        public final void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitLocalClassDeclaration(this); }
-    }
-
-    public static final class PackageMemberClassDeclaration extends NamedClassDeclaration implements PackageMemberTypeDeclaration {
-        public PackageMemberClassDeclaration(
-            Location location,
-            String   optionalDocComment,
-            short    modifiers,
-            String   name,
-            Type     optionalExtendedType,
-            Type[]   implementedTypes
-        ) throws Parser.ParseException {
-            super(
-                location,                         // location
-                optionalDocComment,               // optionalDocComment
-                modifiers,                        // modifiers
-                name,                             // name
-                optionalExtendedType,             // optionalExtendedType
-                implementedTypes                  // implementedTypes
-            );
-
-            // Check for forbidden modifiers (JLS 7.6).
-            if ((modifiers & (
-                Mod.PROTECTED |
-                Mod.PRIVATE |
-                Mod.STATIC
-            )) != 0) this.throwParseException("Modifiers \"protected\", \"private\" and \"static\" not allowed in package member class declaration");
-        }
-
-        // Implement PackageMemberTypeDeclaration.
-        public void setDeclaringCompilationUnit(CompilationUnit declaringCompilationUnit) {
-            this.setEnclosingScope(declaringCompilationUnit);
-        }
-        public CompilationUnit getDeclaringCompilationUnit() {
-            return (CompilationUnit) this.getEnclosingScope();
-        }
-
-        // Implement ClassDeclaration.
-        protected IClass getOuterIClass2() {
-            return null;
-        }
-
-        // Implement TypeDeclaration.
-        public String getClassName() {
-            String className = this.getName();
-
-            CompilationUnit compilationUnit = (CompilationUnit) this.getEnclosingScope();
-            if (compilationUnit.optionalPackageDeclaration != null) className = compilationUnit.optionalPackageDeclaration.packageName + '.' + className;
-
-            return className;
-        }
-
-        public final void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitPackageMemberClassDeclaration(this); }
-    }
-
-    public abstract static class InterfaceDeclaration extends AbstractTypeDeclaration implements NamedTypeDeclaration, DocCommentable {
-        private final String    optionalDocComment;
-        public /*final*/ String name;
-
-        protected InterfaceDeclaration(
-            Location location,
-            String   optionalDocComment,
-            short    modifiers,
-            String   name,
-            Type[]   extendedTypes
-        ) {
-            super(location, modifiers);
-            this.optionalDocComment = optionalDocComment;
-            this.name               = name;
-            this.extendedTypes      = extendedTypes;
-            for (int i = 0; i < extendedTypes.length; ++i) extendedTypes[i].setEnclosingScope(new EnclosingScopeOfTypeDeclaration(this));
-        }
-
-        public String toString() { return this.name; }
-
-        public void addConstantDeclaration(FieldDeclaration fd) {
-            this.constantDeclarations.add(fd);
-            fd.setDeclaringType(this);
-
-            // Clear resolved type cache.
-            if (this.resolvedType != null) this.resolvedType.clearIFieldCaches();
-        }
-
-        public /*final*/ Type[] extendedTypes;
-        public final List       constantDeclarations = new ArrayList(); // FieldDeclaration
-
-        // Set during "compile()".
-        IClass[] interfaces = null;
-
-        // Implement NamedTypeDeclaration.
-        public String getName() { return this.name; }
-
-        // Implement DocCommentable.
-        public String getDocComment() { return this.optionalDocComment; }
-        public boolean hasDeprecatedDocTag() { return this.optionalDocComment != null && this.optionalDocComment.indexOf("@deprecated") != -1; }
-    }
-
-    public static final class MemberInterfaceDeclaration extends InterfaceDeclaration implements MemberTypeDeclaration {
-        public MemberInterfaceDeclaration(
-            Location             location,
-            String               optionalDocComment,
-            short                modifiers,
-            String               name,
-            Type[]               extendedTypes
-        ) {
-            super(
-                location,              // location
-                optionalDocComment,    // optionalDocComment
-                modifiers,             // modifiers
-                name,                  // name
-                extendedTypes          // extendedTypes
-            );
-        }
-
-        // Implement TypeDeclaration.
-        public String getClassName() {
-            NamedTypeDeclaration declaringType = (NamedTypeDeclaration) this.getEnclosingScope();
-            return (
-                declaringType.getClassName()
-                + '$'
-                + this.getName()
-            );
-        }
-
-        // Implement TypeBodyDeclaration.
-        public void setDeclaringType(TypeDeclaration declaringType) { this.setEnclosingScope(declaringType); }
-        public TypeDeclaration getDeclaringType() {
-            return (TypeDeclaration) this.getEnclosingScope();
-        }
-        public boolean isStatic() {
-            return (this.modifiers & Mod.STATIC) != 0;
-        }
-
-        public final void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitMemberInterfaceDeclaration(this); }
-        public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitMemberInterfaceDeclaration(this); }
-    }
-
-    public static final class PackageMemberInterfaceDeclaration extends InterfaceDeclaration implements PackageMemberTypeDeclaration {
-        public PackageMemberInterfaceDeclaration(
-            Location        location,
-            String          optionalDocComment,
-            short           modifiers,
-            String          name,
-            Type[]          extendedTypes
-        ) throws Parser.ParseException {
-            super(
-                location,                         // location
-                optionalDocComment,               // optionalDocComment
-                modifiers,                        // modifiers
-                name,                             // name
-                extendedTypes                     // extendedTypes
-            );
-
-            // Check for forbidden modifiers (JLS 7.6).
-            if ((modifiers & (
-                Mod.PROTECTED |
-                Mod.PRIVATE |
-                Mod.STATIC
-            )) != 0) this.throwParseException("Modifiers \"protected\", \"private\" and \"static\" not allowed in package member interface declaration");
-        }
-
-        // Implement PackageMemberTypeDeclaration.
-        public void setDeclaringCompilationUnit(CompilationUnit declaringCompilationUnit) {
-            this.setEnclosingScope(declaringCompilationUnit);
-        }
-
-        public CompilationUnit getDeclaringCompilationUnit() {
-            return (CompilationUnit) this.getEnclosingScope();
-        }
-
-        // Implement TypeDeclaration.
-        public String getClassName() {
-            String className = this.getName();
-
-            CompilationUnit compilationUnit = (CompilationUnit) this.getEnclosingScope();
-            if (compilationUnit.optionalPackageDeclaration != null) className = compilationUnit.optionalPackageDeclaration.packageName + '.' + className;
-
-            return className;
-        }
-
-        public final void accept(Visitor.TypeDeclarationVisitor visitor) { visitor.visitPackageMemberInterfaceDeclaration(this); }
-    }
-
-    /**
-     * Representation of a "ClassBodyDeclaration" or an "InterfaceMemberDeclaration". These are:
-     * <ul>
-     *   <li>Field declarators
-     *   <li>Method declarators
-     *   <li>Static and non-static initializers
-     *   <li>Member type declarations
-     * </ul>
-     */
-    public interface TypeBodyDeclaration extends Locatable, Scope {
-        void            setDeclaringType(TypeDeclaration declaringType);
-        TypeDeclaration getDeclaringType();
-        boolean         isStatic();
-        void            accept(Visitor.TypeBodyDeclarationVisitor visitor);
-    }
-
-    public abstract static class AbstractTypeBodyDeclaration extends Located implements TypeBodyDeclaration {
-        private TypeDeclaration declaringType;
-        public final boolean    statiC;
-
-        protected AbstractTypeBodyDeclaration(
-            Location location,
-            boolean  statiC
-        ) {
-            super(location);
-            this.statiC = statiC;
-        }
-
-        // Implement TypeBodyDeclaration.
-        public void setDeclaringType(TypeDeclaration declaringType) {
-            if (this.declaringType != null && declaringType != null) throw new RuntimeException("Declaring type for type body declaration \"" + this.toString() + "\"at " + this.getLocation() + " is already set");
-            this.declaringType = declaringType;
-        }
-        public TypeDeclaration getDeclaringType() {
-            return this.declaringType;
-        }
-
-        public boolean isStatic() {
-            return this.statiC;
-        }
-
-        // Implement BlockStatement.
-        public void setEnclosingScope(Scope enclosingScope) {
-            this.declaringType = (TypeDeclaration) enclosingScope;
-        }
-        public Scope getEnclosingScope() {
-            return this.declaringType;
-        }
-    }
-
-    /**
-     * Representation of an instance (JLS2 8.6) or static initializer (JLS2 8.7).
-     */
-    public final static class Initializer extends AbstractTypeBodyDeclaration implements BlockStatement {
-        public final Block block;
-
-        public Initializer(
-            Location location,
-            boolean  statiC,
-            Block    block
-        ) {
-            super(location, statiC);
-            (this.block = block).setEnclosingScope(this);
-        }
-        public String toString() {
-            return this.statiC ? "static " + this.block : this.block.toString();
-        }
-
-        // Implement BlockStatement.
-
-        public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitInitializer(this); }
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitInitializer(this); }
-
-        public Java.LocalVariable findLocalVariable(String name) {
-            return this.block.findLocalVariable(name);
-        }
-    }
-
-    /**
-     * Abstract base class for {@link Java.ConstructorDeclarator} and
-     * {@link Java.MethodDeclarator}.
-     */
-    public abstract static class FunctionDeclarator extends AbstractTypeBodyDeclaration implements DocCommentable {
-        private final String           optionalDocComment;
-        public final short             modifiers;
-        public final Type              type;
-        public final String            name;
-        public final FormalParameter[] formalParameters;
-        public final Type[]            thrownExceptions;
-        public final Block             optionalBody;
-
-        public FunctionDeclarator(
-            Location          location,
-            String            optionalDocComment,
-            short             modifiers,
-            Type              type,
-            String            name,
-            FormalParameter[] formalParameters,
-            Type[]            thrownExceptions,
-            Block             optionalBody
-        ) {
-            super(location, (modifiers & Mod.STATIC) != 0);
-            this.optionalDocComment = optionalDocComment;
-            this.modifiers          = modifiers;
-            (this.type               = type).setEnclosingScope(this);
-            this.name               = name;
-            this.formalParameters   = formalParameters;
-            for (int i = 0; i < formalParameters.length; ++i) formalParameters[i].type.setEnclosingScope(this);
-            this.thrownExceptions   = thrownExceptions;
-            for (int i = 0; i < thrownExceptions.length; ++i) thrownExceptions[i].setEnclosingScope(this);
-            this.optionalBody       = optionalBody;
-            if (optionalBody != null) optionalBody.setEnclosingScope(this);
-        }
-
-        // Implement "Scope".
-        public Scope getEnclosingScope() {
-            return this.getDeclaringType();
-        }
-
-        // Set by "compile()".
-        IClass returnType = null;
-
-        // Implement DocCommentable.
-        public String getDocComment() { return this.optionalDocComment; }
-        public boolean hasDeprecatedDocTag() { return this.optionalDocComment != null && this.optionalDocComment.indexOf("@deprecated") != -1; }
-
-        public static final class FormalParameter extends Java.Located {
-            public final boolean finaL;
-            public final Type    type;
-            public final String  name;
-        
-            public FormalParameter(
-                Location location,
-                boolean  finaL,
-                Type     type,
-                String   name
-            ) {
-                super(location);
-                this.finaL = finaL;
-                this.type  = type;
-                this.name  = name;
-            }
-        
-            public String toString() {
-                return this.type.toString() + ' ' + this.name;
-            }
-        
-            // Compile time members.
-        
-            public Java.LocalVariable localVariable = null;
-        }
-
-        // Compile time members
-        public Map localVariables = null; // String name => Java.LocalVariable
-    }
-
-    public static final class ConstructorDeclarator extends FunctionDeclarator {
-        IClass.IConstructor          iConstructor = null;
-        public ConstructorInvocation optionalConstructorInvocation = null;
-
-        public ConstructorDeclarator(
-            Location                             location,
-            String                               optionalDocComment,
-            short                                modifiers,
-            FunctionDeclarator.FormalParameter[] formalParameters,
-            Type[]                               thrownExceptions,
-            ConstructorInvocation                optionalConstructorInvocation,
-            Block                                optionalBody
-        ) {
-            super(
-                location,                                // location
-                optionalDocComment,                      // optionalDocComment
-                modifiers,                               // modifiers
-                new BasicType(location, BasicType.VOID), // type
-                "<init>",                                // name
-                formalParameters,                        // formalParameters
-                thrownExceptions,                        // thrownExceptions
-                optionalBody                             // optionalBody
-            );
-            this.optionalConstructorInvocation = optionalConstructorInvocation;
-            if (optionalConstructorInvocation != null) optionalConstructorInvocation.setEnclosingScope(this);
-        }
-
-        public ClassDeclaration getDeclaringClass() {
-            return (ClassDeclaration) this.getEnclosingScope();
-        }
-
-        // Compile time members.
-
-        Map syntheticParameters = new HashMap(); // String name => LocalVariable
-
-        // Implement "FunctionDeclarator":
-
-        public String toString() {
-            StringBuffer sb = new StringBuffer(this.getDeclaringClass().getClassName());
-            sb.append('(');
-            FunctionDeclarator.FormalParameter[] fps = this.formalParameters;
-            for (int i = 0; i < fps.length; ++i) {
-                if (i > 0) sb.append(", ");
-                sb.append(fps[i].toString());
-            }
-            sb.append(')');
-            return sb.toString();
-        }
-
-        public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitConstructorDeclarator(this); }
-    }
-
-    public final static class MethodDeclarator extends FunctionDeclarator {
-        public MethodDeclarator(
-            Location                             location,
-            String                               optionalDocComment,
-            short                                modifiers,
-            Type                                 type,
-            String                               name,
-            FunctionDeclarator.FormalParameter[] formalParameters,
-            Type[]                               thrownExceptions,
-            Block                                optionalBody
-        ) {
-            super(
-                location,           // location
-                optionalDocComment, // optionalDocComment
-                modifiers,          // modifiers
-                type,               // type
-                name,               // name
-                formalParameters,   // formalParameters
-                thrownExceptions,   // thrownExceptions
-                optionalBody
-            );
-        }
-
-        public String toString() {
-            StringBuffer sb = new StringBuffer(this.name);
-            sb.append('(');
-            FunctionDeclarator.FormalParameter[] fps = this.formalParameters;
-            for (int i = 0; i < fps.length; ++i) {
-                if (i > 0) sb.append(", ");
-                sb.append(fps[i].toString());
-            }
-            sb.append(')');
-            return sb.toString();
-        }
-
-        public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitMethodDeclarator(this); }
-
-        IClass.IMethod iMethod = null;
-    }
-
-    /**
-     * This class is derived from "Statement", because it provides for the
-     * initialization of the field. In other words, "compile()" generates the
-     * code that initializes the field.
-     */
-    public static final class FieldDeclaration extends Statement implements TypeBodyDeclaration, DocCommentable {
-        private final String              optionalDocComment;
-        public final short                modifiers;
-        public final Type                 type;
-        public final VariableDeclarator[] variableDeclarators;
-
-        public FieldDeclaration(
-            Location             location,
-            String               optionalDocComment,
-            short                modifiers,
-            Type                 type,
-            VariableDeclarator[] variableDeclarators
-        ) {
-            super(location);
-            this.optionalDocComment  = optionalDocComment;
-            this.modifiers           = modifiers;
-            (this.type                = type).setEnclosingScope(this);
-            this.variableDeclarators = variableDeclarators;
-            for (int i = 0; i < variableDeclarators.length; ++i) {
-                VariableDeclarator vd = variableDeclarators[i];
-                if (vd.optionalInitializer != null) Java.setEnclosingBlockStatement(vd.optionalInitializer, this);
-            }
-        }
-
-        // Implement TypeBodyDeclaration.
-        public void setDeclaringType(TypeDeclaration declaringType) {
-            this.setEnclosingScope(declaringType);
-        }
-        public TypeDeclaration getDeclaringType() {
-            return (TypeDeclaration) this.getEnclosingScope();
-        }
-        public boolean isStatic() {
-            return (this.modifiers & Mod.STATIC) != 0;
-        }
-
-        public String toString() {
-            StringBuffer sb = new StringBuffer();
-            sb.append(Mod.shortToString(this.modifiers)).append(' ').append(this.type).append(' ').append(this.variableDeclarators[0]);
-            for (int i = 1; i < this.variableDeclarators.length; ++i) {
-                sb.append(", ").append(this.variableDeclarators[i]);
-            }
-            return sb.toString();
-        }
-
-        public final void accept(Visitor.TypeBodyDeclarationVisitor visitor) { visitor.visitFieldDeclaration(this); }
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitFieldDeclaration(this); }
-
-        // Implement DocCommentable.
-        public String getDocComment() { return this.optionalDocComment; }
-        public boolean hasDeprecatedDocTag() { return this.optionalDocComment != null && this.optionalDocComment.indexOf("@deprecated") != -1; }
-    }
-    private static void setEnclosingBlockStatement(
-        ArrayInitializerOrRvalue aiorv,
-        BlockStatement           enclosingBlockStatement
-    ) {
-        if (aiorv instanceof Rvalue) {
-            ((Rvalue) aiorv).setEnclosingBlockStatement(enclosingBlockStatement);
-        } else
-        if (aiorv instanceof ArrayInitializer) {
-            ArrayInitializerOrRvalue[] values = ((ArrayInitializer) aiorv).values;
-            for (int i = 0; i < values.length; ++i) Java.setEnclosingBlockStatement(values[i], enclosingBlockStatement);
-        } else
-        {
-            throw new RuntimeException("Unexpected array or initializer class " + aiorv.getClass().getName());
-        }
-    }
-
-    // Used by FieldDeclaration and LocalVariableDeclarationStatement.
-    public final static class VariableDeclarator extends Located {
-        public final String                   name;
-        public final int                      brackets;
-        public final ArrayInitializerOrRvalue optionalInitializer;
-
-        public VariableDeclarator(
-            Location                 location,
-            String                   name,
-            int                      brackets,
-            ArrayInitializerOrRvalue optionalInitializer
-        ) {
-            super(location);
-            this.name                = name;
-            this.brackets            = brackets;
-            this.optionalInitializer = optionalInitializer;
-
-            // Used both by field declarations an local variable declarations, so naming
-            // conventions checking (JLS2 6.8) cannot be done here.
-        }
-
-        public String toString() {
-            StringBuffer sb = new StringBuffer();
-            sb.append(this.name);
-            for (int i = 0; i < this.brackets; ++i) sb.append("[]");
-            if (this.optionalInitializer != null) sb.append(" = ").append(this.optionalInitializer);
-            return sb.toString();
-        }
-
-        // Compile time members.
-
-        // Used only if the variable declarator declares a local variable.
-        public LocalVariable localVariable = null;
-    }
-
-    /**
-     * Base of all statements that can appear in a block.
-     */
-    public interface BlockStatement extends Locatable, Scope {
-        void setEnclosingScope(Scope enclosingScope);
-        Scope getEnclosingScope();
-
-        void accept(Visitor.BlockStatementVisitor visitor);
-        Java.LocalVariable findLocalVariable(String name);
-    }
-
-    public static abstract class Statement extends Located implements BlockStatement {
-        private Scope enclosingScope = null;
-
-        protected Statement(Location location) {
-            super(location);
-        }
-
-        // Implement "BlockStatement".
-        public void setEnclosingScope(Scope enclosingScope) {
-            if (this.enclosingScope != null && enclosingScope != this.enclosingScope) throw new RuntimeException("Enclosing scope is already set for statement \"" + this.toString() + "\" at " + this.getLocation());
-            this.enclosingScope = enclosingScope;
-        }
-        public Scope getEnclosingScope() { return this.enclosingScope; }
-
-        // Compile time members
-        public Map localVariables = null; // String name => Java.LocalVariable
-        public Java.LocalVariable findLocalVariable(String name) {
-            if (this.localVariables == null) { return null; }
-            return (LocalVariable) this.localVariables.get(name);
-        }
-    }
-
-    public final static class LabeledStatement extends BreakableStatement {
-        public final String    label;
-        public final Statement body;
-
-        public LabeledStatement(
-            Location  location,
-            String    label,
-            Statement body
-        ) {
-            super(location);
-            this.label = label;
-            (this.body  = body).setEnclosingScope(this);
-        }
-        public String toString() {
-            return this.label + ": " + this.body;
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitLabeledStatement(this); }
-    }
-
-    /**
-     * Representation of a Java<sup>TM</sup> "block" (JLS 14.2).
-     * <p>
-     * The statements that the block defines are executed in sequence.
-     */
-    public final static class Block extends Statement {
-        public final List statements = new ArrayList(); // BlockStatement
-
-        public Block(Location location) {
-            super(location);
-        }
-
-        public void addStatement(BlockStatement statement) {
-            this.statements.add(statement);
-            statement.setEnclosingScope(this);
-        }
-        // This one's for some very special compiler trickery...
-        void addButDontEncloseStatement(BlockStatement statement) {
-            this.statements.add(statement);
-        }
-        public void addStatements(
-            List statements // BlockStatement
-        ) {
-            this.statements.addAll(statements);
-            for (Iterator it = statements.iterator(); it.hasNext();) ((BlockStatement) it.next()).setEnclosingScope(this);
-        }
-        public void addButDontEncloseStatements(
-            List statements // BlockStatement
-        ) {
-            this.statements.addAll(statements);
-        }
-        public BlockStatement[] getStatements() {
-            return (BlockStatement[]) this.statements.toArray(new BlockStatement[this.statements.size()]);
-        }
-
-        // Compile time members.
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitBlock(this); }
-
-        public String toString() {
-            return "{ ... }";
-        }
-    }
-
-    /**
-     * Base class for statements that can be terminated abnormally with a
-     * "break" statement.
-     * <p>
-     * According to the JLS, statements that can be terminated abnormally with
-     * a "break" statement are: "COntinuable" statements ("for", "do" and
-     * "while"), labeled statements, and the "switch" statement.
-     */
-    public static abstract class BreakableStatement extends Statement {
-        protected BreakableStatement(Location location) {
-            super(location);
-        }
-
-        CodeContext.Offset whereToBreak = null;
-    }
-
-    public static abstract class ContinuableStatement extends BreakableStatement {
-        protected ContinuableStatement(Location location) {
-            super(location);
-        }
-
-        protected CodeContext.Offset whereToContinue = null;
-        protected boolean            bodyHasContinue = false;
-    }
-
-    public final static class ExpressionStatement extends Statement {
-        public final Rvalue rvalue;
-
-        public ExpressionStatement(Rvalue rvalue) throws Parser.ParseException {
-            super(rvalue.getLocation());
-            if (!(
-                rvalue instanceof Java.Assignment
-                || rvalue instanceof Java.Crement
-                || rvalue instanceof Java.MethodInvocation
-                || rvalue instanceof Java.SuperclassMethodInvocation
-                || rvalue instanceof Java.NewClassInstance
-                || rvalue instanceof Java.NewAnonymousClassInstance
-            )) this.throwParseException("This kind of expression is not allowed in an expression statement");
-            (this.rvalue = rvalue).setEnclosingBlockStatement(this);
-        }
-        
-        public String toString() {
-            return this.rvalue.toString() + ';';
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitExpressionStatement(this); }
-    }
-
-    public final static class LocalClassDeclarationStatement extends Statement {
-        public final LocalClassDeclaration lcd;
-
-        public LocalClassDeclarationStatement(Java.LocalClassDeclaration lcd) {
-            super(lcd.getLocation());
-            (this.lcd = lcd).setEnclosingScope(this);
-        }
-        public String toString() {
-            return this.lcd.toString();
-        }
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitLocalClassDeclarationStatement(this); }
-    }
-
-    public final static class IfStatement extends Statement {
-        public final Rvalue         condition;
-        public final BlockStatement thenStatement;
-        public final BlockStatement optionalElseStatement;
-
-        /**
-         * Notice that the <code>elseStatement</code> is mandatory; for an if statement without
-         * an "else" clause, a dummy {@link Java.EmptyStatement} should be passed.
-         */
-        public IfStatement(
-            Location       location,
-            Rvalue         condition,
-            BlockStatement thenStatement,
-            BlockStatement optionalElseStatement
-        ) {
-            super(location);
-            (this.condition             = condition).setEnclosingBlockStatement(this);
-            (this.thenStatement         = thenStatement).setEnclosingScope(this);
-            this.optionalElseStatement = optionalElseStatement;
-            if (optionalElseStatement != null) optionalElseStatement.setEnclosingScope(this);
-        }
-
-        public String toString() {
-            return this.optionalElseStatement == null ? "if" : "if ... else";
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitIfStatement(this); }
-    }
-
-    public final static class ForStatement extends ContinuableStatement {
-        public final BlockStatement optionalInit;
-        public final Rvalue         optionalCondition;
-        public final Rvalue[]       optionalUpdate;
-        public final BlockStatement body;
-
-        public ForStatement(
-            Location location,
-            BlockStatement optionalInit,
-            Rvalue         optionalCondition,
-            Rvalue[]       optionalUpdate,
-            BlockStatement body
-        ) {
-            super(location);
-            this.optionalInit = optionalInit;
-            if (optionalInit != null) optionalInit.setEnclosingScope(this);
-            this.optionalCondition = optionalCondition;
-            if (optionalCondition != null) optionalCondition.setEnclosingBlockStatement(this);
-            this.optionalUpdate = optionalUpdate;
-            if (optionalUpdate != null) {
-                for (int i = 0; i < optionalUpdate.length; ++i) optionalUpdate[i].setEnclosingBlockStatement(this);
-            }
-            (this.body = body).setEnclosingScope(this);
-        }
-        public String toString() {
-            return "for (...; ...; ...) ...";
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitForStatement(this); }
-    }
-
-    public final static class WhileStatement extends ContinuableStatement {
-        public final Rvalue         condition;
-        public final BlockStatement body;
-
-        public WhileStatement(
-            Location       location,
-            Rvalue         condition,
-            BlockStatement body
-        ) {
-            super(location);
-            (this.condition = condition).setEnclosingBlockStatement(this);
-            (this.body = body).setEnclosingScope(this);
-        }
-        public String toString() {
-            return "while (" + this.condition + ") " + this.body + ';';
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitWhileStatement(this); }
-    }
-
-    public final static class TryStatement extends Statement {
-        public final BlockStatement body;
-        public final List           catchClauses; // CatchClause
-        public final Block          optionalFinally;
-
-        public TryStatement(
-            Location       location,
-            BlockStatement body,
-            List           catchClauses, // CatchClause
-            Block          optionalFinally
-        ) {
-            super(location);
-            (this.body            = body).setEnclosingScope(this);
-            this.catchClauses    = catchClauses;
-            for (Iterator it = catchClauses.iterator(); it.hasNext();) ((CatchClause) it.next()).setEnclosingTryStatement(this);
-            this.optionalFinally = optionalFinally;
-            if (optionalFinally != null) optionalFinally.setEnclosingScope(this);
-        }
-        public String toString() {
-            return "try ... " + this.catchClauses.size() + (this.optionalFinally == null ? " catches" : " catches ... finally");
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitTryStatement(this); }
-
-        CodeContext.Offset finallyOffset = null;
-    }
-
-    public static class CatchClause extends Located implements Scope {
-        public final FunctionDeclarator.FormalParameter caughtException;
-        public final Block                              body;
-        private TryStatement                            enclosingTryStatement = null;
-
-        public CatchClause(
-            Location                           location,
-            FunctionDeclarator.FormalParameter caughtException,
-            Block                              body
-        ) {
-            super(location);
-            (this.caughtException = caughtException).type.setEnclosingScope(this);
-            (this.body            = body).setEnclosingScope(this);
-        }
-
-        public void setEnclosingTryStatement(TryStatement enclosingTryStatement) {
-            if (this.enclosingTryStatement != null && enclosingTryStatement != this.enclosingTryStatement) throw new RuntimeException("Enclosing TYR statement already set for catch clause " + this.toString() + " at " + this.getLocation());
-            this.enclosingTryStatement = enclosingTryStatement;
-        }
-        public Scope getEnclosingScope() { return this.enclosingTryStatement; }
-    }
-
-    /**
-     * 14.10 The "switch" Statement
-     */
-    public static final class SwitchStatement extends BreakableStatement {
-        public final Rvalue condition;
-        public final List   sbsgs; // SwitchBlockStatementGroup
-
-        public SwitchStatement(
-            Location location,
-            Rvalue   condition,
-            List     sbsgs
-        ) {
-            super(location);
-            (this.condition = condition).setEnclosingBlockStatement(this);
-            this.sbsgs     = sbsgs;
-            for (Iterator it = sbsgs.iterator(); it.hasNext();) {
-                SwitchBlockStatementGroup sbsg = ((SwitchBlockStatementGroup) it.next());
-                for (Iterator it2 = sbsg.caseLabels.iterator(); it2.hasNext();) {
-                    ((Rvalue) (it2.next())).setEnclosingBlockStatement(this);
-                }
-                for (Iterator it2 = sbsg.blockStatements.iterator(); it2.hasNext();) {
-                    ((BlockStatement) (it2.next())).setEnclosingScope(this);
-                }
-            }
-        }
-        public String toString() {
-            return "switch (" + this.condition + ") { (" + this.sbsgs.size() + " statement groups) }";
-        }
-
-        public static class SwitchBlockStatementGroup extends Java.Located {
-            public final List    caseLabels; // Rvalue
-            public final boolean hasDefaultLabel;
-            public final List    blockStatements; // BlockStatement
-        
-            public SwitchBlockStatementGroup(
-                Location location,
-                List     caseLabels,      // Rvalue
-                boolean  hasDefaultLabel,
-                List     blockStatements  // BlockStatement
-            ) {
-                super(location);
-                this.caseLabels      = caseLabels;
-                this.hasDefaultLabel = hasDefaultLabel;
-                this.blockStatements = blockStatements;
-            }
-            public String toString() {
-                return this.caseLabels.size() + (this.hasDefaultLabel ? " case label(s) plus DEFAULT" : " case label(s)");
-            }
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitSwitchStatement(this); }
-    }
-    static class Padder extends CodeContext.Inserter implements CodeContext.FixUp {
-        public Padder(CodeContext codeContext) {
-            codeContext.super();
-        }
-        public void fixUp() {
-            int x = this.offset % 4;
-            if (x != 0) {
-                CodeContext ca = this.getCodeContext();
-                ca.pushInserter(this); {
-                    ca.makeSpace((short) -1, 4 - x);
-                } ca.popInserter();
-            }
-        }
-    }
-
-    public final static class SynchronizedStatement extends Statement {
-        public final Rvalue         expression;
-        public final BlockStatement body;
-
-        public SynchronizedStatement(
-            Location       location,
-            Rvalue         expression,
-            BlockStatement body
-        ) {
-            super(location);
-            (this.expression = expression).setEnclosingBlockStatement(this);
-            (this.body       = body).setEnclosingScope(this);
-        }
-        public String toString() {
-            return "synchronized(" + this.expression + ") " + this.body;
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitSynchronizedStatement(this); }
-
-        short monitorLvIndex = -1;
-    }
-
-    public final static class DoStatement extends ContinuableStatement {
-        public final BlockStatement body;
-        public final Rvalue         condition;
-
-        public DoStatement(
-            Location       location,
-            BlockStatement body,
-            Rvalue         condition
-        ) {
-            super(location);
-            (this.body      = body).setEnclosingScope(this);
-            (this.condition = condition).setEnclosingBlockStatement(this);
-        }
-        public String toString() {
-            return "do " + this.body + " while(" + this.condition + ");";
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitDoStatement(this); }
-    }
-
-    public final static class LocalVariableDeclarationStatement extends Statement {
-        public final short                modifiers;
-        public final Type                 type;
-        public final VariableDeclarator[] variableDeclarators;
-
-        /**
-         * @param modifiers Only "final" allowed.
-         */
-        public LocalVariableDeclarationStatement(
-            Location             location,
-            short                modifiers,
-            Type                 type,
-            VariableDeclarator[] variableDeclarators
-        ) {
-            super(location);
-            this.modifiers           = modifiers;
-            (this.type                = type).setEnclosingScope(this);
-            this.variableDeclarators = variableDeclarators;
-            for (int i = 0; i < variableDeclarators.length; ++i) {
-                VariableDeclarator vd = variableDeclarators[i];
-                if (vd.optionalInitializer != null) Java.setEnclosingBlockStatement(vd.optionalInitializer, this);
-            }
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitLocalVariableDeclarationStatement(this); }
-
-        public String toString() {
-            StringBuffer sb = new StringBuffer();
-            if (this.modifiers != 0) sb.append(Mod.shortToString(this.modifiers)).append(' ');
-            sb.append(this.type).append(' ').append(this.variableDeclarators[0].toString());
-            for (int i = 1; i < this.variableDeclarators.length; ++i) {
-                sb.append(", ").append(this.variableDeclarators[i].toString());
-            }
-            return sb.append(';').toString();
-        }
-    }
-
-    public final static class ReturnStatement extends Statement {
-        public final Rvalue optionalReturnValue;
-
-        public ReturnStatement(
-            Location location,
-            Rvalue   optionalReturnValue
-        ) {
-            super(location);
-            this.optionalReturnValue = optionalReturnValue;
-            if (optionalReturnValue != null) optionalReturnValue.setEnclosingBlockStatement(this);
-        }
-        
-        public String toString() {
-            return this.optionalReturnValue == null ? "return;" : "return " + this.optionalReturnValue + ';';
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitReturnStatement(this); }
-    }
-
-    public final static class ThrowStatement extends Statement {
-        public final Rvalue expression;
-
-        public ThrowStatement(
-            Location location,
-            Rvalue   expression
-        ) {
-            super(location);
-            (this.expression = expression).setEnclosingBlockStatement(this);
-        }
-        public String toString() {
-            return "throw " + this.expression + ';';
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitThrowStatement(this); }
-    }
-
-    /**
-     * Representation of the Java<sup>TM</sup> "break" statement (JLS 14.14).
-     */
-    public final static class BreakStatement extends Statement {
-        public final String optionalLabel;
-
-        public BreakStatement(
-            Location location,
-            String   optionalLabel
-        ) {
-            super(location);
-            this.optionalLabel = optionalLabel;
-        }
-        public String toString() {
-            return this.optionalLabel == null ? "break;" : "break " + this.optionalLabel + ';';
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitBreakStatement(this); }
-    }
-
-    /**
-     * Representation of the Java<sup>TM</sup> "continue" statement (JLS
-     * 14.15).
-     */
-    public final static class ContinueStatement extends Statement {
-        public final String optionalLabel;
-
-        public ContinueStatement(
-            Location location,
-            String   optionalLabel
-        ) {
-            super(location);
-            this.optionalLabel = optionalLabel;
-        }
-        public String toString() {
-            return this.optionalLabel == null ? "continue;" : "continue " + this.optionalLabel + ';';
-        }
-
-        // Compile time members:
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitContinueStatement(this); }
-    }
-
-    /**
-     * Represents the "empty statement", i.e. the blank semicolon.
-     */
-    public final static class EmptyStatement extends Statement {
-        public EmptyStatement(Location location) {
-            super(location);
-        }
-        public String toString() {
-            return ";";
-        }
-
-        public final void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitEmptyStatement(this); }
-    }
-
-    /**
-     * Abstract base class for {@link Java.Type}, {@link Java.Rvalue} and
-     * {@link Java.Lvalue}.
-     */
-    public static abstract class Atom extends Located {
-        public Atom(Location location) {
-            super(location);
-        }
-
-        public Type   toType()   { return null; }
-        public Rvalue toRvalue() { return null; }
-        public Lvalue toLvalue() { return null; }
-
-        public abstract String toString();
-
-        // Parse time members:
-
-        public final Type toTypeOrPE() throws Parser.ParseException {
-            Type result = this.toType();
-            if (result == null) this.throwParseException("Expression \"" + this.toString() + "\" is not a type");
-            return result;
-        }
-        public final Rvalue toRvalueOrPE() throws Parser.ParseException {
-            Rvalue result = this.toRvalue();
-            if (result == null) this.throwParseException("Expression \"" + this.toString() + "\" is not an rvalue");
-            return result;
-        }
-        public final Lvalue toLvalueOrPE() throws Parser.ParseException {
-            Lvalue result = this.toLvalue();
-            if (result == null) this.throwParseException("Expression \"" + this.toString() + "\" is not an lvalue");
-            return result;
-        }
-
-        public abstract void accept(Visitor.AtomVisitor visitor);
-    }
-
-    /**
-     * Representation of a Java<sup>TM</sup> type.
-     */
-    public static abstract class Type extends Atom {
-        private Scope enclosingScope = null;
-
-        protected Type(Location location) {
-            super(location);
-        }
-
-        /**
-         * Sets the enclosing scope for this object and all subordinate
-         * {@link org.codehaus.janino.Java.Type} objects.
-         */
-        public void setEnclosingScope(final Scope enclosingScope) {
-            if (this.enclosingScope != null && enclosingScope != this.enclosingScope) throw new RuntimeException("Enclosing scope already set for type \"" + this.toString() + "\" at " + this.getLocation());
-            this.enclosingScope = enclosingScope;
-        }
-        public Scope getEnclosingScope() {
-            return this.enclosingScope;
-        }
-        public Type toType() { return this; }
-
-        public abstract void accept(Visitor.TypeVisitor visitor);
-    }
-
-    public static final class SimpleType extends Type {
-        public final IClass iClass;
-
-        public SimpleType(Location location, IClass iClass) {
-            super(location);
-            this.iClass = iClass;
-        }
-        public String toString() { return this.iClass.toString(); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitSimpleType(this); }
-        public final void accept(Visitor.TypeVisitor visitor) { visitor.visitSimpleType(this); }
-    };
-
-    /**
-     * Representation of a Java<sup>TM</sup> "basic type" (obviously
-     * equaivalent to a "primitive type") (JLS 4.2).
-     */
-    public static final class BasicType extends Type {
-        public /*final*/ int index;
-
-        public BasicType(Location location, int index) {
-            super(location);
-            this.index = index;
-        }
-
-        public String toString() {
-            switch (this.index) {
-                case BasicType.VOID:    return "void";
-                case BasicType.BYTE:    return "byte";
-                case BasicType.SHORT:   return "short";
-                case BasicType.CHAR:    return "char";
-                case BasicType.INT:     return "int";
-                case BasicType.LONG:    return "long";
-                case BasicType.FLOAT:   return "float";
-                case BasicType.DOUBLE:  return "double";
-                case BasicType.BOOLEAN: return "boolean";
-                default: throw new RuntimeException("Invalid index " + this.index);
-            }
-        }
-
-        public final void accept(Visitor.TypeVisitor visitor) { visitor.visitBasicType(this); }
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitBasicType(this); }
-
-        public static final int VOID    = 0;
-        public static final int BYTE    = 1;
-        public static final int SHORT   = 2;
-        public static final int CHAR    = 3;
-        public static final int INT     = 4;
-        public static final int LONG    = 5;
-        public static final int FLOAT   = 6;
-        public static final int DOUBLE  = 7;
-        public static final int BOOLEAN = 8;
-    }
-
-    public static final class ReferenceType extends Type {
-        public final String[] identifiers;
-
-        public ReferenceType(
-            Location location,
-            String[] identifiers
-        ) {
-            super(location);
-            this.identifiers = identifiers;
-        }
-
-        public String toString() { return Java.join(this.identifiers, "."); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitReferenceType(this); }
-        public final void accept(Visitor.TypeVisitor visitor) { visitor.visitReferenceType(this); }
-    }
-
-    // Helper class for JLS 15.9.1
-    public static final class RvalueMemberType extends Type {
-        public final Rvalue rvalue;
-        public final String identifier;
-
-        /**
-         * Notice: The <code>rvalue</code> is not a subordinate object!
-         */
-        public RvalueMemberType(
-            Location location,
-            Rvalue   rvalue,
-            String   identifier
-        ) {
-            super(location);
-            this.rvalue     = rvalue;
-            this.identifier = identifier;
-        }
-
-        public String toString() { return this.identifier; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitRvalueMemberType(this); }
-        public final void accept(Visitor.TypeVisitor visitor) { visitor.visitRvalueMemberType(this); }
-    }
-
-
-    /**
-     * Representation of a Java<sup>TM</sup> array type (JLS 10.1).
-     */
-    public static final class ArrayType extends Type {
-        public final Type componentType;
-
-        public ArrayType(Type componentType) {
-            super(componentType.getLocation());
-            this.componentType = componentType;
-        }
-
-        public void setEnclosingScope(final Scope enclosingScope) {
-            super.setEnclosingScope(enclosingScope);
-            this.componentType.setEnclosingScope(enclosingScope);
-        }
-        public String toString() {
-            return this.componentType.toString() + "[]";
-        }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitArrayType(this); }
-        public final void accept(Visitor.TypeVisitor visitor) { visitor.visitArrayType(this); }
-    }
-
-    /**
-     * Representation of an "rvalue", i.e. an expression that has a type and
-     * a value, but cannot be assigned to: An expression that can be the
-     * right-hand-side of an assignment.
-     */
-    public static abstract class Rvalue extends Atom implements ArrayInitializerOrRvalue {
-        private Java.BlockStatement enclosingBlockStatement = null;
-
-        protected Rvalue(Location location) {
-            super(location);
-        }
-
-        /**
-         * Sets enclosing block statement for this object and all subordinate
-         * {@link org.codehaus.janino.Java.Rvalue} objects.
-         */
-        public final void setEnclosingBlockStatement(final Java.BlockStatement enclosingBlockStatement) {
-            this.accept((Visitor.RvalueVisitor) new Traverser() {
-                public void traverseRvalue(Java.Rvalue rv) {
-                    if (rv.enclosingBlockStatement != null && enclosingBlockStatement != rv.enclosingBlockStatement) throw new RuntimeException("Enclosing block statement for rvalue \"" + rv + "\" at " + rv.getLocation() + " is already set");
-                    rv.enclosingBlockStatement = enclosingBlockStatement;
-                    super.traverseRvalue(rv);
-                }
-                public void traverseAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) {
-                    acd.setEnclosingScope(enclosingBlockStatement);
-                    ;
-                }
-                public void traverseType(Java.Type t) {
-                    if (t.enclosingScope != null && enclosingBlockStatement != t.enclosingScope) throw new RuntimeException("Enclosing scope already set for type \"" + this.toString() + "\" at " + t.getLocation());
-                    t.enclosingScope = enclosingBlockStatement;
-//                    t.setEnclosingScope(enclosingBlockStatement);
-                    super.traverseType(t);
-                }
-            }.comprehensiveVisitor());
-        }
-        public Java.BlockStatement getEnclosingBlockStatement() {
-            return this.enclosingBlockStatement;
-        }
-        public Rvalue toRvalue() { return this; }
-
-        static final Object CONSTANT_VALUE_UNKNOWN = new Object();
-        Object              constantValue = Java.Rvalue.CONSTANT_VALUE_UNKNOWN;
-        public static final Object CONSTANT_VALUE_NULL = new Throwable();
-
-        public abstract void accept(Visitor.RvalueVisitor rvv);
-
-        public final static boolean JUMP_IF_TRUE  = true;
-        public final static boolean JUMP_IF_FALSE = false;
-    }
-
-    /**
-     * Base class for {@link Java.Rvalue}s that compile better as conditional
-     * branches.
-     */
-    public static abstract class BooleanRvalue extends Rvalue {
-        protected BooleanRvalue(Location location) {
-            super(location);
-        }
-    }
-
-    /**
-     * Representation of an "lvalue", i.e. an expression that has a type and
-     * a value, and can be assigned to: An expression that can be the
-     * left-hand-side of an assignment.
-     */
-    public static abstract class Lvalue extends Rvalue {
-        protected Lvalue(Location location) {
-            super(location);
-        }
-
-        public Lvalue toLvalue() { return this; }
-
-        public abstract void accept(Visitor.LvalueVisitor lvv);
-    }
-
-    /**
-     * This class is special: It does not extend/implement the Atom subclasses,
-     * but overrides Atom's "to...()" methods.
-     */
-    public static final class AmbiguousName extends Lvalue {
-        public final String[] identifiers;
-        public final int      n;
-
-        public AmbiguousName(
-            Location location,
-            String[] identifiers
-        ) {
-            this(location, identifiers, identifiers.length);
-        }
-        public AmbiguousName(
-            Location location,
-            String[] identifiers,
-            int      n
-        ) {
-            super(location);
-            this.identifiers = identifiers;
-            this.n           = n;
-        }
-
-        // Override "Atom.toType()".
-        private Type type = null;
-        public Type toType() {
-            if (this.type == null) {
-                String[] is = new String[this.n];
-                System.arraycopy(this.identifiers, 0, is, 0, this.n);
-                this.type = new ReferenceType(this.getLocation(), is);
-                this.type.setEnclosingScope(this.getEnclosingBlockStatement());
-            }
-            return this.type;
-        }
-
-        // Compile time members.
-
-        public String toString() {
-            return Java.join(this.identifiers, ".", 0, this.n);
-        }
-
-        Atom reclassified = null;
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitAmbiguousName(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitAmbiguousName(this); }
-        public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitAmbiguousName(this); }
-    }
-
-    // Helper class for 6.5.2.1.7, 6.5.2.2.1
-    public static final class Package extends Atom {
-        public final String name;
-
-        public Package(Location location, String name) {
-            super(location);
-            this.name = name;
-        }
-        public String toString() { return this.name; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitPackage(this); }
-    }
-
-    /**
-     * Representation of a local variable access -- used during compilation.
-     */
-    public static final class LocalVariableAccess extends Lvalue {
-        public /*final*/ LocalVariable localVariable;
-
-        public LocalVariableAccess(
-            Location      location,
-            LocalVariable localVariable
-        ) {
-            super(location);
-            this.localVariable = localVariable;
-        }
-
-        // Compile time members.
-
-        public String toString() { return this.localVariable.toString(); }
-
-        public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitLocalVariableAccess(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitLocalVariableAccess(this); }
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitLocalVariableAccess(this); }
-    }
-
-    /**
-     * Representation of an access to a field of a class or an interface. (Does not implement the
-     * "array length" expression, e.g. "ia.length".)
-     */
-    public static final class FieldAccess extends Lvalue {
-        public final Atom           lhs;
-        public final IClass.IField  field;
-
-        public FieldAccess(
-            Location       location,
-            Atom           lhs,
-            IClass.IField  field
-        ) {
-            super(location);
-            this.lhs   = lhs;
-            this.field = field;
-        }
-
-        // Compile time members.
-
-        // Implement "Atom".
-        public String toString() { return this.lhs.toString() + '.' + this.field.toString(); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitFieldAccess(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitFieldAccess(this); }
-        public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitFieldAccess(this); }
-    }
-
-    public static final class ArrayLength extends Rvalue {
-        public final Rvalue lhs;
-
-        public ArrayLength(
-            Location location,
-            Rvalue   lhs
-        ) {
-            super(location);
-            this.lhs = lhs;
-        }
-
-        // Compile time members.
-
-        // Implement "Atom".
-        public String toString() { return this.lhs.toString() + ".length"; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitArrayLength(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitArrayLength(this); }
-    }
-
-    /**
-     * Representation of an access to the innermost enclosing instance.
-     */
-    public static final class ThisReference extends Rvalue {
-
-        /**
-         * Access the declaring class.
-         */
-        public ThisReference(Location location) {
-            super(location);
-        }
-
-        // Compile time members.
-
-        IClass iClass = null;
-
-        // Implement "Atom".
-        public String toString() { return "this"; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitThisReference(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitThisReference(this); }
-    }
-
-    /**
-     * Representation of an access to the current object or an enclosing instance.
-     */
-    public static final class QualifiedThisReference extends Rvalue {
-        public final Type qualification;
-
-        /**
-         * Access the given enclosing instance of the declaring class.
-         */
-        public QualifiedThisReference(
-            Location location,
-            Type     qualification
-        ) {
-            super(location);
-
-            if (qualification == null) throw new NullPointerException();
-            this.qualification = qualification;
-        }
-
-        // Compile time members.
-
-        ClassDeclaration    declaringClass               = null;
-        TypeBodyDeclaration declaringTypeBodyDeclaration = null;
-        IClass              targetIClass                 = null;
-
-        // Used at compile time.
-//        public QualifiedThisReference(
-//            Location            location,
-//            ClassDeclaration    declaringClass,
-//            TypeBodyDeclaration declaringTypeBodyDeclaration,
-//            IClass              targetIClass
-//        ) {
-//            super(location);
-//            if (declaringClass               == null) throw new NullPointerException();
-//            if (declaringTypeBodyDeclaration == null) throw new NullPointerException();
-//            if (targetIClass                 == null) throw new NullPointerException();
-//
-//            this.qualification                = null;
-//            this.declaringClass               = declaringClass;
-//            this.declaringTypeBodyDeclaration = declaringTypeBodyDeclaration;
-//            this.targetIClass                 = targetIClass;
-//        }
-
-        // Implement "Atom".
-        public String toString() {
-            return this.qualification.toString() + ".this";
-        }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitQualifiedThisReference(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitQualifiedThisReference(this); }
-    }
-
-    public static final class ClassLiteral extends Rvalue {
-        public final Type type;
-
-        public ClassLiteral(
-            Location location,
-            Type     type
-        ) {
-            super(location);
-            this.type = type;
-        }
-
-        // Compile time members.
-
-        //Implement "Atom".
-        public String toString() { return this.type.toString() + ".class"; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitClassLiteral(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitClassLiteral(this); }
-    }
-
-    public static final class Assignment extends Rvalue {
-        public final Lvalue lhs;
-        public final String operator;
-        public final Rvalue rhs;
-
-        public Assignment(
-            Location location,
-            Lvalue   lhs,
-            String   operator,
-            Rvalue   rhs
-        ) {
-            super(location);
-            this.lhs      = lhs;
-            this.operator = operator;
-            this.rhs      = rhs;
-        }
-
-        // Compile time members.
-
-        // Implement "Atom".
-        public String toString() { return this.lhs.toString() + ' ' + this.operator + ' ' + this.rhs.toString(); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitAssignment(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitAssignment(this); }
-    }
-
-    public static final class ConditionalExpression extends Rvalue {
-        public final Rvalue lhs, mhs, rhs;
-
-        public ConditionalExpression(
-            Location location,
-            Rvalue   lhs,
-            Rvalue   mhs,
-            Rvalue   rhs
-        ) {
-            super(location);
-            this.lhs = lhs;
-            this.mhs = mhs;
-            this.rhs = rhs;
-        }
-
-        // Implement "Atom".
-        public String toString() { return this.lhs.toString() + " ? " + this.mhs.toString() + " : " + this.rhs.toString(); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitConditionalExpression(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitConditionalExpression(this); }
-    }
-
-    /**
-     * Objects of this class represent represent one pre- or post-increment
-     * or decrement.
-     */
-    public static final class Crement extends Rvalue {
-        public final boolean pre;
-        public final String  operator; // "++" or "--"
-        public final Lvalue  operand;
-
-        public Crement(Location location, String operator, Lvalue operand) {
-            super(location);
-            this.pre      = true;
-            this.operator = operator;
-            this.operand  = operand;
-        }
-        public Crement(Location location, Lvalue operand, String operator) {
-            super(location);
-            this.pre      = false;
-            this.operator = operator;
-            this.operand  = operand;
-        }
-
-        // Compile time members.
-
-        // Implement "Atom".
-        public String toString() {
-            return (
-                this.pre ?
-                this.operator + this.operand :
-                this.operand + this.operator
-            );
-        }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitCrement(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitCrement(this); }
-    }
-
-    /**
-     * This class implements an array access.
-     */
-    public static final class ArrayAccessExpression extends Lvalue {
-        public final Rvalue lhs;
-        public final Rvalue index;
-
-        public ArrayAccessExpression(
-            Location location,
-            Rvalue   lhs,
-            Rvalue   index
-        ) {
-            super(location);
-            this.lhs = lhs;
-            this.index = index;
-        }
-
-        // Compile time members:
-
-        // Implement "Atom".
-        public String toString() { return this.lhs.toString() + '[' + this.index + ']'; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitArrayAccessExpression(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitArrayAccessExpression(this); }
-        public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitArrayAccessExpression(this); }
-    }
-
-    /**
-     * This class implements class or interface field access, and also the "array length"
-     * expression "xy.length".
-     */
-    public static final class FieldAccessExpression extends Lvalue {
-        public final Atom   lhs;
-        public final String fieldName;
-
-        public FieldAccessExpression(
-            Location location,
-            Atom     lhs,
-            String   fieldName
-        ) {
-            super(location);
-            this.lhs       = lhs;
-            this.fieldName = fieldName;
-        }
-
-        // Compile time members:
-
-        // Implement "Atom".
-        public String toString() { return this.lhs.toString() + '.' + this.fieldName; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitFieldAccessExpression(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitFieldAccessExpression(this); }
-        public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitFieldAccessExpression(this); }
-
-        Rvalue value = null;
-    }
-
-    /**
-     * Representation of "super.fld" and "Type.super.fld".
-     */
-    public static final class SuperclassFieldAccessExpression extends Lvalue {
-        public final Type   optionalQualification;
-        public final String fieldName;
-        
-        public SuperclassFieldAccessExpression(
-            Location location,
-            Type     optionalQualification,
-            String   fieldName
-        ) {
-            super(location);
-            this.optionalQualification = optionalQualification;
-            this.fieldName             = fieldName;
-        }
-        
-        // Compile time members.
-        
-        // Implement "Atom".
-        public String toString() { return (this.optionalQualification == null ? "super." : this.optionalQualification.toString() + ".super.") + this.fieldName; }
-        
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitSuperclassFieldAccessExpression(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitSuperclassFieldAccessExpression(this); }
-        public final void accept(Visitor.LvalueVisitor visitor) { visitor.visitSuperclassFieldAccessExpression(this); }
-
-        Rvalue value = null;
-    }
-    
-    /**
-     * This class implements the unary operators "+", "-", "~" and "!".
-     */
-    public static final class UnaryOperation extends BooleanRvalue {
-        public final String operator;
-        public final Rvalue operand;
-
-        public UnaryOperation(
-            Location location,
-            String   operator,
-            Rvalue   operand
-        ) {
-            super(location);
-            this.operator = operator;
-            this.operand  = operand;
-        }
-
-        // Implement "Atom".
-        public String toString() { return this.operator + this.operand.toString(); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitUnaryOperation(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitUnaryOperation(this); }
-    }
-
-    public static final class Instanceof extends Rvalue {
-        public final Rvalue lhs;
-        public final Type   rhs;
-
-        public Instanceof(
-            Location location,
-            Rvalue   lhs,
-            Type     rhs // ReferenceType or ArrayType
-        ) {
-            super(location);
-            this.lhs = lhs;
-            this.rhs = rhs;
-        }
-
-        // Compile time members.
-
-        // Implement "Atom".
-        public String toString() { return this.lhs.toString() + " instanceof " + this.rhs.toString(); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitInstanceof(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitInstanceof(this); }
-    }
-
-    /**
-     * Representation of all non-operand-modifying Java<sup>TM</sup> binary
-     * operations.
-     * <p>
-     * Operations with boolean result:<br>
-     * <tt>|| && == != < > <= >=</tt>
-     * <p>
-     * Operations with non-boolean result:<br>
-     * <tt>| ^ & * / % + - << >> >>></tt>
-     */
-    public static final class BinaryOperation extends BooleanRvalue {
-        public final Rvalue lhs;
-        public final String op;
-        public final Rvalue rhs;
-
-        public BinaryOperation(
-            Location location,
-            Rvalue   lhs,
-            String   op,
-            Rvalue   rhs
-        ) {
-            super(location);
-            this.lhs = lhs;
-            this.op = op;
-            this.rhs = rhs;
-        }
-
-        // Compile time members.
-
-        // Implement "Atom".
-        public String toString() {
-            return this.lhs.toString() + ' ' + this.op + ' ' + this.rhs.toString();
-        }
-
-        /**
-         * Returns an {@link Iterator} over a left-to-right sequence of {@link Java.Rvalue}s.
-         */
-        public Iterator unrollLeftAssociation() {
-            List operands = new ArrayList();
-            BinaryOperation x = this;
-            for (;;) {
-                operands.add(x.rhs);
-                Rvalue lhs = x.lhs;
-                if (
-                    lhs instanceof BinaryOperation &&
-                    ((BinaryOperation) lhs).op == this.op
-                ) {
-                    x = (BinaryOperation) lhs;
-                } else {
-                    operands.add(lhs);
-                    break;
-                }
-            }
-            return new ReverseListIterator(operands.listIterator(operands.size()));
-        }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitBinaryOperation(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitBinaryOperation(this); }
-    }
-
-    public static final class Cast extends Rvalue {
-        public final Type   targetType;
-        public final Rvalue value;
-
-        public Cast(
-            Location location,
-            Type     targetType,
-            Rvalue   value
-        ) {
-            super(location);
-            this.targetType = targetType;
-            this.value      = value;
-        }
-
-        // Compile time members.
-
-        // Implement "Atom".
-        public String toString() { return '(' + this.targetType.toString() + ") " + this.value.toString(); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitCast(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitCast(this); }
-    }
-
-    public final static class ParenthesizedExpression extends Lvalue {
-        public final Rvalue value;
-
-        public ParenthesizedExpression(Location location, Rvalue value) {
-            super(location);
-            this.value = value;
-        }
-
-        public String toString() {
-            return '(' + this.value.toString() + ')';
-        }
-        public void accept(Visitor.AtomVisitor visitor) { visitor.visitParenthesizedExpression(this); }
-        public void accept(Visitor.RvalueVisitor visitor) { visitor.visitParenthesizedExpression(this); }
-        public void accept(Visitor.LvalueVisitor visitor) { visitor.visitParenthesizedExpression(this); }
-    }
-
-    public static abstract class ConstructorInvocation extends Atom implements BlockStatement {
-        public final Rvalue[] arguments;
-        private Scope         enclosingScope = null;
-
-        protected ConstructorInvocation(
-            Location location,
-            Rvalue[] arguments
-        ) {
-            super(location);
-            this.arguments = arguments;
-            for (int i = 0; i < arguments.length; ++i) arguments[i].setEnclosingBlockStatement(this);
-        }
-
-        // Implement BlockStatement
-        public void setEnclosingScope(Scope enclosingScope) {
-            if (this.enclosingScope != null && enclosingScope != null) throw new RuntimeException("Enclosing scope is already set for statement \"" + this.toString() + "\" at " + this.getLocation());
-            this.enclosingScope = enclosingScope;
-        }
-        public Scope getEnclosingScope() { return this.enclosingScope; }
-
-        // Compile time members
-        public Map localVariables = null; // String name => Java.LocalVariable
-        public Java.LocalVariable findLocalVariable(String name) {
-            if (this.localVariables == null) { return null; }
-            return (LocalVariable) this.localVariables.get(name);
-        }
-    }
-
-    public final static class AlternateConstructorInvocation extends ConstructorInvocation {
-        public AlternateConstructorInvocation(
-            Location location,
-            Rvalue[] arguments
-        ) {
-            super(location, arguments);
-        }
-
-        // Implement Atom.
-        public String toString() { return "this()"; }
-        public void accept(Visitor.AtomVisitor visitor) { ((Visitor.BlockStatementVisitor) visitor).visitAlternateConstructorInvocation(this); }
-
-        // Implement BlockStatement.
-        public void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitAlternateConstructorInvocation(this); }
-    }
-
-    public final static class SuperConstructorInvocation extends ConstructorInvocation {
-        public final Rvalue optionalQualification;
-
-        public SuperConstructorInvocation(
-            Location              location,
-            Rvalue                optionalQualification,
-            Rvalue[]              arguments
-        ) {
-            super(location, arguments);
-            this.optionalQualification = optionalQualification;
-            if (optionalQualification != null) optionalQualification.setEnclosingBlockStatement(this);
-        }
-
-        // Implement Atom.
-        public String toString() { return "super()"; }
-        public void accept(Visitor.AtomVisitor visitor) { ((Visitor.BlockStatementVisitor) visitor).visitSuperConstructorInvocation(this); }
-
-        // Implement BlockStatement.
-        public void accept(Visitor.BlockStatementVisitor visitor) { visitor.visitSuperConstructorInvocation(this); }
-    }
-
-    public static final class MethodInvocation extends Invocation {
-        public final Atom   optionalTarget; // null == simple method name.
-        public final String methodName;
-
-        public MethodInvocation(
-            Location location,
-            Atom     optionalTarget,
-            String   methodName,
-            Rvalue[] arguments
-        ) {
-            super(location, arguments);
-            this.optionalTarget = optionalTarget;
-            this.methodName     = methodName;
-        }
-
-        // Implement "Atom".
-        IClass.IMethod iMethod;
-        public String toString() {
-            StringBuffer sb = new StringBuffer();
-            if (this.optionalTarget != null) sb.append(this.optionalTarget.toString()).append('.');
-            sb.append(this.methodName).append('(');
-            for (int i = 0; i < this.arguments.length; ++i) {
-                if (i > 0) sb.append(", ");
-                sb.append(this.arguments[i].toString());
-            }
-            sb.append(')');
-            return sb.toString();
-        }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitMethodInvocation(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitMethodInvocation(this); }
-    }
-
-    public static final class SuperclassMethodInvocation extends Invocation {
-        public final String methodName;
-
-        public SuperclassMethodInvocation(
-            Location       location,
-            String         methodName,
-            Rvalue[]       arguments
-        ) {
-            super(location, arguments);
-            this.methodName = methodName;
-        }
-
-        // Implement "Atom".
-        public String toString() { return "super." + this.methodName + "()"; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitSuperclassMethodInvocation(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitSuperclassMethodInvocation(this); }
-    }
-
-    public static abstract class Invocation extends Rvalue {
-        public final Rvalue[] arguments;
-
-        protected Invocation(
-            Location location,
-            Rvalue[] arguments
-        ) {
-            super(location);
-            this.arguments = arguments;
-        }
-    }
-
-    public static final class NewClassInstance extends Rvalue {
-        public final Rvalue   optionalQualification;
-        public final Type     type;
-        public final Rvalue[] arguments;
-
-        public NewClassInstance(
-            Location location,
-            Rvalue   optionalQualification,
-            Type     type,
-            Rvalue[] arguments
-        ) {
-            super(location);
-            this.optionalQualification = optionalQualification;
-            this.type                  = type;
-            this.arguments             = arguments;
-        }
-
-        // Compile time members.
-
-        protected IClass iClass = null;
-
-        public NewClassInstance(
-            Location location,
-            Rvalue   optionalQualification,
-            IClass   iClass,
-            Rvalue[] arguments
-        ) {
-            super(location);
-            this.optionalQualification = optionalQualification;
-            this.type                  = null;
-            this.arguments             = arguments;
-            this.iClass                = iClass;
-        }
-
-        // Implement "Atom".
-        public String toString() {
-            StringBuffer sb = new StringBuffer();
-            if (this.optionalQualification != null) sb.append(this.optionalQualification.toString()).append('.');
-            sb.append("new ");
-            if (this.type != null) {
-                sb.append(this.type.toString());
-            } else
-            if (this.iClass != null) {
-                sb.append(this.iClass.toString());
-            } else {
-                sb.append("???");
-            }
-            sb.append('(');
-            for (int i = 0; i < this.arguments.length; ++i) {
-                if (i > 0) sb.append(", ");
-                sb.append(this.arguments[i].toString());
-            }
-            sb.append(')');
-            return sb.toString();
-        }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitNewClassInstance(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitNewClassInstance(this); }
-    }
-
-    public static final class NewAnonymousClassInstance extends Rvalue {
-        public final Rvalue                    optionalQualification;
-        public final AnonymousClassDeclaration anonymousClassDeclaration;
-        public final Rvalue[]                  arguments;
-
-        public NewAnonymousClassInstance(
-            Location                  location,
-            Rvalue                    optionalQualification,
-            AnonymousClassDeclaration anonymousClassDeclaration,
-            Rvalue[]                  arguments
-        ) {
-            super(location);
-            this.optionalQualification     = optionalQualification;
-            this.anonymousClassDeclaration = anonymousClassDeclaration;
-            this.arguments                 = arguments;
-        }
-
-        // Implement "Atom".
-        public String toString() {
-            StringBuffer sb = new StringBuffer();
-            if (this.optionalQualification != null) sb.append(this.optionalQualification.toString()).append('.');
-            sb.append("new ").append(this.anonymousClassDeclaration.baseType.toString()).append("() { ... }");
-            return sb.toString();
-        }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitNewAnonymousClassInstance(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitNewAnonymousClassInstance(this); }
-    }
-
-    // Used during compile-time.
-    public static final class ParameterAccess extends Rvalue {
-        public final FunctionDeclarator.FormalParameter formalParameter;
-
-        public ParameterAccess(
-            Location             location,
-            FunctionDeclarator.FormalParameter formalParameter
-        ) {
-            super(location);
-            this.formalParameter   = formalParameter;
-        }
-
-        // Implement Atom
-        public String toString() { return this.formalParameter.name; }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitParameterAccess(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitParameterAccess(this); }
-    }
-
-    public static final class NewArray extends Rvalue {
-        public final Type     type;
-        public final Rvalue[] dimExprs;
-        public final int      dims;
-
-        /**
-         * Create a new array with dimension dimExprs.length + dims
-         * <p>
-         * e.g. byte[12][][] is created with
-         *     new NewArray(
-         *         null,
-         *         Java.BasicType(NULL, Java.BasicType.BYTE),
-         *         new Rvalue[] {
-         *             new Java.Literal(null, Integer.valueOf(12)
-         *         },
-         *         2
-         *     )
-         * @param location  the location of this element
-         * @param type      the base type of the array
-         * @param dimExprs  sizes for dimensions being allocated with specific sizes
-         * @param dims      the number of dimensions that are not yet allocated
-         */
-        public NewArray(
-            Location location,
-            Type     type,
-            Rvalue[] dimExprs,
-            int      dims
-        ) {
-            super(location);
-            this.type     = type;
-            this.dimExprs = dimExprs;
-            this.dims     = dims;
-        }
-
-        // Implement "Atom".
-        public String toString() { return "new " + this.type.toString() + "[]..."; }
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitNewArray(this); }
-
-        // Implement "Rvalue".
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitNewArray(this); }
-    }
-
-    public static final class NewInitializedArray extends Rvalue {
-        public final ArrayType        arrayType;
-        public final ArrayInitializer arrayInitializer;
-
-        public NewInitializedArray(
-            Location         location,
-            ArrayType        arrayType,
-            ArrayInitializer arrayInitializer
-        ) {
-            super(location);
-            this.arrayType        = arrayType;
-            this.arrayInitializer = arrayInitializer;
-        }
-
-        // Implement "Atom".
-        public String toString() { return "new " + this.arrayType.toString() + " { ... }"; }
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitNewInitializedArray(this); }
-
-        // Implement "Rvalue".
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitNewInitializedArray(this); }
-    }
-
-    /**
-     * Represents a Java<sup>TM</sup> array initializer (JLS 10.6).
-     * <p>
-     * Allocates an array and initializes its members with (not necessarily
-     * constant) values.
-     */
-    public static final class ArrayInitializer extends Located implements ArrayInitializerOrRvalue {
-        public final ArrayInitializerOrRvalue[] values;
-
-        public ArrayInitializer(
-            Location                   location,
-            ArrayInitializerOrRvalue[] values
-        ) {
-            super(location);
-            this.values = values;
-        }
-        public String toString() {
-            return " { (" + this.values.length + " values) }";
-        }
-    }
-
-    public interface ArrayInitializerOrRvalue {
-    }
-
-    public static final class Literal extends Rvalue {
-        public final Object value; // The "null" literal has "value == null".
-
-        /**
-         * @param value An {@link Integer}, {@link Long}, {@link Float}, {@link Double}, {@link String}, {@link Character}, {@link Boolean}, or <code>null</code>
-         */
-        public Literal(Location location, Object value) {
-            super(location);
-            if (!(
-                value instanceof Integer
-                || value instanceof Long
-                || value instanceof Float
-                || value instanceof Double
-                || value instanceof String
-                || value instanceof Character
-                || value instanceof Boolean
-                || value == null
-            )) throw new IllegalArgumentException(value.getClass().getName());
-            this.value = value;
-        }
-
-        // Implement "Atom".
-        public String toString() { return Scanner.literalValueToString(this.value); }
-
-        public final void accept(Visitor.AtomVisitor visitor) { visitor.visitLiteral(this); }
-        public final void accept(Visitor.RvalueVisitor visitor) { visitor.visitLiteral(this); }
-    }
-
-    /**
-     * Used during resolution.
-     */
-    public static class LocalVariable {
-        public final boolean finaL;
-        public final IClass  type;
-        public short         localVariableArrayIndex = -1; // Used during compilation
-
-        public LocalVariable(
-            boolean finaL,
-            IClass  type
-        ) {
-            this.finaL = finaL;
-            this.type  = type;
-        }
-    }
-
-    public static String join(Object[] a, String separator) {
-        return Java.join(a, separator, 0, a.length);
-    }
-
-    public static String join(Object[] a, String separator, int off, int len) {
-        if (a == null) return ("(null)");
-        if (off >= len) return "";
-        StringBuffer sb = new StringBuffer(a[off].toString());
-        for (++off; off < len; ++off) {
-            sb.append(separator);
-            sb.append(a[off]);
-        }
-        return sb.toString();
-    }
-}
diff --git a/src/org/codehaus/janino/JavaSourceClassLoader.java b/src/org/codehaus/janino/JavaSourceClassLoader.java
deleted file mode 100644
index 98e125b..0000000
--- a/src/org/codehaus/janino/JavaSourceClassLoader.java
+++ /dev/null
@@ -1,412 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import java.security.ProtectionDomain;
-
-import org.codehaus.janino.tools.Disassembler;
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * A {@link ClassLoader} that, unlike usual {@link ClassLoader}s,
- * does not load byte code, but reads Java<sup>TM</sup> source code and then scans, parses,
- * compiles and loads it into the virtual machine.
- * <p>
- * As with any {@link ClassLoader}, it is not possible to "update" classes after they've been
- * loaded. The way to achieve this is to give up on the {@link JavaSourceClassLoader} and create
- * a new one.
- */
-public class JavaSourceClassLoader extends ClassLoader {
-    private final static boolean DEBUG = false;
-
-    public interface ProtectionDomainFactory {
-        ProtectionDomain getProtectionDomain(String name);
-    }
-    
-    /**
-     * Read Java<sup>TM</sup> source code for a given class name, scan, parse, compile and load
-     * it into the virtual machine, and invoke its "main()" method with the given args.
-     * <p>
-     * Usage is as follows:
-     * <pre>
-     *   java [ <i>java-option</i> ] org.codehaus.janino.JavaSourceClassLoader [ <i>option</i> ] ... <i>class-name</i> [ <i>arg</i> ] ... 
-     *     <i>java-option</i> Any valid option for the Java Virtual Machine (e.g. "-classpath <i>colon-separated-list-of-class-directories</i>") 
-     *     <i>option</i>:
-     *       -sourcepath <i>colon-separated-list-of-source-directories</i> 
-     *       -encoding <i>character-encoding</i>
-     *       -g                           Generate all debugging info");
-     *       -g:none                      Generate no debugging info");
-     *       -g:{lines,vars,source}       Generate only some debugging info");
-     *       -cache <i>dir</i>                   Cache compiled classes here");
-
-     * </pre>
-     */
-    public static void main(String[] args) {
-        File[]        optionalSourcePath = null;
-        String        optionalCharacterEncoding = null;
-        EnumeratorSet debuggingInformation = DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION;
-        String        optionalCacheDirName = null;
-
-        // Scan command line options.
-        int i;
-        for (i = 0; i < args.length; ++i) {
-            String arg = args[i];
-            if (!arg.startsWith("-")) break;
-
-            if ("-sourcepath".equals(arg)) {
-                optionalSourcePath = PathResourceFinder.parsePath(args[++i]);
-            } else
-            if ("-encoding".equals(arg)) {
-                optionalCharacterEncoding = args[++i]; 
-            } else
-            if (arg.equals("-g")) {
-                debuggingInformation = DebuggingInformation.ALL;
-            } else
-            if (arg.equals("-g:none")) {
-                debuggingInformation = DebuggingInformation.NONE;
-            } else
-            if (arg.startsWith("-g:")) {
-                try {
-                    debuggingInformation = new EnumeratorSet(DebuggingInformation.class, arg.substring(3));
-                } catch (EnumeratorFormatException ex) {
-                    debuggingInformation = DebuggingInformation.NONE;
-                }
-            } else
-            if ("-cache".equals(arg)) {
-                optionalCacheDirName = args[++i]; 
-            } else
-            if ("-help".equals(arg)) {
-                System.out.println("Usage:"); 
-                System.out.println("  java [ <java-option> ] " + JavaSourceClassLoader.class.getName() + " { <option> } <class-name> { <argument> }"); 
-                System.out.println("Load the named class by name and invoke its \"main(String[])\" method,"); 
-                System.out.println("passing the given <argument>s.");
-                System.out.println("  <java-option> Any valid option for the Java Virtual Machine (e.g. \"-classpath <dir>\")"); 
-                System.out.println("  <option>:"); 
-                System.out.println("    -sourcepath <" + File.pathSeparator + "-separated-list-of-source-directories>"); 
-                System.out.println("    -encoding <character-encoding>");
-                System.out.println("    -g                     Generate all debugging info");
-                System.out.println("    -g:none                Generate no debugging info");
-                System.out.println("    -g:{lines,vars,source} Generate only some debugging info");
-                System.out.println("    -cache <dir>           Cache compiled classes here");
-                System.exit(0); 
-            } else
-            {
-                System.err.println("Invalid command line option \"" + arg + "\"; try \"-help\"");
-                System.exit(1);
-            }
-        }
-
-        // Determine class name.
-        if (i == args.length) {
-            System.err.println("No class name given, try \"-help\"");
-            System.exit(1);
-        }
-        String className = args[i++];
-
-        // Determine arguments passed to "main()".
-        String[] mainArgs = new String[args.length - i];
-        System.arraycopy(args, i, mainArgs, 0, args.length - i);
-
-        // Set up a JavaSourceClassLoader or a CachingJavaSourceClassLoader.
-        ClassLoader cl;
-        if (optionalCacheDirName == null) {
-            cl = new JavaSourceClassLoader(
-                ClassLoader.getSystemClassLoader(), // parentClassLoader
-                optionalSourcePath,                 // optionalSourcePath
-                optionalCharacterEncoding,          // optionalCharacterEncoding
-                debuggingInformation                // debuggingInformation
-            );
-        } else {
-            cl = new CachingJavaSourceClassLoader(
-                SimpleCompiler.BOOT_CLASS_LOADER, // parentClassLoader
-                optionalSourcePath,               // optionalSourcePath
-                optionalCharacterEncoding,        // optionalCharacterEncoding
-                new File(optionalCacheDirName),   // cacheDirectory
-                debuggingInformation              // debuggingInformation
-            );
-        }
-
-        // Load the given class.
-        Class clazz;
-        try {
-            clazz = cl.loadClass(className);
-        } catch (ClassNotFoundException ex) {
-            System.err.println("Loading class \"" + className + "\": " + ex.getMessage());
-            System.exit(1);
-            return; // NEVER REACHED
-        }
-
-        // Find its "main" method.
-        Method mainMethod;
-        try {
-            mainMethod = clazz.getMethod("main", new Class[] { String[].class });
-        } catch (NoSuchMethodException ex) {
-            System.err.println("Class \"" + className + "\" has not public method \"main(String[])\".");
-            System.exit(1);
-            return; // NEVER REACHED
-        }
-
-        // Invoke the "main" method.
-        try {
-            mainMethod.invoke(null, new Object[] { mainArgs });
-        } catch (IllegalArgumentException e) {
-            e.printStackTrace();
-            System.exit(1);
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-            System.exit(1);
-        } catch (InvocationTargetException e) {
-            e.printStackTrace();
-            System.exit(1);
-        }
-    }
-
-    /**
-     * Set up a {@link JavaSourceClassLoader} that finds Java<sup>TM</sup> source code in a file
-     * that resides in either of the directories specified by the given source path.
-     * <p>
-     * You can specify to include certain debugging information in the generated class files, which
-     * is useful if you want to debug through the generated classes (see
-     * {@link Scanner#Scanner(String, Reader)}).
-     *
-     * @param parentClassLoader See {@link ClassLoader}
-     * @param optionalSourcePath A collection of directories that are searched for Java<sup>TM</sup> source files in the given order
-     * @param optionalCharacterEncoding The encoding of the Java<sup>TM</sup> source files (<code>null</code> for platform default encoding)
-     * @param debuggingInformation What kind of debugging information to generate, see {@link DebuggingInformation}
-     */
-    public JavaSourceClassLoader(
-        ClassLoader   parentClassLoader,
-        File[]        optionalSourcePath,
-        String        optionalCharacterEncoding,
-        EnumeratorSet debuggingInformation
-    ) {
-        this(
-            parentClassLoader,         // parentClassLoader
-            (                          // sourceFinder
-                optionalSourcePath == null ?
-                (ResourceFinder) new DirectoryResourceFinder(new File(".")) :
-                (ResourceFinder) new PathResourceFinder(optionalSourcePath)
-            ),
-            optionalCharacterEncoding, // optionalCharacterEncoding
-            debuggingInformation       // debuggingInformation
-        );
-    }
-
-    /**
-     * Set up a {@link JavaSourceClassLoader} that finds Java<sup>TM</sup> source code through
-     * a given {@link ResourceFinder}.
-     * <p>
-     * You can specify to include certain debugging information in the generated class files, which
-     * is useful if you want to debug through the generated classes (see
-     * {@link Scanner#Scanner(String, Reader)}).
-     *
-     * @param parentClassLoader See {@link ClassLoader}
-     * @param sourceFinder Used to locate additional source files 
-     * @param optionalCharacterEncoding The encoding of the Java<sup>TM</sup> source files (<code>null</code> for platform default encoding)
-     * @param debuggingInformation What kind of debugging information to generate, see {@link DebuggingInformation}
-     */
-    public JavaSourceClassLoader(
-        ClassLoader    parentClassLoader,
-        ResourceFinder sourceFinder,
-        String         optionalCharacterEncoding,
-        EnumeratorSet  debuggingInformation
-    ) {
-        super(parentClassLoader);
-
-        this.iClassLoader = new JavaSourceIClassLoader(
-            sourceFinder,                                  // sourceFinder
-            optionalCharacterEncoding,                     // optionalCharacterEncoding
-            this.unitCompilers,                            // unitCompilers
-            new ClassLoaderIClassLoader(parentClassLoader) // optionalParentIClassLoader
-        );
-
-        this.debuggingInformation = debuggingInformation;
-    }
-
-    /**
-     * @see UnitCompiler#setCompileErrorHandler
-     */
-    public void setCompileErrorHandler(UnitCompiler.ErrorHandler optionalCompileErrorHandler) {
-        this.iClassLoader.setCompileErrorHandler(optionalCompileErrorHandler);
-    }
-
-    /**
-     * @see Parser#setWarningHandler(WarningHandler)
-     * @see UnitCompiler#setCompileErrorHandler
-     */
-    public void setWarningHandler(WarningHandler optionalWarningHandler) {
-        this.iClassLoader.setWarningHandler(optionalWarningHandler);
-    }
-
-    /**
-     * Implementation of {@link ClassLoader#findClass(String)}.
-     * 
-     * @throws ClassNotFoundException
-     */
-    protected Class findClass(String name) throws ClassNotFoundException {
-
-        // Check if the bytecode for that class was generated already.
-        byte[] bytecode = (byte[]) this.precompiledClasses.remove(name);
-        if (bytecode == null) {
-
-            // Read, scan, parse and compile the right compilation unit.
-            {
-                Map bytecodes = this.generateBytecodes(name);
-                if (bytecodes == null) throw new ClassNotFoundException(name);
-                this.precompiledClasses.putAll(bytecodes);
-            }
-
-            // Now the bytecode for our class should be available.
-            bytecode = (byte[]) this.precompiledClasses.remove(name);
-            if (bytecode == null) throw new RuntimeException("SNO: Scanning, parsing and compiling class \"" + name + "\" did not create a class file!?");
-        }
-
-        return this.defineBytecode(name, bytecode);
-    }
-
-    /**
-     * This {@link Map} keeps those classes which were already compiled, but not
-     * yet defined i.e. which were not yet passed to
-     * {@link ClassLoader#defineClass(java.lang.String, byte[], int, int)}.
-     */
-    Map precompiledClasses = new HashMap(); // String name => byte[] bytecode
-
-    /**
-     * Find, scan, parse the right compilation unit. Compile the parsed compilation unit to
-     * bytecode. This may cause more compilation units being scanned and parsed. Continue until
-     * all compilation units are compiled.
-     *
-     * @return String name => byte[] bytecode, or <code>null</code> if no source code could be found
-     * @throws ClassNotFoundException on compilation problems
-     */
-    protected Map generateBytecodes(String name) throws ClassNotFoundException {
-        if (this.iClassLoader.loadIClass(Descriptor.fromClassName(name)) == null) return null;
-
-        Map bytecodes = new HashMap(); // String name => byte[] bytecode
-        Set compiledUnitCompilers = new HashSet();
-        COMPILE_UNITS:
-        for (;;) {
-            for (Iterator it = this.unitCompilers.iterator(); it.hasNext();) {
-                UnitCompiler uc = (UnitCompiler) it.next();
-                if (!compiledUnitCompilers.contains(uc)) {
-                    ClassFile[] cfs;
-                    try {
-                        cfs = uc.compileUnit(this.debuggingInformation);
-                    } catch (CompileException ex) {
-                        throw new ClassNotFoundException("Compiling unit \"" + uc.compilationUnit.optionalFileName + "\"", ex);
-                    }
-                    for (int i = 0; i < cfs.length; ++i) {
-                        ClassFile cf = cfs[i];
-                        bytecodes.put(cf.getThisClassName(), cf.toByteArray());
-                    }
-                    compiledUnitCompilers.add(uc);
-                    continue COMPILE_UNITS;
-                }
-            }
-            return bytecodes;
-        }
-    }
-
-    /**
-     * Define a set of classes, like
-     * {@link java.lang.ClassLoader#defineClass(java.lang.String, byte[], int, int)}.
-     * If the <code>bytecodes</code> contains an entry for <code>name</code>, then the
-     * {@link Class} defined for that name is returned.
-     *
-     * @param bytecodes String name => byte[] bytecode
-     */
-    protected Class defineBytecodes(String name, Map bytecodes) throws ClassFormatError {
-        Class clazz = null;
-        for (Iterator it = bytecodes.entrySet().iterator(); it.hasNext();) {
-            Map.Entry me = (Map.Entry) it.next();
-            String name2 = (String) me.getKey();
-            byte[] ba = (byte[]) me.getValue();
-
-            Class c = this.defineBytecode(name2, ba);
-            if (name2.equals(name)) clazz = c;
-        }
-        return clazz;
-    }
-
-    /**
-     * Calls {@link java.lang.ClassLoader#defineClass(java.lang.String, byte[], int, int)}
-     * or {@link java.lang.ClassLoader#defineClass(java.lang.String, byte[], int, int, java.security.ProtectionDomain)},
-     * depending on whether or not a {@link ProtectionDomainFactory} was set.
-     *
-     * @see #setProtectionDomainFactory
-     */
-    protected Class defineBytecode(String className, byte[] ba) throws ClassFormatError {
-
-        // Disassemble the the class bytecode(for debugging).
-        if (JavaSourceClassLoader.DEBUG) {
-            System.out.println("*** Disassembly of class \"" + className + "\":");
-            try {
-                new Disassembler().disasm(new ByteArrayInputStream(ba));
-                System.out.flush();
-            } catch (IOException ex) {
-                throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
-            }
-        }
-
-        if (this.protectionDomainFactory == null) {
-            return this.defineClass(className, ba, 0, ba.length);
-        } else
-        {
-            String sourceName = ClassFile.getSourceResourceName(className);
-            ProtectionDomain domain = this.protectionDomainFactory.getProtectionDomain(sourceName);
-            return this.defineClass(className, ba, 0, ba.length, domain);
-        }
-    }
-
-    public void setProtectionDomainFactory(ProtectionDomainFactory protectionDomainFactory) {
-        this.protectionDomainFactory = protectionDomainFactory;
-    }
-
-    private final JavaSourceIClassLoader iClassLoader;
-    private final EnumeratorSet          debuggingInformation;
-    private ProtectionDomainFactory      protectionDomainFactory;
-
-    /**
-     * Collection of parsed, but uncompiled compilation units.
-     */
-    private final Set unitCompilers = new HashSet(); // UnitCompiler
-}
diff --git a/src/org/codehaus/janino/JavaSourceIClassLoader.java b/src/org/codehaus/janino/JavaSourceIClassLoader.java
deleted file mode 100644
index 461215c..0000000
--- a/src/org/codehaus/janino/JavaSourceIClassLoader.java
+++ /dev/null
@@ -1,173 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * This {@link org.codehaus.janino.IClassLoader} finds, scans and parses compilation units.
- * <p>
- * Notice that it does not compile them!
- */
-public final class JavaSourceIClassLoader extends IClassLoader {
-    private static final boolean DEBUG = false;
-
-    private final ResourceFinder      sourceFinder;
-    private final String              optionalCharacterEncoding;
-    private final Set                 unitCompilers; // UnitCompiler
-    private UnitCompiler.ErrorHandler optionalCompileErrorHandler = null;
-    private WarningHandler            optionalWarningHandler = null;
-
-    /**
-     * Notice that the <code>unitCompilers</code> set is both read and written
-     * by the {@link JavaSourceIClassLoader}: As it searches for {@link IClass}es, it looks
-     * into <code>unitCompilers</code> for class declarations, and as it opens,
-     * scans and parses compilation units on-the-fly, it adds them to
-     * <code>unitCompilers</code>.
-     */
-    public JavaSourceIClassLoader(
-        ResourceFinder sourceFinder,
-        String         optionalCharacterEncoding,
-        Set            unitCompilers, // UnitCompiler
-        IClassLoader   optionalParentIClassLoader
-    ) {
-        super(optionalParentIClassLoader);
-
-        this.sourceFinder               = sourceFinder;
-        this.optionalCharacterEncoding  = optionalCharacterEncoding;
-        this.unitCompilers              = unitCompilers;
-        super.postConstruct();
-    }
-
-    /**
-     * @see UnitCompiler#setCompileErrorHandler(ErrorHandler)
-     */
-    public void setCompileErrorHandler(UnitCompiler.ErrorHandler optionalCompileErrorHandler) {
-        this.optionalCompileErrorHandler = optionalCompileErrorHandler;
-    }
-
-    /**
-     * @see Parser#setWarningHandler(WarningHandler)
-     * @see UnitCompiler#setCompileErrorHandler(ErrorHandler)
-     */
-    public void setWarningHandler(WarningHandler optionalWarningHandler) {
-        this.optionalWarningHandler = optionalWarningHandler;
-    }
-
-    /**
-     * @param type field descriptor of the {@link IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
-     * @throws ClassNotFoundException if an exception was raised while loading the {@link IClass}
-     */
-    public IClass findIClass(final String type) throws ClassNotFoundException {
-        if (JavaSourceIClassLoader.DEBUG) System.out.println("type = " + type);
-    
-        // Class type.
-        String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
-        if (JavaSourceIClassLoader.DEBUG) System.out.println("2 className = \"" + className + "\"");
-    
-        // Do not attempt to load classes from package "java".
-        if (className.startsWith("java.")) return null;
-    
-        // Determine the name of the top-level class.
-        String topLevelClassName;
-        {
-            int idx = className.indexOf('$');
-            topLevelClassName = idx == -1 ? className : className.substring(0, idx);
-        }
-
-        // Check the already-parsed compilation units.
-        for (Iterator it = this.unitCompilers.iterator(); it.hasNext();) {
-            UnitCompiler uc = (UnitCompiler) it.next();
-            IClass res = uc.findClass(topLevelClassName);
-            if (res != null) {
-                if (!className.equals(topLevelClassName)) {
-                    res = uc.findClass(className);
-                    if (res == null) return null;
-                }
-                this.defineIClass(res);
-                return res;
-            } 
-        }
-
-        // Find source file.
-        Resource sourceResource = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
-        if (sourceResource == null) return null;
-        if (JavaSourceIClassLoader.DEBUG) System.out.println("sourceURL=" + sourceResource);
-
-        try {
-
-            // Scan and parse the source file.
-            InputStream inputStream = sourceResource.open();
-            Java.CompilationUnit cu;
-            try {
-                Scanner scanner = new Scanner(sourceResource.getFileName(), inputStream, this.optionalCharacterEncoding);
-                scanner.setWarningHandler(this.optionalWarningHandler);
-                Parser parser = new Parser(scanner);
-                parser.setWarningHandler(this.optionalWarningHandler);
-                cu = parser.parseCompilationUnit();
-            } finally {
-                try { inputStream.close(); } catch (IOException ex) {}
-            }
-            UnitCompiler uc = new UnitCompiler(cu, this);
-            uc.setCompileErrorHandler(this.optionalCompileErrorHandler);
-            uc.setWarningHandler(this.optionalWarningHandler);
-
-            // Remember compilation unit for later compilation.
-            this.unitCompilers.add(uc);
-
-            // Find the class/interface declaration in the compiled unit.
-            IClass res = uc.findClass(className);
-            if (res == null) {
-                if (className.equals(topLevelClassName)) throw new Parser.ParseException("Source file \"" + sourceResource.getFileName() + "\" does not declare class \"" + className + "\"", (Location) null);
-                return null;
-            }
-            this.defineIClass(res);
-            return res;
-        } catch (Scanner.ScanException e) {
-            throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", e);
-        } catch (Parser.ParseException e) {
-            throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", e);
-        } catch (IOException e) {
-            throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", e);
-        } catch (CompileException e) {
-            throw new ClassNotFoundException("Parsing compilation unit \"" + sourceResource + "\"", e);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/org/codehaus/janino/Location.java b/src/org/codehaus/janino/Location.java
deleted file mode 100644
index dfe899c..0000000
--- a/src/org/codehaus/janino/Location.java
+++ /dev/null
@@ -1,69 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-/**
- * Represents the location of a character in a file, as defined by
- * file name, line number and column number.
- */
-public class Location {
-    public Location(String optionalFileName, short lineNumber, short columnNumber) {
-        this.optionalFileName = optionalFileName;
-        this.lineNumber       = lineNumber;
-        this.columnNumber     = columnNumber;
-    }
-
-    public String getFileName()     { return this.optionalFileName; }
-    public short  getLineNumber()   { return this.lineNumber; }
-    public short  getColumnNumber() { return this.columnNumber; }
-
-    /**
-     * Converts this {@link Location} into an english text, like<pre>
-     * File Main.java, Line 23, Column 79</pre>
-     */
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        if (this.optionalFileName != null) {
-            sb.append("File ").append(this.optionalFileName).append(", ");
-        }
-        sb.append("Line ").append(this.lineNumber).append(", ");
-        sb.append("Column ").append(this.columnNumber);
-        return sb.toString();
-    }
-
-    private /*final*/ String optionalFileName;
-    private /*final*/ short  lineNumber;
-    private /*final*/ short  columnNumber;
-}
\ No newline at end of file
diff --git a/src/org/codehaus/janino/MethodDescriptor.java b/src/org/codehaus/janino/MethodDescriptor.java
deleted file mode 100644
index d2c312c..0000000
--- a/src/org/codehaus/janino/MethodDescriptor.java
+++ /dev/null
@@ -1,98 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.util.*;
-
-/**
- * Representation of a "method descriptor" (JVMS 4.3.3).
- */
-public class MethodDescriptor {
-
-    /** The field descriptors of the method parameters. */
-    public final String[] parameterFDs;
-
-    /** The field descriptor of the method return value. */
-    public final String   returnFD;
-
-    /** */
-    public MethodDescriptor(String[] parameterFDs, String returnFD) {
-        this.parameterFDs = parameterFDs;
-        this.returnFD     = returnFD;
-    }
-
-    /**
-     * Parse a method descriptor into parameter FDs and return FDs.
-     */
-    public MethodDescriptor(String s) {
-        if (s.charAt(0) != '(') throw new RuntimeException();
-
-        int from = 1;
-        List parameterFDs = new ArrayList(); // String
-        while (s.charAt(from) != ')') {
-            int to = from;
-            while (s.charAt(to) =='[') ++to;
-            if ("BCDFIJSZ".indexOf(s.charAt(to)) != -1) {
-                ++to;
-            } else
-            if (s.charAt(to) == 'L') {
-                for (++to; s.charAt(to) != ';'; ++to);
-                ++to;
-            } else {
-                throw new RuntimeException();
-            }
-            parameterFDs.add(s.substring(from, to));
-            from = to;
-        }
-        this.parameterFDs = (String[]) parameterFDs.toArray(new String[parameterFDs.size()]);
-        this.returnFD = s.substring(++from);
-    }
-
-    /**
-     * Returns the "method descriptor" (JVMS 4.3.3).
-     */
-    public String toString() {
-        StringBuffer sb = new StringBuffer("(");
-        for (int i = 0; i < this.parameterFDs.length; ++i) sb.append(this.parameterFDs[i]);
-        return sb.append(')').append(this.returnFD).toString();
-    }
-
-    /**
-     * Patch an additional parameter into a given method descriptor.
-     */
-    public static String prependParameter(String md, String parameterFD) {
-        return '(' + parameterFD + md.substring(1);
-    }
-}
diff --git a/src/org/codehaus/janino/Mod.java b/src/org/codehaus/janino/Mod.java
deleted file mode 100644
index fd5af52..0000000
--- a/src/org/codehaus/janino/Mod.java
+++ /dev/null
@@ -1,104 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-/**
- * This class defines constants and convenience methods for the handling of
- * modifiers as defined by the JVM.
- * <p>
- * Notice: This class should be named <code>IClass.IModifier</code>, but changing the name would
- * break existing client code. Thus it won't be renamed until there's a really good reason to
- * do it (maybe with a major desing change).
- */
-public class Mod {
-    private Mod() {} // Don't instantiate me!
-
-    public final static short NONE         = 0x0000;
-
-    public final static short PUBLIC       = 0x0001;
-    public final static short PRIVATE      = 0x0002;
-    public final static short PROTECTED    = 0x0004;
-    public final static short PACKAGE      = 0x0000;
-    public final static short PPP          = 0x0007;
-
-    public static boolean isPublicAccess(short sh)    { return (sh & Mod.PPP) == Mod.PUBLIC; }
-    public static boolean isPrivateAccess(short sh)   { return (sh & Mod.PPP) == Mod.PRIVATE; }
-    public static boolean isProtectedAccess(short sh) { return (sh & Mod.PPP) == Mod.PROTECTED; }
-    public static boolean isPackageAccess(short sh)   { return (sh & Mod.PPP) == Mod.PACKAGE; }
-    public static short changeAccess(short sh, short newAccess) { return (short) ((sh & ~Mod.PPP) | newAccess); }
-
-    public final static short STATIC       = 0x0008;
-    public final static short FINAL        = 0x0010;
-    public final static short SUPER        = 0x0020;
-    public final static short SYNCHRONIZED = 0x0020;
-    public final static short VOLATILE     = 0x0040;
-    public final static short TRANSIENT    = 0x0080;
-    public final static short NATIVE       = 0x0100;
-    public final static short INTERFACE    = 0x0200;
-    public final static short ABSTRACT     = 0x0400;
-    public final static short STRICTFP     = 0x0800;
-
-    // Poorly documented JDK 1.5 modifiers:
-    public final static short SYNTHETIC    = 0x1000;
-    public final static short ANNOTATION   = 0x2000;
-    public final static short ENUM         = 0x4000;
-
-    public static String shortToString(short sh) {
-        String res = "";
-        for (int i = 0; i < Mod.mappings.length; i += 2) {
-            if ((sh & ((Short) Mod.mappings[i + 1]).shortValue()) == 0) continue;
-            if (res.length() > 0) res += ' ';
-            res += (String) Mod.mappings[i];
-        }
-        return res;
-    }
-
-    private final static Object[] mappings = {
-        "public",       new Short(Mod.PUBLIC),
-        "private",      new Short(Mod.PRIVATE),
-        "protected",    new Short(Mod.PROTECTED),
-        "static",       new Short(Mod.STATIC),
-        "final",        new Short(Mod.FINAL),
-//      "super",        new Short(Mod.SUPER),
-        "synchronized", new Short(Mod.SYNCHRONIZED),
-        "volatile",     new Short(Mod.VOLATILE),
-        "transient",    new Short(Mod.TRANSIENT),
-        "native",       new Short(Mod.NATIVE),
-        "interface",    new Short(Mod.INTERFACE),
-        "abstract",     new Short(Mod.ABSTRACT),
-        "strictfp",     new Short(Mod.STRICTFP),
-    };
-}
-
diff --git a/src/org/codehaus/janino/Opcode.java b/src/org/codehaus/janino/Opcode.java
deleted file mode 100644
index 0f627c8..0000000
--- a/src/org/codehaus/janino/Opcode.java
+++ /dev/null
@@ -1,612 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-/**
- * Definitions of Java bytecode opcodes.
- */
-
-/*package*/ interface Opcode {
-    public final static byte AALOAD = 50;
-    public final static byte AASTORE = 83;
-    public final static byte ACONST_NULL = 1;
-    public final static byte ALOAD = 25;
-    public final static byte ALOAD_0 = 42;
-    public final static byte ALOAD_1 = 43;
-    public final static byte ALOAD_2 = 44;
-    public final static byte ALOAD_3 = 45;
-    public final static byte ANEWARRAY = (byte) 189;
-    public final static byte ARETURN = (byte) 176;
-    public final static byte ARRAYLENGTH = (byte) 190;
-    public final static byte ASTORE = 58;
-    public final static byte ASTORE_0 = 75;
-    public final static byte ASTORE_1 = 76;
-    public final static byte ASTORE_2 = 77;
-    public final static byte ASTORE_3 = 78;
-    public final static byte ATHROW = (byte) 191;
-    public final static byte BALOAD = 51;
-    public final static byte BASTORE = 84;
-    public final static byte BIPUSH = 16;
-    public final static byte CALOAD = 52;
-    public final static byte CASTORE = 85;
-    public final static byte CHECKCAST = (byte) 192;
-    public final static byte D2F = (byte) 144;
-    public final static byte D2I = (byte) 142;
-    public final static byte D2L = (byte) 143;
-    public final static byte DADD = 99;
-    public final static byte DALOAD = 49;
-    public final static byte DASTORE = 82;
-    public final static byte DCMPG = (byte) 152;
-    public final static byte DCMPL = (byte) 151;
-    public final static byte DCONST_0 = 14;
-    public final static byte DCONST_1 = 15;
-    public final static byte DDIV = 111;
-    public final static byte DLOAD = 24;
-    public final static byte DLOAD_0 = 38;
-    public final static byte DLOAD_1 = 39;
-    public final static byte DLOAD_2 = 40;
-    public final static byte DLOAD_3 = 41;
-    public final static byte DMUL = 107;
-    public final static byte DNEG = 119;
-    public final static byte DREM = 115;
-    public final static byte DRETURN = (byte) 175;
-    public final static byte DSTORE = 57;
-    public final static byte DSTORE_0 = 71;
-    public final static byte DSTORE_1 = 72;
-    public final static byte DSTORE_2 = 73;
-    public final static byte DSTORE_3 = 74;
-    public final static byte DSUB = 103;
-    public final static byte DUP = 89;
-    public final static byte DUP_X1 = 90;
-    public final static byte DUP_X2 = 91;
-    public final static byte DUP2 = 92;
-    public final static byte DUP2_X1 = 93;
-    public final static byte DUP2_X2 = 94;
-    public final static byte F2D = (byte) 141;
-    public final static byte F2I = (byte) 139;
-    public final static byte F2L = (byte) 140;
-    public final static byte FADD = 98;
-    public final static byte FALOAD = 48;
-    public final static byte FASTORE = 81;
-    public final static byte FCMPG = (byte) 150;
-    public final static byte FCMPL = (byte) 149;
-    public final static byte FCONST_0 = 11;
-    public final static byte FCONST_1 = 12;
-    public final static byte FCONST_2 = 13;
-    public final static byte FDIV = 110;
-    public final static byte FLOAD = 23;
-    public final static byte FLOAD_0 = 34;
-    public final static byte FLOAD_1 = 35;
-    public final static byte FLOAD_2 = 36;
-    public final static byte FLOAD_3 = 37;
-    public final static byte FMUL = 106;
-    public final static byte FNEG = 118;
-    public final static byte FREM = 114;
-    public final static byte FRETURN = (byte) 174;
-    public final static byte FSTORE = 56;
-    public final static byte FSTORE_0 = 67;
-    public final static byte FSTORE_1 = 68;
-    public final static byte FSTORE_2 = 69;
-    public final static byte FSTORE_3 = 70;
-    public final static byte FSUB = 102;
-    public final static byte GETFIELD = (byte) 180;
-    public final static byte GETSTATIC = (byte) 178;
-    public final static byte GOTO = (byte) 167;
-    public final static byte GOTO_W = (byte) 200;
-    public final static byte I2B = (byte) 145;
-    public final static byte I2C = (byte) 146;
-    public final static byte I2D = (byte) 135;
-    public final static byte I2F = (byte) 134;
-    public final static byte I2L = (byte) 133;
-    public final static byte I2S = (byte) 147;
-    public final static byte IADD = 96;
-    public final static byte IALOAD = 46;
-    public final static byte IAND = 126;
-    public final static byte IASTORE = 79;
-    public final static byte ICONST_M1 = 2;
-    public final static byte ICONST_0 = 3;
-    public final static byte ICONST_1 = 4;
-    public final static byte ICONST_2 = 5;
-    public final static byte ICONST_3 = 6;
-    public final static byte ICONST_4 = 7;
-    public final static byte ICONST_5 = 8;
-    public final static byte IDIV = 108;
-    public final static byte IF_ACMPEQ = (byte) 165;
-    public final static byte IF_ACMPNE = (byte) 166;
-    public final static byte IF_ICMPEQ = (byte) 159;
-    public final static byte IF_ICMPNE = (byte) 160;
-    public final static byte IF_ICMPLT = (byte) 161;
-    public final static byte IF_ICMPGE = (byte) 162;
-    public final static byte IF_ICMPGT = (byte) 163;
-    public final static byte IF_ICMPLE = (byte) 164;
-    public final static byte IFEQ = (byte) 153;
-    public final static byte IFNE = (byte) 154;
-    public final static byte IFLT = (byte) 155;
-    public final static byte IFGE = (byte) 156;
-    public final static byte IFGT = (byte) 157;
-    public final static byte IFLE = (byte) 158;
-    public final static byte IFNONNULL = (byte) 199;
-    public final static byte IFNULL = (byte) 198;
-    public final static byte IINC = (byte) 132;
-    public final static byte ILOAD = 21;
-    public final static byte ILOAD_0 = 26;
-    public final static byte ILOAD_1 = 27;
-    public final static byte ILOAD_2 = 28;
-    public final static byte ILOAD_3 = 29;
-    public final static byte IMUL = 104;
-    public final static byte INEG = 116;
-    public final static byte INSTANCEOF = (byte) 193;
-    public final static byte INVOKEINTERFACE = (byte) 185;
-    public final static byte INVOKESPECIAL = (byte) 183;
-    public final static byte INVOKESTATIC = (byte) 184;
-    public final static byte INVOKEVIRTUAL = (byte) 182;
-    public final static byte IOR = (byte) 128;
-    public final static byte IREM = 112;
-    public final static byte IRETURN = (byte) 172;
-    public final static byte ISHL = 120;
-    public final static byte ISHR = 122;
-    public final static byte ISTORE = 54;
-    public final static byte ISTORE_0 = 59;
-    public final static byte ISTORE_1 = 60;
-    public final static byte ISTORE_2 = 61;
-    public final static byte ISTORE_3 = 62;
-    public final static byte ISUB = 100;
-    public final static byte IUSHR = 124;
-    public final static byte IXOR = (byte) 130;
-    public final static byte JSR = (byte) 168;
-    public final static byte JSR_W = (byte) 201;
-    public final static byte L2D = (byte) 138;
-    public final static byte L2F = (byte) 137;
-    public final static byte L2I = (byte) 136;
-    public final static byte LADD = 97;
-    public final static byte LALOAD = 47;
-    public final static byte LAND = 127;
-    public final static byte LASTORE = 80;
-    public final static byte LCMP = (byte) 148;
-    public final static byte LCONST_0 = 9;
-    public final static byte LCONST_1 = 10;
-    public final static byte LDC = 18;
-    public final static byte LDC_W = 19;
-    public final static byte LDC2_W = 20;
-    public final static byte LDIV = 109;
-    public final static byte LLOAD = 22;
-    public final static byte LLOAD_0 = 30;
-    public final static byte LLOAD_1 = 31;
-    public final static byte LLOAD_2 = 32;
-    public final static byte LLOAD_3 = 33;
-    public final static byte LMUL = 105;
-    public final static byte LNEG = 117;
-    public final static byte LOOKUPSWITCH = (byte) 171;
-    public final static byte LOR = (byte) 129;
-    public final static byte LREM = 113;
-    public final static byte LRETURN = (byte) 173;
-    public final static byte LSHL = 121;
-    public final static byte LSHR = 123;
-    public final static byte LSTORE = 55;
-    public final static byte LSTORE_0 = 63;
-    public final static byte LSTORE_1 = 64;
-    public final static byte LSTORE_2 = 65;
-    public final static byte LSTORE_3 = 66;
-    public final static byte LSUB = 101;
-    public final static byte LUSHR = 125;
-    public final static byte LXOR = (byte) 131;
-    public final static byte MONITORENTER = (byte) 194;
-    public final static byte MONITOREXIT = (byte) 195;
-    public final static byte MULTIANEWARRAY = (byte) 197;
-    public final static byte NEW = (byte) 187;
-    public final static byte NEWARRAY = (byte) 188;
-    public final static byte NOP = 0;
-    public final static byte POP = 87;
-    public final static byte POP2 = 88;
-    public final static byte PUTFIELD = (byte) 181;
-    public final static byte PUTSTATIC = (byte) 179;
-    public final static byte RET = (byte) 169;
-    public final static byte RETURN = (byte) 177;
-    public final static byte SALOAD = 53;
-    public final static byte SASTORE = 86;
-    public final static byte SIPUSH = 17;
-    public final static byte SWAP = 95;
-    public final static byte TABLESWITCH = (byte) 170;
-    public final static byte WIDE = (byte) 196;
-
-    /**
-     * Constants for the "OPCODE_PROPERTIES" array.
-     */
-    public static final short INVALID_OPCODE = -1;
-
-    // "Stack delta" constants.
-    public static final short SD_MASK            = 31;
-    public static final short SD_M4              = 0;
-    public static final short SD_M3              = 1;
-    public static final short SD_M2              = 2;
-    public static final short SD_M1              = 3;
-    public static final short SD_P0              = 4;
-    public static final short SD_P1              = 5;
-    public static final short SD_P2              = 6;
-    public static final short SD_0               = 7;
-    public static final short SD_GETFIELD        = 9;
-    public static final short SD_GETSTATIC       = 10;
-    public static final short SD_PUTFIELD        = 11;
-    public static final short SD_PUTSTATIC       = 12;
-    public static final short SD_INVOKEVIRTUAL   = 13;
-    public static final short SD_INVOKESPECIAL   = 14;
-    public static final short SD_INVOKESTATIC    = 15;
-    public static final short SD_INVOKEINTERFACE = 16;
-    public static final short SD_MULTIANEWARRAY  = 18;
-
-    // Operand 1 types.
-    public static final short OP1_MASK         = 15 * 32;
-    public static final short OP1_SB           =  1 * 32;
-    public static final short OP1_UB           =  2 * 32;
-    public static final short OP1_SS           =  3 * 32;
-    public static final short OP1_CP1          =  4 * 32;
-    public static final short OP1_CP2          =  5 * 32;
-    public static final short OP1_LV1          =  6 * 32;
-    public static final short OP1_LV2          =  7 * 32;
-    public static final short OP1_BO2          =  8 * 32;
-    public static final short OP1_BO4          =  9 * 32;
-    public static final short OP1_LOOKUPSWITCH = 10 * 32;
-    public static final short OP1_TABLESWITCH  = 11 * 32;
-    public static final short OP1_JSR          = 12 * 32;
-
-    // Operand 2 types.
-    public static final short OP2_MASK = 3 * 512;
-    public static final short OP2_SB   = 1 * 512;
-    public static final short OP2_SS   = 2 * 512;
-
-    // Operand 3 types.
-    public static final short OP3_MASK = 1 * 2048;
-    public static final short OP3_SB   = 1 * 2048;
-
-    // Implicit operands.
-    public static final short IO_MASK = 7 * 4096;
-    public static final short IO_LV_0 = 1 * 4096;
-    public static final short IO_LV_1 = 2 * 4096;
-    public static final short IO_LV_2 = 3 * 4096;
-    public static final short IO_LV_3 = 4 * 4096;
-
-    public static final short NO_FALLTHROUGH = (short) 32768;
-
-    public static final short[] OPCODE_PROPERTIES = {
-/*  0*/ /*NOP*/             Opcode.SD_P0,
-        /*ACONST_NULL*/     Opcode.SD_P1,
-        /*ICONST_M1*/       Opcode.SD_P1,
-        /*ICONST_0*/        Opcode.SD_P1,
-        /*ICONST_1*/        Opcode.SD_P1,
-        /*ICONST_2*/        Opcode.SD_P1,
-        /*ICONST_3*/        Opcode.SD_P1,
-        /*ICONST_4*/        Opcode.SD_P1,
-        /*ICONST_5*/        Opcode.SD_P1,
-        /*LCONST_0*/        Opcode.SD_P2,
-/* 10*/ /*LCONST_1*/        Opcode.SD_P2,
-        /*FCONST_0*/        Opcode.SD_P1,
-        /*FCONST_1*/        Opcode.SD_P1,
-        /*FCONST_2*/        Opcode.SD_P1,
-        /*DCONST_0*/        Opcode.SD_P2,
-        /*DCONST_1*/        Opcode.SD_P2,
-        /*BIPUSH*/          Opcode.SD_P1 | Opcode.OP1_SB,
-        /*SIPUSH*/          Opcode.SD_P1 | Opcode.OP1_SS,
-        /*LDC*/             Opcode.SD_P1 | Opcode.OP1_CP1,
-        /*LDC_W*/           Opcode.SD_P1 | Opcode.OP1_CP2,
-/* 20*/ /*LDC2_W*/          Opcode.SD_P2 | Opcode.OP1_CP2,
-        /*ILOAD*/           Opcode.SD_P1 | Opcode.OP1_LV1,
-        /*LLOAD*/           Opcode.SD_P2 | Opcode.OP1_LV1,
-        /*FLOAD*/           Opcode.SD_P1 | Opcode.OP1_LV1,
-        /*DLOAD*/           Opcode.SD_P2 | Opcode.OP1_LV1,
-        /*ALOAD*/           Opcode.SD_P1 | Opcode.OP1_LV1,
-        /*ILOAD_0*/         Opcode.SD_P1 | Opcode.IO_LV_0,
-        /*ILOAD_1*/         Opcode.SD_P1 | Opcode.IO_LV_1,
-        /*ILOAD_2*/         Opcode.SD_P1 | Opcode.IO_LV_2,
-        /*ILOAD_3*/         Opcode.SD_P1 | Opcode.IO_LV_3,
-/* 30*/ /*LLOAD_0*/         Opcode.SD_P2 | Opcode.IO_LV_0,
-        /*LLOAD_1*/         Opcode.SD_P2 | Opcode.IO_LV_1,
-        /*LLOAD_2*/         Opcode.SD_P2 | Opcode.IO_LV_2,
-        /*LLOAD_3*/         Opcode.SD_P2 | Opcode.IO_LV_3,
-        /*FLOAD_0*/         Opcode.SD_P1 | Opcode.IO_LV_0,
-        /*FLOAD_1*/         Opcode.SD_P1 | Opcode.IO_LV_1,
-        /*FLOAD_2*/         Opcode.SD_P1 | Opcode.IO_LV_2,
-        /*FLOAD_3*/         Opcode.SD_P1 | Opcode.IO_LV_3,
-        /*DLOAD_0*/         Opcode.SD_P2 | Opcode.IO_LV_0,
-        /*DLOAD_1*/         Opcode.SD_P2 | Opcode.IO_LV_1,
-/* 40*/ /*DLOAD_2*/         Opcode.SD_P2 | Opcode.IO_LV_2,
-        /*DLOAD_3*/         Opcode.SD_P2 | Opcode.IO_LV_3,
-        /*ALOAD_0*/         Opcode.SD_P1 | Opcode.IO_LV_0,
-        /*ALOAD_1*/         Opcode.SD_P1 | Opcode.IO_LV_1,
-        /*ALOAD_2*/         Opcode.SD_P1 | Opcode.IO_LV_2,
-        /*ALOAD_3*/         Opcode.SD_P1 | Opcode.IO_LV_3,
-        /*IALOAD*/          Opcode.SD_M1,
-        /*LALOAD*/          Opcode.SD_P0,
-        /*FALOAD*/          Opcode.SD_M1,
-        /*DALOAD*/          Opcode.SD_P0,
-/* 50*/ /*AALOAD*/          Opcode.SD_M1,
-        /*BALOAD*/          Opcode.SD_M1,
-        /*CALOAD*/          Opcode.SD_M1,
-        /*SALOAD*/          Opcode.SD_M1,
-        /*ISTORE*/          Opcode.SD_M1 | Opcode.OP1_LV1,
-        /*LSTORE*/          Opcode.SD_M2 | Opcode.OP1_LV1,
-        /*FSTORE*/          Opcode.SD_M1 | Opcode.OP1_LV1,
-        /*DSTORE*/          Opcode.SD_M2 | Opcode.OP1_LV1,
-        /*ASTORE*/          Opcode.SD_M1 | Opcode.OP1_LV1,
-        /*ISTORE_0*/        Opcode.SD_M1 | Opcode.IO_LV_0,
-/* 60*/ /*ISTORE_1*/        Opcode.SD_M1 | Opcode.IO_LV_1,
-        /*ISTORE_2*/        Opcode.SD_M1 | Opcode.IO_LV_2,
-        /*ISTORE_3*/        Opcode.SD_M1 | Opcode.IO_LV_3,
-        /*LSTORE_0*/        Opcode.SD_M2 | Opcode.IO_LV_0,
-        /*LSTORE_1*/        Opcode.SD_M2 | Opcode.IO_LV_1,
-        /*LSTORE_2*/        Opcode.SD_M2 | Opcode.IO_LV_2,
-        /*LSTORE_3*/        Opcode.SD_M2 | Opcode.IO_LV_3,
-        /*FSTORE_0*/        Opcode.SD_M1 | Opcode.IO_LV_0,
-        /*FSTORE_1*/        Opcode.SD_M1 | Opcode.IO_LV_1,
-        /*FSTORE_2*/        Opcode.SD_M1 | Opcode.IO_LV_2,
-/* 70*/ /*FSTORE_3*/        Opcode.SD_M1 | Opcode.IO_LV_3,
-        /*DSTORE_0*/        Opcode.SD_M2 | Opcode.IO_LV_0,
-        /*DSTORE_1*/        Opcode.SD_M2 | Opcode.IO_LV_1,
-        /*DSTORE_2*/        Opcode.SD_M2 | Opcode.IO_LV_2,
-        /*DSTORE_3*/        Opcode.SD_M2 | Opcode.IO_LV_3,
-        /*ASTORE_0*/        Opcode.SD_M1 | Opcode.IO_LV_0,
-        /*ASTORE_1*/        Opcode.SD_M1 | Opcode.IO_LV_1,
-        /*ASTORE_2*/        Opcode.SD_M1 | Opcode.IO_LV_2,
-        /*ASTORE_3*/        Opcode.SD_M1 | Opcode.IO_LV_3,
-        /*IASTORE*/         Opcode.SD_M3,
-/* 80*/ /*LASTORE*/         Opcode.SD_M4,
-        /*FASTORE*/         Opcode.SD_M3,
-        /*DASTORE*/         Opcode.SD_M4,
-        /*AASTORE*/         Opcode.SD_M3,
-        /*BASTORE*/         Opcode.SD_M3,
-        /*CASTORE*/         Opcode.SD_M3,
-        /*SASTORE*/         Opcode.SD_M3,
-        /*POP*/             Opcode.SD_M1,
-        /*POP2*/            Opcode.SD_M2,
-        /*DUP*/             Opcode.SD_P1,
-/* 90*/ /*DUP_X1*/          Opcode.SD_P1,
-        /*DUP_X2*/          Opcode.SD_P1,
-        /*DUP2*/            Opcode.SD_P2,
-        /*DUP2_X1*/         Opcode.SD_P2,
-        /*DUP2_X2*/         Opcode.SD_P2,
-        /*SWAP*/            Opcode.SD_P0,
-        /*IADD*/            Opcode.SD_M1,
-        /*LADD*/            Opcode.SD_M2,
-        /*FADD*/            Opcode.SD_M1,
-        /*DADD*/            Opcode.SD_M2,
-/*100*/ /*ISUB*/            Opcode.SD_M1,
-        /*LSUB*/            Opcode.SD_M2,
-        /*FSUB*/            Opcode.SD_M1,
-        /*DSUB*/            Opcode.SD_M2,
-        /*IMUL*/            Opcode.SD_M1,
-        /*LMUL*/            Opcode.SD_M2,
-        /*FMUL*/            Opcode.SD_M1,
-        /*DMUL*/            Opcode.SD_M2,
-        /*IDIV*/            Opcode.SD_M1,
-        /*LDIV*/            Opcode.SD_M2,
-/*110*/ /*FDIV*/            Opcode.SD_M1,
-        /*DDIV*/            Opcode.SD_M2,
-        /*IREM*/            Opcode.SD_M1,
-        /*LREM*/            Opcode.SD_M2,
-        /*FREM*/            Opcode.SD_M1,
-        /*DREM*/            Opcode.SD_M2,
-        /*INEG*/            Opcode.SD_P0,
-        /*LNEG*/            Opcode.SD_P0,
-        /*FNEG*/            Opcode.SD_P0,
-        /*DNEG*/            Opcode.SD_P0,
-/*120*/ /*ISHL*/            Opcode.SD_M1,
-        /*LSHL*/            Opcode.SD_M1,
-        /*ISHR*/            Opcode.SD_M1,
-        /*LSHR*/            Opcode.SD_M1,
-        /*IUSHR*/           Opcode.SD_M1,
-        /*LUSHR*/           Opcode.SD_M1,
-        /*IAND*/            Opcode.SD_M1,
-        /*LAND*/            Opcode.SD_M2,
-        /*IOR*/             Opcode.SD_M1,
-        /*LOR*/             Opcode.SD_M2,
-/*130*/ /*IXOR*/            Opcode.SD_M1,
-        /*LXOR*/            Opcode.SD_M2,
-        /*IINC*/            Opcode.SD_P0 | Opcode.OP1_LV1 | Opcode.OP2_SB,
-        /*I2L*/             Opcode.SD_P1,
-        /*I2F*/             Opcode.SD_P0,
-        /*I2D*/             Opcode.SD_P1,
-        /*L2I*/             Opcode.SD_M1,
-        /*L2F*/             Opcode.SD_M1,
-        /*L2D*/             Opcode.SD_P0,
-        /*F2I*/             Opcode.SD_P0,
-/*140*/ /*F2L*/             Opcode.SD_P1,
-        /*F2D*/             Opcode.SD_P1,
-        /*D2I*/             Opcode.SD_M1,
-        /*D2L*/             Opcode.SD_P0,
-        /*D2F*/             Opcode.SD_M1,
-        /*I2B*/             Opcode.SD_P0,
-        /*I2C*/             Opcode.SD_P0,
-        /*I2S*/             Opcode.SD_P0,
-        /*LCMP*/            Opcode.SD_M3,
-        /*FCMPL*/           Opcode.SD_M1,
-/*150*/ /*FCMPG*/           Opcode.SD_M1,
-        /*DCMPL*/           Opcode.SD_M3,
-        /*DCMPG*/           Opcode.SD_M3,
-        /*IFEQ*/            Opcode.SD_M1 | Opcode.OP1_BO2,
-        /*IFNE*/            Opcode.SD_M1 | Opcode.OP1_BO2,
-        /*IFLT*/            Opcode.SD_M1 | Opcode.OP1_BO2,
-        /*IFGE*/            Opcode.SD_M1 | Opcode.OP1_BO2,
-        /*IFGT*/            Opcode.SD_M1 | Opcode.OP1_BO2,
-        /*IFLE*/            Opcode.SD_M1 | Opcode.OP1_BO2,
-        /*IF_ICMPEQ*/       Opcode.SD_M2 | Opcode.OP1_BO2,
-/*160*/ /*IF_ICMPNE*/       Opcode.SD_M2 | Opcode.OP1_BO2,
-        /*IF_ICMPLT*/       Opcode.SD_M2 | Opcode.OP1_BO2,
-        /*IF_ICMPGE*/       Opcode.SD_M2 | Opcode.OP1_BO2,
-        /*IF_ICMPGT*/       Opcode.SD_M2 | Opcode.OP1_BO2,
-        /*IF_ICMPLE*/       Opcode.SD_M2 | Opcode.OP1_BO2,
-        /*IF_ACMPEQ*/       Opcode.SD_M2 | Opcode.OP1_BO2,
-        /*IF_ACMPNE*/       Opcode.SD_M2 | Opcode.OP1_BO2,
-        /*GOTO*/            Opcode.SD_P0 | Opcode.OP1_BO2 | Opcode.NO_FALLTHROUGH,
-        /*JSR*/             Opcode.SD_P0 | Opcode.OP1_JSR,
-        /*RET*/             Opcode.SD_P0 | Opcode.OP1_LV1 | Opcode.NO_FALLTHROUGH,
-/*170*/ /*TABLESWITCH*/     Opcode.SD_M1 | Opcode.OP1_TABLESWITCH,
-        /*LOOKUPSWITCH*/    Opcode.SD_M1 | Opcode.OP1_LOOKUPSWITCH,
-        /*IRETURN*/         Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
-        /*LRETURN*/         Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
-        /*FRETURN*/         Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
-        /*DRETURN*/         Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
-        /*ARETURN*/         Opcode.SD_M1 | Opcode.NO_FALLTHROUGH,
-        /*RETURN*/          Opcode.SD_0 | Opcode.NO_FALLTHROUGH,
-        /*GETSTATIC*/       Opcode.SD_GETSTATIC | Opcode.OP1_CP2,
-        /*PUTSTATIC*/       Opcode.SD_PUTSTATIC | Opcode.OP1_CP2,
-/*180*/ /*GETFIELD*/        Opcode.SD_GETFIELD | Opcode.OP1_CP2,
-        /*PUTFIELD*/        Opcode.SD_PUTFIELD | Opcode.OP1_CP2,
-        /*INVOKEVIRTUAL*/   Opcode.SD_INVOKEVIRTUAL | Opcode.OP1_CP2,
-        /*INVOKESPECIAL*/   Opcode.SD_INVOKESPECIAL | Opcode.OP1_CP2,
-        /*INVOKESTATIC*/    Opcode.SD_INVOKESTATIC | Opcode.OP1_CP2,
-        /*INVOKEINTERFACE*/ Opcode.SD_INVOKEINTERFACE | Opcode.OP1_CP2 | Opcode.OP2_SB | Opcode.OP3_SB,
-        /*UNUSED*/          Opcode.INVALID_OPCODE,
-        /*NEW*/             Opcode.SD_P1 | Opcode.OP1_CP2,
-        /*NEWARRAY*/        Opcode.SD_P0 | Opcode.OP1_UB,
-        /*ANEWARRAY*/       Opcode.SD_P0 | Opcode.OP1_CP2,
-/*190*/ /*ARRAYLENGTH*/     Opcode.SD_P0,
-        /*ATHROW*/          Opcode.SD_M1 | Opcode.NO_FALLTHROUGH,
-        /*CHECKCAST*/       Opcode.SD_P0 | Opcode.OP1_CP2,
-        /*INSTANCEOF*/      Opcode.SD_P0 | Opcode.OP1_CP2,
-        /*MONITORENTER*/    Opcode.SD_M1,
-        /*MONITOREXIT*/     Opcode.SD_M1,
-        /*WIDE*/            Opcode.INVALID_OPCODE,
-        /*MULTIANEWARRAY*/  Opcode.SD_MULTIANEWARRAY | Opcode.OP1_CP2 | Opcode.OP2_SB,
-        /*IFNULL*/          Opcode.SD_M1 | Opcode.OP1_BO2,
-        /*IFNONNULL*/       Opcode.SD_M1 | Opcode.OP1_BO2,
-/*200*/ /*GOTO_W*/          Opcode.SD_P0 | Opcode.OP1_BO4 | Opcode.NO_FALLTHROUGH,
-        /*JSR_W*/           Opcode.SD_P1 | Opcode.OP1_BO4,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*210*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*220*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*230*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*240*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*250*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-    };
-
-    public static final short[] WIDE_OPCODE_PROPERTIES = {
-/*  0*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*010*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*020*/ Opcode.INVALID_OPCODE,
-        /*ILOAD*/ Opcode.SD_P1 | Opcode.OP1_LV2,
-        /*LLOAD*/ Opcode.SD_P2 | Opcode.OP1_LV2,
-        /*FLOAD*/ Opcode.SD_P1 | Opcode.OP1_LV2,
-        /*DLOAD*/ Opcode.SD_P2 | Opcode.OP1_LV2,
-        /*ALOAD*/ Opcode.SD_P1 | Opcode.OP1_LV2,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 30*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 40*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 50*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        /*ISTORE*/ Opcode.SD_M1 | Opcode.OP1_LV2,
-        /*LSTORE*/ Opcode.SD_M2 | Opcode.OP1_LV2,
-        /*FSTORE*/ Opcode.SD_M1 | Opcode.OP1_LV2,
-        /*DSTORE*/ Opcode.SD_M2 | Opcode.OP1_LV2,
-        /*ASTORE*/ Opcode.SD_M1 | Opcode.OP1_LV2,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 60*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 70*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 80*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/* 90*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*100*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*110*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*120*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*130*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        /*IINC*/ Opcode.SD_P0 | Opcode.OP1_LV2 | Opcode.OP2_SS,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*140*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*150*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*160*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE,
-        /*RET*/ Opcode.SD_P0 | Opcode.OP1_LV2,
-/*170*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*180*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*190*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*200*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*210*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*220*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*230*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*240*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-/*250*/ Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-        Opcode.INVALID_OPCODE, Opcode.INVALID_OPCODE,
-    };
-}
diff --git a/src/org/codehaus/janino/Parser.java b/src/org/codehaus/janino/Parser.java
deleted file mode 100644
index 929333f..0000000
--- a/src/org/codehaus/janino/Parser.java
+++ /dev/null
@@ -1,2540 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.Java.CompilationUnit.ImportDeclaration;
-import org.codehaus.janino.util.LocatedException;
-import org.codehaus.janino.util.enumerator.Enumerator;
-
-/**
- * A parser for the Java<sup>TM</sup> programming language.
- */
-public class Parser {
-    private final Scanner scanner;
-
-    public Parser(Scanner scanner) {
-        this.scanner = scanner;
-    }
-
-    public Scanner getScanner() {
-        return this.scanner;
-    }
-
-    /**
-     * <pre>
-     *   CompilationUnit := [ PackageDeclaration ]
-     *                      { ImportDeclaration }
-     *                      { TypeDeclaration }
-     * </pre>
-     */
-    public Java.CompilationUnit parseCompilationUnit() throws ParseException, Scanner.ScanException, IOException {
-        Java.CompilationUnit compilationUnit = new Java.CompilationUnit(this.location().getFileName());
-
-        if (this.peekKeyword("package")) {
-            compilationUnit.setPackageDeclaration(this.parsePackageDeclaration());
-        }
-
-        while (this.peekKeyword("import")) {
-            compilationUnit.addImportDeclaration(this.parseImportDeclaration());
-        }
-
-        while (!this.scanner.peek().isEOF()) {
-            if (this.peekOperator(";")) {
-                this.eatToken();
-            } else
-            {
-                compilationUnit.addPackageMemberTypeDeclaration(this.parsePackageMemberTypeDeclaration());
-            }
-        }
-
-        return compilationUnit;
-    }
-
-    /**
-     * <pre>
-     *   PackageDeclaration := 'package' QualifiedIdentifier ';'
-     * </pre>
-     */
-    public Java.PackageDeclaration parsePackageDeclaration() throws Parser.ParseException, Scanner.ScanException, IOException {
-        this.readKeyword("package");
-        Location loc = this.location();
-        String packageName = Parser.join(this.parseQualifiedIdentifier(), ".");
-        this.readOperator(";");
-        this.verifyStringIsConventionalPackageName(packageName, loc);
-        return new Java.PackageDeclaration(loc, packageName);
-    }
-
-    /**
-     * <pre>
-     *   ImportDeclaration := 'import' ImportDeclarationBody ';'
-     * </pre>
-     */
-    public Java.CompilationUnit.ImportDeclaration parseImportDeclaration() throws ParseException, Scanner.ScanException, IOException {
-        this.readKeyword("import");
-        Java.CompilationUnit.ImportDeclaration importDeclaration = this.parseImportDeclarationBody();
-        this.readOperator(";");
-        return importDeclaration;
-    }
-
-    /**
-     * <pre>
-     *   ImportDeclarationBody := [ 'static' ] Identifier { '.' Identifier } [ '.' '*' ]
-     * </pre>
-     */
-    public Java.CompilationUnit.ImportDeclaration parseImportDeclarationBody() throws ParseException, Scanner.ScanException, IOException {
-        Location loc = this.location();
-        boolean isStatic;
-        if (this.peekKeyword("static")) {
-            isStatic = true;
-            this.eatToken();
-        } else
-        {
-            isStatic = false;
-        }
-        List l = new ArrayList();
-        l.add(this.readIdentifier());
-        for (;;) {
-            if (!this.peekOperator(".")) {
-                String[] identifiers = (String[]) l.toArray(new String[l.size()]);
-                return (
-                    isStatic
-                    ? (ImportDeclaration) new Java.CompilationUnit.SingleStaticImportDeclaration(loc, identifiers)
-                    : (ImportDeclaration) new Java.CompilationUnit.SingleTypeImportDeclaration(loc, identifiers)
-                );
-            }
-            this.readOperator(".");
-            if (this.peekOperator("*")) {
-                this.eatToken();
-                String[] identifiers = (String[]) l.toArray(new String[l.size()]);
-                return (
-                    isStatic
-                    ? (ImportDeclaration) new Java.CompilationUnit.StaticImportOnDemandDeclaration(loc, identifiers)
-                    : (ImportDeclaration) new Java.CompilationUnit.TypeImportOnDemandDeclaration(loc, identifiers)
-                );
-            }
-            l.add(this.readIdentifier());
-        }
-    }
-
-    /**
-     * QualifiedIdentifier := Identifier { '.' Identifier }
-     */
-    public String[] parseQualifiedIdentifier() throws ParseException, Scanner.ScanException, IOException {
-        if (!this.scanner.peek().isIdentifier()) this.throwParseException("Identifier expected");
-        List l = new ArrayList();
-        l.add(this.readIdentifier());
-        while (this.peekOperator(".") && this.scanner.peekNextButOne().isIdentifier()) {
-            this.eatToken();
-            l.add(this.readIdentifier());
-        }
-        return (String[]) l.toArray(new String[l.size()]);
-    }
-
-    /**
-     * <pre>
-     *   PackageMemberTypeDeclaration :=
-     *             ModifiersOpt 'class' ClassDeclarationRest |
-     *             ModifiersOpt 'interface' InterfaceDeclarationRest
-     * </pre>
-     */
-    public Java.PackageMemberTypeDeclaration parsePackageMemberTypeDeclaration() throws ParseException, Scanner.ScanException, IOException {
-        String optionalDocComment = this.scanner.doc();
-
-        short modifiers = this.parseModifiersOpt();
-
-        Java.PackageMemberTypeDeclaration res;
-        if (this.peekKeyword("class")) {
-            if (optionalDocComment == null) this.warning("CDCM", "Class doc comment missing", this.location());
-            this.eatToken();
-            res = (Java.PackageMemberClassDeclaration) this.parseClassDeclarationRest(
-                optionalDocComment,                      // optionalDocComment
-                modifiers,                               // modifiers
-                ClassDeclarationContext.COMPILATION_UNIT // context
-            );
-        } else
-        if (this.peekKeyword("interface")) {
-            if (optionalDocComment == null) this.warning("IDCM", "Interface doc comment missing", this.location());
-            this.eatToken();
-            res = (Java.PackageMemberInterfaceDeclaration) this.parseInterfaceDeclarationRest(
-                optionalDocComment,                          // optionalDocComment
-                modifiers,                                   // modifiers
-                InterfaceDeclarationContext.COMPILATION_UNIT // context
-            );
-        } else
-        {
-            this.throwParseException("Unexpected token \"" + this.scanner.peek() + "\" in class or interface declaration");
-            /* NEVER REACHED */ return null;
-        }
-        return res;
-    }
-
-    /**
-     * <pre>
-     *   ModifiersOpt := { 'public' | 'protected' | 'private' | 'static' |
-     *           'abstract' | 'final' | 'native' | 'synchronized' |
-     *           'transient' | 'volatile' | 'strictfp'
-     * </pre>
-     */
-    public short parseModifiersOpt() throws ParseException, Scanner.ScanException, IOException {
-        short mod = 0;
-        while (this.peekKeyword()) {
-            String kw = this.scanner.peek().getKeyword();
-            short x = (short) (
-                kw == "public"       ? Mod.PUBLIC       :
-                kw == "protected"    ? Mod.PROTECTED    :
-                kw == "private"      ? Mod.PRIVATE      :
-                kw == "static"       ? Mod.STATIC       :
-                kw == "abstract"     ? Mod.ABSTRACT     :
-                kw == "final"        ? Mod.FINAL        :
-                kw == "native"       ? Mod.NATIVE       :
-                kw == "synchronized" ? Mod.SYNCHRONIZED :
-                kw == "transient"    ? Mod.TRANSIENT    :
-                kw == "volatile"     ? Mod.VOLATILE     :
-                kw == "strictfp"     ? Mod.STRICTFP     :
-                -1
-            );
-            if (x == -1) break;
-
-            this.eatToken();
-            if ((mod & x) != 0) this.throwParseException("Duplicate modifier \"" + kw + "\"");
-            for (int i = 0; i < Parser.MUTUALS.length; ++i) {
-                short m = Parser.MUTUALS[i];
-                if ((x & m) != 0 && (mod & m) != 0) {
-                    this.throwParseException("Only one of \"" + Mod.shortToString(m) + "\" allowed");
-                }
-            }
-            mod |= x;
-        }
-        return mod;
-    }
-    private static final short[] MUTUALS = {
-        Mod.PUBLIC | Mod.PROTECTED | Mod.PRIVATE,
-    };
-
-    /**
-     * <pre>
-     *   ClassDeclarationRest :=
-     *        Identifier
-     *        [ 'extends' ReferenceType ]
-     *        [ 'implements' ReferenceTypeList ]
-     *        ClassBody
-     * </pre>
-     */
-    public Java.NamedClassDeclaration parseClassDeclarationRest(
-        String                  optionalDocComment,
-        short                   modifiers,
-        ClassDeclarationContext context
-    ) throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        String className = this.readIdentifier();
-        this.verifyIdentifierIsConventionalClassOrInterfaceName(className, location);
-
-        Java.ReferenceType optionalExtendedType = null;
-        if (this.peekKeyword("extends")) {
-            this.eatToken();
-            optionalExtendedType = this.parseReferenceType();
-        }
-
-        Java.ReferenceType[] implementedTypes = new Java.ReferenceType[0];
-        if (this.peekKeyword("implements")) {
-            this.eatToken();
-            implementedTypes = this.parseReferenceTypeList();
-        }
-
-        Java.NamedClassDeclaration namedClassDeclaration;
-        if (context == ClassDeclarationContext.COMPILATION_UNIT) {
-            namedClassDeclaration = new Java.PackageMemberClassDeclaration(
-                location,                              // location
-                optionalDocComment,                    // optionalDocComment
-                modifiers,                             // modifiers
-                className,                             // name
-                optionalExtendedType,                  // optinalExtendedType
-                implementedTypes                       // implementedTypes
-            );
-        } else
-        if (context == ClassDeclarationContext.TYPE_DECLARATION) {
-            namedClassDeclaration = new Java.MemberClassDeclaration(
-                location,             // location
-                optionalDocComment,   // optionalDocComment
-                modifiers,            // modifiers
-                className,            // name
-                optionalExtendedType, // optionalExtendedType
-                implementedTypes      // implementedTypes
-            );
-        } else
-        if (context == ClassDeclarationContext.BLOCK) {
-            namedClassDeclaration = new Java.LocalClassDeclaration(
-                location,             // location
-                optionalDocComment,   // optionalDocComment
-                modifiers,            // modifiers
-                className,            // name
-                optionalExtendedType, // optionalExtendedType
-                implementedTypes      // implementedTypes
-            );
-        } else
-        {
-            throw new RuntimeException("SNO: Class declaration in unexpected context " + context);
-        }
-
-        this.parseClassBody(namedClassDeclaration);
-        return namedClassDeclaration;
-    }
-    public static class ClassDeclarationContext extends Enumerator {
-        public static final ClassDeclarationContext BLOCK            = new ClassDeclarationContext("block");
-        public static final ClassDeclarationContext TYPE_DECLARATION = new ClassDeclarationContext("type_declaration");
-        public static final ClassDeclarationContext COMPILATION_UNIT = new ClassDeclarationContext("compilation_unit");
-        private ClassDeclarationContext(String name) { super(name); }
-    }
-
-    /**
-     * <pre>
-     *   ClassBody := '{' { ClassBodyDeclaration } '}'
-     * </pre>
-     */
-    public void parseClassBody(
-        Java.ClassDeclaration classDeclaration
-    ) throws ParseException, Scanner.ScanException, IOException {
-        if (!this.peekOperator("{")) this.throwParseException("\"{\" expected at start of class body");
-        this.eatToken();
-
-        for (;;) {
-            if (this.peekOperator("}")) {
-                this.eatToken();
-                return;
-            }
-
-            this.parseClassBodyDeclaration(classDeclaration);
-        }
-    }
-
-    /**
-     * <pre>
-     *   ClassBodyDeclaration :=
-     *     ';' |
-     *     ModifiersOpt (
-     *       Block |                                    // Instance (JLS2 8.6) or static initializer (JLS2 8.7)
-     *       'void' Identifier MethodDeclarationRest |
-     *       'class' ClassDeclarationRest |
-     *       'interface' InterfaceDeclarationRest |
-     *       ConstructorDeclarator |
-     *       Type Identifier (
-     *         MethodDeclarationRest |
-     *         FieldDeclarationRest ';'
-     *       )
-     *     )
-     *
-     * </pre>
-     */
-    public void parseClassBodyDeclaration(
-        Java.ClassDeclaration classDeclaration
-    ) throws ParseException, Scanner.ScanException, IOException {
-        if (this.peekOperator(";")) {
-            this.eatToken();
-            return;
-        }
-
-        String optionalDocComment = this.scanner.doc();
-        short modifiers = this.parseModifiersOpt();
-
-        // Initializer?
-        if (this.peekOperator("{")) {
-            if ((modifiers & ~Mod.STATIC) != 0) this.throwParseException("Only modifier \"static\" allowed on initializer");
-
-            Java.Initializer initializer = new Java.Initializer(
-                this.location(),               // location
-                (modifiers & Mod.STATIC) != 0, // statiC
-                this.parseBlock()              // block
-            );
-
-            classDeclaration.addVariableDeclaratorOrInitializer(initializer);
-            return;
-        }
-
-        // "void" method declaration.
-        if (this.peekKeyword("void")) {
-            Location location = this.location();
-            this.eatToken();
-            if (optionalDocComment == null) this.warning("MDCM", "Method doc comment missing", location);
-            String name = this.readIdentifier();
-            classDeclaration.addDeclaredMethod(this.parseMethodDeclarationRest(
-                optionalDocComment,                                  // declaringType
-                modifiers,                                // optionalDocComment
-                new Java.BasicType(location, Java.BasicType.VOID),                                         // modifiers
-                name                                               // name
-            ));
-            return;
-        }
-
-        // Member class.
-        if (this.peekKeyword("class")) {
-            if (optionalDocComment == null) this.warning("MCDCM", "Member class doc comment missing", this.location());
-            this.eatToken();
-            classDeclaration.addMemberTypeDeclaration((Java.MemberTypeDeclaration) this.parseClassDeclarationRest(
-                optionalDocComment,                      // optionalDocComment
-                modifiers,                               // modifiers
-                ClassDeclarationContext.TYPE_DECLARATION // context
-            ));
-            return;
-        }
-
-        // Member interface.
-        if (this.peekKeyword("interface")) {
-            if (optionalDocComment == null) this.warning("MIDCM", "Member interface doc comment missing", this.location());
-            this.eatToken();
-            classDeclaration.addMemberTypeDeclaration((Java.MemberTypeDeclaration) this.parseInterfaceDeclarationRest(
-                optionalDocComment,                                // optionalDocComment
-                (short) (modifiers | Mod.STATIC),                  // modifiers
-                InterfaceDeclarationContext.NAMED_TYPE_DECLARATION // context
-            ));
-            return;
-        }
-
-        // Constructor.
-        if (
-            classDeclaration instanceof Java.NamedClassDeclaration &&
-            this.scanner.peek().isIdentifier(((Java.NamedClassDeclaration) classDeclaration).getName()) &&
-            this.scanner.peekNextButOne().isOperator("(")
-        ) {
-            if (optionalDocComment == null) this.warning("CDCM", "Constructor doc comment missing", this.location());
-            classDeclaration.addConstructor(this.parseConstructorDeclarator(
-                optionalDocComment,   // declaringClass
-                modifiers           // modifiers
-            ));
-            return;
-        }
-
-        // Member method or field.
-        Java.Type memberType = this.parseType();
-        Location location = this.location();
-        String memberName = this.readIdentifier();
-
-        // Method declarator.
-        if (this.peekOperator("(")) {
-            if (optionalDocComment == null) this.warning("MDCM", "Method doc comment missing", this.location());
-            classDeclaration.addDeclaredMethod(this.parseMethodDeclarationRest(
-                optionalDocComment,   // declaringType
-                modifiers, // optionalDocComment
-                memberType,          // modifiers
-                memberName          // name
-            ));
-            return;
-        }
-
-        // Field declarator.
-        if (optionalDocComment == null) this.warning("FDCM", "Field doc comment missing", this.location());
-        Java.FieldDeclaration fd = new Java.FieldDeclaration(
-            location,                                  // location
-            optionalDocComment,                        // optionalDocComment
-            modifiers,                                 // modifiers
-            memberType,                                // type
-            this.parseFieldDeclarationRest(memberName) // variableDeclarators
-        );
-        this.readOperator(";");
-        classDeclaration.addVariableDeclaratorOrInitializer(fd);
-    }
-
-    /**
-     * <pre>
-     *   InterfaceDeclarationRest :=
-     *     Identifier
-     *     [ 'extends' ReferenceTypeList ]
-     *     InterfaceBody
-     * </pre>
-     */
-    public Java.InterfaceDeclaration parseInterfaceDeclarationRest(
-        String                      optionalDocComment,
-        short                       modifiers,
-        InterfaceDeclarationContext context
-    ) throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        String interfaceName = this.readIdentifier();
-        this.verifyIdentifierIsConventionalClassOrInterfaceName(interfaceName, location);
-
-        Java.ReferenceType[] extendedTypes = new Java.ReferenceType[0];
-        if (this.peekKeyword("extends")) {
-            this.eatToken();
-            extendedTypes = this.parseReferenceTypeList();
-        }
-
-        Java.InterfaceDeclaration interfaceDeclaration;
-        if (context == InterfaceDeclarationContext.COMPILATION_UNIT) {
-            interfaceDeclaration = new Java.PackageMemberInterfaceDeclaration(
-                location,                              // location
-                optionalDocComment,                    // optionalDocComment
-                modifiers,                             // modifiers
-                interfaceName,                         // name
-                extendedTypes                          // extendedTypes
-            );
-        } else
-        if (context == InterfaceDeclarationContext.NAMED_TYPE_DECLARATION) {
-            interfaceDeclaration = new Java.MemberInterfaceDeclaration(
-                location,                                   // location
-                optionalDocComment,                         // optionalDocComment
-                modifiers,                                  // modifiers
-                interfaceName,                              // name
-                extendedTypes                               // extendedTypes
-            );
-        } else
-        {
-            throw new RuntimeException("SNO: Interface declaration in unexpected context " + context);
-        }
-
-        this.parseInterfaceBody(interfaceDeclaration);
-        return interfaceDeclaration;
-    }
-    public static class InterfaceDeclarationContext extends Enumerator {
-        public static final InterfaceDeclarationContext NAMED_TYPE_DECLARATION = new InterfaceDeclarationContext("named_type_declaration");
-        public static final InterfaceDeclarationContext COMPILATION_UNIT       = new InterfaceDeclarationContext("compilation_unit");
-        private InterfaceDeclarationContext(String name) { super(name); }
-    }
-
-    /**
-     * <pre>
-     *   InterfaceBody := '{' {
-     *     ';' |
-     *     ModifiersOpt (
-     *       'void' Identifier MethodDeclarationRest |
-     *       'class' ClassDeclarationRest |
-     *       'interface' InterfaceDeclarationRest |
-     *       Type Identifier (
-     *         MethodDeclarationRest |
-     *         FieldDeclarationRest
-     *       )
-     *     )
-     *   } '}'
-     * </pre>
-     */
-    public void parseInterfaceBody(
-        Java.InterfaceDeclaration interfaceDeclaration
-    ) throws ParseException, Scanner.ScanException, IOException {
-        this.readOperator("{");
-
-        for (;;) {
-            if (this.peekOperator("}")) {
-                this.eatToken();
-                break;
-            }
-
-            if (this.peekOperator(";")) {
-                this.eatToken();
-                continue;
-            }
-
-            String optionalDocComment = this.scanner.doc();
-            short modifiers = this.parseModifiersOpt();
-
-            // "void" method declaration.
-            if (this.peekKeyword("void")) {
-                if (optionalDocComment == null) this.warning("MDCM", "Method doc comment missing", this.location());
-                Location location = this.location();
-                this.eatToken();
-                String name = this.readIdentifier();
-                interfaceDeclaration.addDeclaredMethod(this.parseMethodDeclarationRest(
-                    optionalDocComment,                              // declaringType
-                    (short) (modifiers | Mod.ABSTRACT | Mod.PUBLIC),                                // optionalDocComment
-                    new Java.BasicType(location, Java.BasicType.VOID),   // modifiers
-                    name                                               // name
-                ));
-            } else
-
-            // Member class.
-            if (this.peekKeyword("class")) {
-                if (optionalDocComment == null) this.warning("MCDCM", "Member class doc comment missing", this.location());
-                this.eatToken();
-                interfaceDeclaration.addMemberTypeDeclaration((Java.MemberTypeDeclaration) this.parseClassDeclarationRest(
-                    optionalDocComment,                            // optionalDocComment
-                    (short) (modifiers | Mod.STATIC | Mod.PUBLIC), // modifiers
-                    ClassDeclarationContext.TYPE_DECLARATION       // context
-                ));
-            } else
-
-            // Member interface.
-            if (this.peekKeyword("interface")) {
-                if (optionalDocComment == null) this.warning("MIDCM", "Member interface doc comment missing", this.location());
-                this.eatToken();
-                interfaceDeclaration.addMemberTypeDeclaration((Java.MemberTypeDeclaration) this.parseInterfaceDeclarationRest(
-                    optionalDocComment,                                // optionalDocComment
-                    (short) (modifiers | Mod.STATIC | Mod.PUBLIC),     // modifiers
-                    InterfaceDeclarationContext.NAMED_TYPE_DECLARATION // context
-                ));
-            } else
-
-            // Member method or field.
-            {
-                Java.Type memberType = this.parseType();
-                if (!this.scanner.peek().isIdentifier()) this.throwParseException("Identifier expected in member declaration");
-                Location location = this.location();
-                String memberName = this.readIdentifier();
-
-                // Method declarator.
-                if (this.peekOperator("(")) {
-                    if (optionalDocComment == null) this.warning("MDCM", "Method doc comment missing", this.location());
-                    interfaceDeclaration.addDeclaredMethod(this.parseMethodDeclarationRest(
-                        optionalDocComment,                            // declaringType
-                        (short) (modifiers | Mod.ABSTRACT | Mod.PUBLIC),                              // optionalDocComment
-                        memberType, // modifiers
-                        memberName                                       // name
-                    ));
-                } else
-
-                // Field declarator.
-                {
-                    if (optionalDocComment == null) this.warning("FDCM", "Field doc comment missing", this.location());
-                    Java.FieldDeclaration fd = new Java.FieldDeclaration(
-                        location,                                  // location
-                        optionalDocComment,                        // optionalDocComment
-                        (short) (                                  // modifiers
-                            modifiers |
-                            Mod.PUBLIC | Mod.STATIC | Mod.FINAL
-                        ),
-                        memberType,                                // type
-                        this.parseFieldDeclarationRest(memberName) // variableDeclarators
-                    );
-                    interfaceDeclaration.addConstantDeclaration(fd);
-                }
-            }
-        }
-    }
-
-    /**
-     * <pre>
-     *   ConstructorDeclarator :=
-     *     Identifier
-     *     FormalParameters
-     *     [ 'throws' ReferenceTypeList ]
-     *     '{'
-     *       [ 'this' Arguments ';' | 'super' Arguments ';' | Primary '.' 'super' Arguments ';' ]
-     *       BlockStatements
-     *     '}'
-     * </pre>
-     */
-    public Java.ConstructorDeclarator parseConstructorDeclarator(
-        String optionalDocComment,
-        short  modifiers
-    ) throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readIdentifier();  // Class name
-
-        // Parse formal parameters.
-        Java.FunctionDeclarator.FormalParameter[] formalParameters = this.parseFormalParameters(
-        );
-
-        // Parse "throws" clause.
-        Java.ReferenceType[] thrownExceptions;
-        if (this.peekKeyword("throws")) {
-            this.eatToken();
-            thrownExceptions = this.parseReferenceTypeList();
-        } else {
-            thrownExceptions = new Java.ReferenceType[0];
-        }
-
-        // Parse constructor body.
-        location = this.location();
-        this.readOperator("{");
-
-        // Special treatment for the first statement of the constructor body: If this is surely an
-        // expression statement, and if it could be a "ConstructorInvocation", then parse the
-        // expression and check if it IS a ConstructorInvocation.
-        Java.ConstructorInvocation optionalConstructorInvocation = null;
-        Java.Block body = new Java.Block(location);
-        if (
-            this.peekKeyword(new String[] {
-                "this", "super", "new", "void",
-                "byte", "char", "short", "int", "long", "float", "double", "boolean",
-            } ) ||
-            this.scanner.peek().isLiteral() ||
-            this.scanner.peek().isIdentifier()
-        ) {
-            Java.Atom a = this.parseExpression();
-            if (a instanceof Java.ConstructorInvocation) {
-                this.readOperator(";");
-                optionalConstructorInvocation = (Java.ConstructorInvocation) a;
-            } else {
-                Java.Statement s;
-                if (this.scanner.peek().isIdentifier()) {
-                    Java.Type variableType = a.toTypeOrPE();
-                    s = new Java.LocalVariableDeclarationStatement(
-                        a.getLocation(),                     // location
-                        (short) 0,                           // modifiers
-                        variableType,                        // type
-                        this.parseLocalVariableDeclarators() // variableDeclarators
-                    );
-                    this.readOperator(";");
-                } else {
-                    s = new Java.ExpressionStatement(a.toRvalueOrPE());
-                    this.readOperator(";");
-                }
-                body.addStatement(s);
-            }
-        }
-        body.addStatements(this.parseBlockStatements());
-
-        this.readOperator("}");
-
-        return new Java.ConstructorDeclarator(
-            location,                      // location
-            optionalDocComment,            // optionalDocComment
-            modifiers,                     // modifiers
-            formalParameters,              // formalParameters
-            thrownExceptions,              // thrownExceptions
-            optionalConstructorInvocation, // optionalConstructorInvocationStatement
-            body                           // body
-        );
-    }
-
-    /**
-     * <pre>
-     *   MethodDeclarationRest :=
-     *     FormalParameters
-     *     { '[' ']' }
-     *     [ 'throws' ReferenceTypeList ]
-     *     ( ';' | MethodBody )
-     * </pre>
-     */
-    public Java.MethodDeclarator parseMethodDeclarationRest(
-        String                       optionalDocComment,
-        short                        modifiers,
-        Java.Type                    type,
-        String                       name
-    ) throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-
-        this.verifyIdentifierIsConventionalMethodName(name, location);
-
-        Java.FunctionDeclarator.FormalParameter[] formalParameters = this.parseFormalParameters(
-        );
-
-        for (int i = this.parseBracketsOpt(); i > 0; --i) type = new Java.ArrayType(type);
-
-        Java.ReferenceType[] thrownExceptions;
-        if (this.peekKeyword("throws")) {
-            this.eatToken();
-            thrownExceptions = this.parseReferenceTypeList();
-        } else {
-            thrownExceptions = new Java.ReferenceType[0];
-        }
-
-        Java.Block optionalBody;
-        if (this.peekOperator(";")) {
-            if ((modifiers & (Mod.ABSTRACT | Mod.NATIVE)) == 0) this.throwParseException("Non-abstract, non-native method must have a body");
-            this.eatToken();
-            optionalBody = null;
-        } else {
-            if ((modifiers & (Mod.ABSTRACT | Mod.NATIVE)) != 0) this.throwParseException("Abstract or native method must not have a body");
-            optionalBody = this.parseMethodBody();
-        }
-        return new Java.MethodDeclarator(
-            location,           // location
-            optionalDocComment, // optionalDocComment
-            modifiers,          // modifiers
-            type,               // type
-            name,               // name
-            formalParameters,   // formalParameters
-            thrownExceptions,   // thrownExceptions
-            optionalBody        // optionalBody
-        );
-    }
-
-    /**
-     * <pre>
-     *   VariableInitializer :=
-     *     ArrayInitializer |
-     *     Expression
-     * </pre>
-     */
-    public Java.ArrayInitializerOrRvalue parseVariableInitializer() throws ParseException, Scanner.ScanException, IOException {
-        if (this.peekOperator("{")) {
-            return this.parseArrayInitializer();
-        } else
-        {
-            return this.parseExpression().toRvalueOrPE();
-        }
-    }
-
-    /**
-     * <pre>
-     *   ArrayInitializer :=
-     *     '{' [ VariableInitializer { ',' VariableInitializer } [ ',' ] '}'
-     * </pre>
-     */
-    public Java.ArrayInitializer parseArrayInitializer() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readOperator("{");
-        List l = new ArrayList(); // ArrayInitializerOrRvalue
-        while (!this.peekOperator("}")) {
-            l.add(this.parseVariableInitializer());
-            if (this.peekOperator("}")) break;
-            if (!this.peekOperator(",")) this.throwParseException("\",\" or \"}\" expected");
-            this.eatToken();
-        }
-        this.eatToken();
-        return new Java.ArrayInitializer(
-            location,
-            (Java.ArrayInitializerOrRvalue[]) l.toArray(new Java.ArrayInitializerOrRvalue[l.size()])
-        );
-    }
-
-    /**
-     * <pre>
-     *   FormalParameters := '(' [ FormalParameter { ',' FormalParameter } ] ')'
-     * </pre>
-     */
-    public Java.FunctionDeclarator.FormalParameter[] parseFormalParameters()
-    throws ParseException, Scanner.ScanException, IOException {
-        this.readOperator("(");
-        if (this.peekOperator(")")) {
-            this.eatToken();
-            return new Java.FunctionDeclarator.FormalParameter[0];
-        }
-
-        List l = new ArrayList(); // Java.FormalParameter
-        for (;;) {
-            l.add(this.parseFormalParameter());
-            if (!this.peekOperator(",")) break;
-            this.eatToken();
-        }
-        this.readOperator(")");
-        return (Java.FunctionDeclarator.FormalParameter[]) l.toArray(new Java.FunctionDeclarator.FormalParameter[l.size()]);
-    }
-
-    /**
-     * <pre>
-     *   FormalParameter := [ 'final' ] Type Identifier BracketsOpt
-     * </pre>
-     */
-    public Java.FunctionDeclarator.FormalParameter parseFormalParameter() throws ParseException, Scanner.ScanException, IOException {
-        boolean finaL = this.peekKeyword("final");
-        if (finaL) this.eatToken();
-
-        Java.Type type = this.parseType();
-
-        Location location = this.location();
-        String name = this.readIdentifier();
-        this.verifyIdentifierIsConventionalLocalVariableOrParameterName(name, location);
-
-        for (int i = this.parseBracketsOpt(); i > 0; --i) type = new Java.ArrayType(type);
-        return new Java.FunctionDeclarator.FormalParameter(location, finaL, type, name);
-    }
-
-    /**
-     * <pre>
-     *   BracketsOpt := { '[' ']' }
-     * </pre>
-     */
-    int parseBracketsOpt() throws Scanner.ScanException, IOException {
-        int res = 0;
-        while (
-            this.scanner.peek().          isOperator("[") &&
-            this.scanner.peekNextButOne().isOperator("]")
-        ) {
-            this.eatToken();
-            this.eatToken();
-            ++res;
-        }
-        return res;
-    }
-
-    /**
-     * <pre>
-     *   MethodBody := Block
-     * </pre>
-     */
-    public Java.Block parseMethodBody() throws ParseException, Scanner.ScanException, IOException {
-        return this.parseBlock();
-    }
-
-    /**
-     * <pre>
-     *   '{' BlockStatements '}'
-     * </pre>
-     */
-    public Java.Block parseBlock() throws ParseException, Scanner.ScanException, IOException {
-        Java.Block block = new Java.Block(this.location());
-        this.readOperator("{");
-        block.addStatements(this.parseBlockStatements());
-        this.readOperator("}");
-        return block;
-    }
-
-    /**
-     * <pre>
-     *   BlockStatements := { BlockStatement }
-     * </pre>
-     */
-    public List parseBlockStatements() throws ParseException, Scanner.ScanException, IOException {
-        List l = new ArrayList();
-        while (
-            !this.peekOperator("}") &&
-            !this.peekKeyword("case") &&
-            !this.peekKeyword("default")
-        ) l.add(this.parseBlockStatement());
-        return l;
-    }
-
-    /**
-     * <pre>
-     *   BlockStatement := { Identifier ':' } (
-     *     ( Modifiers Type | ModifiersOpt BasicType ) LocalVariableDeclarators ';' |
-     *     'class' ... |
-     *     Statement |
-     *     'final' Type LocalVariableDeclarators ';' |
-     *     Expression ';' |
-     *     Expression LocalVariableDeclarators ';'   (1)
-     *   )
-     * </pre>
-     *
-     * (1) "Expression" must pose a type, and has optional trailing brackets.
-     */
-    public Java.BlockStatement parseBlockStatement() throws ParseException, Scanner.ScanException, IOException {
-
-        // Statement?
-        if (
-            (
-                this.scanner.peek().isIdentifier() &&
-                this.scanner.peekNextButOne().isOperator(":")
-            ) ||
-            this.peekKeyword(new String[] {
-                "if", "for", "while", "do", "try", "switch", "synchronized",
-                "return", "throw", "break", "continue"
-            }) ||
-            this.peekOperator(new String[] { "{", ";" })
-        ) return this.parseStatement();
-
-        // Local class declaration?
-        if (this.peekKeyword("class")) {
-            // JAVADOC[TM] ignores doc comments for local classes, but we
-            // don't...
-            String optionalDocComment = this.scanner.doc();
-            if (optionalDocComment == null) this.warning("LCDCM", "Local class doc comment missing", this.location());
-
-            this.eatToken();
-            final Java.LocalClassDeclaration lcd = (Java.LocalClassDeclaration) this.parseClassDeclarationRest(
-                optionalDocComment,           // optionalDocComment
-                Mod.NONE,                     // modifiers
-                ClassDeclarationContext.BLOCK // context
-            );
-            return new Java.LocalClassDeclarationStatement(lcd);
-        }
-
-        // 'final' Type LocalVariableDeclarators ';'
-        if (this.peekKeyword("final")) {
-            Location location = this.location();
-            this.eatToken();
-            Java.Type variableType = this.parseType();
-            Java.LocalVariableDeclarationStatement lvds = new Java.LocalVariableDeclarationStatement(
-                location,                            // location
-                Mod.FINAL,                           // modifiers
-                variableType,                        // type
-                this.parseLocalVariableDeclarators() // variableDeclarators
-            );
-            this.readOperator(";");
-            return lvds;
-        }
-
-        // It's either a non-final local variable declaration or an expression statement. We can
-        // only tell after parsing an expression.
-        Java.Atom a = this.parseExpression();
-
-        // Expression ';'
-        if (this.peekOperator(";")) {
-            this.eatToken();
-            return new Java.ExpressionStatement(a.toRvalueOrPE());
-        }
-
-        // Expression LocalVariableDeclarators ';'
-        Java.Type variableType = a.toTypeOrPE();
-        Java.LocalVariableDeclarationStatement lvds = new Java.LocalVariableDeclarationStatement(
-            a.getLocation(),                     // location
-            Mod.NONE,                            // modifiers
-            variableType,                        // type
-            this.parseLocalVariableDeclarators() // variableDeclarators
-        );
-        this.readOperator(";");
-        return lvds;
-    }
-
-    /**
-     * <pre>
-     *   LocalVariableDeclarators := VariableDeclarator { ',' VariableDeclarator }
-     * </pre>
-     */
-    public Java.VariableDeclarator[] parseLocalVariableDeclarators() throws ParseException, Scanner.ScanException, IOException {
-        List l = new ArrayList();
-        for (;;) {
-            Java.VariableDeclarator vd = this.parseVariableDeclarator();
-            this.verifyIdentifierIsConventionalLocalVariableOrParameterName(vd.name, vd.getLocation());
-            l.add(vd);
-            if (!this.peekOperator(",")) break;
-            this.eatToken();
-        }
-        return (Java.VariableDeclarator[]) l.toArray(new Java.VariableDeclarator[l.size()]);
-    }
-
-    /**
-     * <pre>
-     *   FieldDeclarationRest :=
-     *     VariableDeclaratorRest
-     *     { ',' VariableDeclarator }
-     * </pre>
-     */
-    public Java.VariableDeclarator[] parseFieldDeclarationRest(String name) throws ParseException, Scanner.ScanException, IOException {
-        List l = new ArrayList();
-
-        Java.VariableDeclarator vd = this.parseVariableDeclaratorRest(name);
-        this.verifyIdentifierIsConventionalFieldName(vd.name, vd.getLocation());
-        l.add(vd);
-
-        while (this.peekOperator(",")) {
-            this.eatToken();
-
-            vd = this.parseVariableDeclarator();
-            this.verifyIdentifierIsConventionalFieldName(vd.name, vd.getLocation());
-            l.add(vd);
-        }
-        return (Java.VariableDeclarator[]) l.toArray(new Java.VariableDeclarator[l.size()]);
-    }
-
-    /**
-     * <pre>
-     *   VariableDeclarator := Identifier VariableDeclaratorRest
-     * </pre>
-     */
-    public Java.VariableDeclarator parseVariableDeclarator() throws ParseException, Scanner.ScanException, IOException {
-        return this.parseVariableDeclaratorRest(this.readIdentifier());
-    }
-
-    /**
-     * <pre>
-     *   VariableDeclaratorRest := { '[' ']' } [ '=' VariableInitializer ]
-     * </pre>
-     * Used by field declarations and local variable declarations.
-     */
-    public Java.VariableDeclarator parseVariableDeclaratorRest(String name) throws ParseException, Scanner.ScanException, IOException  {
-        Location loc = this.location();
-        int brackets = this.parseBracketsOpt();
-        Java.ArrayInitializerOrRvalue initializer = null;
-        if (this.peekOperator("=")) {
-            this.eatToken();
-            initializer = this.parseVariableInitializer();
-        }
-        return new Java.VariableDeclarator(loc, name, brackets, initializer);
-    }
-
-    /**
-     * <pre>
-     *   Statement :=
-     *     LabeledStatement |
-     *     Block |
-     *     IfStatement |
-     *     ForStatement |
-     *     WhileStatement |
-     *     DoStatement |
-     *     TryStatement |
-     *     'switch' ... |
-     *     'synchronized' ... |
-     *     ReturnStatement |
-     *     ThrowStatement |
-     *     BreakStatement |
-     *     ContinueStatement |
-     *     EmptyStatement |
-     *     ExpressionStatement
-     * </pre>
-     */
-    public Java.Statement parseStatement() throws ParseException, Scanner.ScanException, IOException {
-        if (
-            this.scanner.peek().isIdentifier() &&
-            this.scanner.peekNextButOne().isOperator(":")
-        ) {
-            return this.parseLabeledStatement();
-        }
-
-        Scanner.Token t = this.scanner.peek();
-        Java.Statement stmt = (
-            t.isOperator("{")           ? this.parseBlock() :
-            t.isKeyword("if")           ? this.parseIfStatement() :
-            t.isKeyword("for")          ? this.parseForStatement() :
-            t.isKeyword("while")        ? this.parseWhileStatement() :
-            t.isKeyword("do")           ? this.parseDoStatement() :
-            t.isKeyword("try")          ? this.parseTryStatement() :
-            t.isKeyword("switch")       ? this.parseSwitchStatement() :
-            t.isKeyword("synchronized") ? this.parseSynchronizedStatement() :
-            t.isKeyword("return")       ? this.parseReturnStatement() :
-            t.isKeyword("throw")        ? this.parseThrowStatement() :
-            t.isKeyword("break")        ? this.parseBreakStatement() :
-            t.isKeyword("continue")     ? this.parseContinueStatement() :
-            t.isOperator(";")           ? this.parseEmptyStatement() :
-            this.parseExpressionStatement()
-        );
-        if (stmt == null) this.throwParseException("\"" + t.getKeyword() + "\" NYI");
-
-        return stmt;
-    }
-
-    /**
-     * <pre>
-     *   LabeledStatement := Identifier ':' Statement
-     * </pre>
-     */
-    public Java.Statement parseLabeledStatement() throws ParseException, Scanner.ScanException, IOException {
-        String label = this.readIdentifier();
-        this.readOperator(":");
-        return new Java.LabeledStatement(
-            this.location(),        // location
-            label,                  // label
-            this.parseStatement()   // body
-        );
-    }
-
-    /**
-     * <pre>
-     *   IfStatement := 'if' '(' Expression ')' Statement [ 'else' Statement ]
-     * </pre>
-     */
-    public Java.Statement parseIfStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("if");
-        this.readOperator("(");
-        final Java.Rvalue condition = this.parseExpression().toRvalueOrPE();
-        this.readOperator(")");
-
-        Java.Statement thenStatement = this.parseStatement();
-
-        Java.Statement optionalElseStatement = null;
-        if (this.peekKeyword("else")) {
-            this.eatToken();
-            optionalElseStatement = this.parseStatement();
-        }
-
-        return new Java.IfStatement(
-            location,             // location
-            condition,            // condition
-            thenStatement,        // thenStatement
-            optionalElseStatement // optionalElseStatement
-        );
-    }
-
-    /**
-     * <pre>
-     *   ForStatement :=
-     *     'for' '('
-     *       [ ForInit ] ';'
-     *       [ Expression ] ';'
-     *       [ ExpressionList ]
-     *     ')' Statement
-     * </pre>
-     */
-    public Java.Statement parseForStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("for");
-
-        this.readOperator("(");
-
-        Java.BlockStatement optionalInit = null;
-        if (!this.peekOperator(";")) optionalInit = this.parseForInit();
-
-        this.readOperator(";");
-
-        Java.Rvalue optionalCondition = null;
-        if (!this.peekOperator(";")) optionalCondition = this.parseExpression().toRvalueOrPE();
-
-        this.readOperator(";");
-
-        Java.Rvalue[] optionalUpdate = null;
-        if (!this.peekOperator(")")) optionalUpdate = this.parseExpressionList();
-
-        this.readOperator(")");
-
-        // KLUDGE: Insert an implicit Block here.
-//        Java.Block implicitBlock = new Java.Block(location);
-        return /*Java.ForStatement forStatement =*/ new Java.ForStatement(
-            location,             // location
-            optionalInit,         // optionalInit
-            optionalCondition,    // optionalCondition
-            optionalUpdate,       // optionalUpdate
-            this.parseStatement() // body
-        );
-//        implicitBlock.addStatement(forStatement);
-
-//        return implicitBlock;
-    }
-
-    /**
-     * <pre>
-     *   ForInit :=
-     *     Modifiers Type LocalVariableDeclarators |
-     *     ModifiersOpt BasicType LocalVariableDeclarators |
-     *     Expression (
-     *       LocalVariableDeclarators |       (1)
-     *       { ',' Expression }
-     *     )
-     * </pre>
-     *
-     * (1) "Expression" must pose a type.
-     */
-    private Java.BlockStatement parseForInit() throws ParseException, Scanner.ScanException, IOException {
-
-        // Modifiers Type LocalVariableDeclarators
-        // ModifiersOpt BasicType LocalVariableDeclarators
-        if (this.peekKeyword(new String[] { "final", "byte", "short", "char", "int", "long", "float", "double", "boolean" })) {
-            short modifiers = this.parseModifiersOpt();
-            Java.Type variableType = this.parseType();
-            return new Java.LocalVariableDeclarationStatement(
-                this.location(),                     // location
-                modifiers,                           // modifiers
-                variableType,                        // type
-                this.parseLocalVariableDeclarators() // variableDeclarators
-            );
-        }
-
-        Java.Atom a = this.parseExpression();
-
-        // Expression LocalVariableDeclarators
-        if (this.scanner.peek().isIdentifier()) {
-            Java.Type variableType = a.toTypeOrPE();
-            return new Java.LocalVariableDeclarationStatement(
-                a.getLocation(),                     // location
-                Mod.NONE,                            // modifiers
-                variableType,                        // type
-                this.parseLocalVariableDeclarators() // variableDeclarators
-            );
-        }
-
-        // Expression { ',' Expression }
-        if (!this.peekOperator(",")) {
-            return new Java.ExpressionStatement(a.toRvalueOrPE());
-        }
-        this.eatToken();
-        List l = new ArrayList();
-        l.add(new Java.ExpressionStatement(a.toRvalueOrPE()));
-        for (;;) {
-            l.add(new Java.ExpressionStatement(this.parseExpression().toRvalueOrPE()));
-            if (!this.peekOperator(",")) break;
-            this.eatToken();
-        }
-
-        Java.Block b = new Java.Block(a.getLocation());
-        b.addStatements(l);
-        return b;
-    }
-
-    /**
-     * <pre>
-     *   WhileStatement := 'while' '(' Expression ')' Statement
-     * </pre>
-     */
-    public Java.Statement parseWhileStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("while");
-
-        this.readOperator("(");
-        Java.Rvalue condition = this.parseExpression().toRvalueOrPE();
-        this.readOperator(")");
-
-        return new Java.WhileStatement(
-            location,             // location
-            condition,            // condition
-            this.parseStatement() // body
-        );
-    }
-
-    /**
-     * <pre>
-     *   DoStatement := 'do' Statement 'while' '(' Expression ')' ';'
-     * </pre>
-     */
-    public Java.Statement parseDoStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("do");
-
-        Java.Statement body = this.parseStatement();
-
-        this.readKeyword("while");
-        this.readOperator("(");
-        Java.Rvalue condition = this.parseExpression().toRvalueOrPE();
-        this.readOperator(")");
-        this.readOperator(";");
-
-        return new Java.DoStatement(
-            location, // location
-            body,     // body
-            condition // condition
-        );
-    }
-
-    /**
-     * <pre>
-     *   TryStatement :=
-     *     'try' Block Catches [ Finally ] |
-     *     'try' Block Finally
-     *
-     *   Catches := CatchClause { CatchClause }
-     *
-     *   CatchClause := 'catch' '(' FormalParameter ')' Block
-     *
-     *   Finally := 'finally' Block
-     * </pre>
-     */
-    public Java.Statement parseTryStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("try");
-
-        Java.Block body = this.parseBlock();
-
-        // { CatchClause }
-        List ccs = new ArrayList();
-        while (this.peekKeyword("catch")) {
-            Location loc = this.location();
-            this.eatToken();
-            this.readOperator("(");
-            Java.FunctionDeclarator.FormalParameter caughtException = this.parseFormalParameter();
-            this.readOperator(")");
-            ccs.add(new Java.CatchClause(
-                loc,              // location
-                caughtException,  // caughtException
-                this.parseBlock() // body
-            ));
-        }
-        Java.Block optionalFinally = null;
-        if (this.peekKeyword("finally")) {
-            this.eatToken();
-            optionalFinally = this.parseBlock();
-        }
-        if (ccs.size() == 0 && optionalFinally == null) this.throwParseException("\"try\" statement must have at least one \"catch\" clause or a \"finally\" clause");
-
-        return new Java.TryStatement(
-            location,       // location
-            body,           // body
-            ccs,            // catchClauses
-            optionalFinally // optionalFinally
-        );
-    }
-
-    /**
-     * <pre>
-     *   SwitchStatement :=
-     *     'switch' '(' Expression ')' '{' { SwitchLabels BlockStatements } '}'
-     *
-     *   SwitchLabels := SwitchLabels { SwitchLabels }
-     *
-     *   SwitchLabel := 'case' Expression ':' | 'default' ':'
-     * </pre>
-     */
-    public Java.Statement parseSwitchStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("switch");
-
-        this.readOperator("(");
-        Java.Rvalue condition = this.parseExpression().toRvalueOrPE();
-        this.readOperator(")");
-
-        this.readOperator("{");
-        List sbsgs = new ArrayList();
-        while (!this.peekOperator("}")) {
-            Location location2 = this.location();
-            boolean hasDefaultLabel = false;
-            List caseLabels = new ArrayList();
-            do {
-                if (this.peekKeyword("case")) {
-                    this.eatToken();
-                    caseLabels.add(this.parseExpression().toRvalueOrPE());
-                } else
-                if (this.peekKeyword("default")) {
-                    this.eatToken();
-                    if (hasDefaultLabel) this.throwParseException("Duplicate \"default\" label");
-                    hasDefaultLabel = true;
-                } else {
-                    this.throwParseException("\"case\" or \"default\" expected");
-                }
-                this.readOperator(":");
-            } while (this.peekKeyword(new String[] { "case", "default" }));
-
-            Java.SwitchStatement.SwitchBlockStatementGroup sbsg = new Java.SwitchStatement.SwitchBlockStatementGroup(
-                location2, // location
-                caseLabels, // caseLabels
-                hasDefaultLabel, // hasDefaultLabel
-                this.parseBlockStatements() // blockStatements
-            );
-            sbsgs.add(sbsg);
-        }
-        this.eatToken();
-        return new Java.SwitchStatement(
-                location,  // location
-                condition, // condition
-                sbsgs      // sbsgs
-            );
-    }
-
-    /**
-     * <pre>
-     *   SynchronizedStatement :=
-     *     'synchronized' '(' expression ')' Block
-     * </pre>
-     */
-    public Java.Statement parseSynchronizedStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("synchronized");
-        this.readOperator("(");
-        Java.Rvalue expression = this.parseExpression().toRvalueOrPE();
-        this.readOperator(")");
-        return new Java.SynchronizedStatement(
-            location,         // location
-            expression,       // expression
-            this.parseBlock() // body
-        );
-    }
-
-    /**
-     * <pre>
-     *   ReturnStatement := 'return' [ Expression ] ';'
-     * </pre>
-     */
-    public Java.Statement parseReturnStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("return");
-        Java.Rvalue returnValue = this.peekOperator(";") ? null : this.parseExpression().toRvalueOrPE();
-        this.readOperator(";");
-        return new Java.ReturnStatement(location, returnValue);
-    }
-
-    /**
-     * <pre>
-     *   ThrowStatement := 'throw' Expression ';'
-     * </pre>
-     */
-    public Java.Statement parseThrowStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("throw");
-        final Java.Rvalue expression = this.parseExpression().toRvalueOrPE();
-        this.readOperator(";");
-
-        return new Java.ThrowStatement(location, expression);
-    }
-
-    /**
-     * <pre>
-     *   BreakStatement := 'break' [ Identifier ] ';'
-     * </pre>
-     */
-    public Java.Statement parseBreakStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("break");
-        String optionalLabel = null;
-        if (this.scanner.peek().isIdentifier()) optionalLabel = this.readIdentifier();
-        this.readOperator(";");
-        return new Java.BreakStatement(location, optionalLabel);
-    }
-
-    /**
-     * <pre>
-     *   ContinueStatement := 'continue' [ Identifier ] ';'
-     * </pre>
-     */
-    public Java.Statement parseContinueStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readKeyword("continue");
-        String optionalLabel = null;
-        if (this.scanner.peek().isIdentifier()) optionalLabel = this.readIdentifier();
-        this.readOperator(";");
-        return new Java.ContinueStatement(location, optionalLabel);
-    }
-
-    /**
-     * <pre>
-     *   EmptyStatement := ';'
-     * </pre>
-     */
-    public Java.Statement parseEmptyStatement() throws ParseException, Scanner.ScanException, IOException {
-        Location location = this.location();
-        this.readOperator(";");
-        return new Java.EmptyStatement(location);
-    }
-
-    /**
-     * <pre>
-     *   ExpressionList := Expression { ',' Expression }
-     * </pre>
-     */
-    public Java.Rvalue[] parseExpressionList() throws ParseException, Scanner.ScanException, IOException {
-        List l = new ArrayList();
-        for (;;) {
-            l.add(this.parseExpression().toRvalueOrPE());
-            if (!this.peekOperator(",")) break;
-            this.eatToken();
-        }
-        return (Java.Rvalue[]) l.toArray(new Java.Rvalue[l.size()]);
-    }
-
-    /**
-     * <pre>
-     *   Type := (
-     *     'byte' | 'short' | 'char' | 'int' | 'long' |
-     *     'float' | 'double' | 'boolean' |
-     *     ReferenceType
-     *   ) { '[' ']' }
-     * </pre>
-     */
-    public Java.Type parseType() throws ParseException, Scanner.ScanException, IOException {
-        Scanner.Token t = this.scanner.peek();
-        int bt = -1;
-        if (t.isKeyword("byte"   )) { bt = Java.BasicType.BYTE   ; } else
-        if (t.isKeyword("short"  )) { bt = Java.BasicType.SHORT  ; } else
-        if (t.isKeyword("char"   )) { bt = Java.BasicType.CHAR   ; } else
-        if (t.isKeyword("int"    )) { bt = Java.BasicType.INT    ; } else
-        if (t.isKeyword("long"   )) { bt = Java.BasicType.LONG   ; } else
-        if (t.isKeyword("float"  )) { bt = Java.BasicType.FLOAT  ; } else
-        if (t.isKeyword("double" )) { bt = Java.BasicType.DOUBLE ; } else
-        if (t.isKeyword("boolean")) { bt = Java.BasicType.BOOLEAN; }
-        Java.Type res;
-        if (bt != -1) {
-            res = new Java.BasicType(t.getLocation(), bt);
-            this.eatToken();
-        } else {
-            res = this.parseReferenceType();
-        }
-        for (int i = this.parseBracketsOpt(); i > 0; --i) res = new Java.ArrayType(res);
-        return res;
-    }
-
-    /**
-     * <pre>
-     *   ReferenceType := QualifiedIdentifier
-     * </pre>
-     */
-    public Java.ReferenceType parseReferenceType() throws ParseException, Scanner.ScanException, IOException {
-        return new Java.ReferenceType(
-            this.location(),                // location
-            this.parseQualifiedIdentifier() // identifiers
-        );
-    }
-
-    /**
-     * <pre>
-     *   ReferenceTypeList := ReferenceType { ',' ReferenceType }
-     * </pre>
-     */
-    public Java.ReferenceType[] parseReferenceTypeList() throws ParseException, Scanner.ScanException, IOException {
-        List l = new ArrayList();
-        l.add(this.parseReferenceType());
-        while (this.peekOperator(",")) {
-            this.eatToken();
-            l.add(this.parseReferenceType());
-        }
-        return (Java.ReferenceType[]) l.toArray(new Java.ReferenceType[l.size()]);
-    }
-
-    /**
-     * <pre>
-     *   Expression := AssignmentExpression
-     * </pre>
-     */
-    public Java.Atom parseExpression() throws ParseException, Scanner.ScanException, IOException  {
-        return this.parseAssignmentExpression();
-    }
-
-    /**
-     * <pre>
-     *   AssignmentExpression :=
-     *     ConditionalExpression [ AssignmentOperator AssignmentExpression ]
-     *
-     *   AssignmentOperator :=
-     *     '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' |
-     *     '>>=' | '>>>=' | '&=' | '^=' | '|='
-     * </pre>
-     */
-    public Java.Atom parseAssignmentExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseConditionalExpression();
-        if (this.peekOperator(new String[] { "=", "+=", "-=", "*=", "/=", "&=", "|=", "^=", "%=", "<<=", ">>=", ">>>=" })) {
-            Location location = this.location();
-            String operator = this.readOperator();
-            final Java.Lvalue lhs = a.toLvalueOrPE();
-            final Java.Rvalue rhs = this.parseAssignmentExpression().toRvalueOrPE();
-            return new Java.Assignment(location, lhs, operator, rhs);
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   ConditionalExpression :=
-     *     ConditionalOrExpression [ '?' Expression ':' ConditionalExpression ]
-     * </pre>
-     */
-    public Java.Atom parseConditionalExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseConditionalOrExpression();
-        if (!this.peekOperator("?")) return a;
-        Location location = this.location();
-        this.eatToken();
-
-        Java.Rvalue lhs = a.toRvalueOrPE();
-        Java.Rvalue mhs = this.parseExpression().toRvalueOrPE();
-        this.readOperator(":");
-        Java.Rvalue rhs = this.parseConditionalExpression().toRvalueOrPE();
-        return new Java.ConditionalExpression(location, lhs, mhs, rhs);
-    }
-
-    /**
-     * <pre>
-     *   ConditionalOrExpression :=
-     *     ConditionalAndExpression { '||' ConditionalAndExpression ]
-     * </pre>
-     */
-    public Java.Atom parseConditionalOrExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseConditionalAndExpression();
-        while (this.peekOperator("||")) {
-            Location location = this.location();
-            this.eatToken();
-            a = new Java.BinaryOperation(
-                location,
-                a.toRvalueOrPE(),
-                "||",
-                this.parseConditionalAndExpression().toRvalueOrPE()
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   ConditionalAndExpression :=
-     *     InclusiveOrExpression { '&&' InclusiveOrExpression }
-     * </pre>
-     */
-    public Java.Atom parseConditionalAndExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseInclusiveOrExpression();
-        while (this.peekOperator("&&")) {
-            Location location = this.location();
-            this.eatToken();
-            a = new Java.BinaryOperation(
-                location,
-                a.toRvalueOrPE(),
-                "&&",
-                this.parseInclusiveOrExpression().toRvalueOrPE()
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   InclusiveOrExpression :=
-     *     ExclusiveOrExpression { '|' ExclusiveOrExpression }
-     * </pre>
-     */
-    public Java.Atom parseInclusiveOrExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseExclusiveOrExpression();
-        while (this.peekOperator("|")) {
-            Location location = this.location();
-            this.eatToken();
-            a = new Java.BinaryOperation(
-                location,
-                a.toRvalueOrPE(),
-                "|",
-                this.parseExclusiveOrExpression().toRvalueOrPE()
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   ExclusiveOrExpression :=
-     *     AndExpression { '^' AndExpression }
-     * </pre>
-     */
-    public Java.Atom parseExclusiveOrExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseAndExpression();
-        while (this.peekOperator("^")) {
-            Location location = this.location();
-            this.eatToken();
-            a = new Java.BinaryOperation(
-                location,
-                a.toRvalueOrPE(),
-                "^",
-                this.parseAndExpression().toRvalueOrPE()
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   AndExpression :=
-     *     EqualityExpression { '&' EqualityExpression }
-     * </pre>
-     */
-    public Java.Atom parseAndExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseEqualityExpression();
-        while (this.peekOperator("&")) {
-            Location location = this.location();
-            this.eatToken();
-            a = new Java.BinaryOperation(
-                location,
-                a.toRvalueOrPE(),
-                "&",
-                this.parseEqualityExpression().toRvalueOrPE()
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   EqualityExpression :=
-     *     RelationalExpression { ( '==' | '!=' ) RelationalExpression }
-     * </pre>
-     */
-    public Java.Atom parseEqualityExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseRelationalExpression();
-
-        while (this.peekOperator(new String[] { "==", "!=" })) {
-            a = new Java.BinaryOperation(
-                this.location(),                                // location
-                a.toRvalueOrPE(),                               // lhs
-                this.readOperator(),                            // op
-                this.parseRelationalExpression().toRvalueOrPE() // rhs
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   RelationalExpression :=
-     *     ShiftExpression {
-     *       ( ( '<' | '>' | '<=' | '>=' ) ShiftExpression ) |
-     *       ( 'instanceof' ReferenceType )
-     *     }
-     * </pre>
-     */
-    public Java.Atom parseRelationalExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseShiftExpression();
-
-        for (;;) {
-            if (this.peekKeyword("instanceof")) {
-                Location location = this.location();
-                this.eatToken();
-                a = new Java.Instanceof(
-                    location,
-                    a.toRvalueOrPE(),
-                    this.parseType()
-                );
-            } else
-            if (this.peekOperator(new String[] { "<", ">", "<=", ">=" })) {
-                a = new Java.BinaryOperation(
-                    this.location(),                    // location
-                    a.toRvalueOrPE(),                          // lhs
-                    this.readOperator(),                       // op
-                    this.parseShiftExpression().toRvalueOrPE() // rhs
-                );
-            } else {
-                return a;
-            }
-        }
-    }
-
-    /**
-     * <pre>
-     *   ShiftExpression :=
-     *     AdditiveExpression { ( '<<' | '>>' | '>>>' ) AdditiveExpression }
-     * </pre>
-     */
-    public Java.Atom parseShiftExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseAdditiveExpression();
-
-        while (this.peekOperator(new String[] { "<<", ">>", ">>>" })) {
-            a = new Java.BinaryOperation(
-                this.location(),                       // location
-                a.toRvalueOrPE(),                             // lhs
-                this.readOperator(),                          // op
-                this.parseAdditiveExpression().toRvalueOrPE() // rhs
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   AdditiveExpression :=
-     *     MultiplicativeExpression { ( '+' | '-' ) MultiplicativeExpression }
-     * </pre>
-     */
-    public Java.Atom parseAdditiveExpression() throws ParseException, Scanner.ScanException, IOException  {
-        Java.Atom a = this.parseMultiplicativeExpression();
-
-        while (this.peekOperator(new String[] { "+", "-" })) {
-            a = new Java.BinaryOperation(
-                this.location(),                                    // location
-                a.toRvalueOrPE(),                                   // lhs
-                this.readOperator(),                                // op
-                this.parseMultiplicativeExpression().toRvalueOrPE() // rhs
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   MultiplicativeExpression :=
-     *     UnaryExpression { ( '*' | '/' | '%' ) UnaryExpression }
-     * </pre>
-     */
-    public Java.Atom parseMultiplicativeExpression() throws ParseException, Scanner.ScanException, IOException {
-        Java.Atom a = this.parseUnaryExpression();
-
-        while (this.peekOperator(new String[] { "*", "/", "%" })) {
-            a = new Java.BinaryOperation(
-                this.location(),                    // location
-                a.toRvalueOrPE(),                          // lhs
-                this.readOperator(),                       // op
-                this.parseUnaryExpression().toRvalueOrPE() // rhs
-            );
-        }
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   UnaryExpression :=
-     *     { PrefixOperator } Primary { Selector } { PostfixOperator }
-     *
-     *   PrefixOperator := '++' | '--' | '+' | '-' | '~' | '!'
-     *
-     *   PostfixOperator := '++' | '--'
-     * </pre>
-     */
-    public Java.Atom parseUnaryExpression() throws ParseException, Scanner.ScanException, IOException {
-        if (this.peekOperator(new String[] { "++", "--" })) {
-            return new Java.Crement(
-                this.location(),                           // location
-                this.readOperator(),                       // operator
-                this.parseUnaryExpression().toLvalueOrPE() // operand
-            );
-        }
-
-        if (this.peekOperator(new String[] { "+", "-", "~", "!" })) {
-            return new Java.UnaryOperation(
-                this.location(),                           // location
-                this.readOperator(),                       // operator
-                this.parseUnaryExpression().toRvalueOrPE() // operand
-            );
-        }
-
-        Java.Atom a = this.parsePrimary();
-
-        while (this.peekOperator(new String[] { ".", "[" })) {
-            a = this.parseSelector(a);
-        }
-
-        while (this.peekOperator(new String[] { "++", "--" })) {
-            a = new Java.Crement(
-                this.location(),    // location
-                a.toLvalueOrPE(),   // operand
-                this.readOperator() // operator
-            );
-        }
-
-        return a;
-    }
-
-    /**
-     * <pre>
-     *   Primary :=
-     *     CastExpression |                        // CastExpression 15.16
-     *     '(' Expression ')' |                    // ParenthesizedExpression 15.8.5
-     *     Literal |                               // Literal 15.8.1
-     *     Name |                                  // AmbiguousName
-     *     Name Arguments |                        // MethodInvocation
-     *     Name '[]' { '[]' } |                    // ArrayType 10.1
-     *     Name '[]' { '[]' } '.' 'class' |        // ClassLiteral 15.8.2
-     *     'this' |                                // This 15.8.3
-     *     'this' Arguments |                      // Alternate constructor invocation 8.8.5.1
-     *     'super' Arguments |                     // Unqualified superclass constructor invocation 8.8.5.1
-     *     'super' '.' Identifier |                // SuperclassFieldAccess 15.11.2
-     *     'super' '.' Identifier Arguments |      // SuperclassMethodInvocation 15.12.4.9
-     *     NewClassInstance |
-     *     NewAnonymousClassInstance |             // ClassInstanceCreationExpression 15.9
-     *     NewArray |                              // ArrayCreationExpression 15.10
-     *     NewInitializedArray |                   // ArrayInitializer 10.6
-     *     BasicType { '[]' } |                    // Type
-     *     BasicType { '[]' } '.' 'class' |        // ClassLiteral 15.8.2
-     *     'void' '.' 'class'                      // ClassLiteral 15.8.2
-     *
-     *   CastExpression :=
-     *     '(' PrimitiveType { '[]' } ')' UnaryExpression |
-     *     '(' Expression ')' UnaryExpression
-     * 
-     *   NewClassInstance := 'new' ReferenceType Arguments
-     * 
-     *   NewAnonymousClassInstance := 'new' ReferenceType Arguments [ ClassBody ]
-     * 
-     *   NewArray := 'new' Type DimExprs { '[]' }
-     * 
-     *   NewInitializedArray := 'new' ArrayType ArrayInitializer
-     * </pre>
-     */
-    public Java.Atom parsePrimary() throws ParseException, Scanner.ScanException, IOException {
-        if (this.peekOperator("(")) {
-            this.eatToken();
-            if (this.peekKeyword(new String[] { "boolean", "char", "byte", "short", "int", "long", "float", "double", })) {
-                // '(' PrimitiveType { '[]' } ')' UnaryExpression
-                Java.Type type = this.parseType();
-                int brackets = this.parseBracketsOpt();
-                this.readOperator(")");
-                for (int i = 0; i < brackets; ++i) type = new Java.ArrayType(type);
-                return new Java.Cast(
-                    this.location(),                           // location
-                    type,                                      // targetType
-                    this.parseUnaryExpression().toRvalueOrPE() // value
-                );
-            }
-            Java.Atom a = this.parseExpression();
-            this.readOperator(")");
-
-            if (
-                this.scanner.peek().isLiteral() ||
-                this.scanner.peek().isIdentifier() ||
-                this.peekOperator(new String[] { "(", "~", "!", }) ||
-                this.peekKeyword(new String[] { "this", "super", "new", } )
-            ) {
-                // '(' Expression ')' UnaryExpression
-                return new Java.Cast(
-                    this.location(),                           // location
-                    a.toTypeOrPE(),                            // targetType
-                    this.parseUnaryExpression().toRvalueOrPE() // value
-                );
-            }
-
-            // '(' Expression ')'
-            return new Java.ParenthesizedExpression(a.getLocation(), a.toRvalueOrPE());
-        }
-
-        if (this.scanner.peek().isLiteral()) {
-            // Literal
-            return this.parseLiteral();
-        }
-
-        if (this.scanner.peek().isIdentifier()) {
-            Location location = this.location();
-            String[] qi = this.parseQualifiedIdentifier();
-            if (this.peekOperator("(")) {
-                // Name Arguments
-                return new Java.MethodInvocation(
-                    this.location(),                                // location
-                    qi.length == 1 ? null : new Java.AmbiguousName( // optionalTarget
-                        location,       // location
-                        qi,             // identifiers
-                        qi.length - 1   // n
-                    ),
-                    qi[qi.length - 1],                              // methodName
-                    this.parseArguments()                           // arguments
-                );
-            }
-            if (
-                this.peekOperator("[")
-                && this.scanner.peekNextButOne().isOperator("]")
-            ) {
-                // Name '[]' { '[]' }
-                // Name '[]' { '[]' } '.' 'class'
-                Java.Type res = new Java.ReferenceType(
-                    location, // location
-                    qi        // identifiers
-                );
-                int brackets = this.parseBracketsOpt();
-                for (int i = 0; i < brackets; ++i) res = new Java.ArrayType(res);
-                if (
-                    this.peekOperator(".")
-                    && this.scanner.peekNextButOne().isKeyword("class")
-                ) {
-                    this.eatToken();
-                    Location location2 = this.location();
-                    this.eatToken();
-                    return new Java.ClassLiteral(location2, res);
-                } else {
-                    return res;
-                }
-            }
-            // Name
-            return new Java.AmbiguousName(
-                this.location(), // location
-                qi               // identifiers
-            );
-        }
-
-        if (this.peekKeyword("this")) {
-            Location location = this.location();
-            this.eatToken();
-            if (this.peekOperator("(")) {
-
-                // 'this' Arguments
-                // Alternate constructor invocation (JLS 8.8.5.1)
-                return new Java.AlternateConstructorInvocation(
-                    location,             // location
-                    this.parseArguments() // arguments
-                );
-            } else
-            {
-
-                // 'this'
-                return new Java.ThisReference(location);
-            }
-        }
-
-        if (this.peekKeyword("super")) {
-            this.eatToken();
-            if (this.peekOperator("(")) {
-
-                // 'super' Arguments
-                // Unqualified superclass constructor invocation (JLS 8.8.5.1)
-                return new Java.SuperConstructorInvocation(
-                    this.location(),      // location
-                    (Java.Rvalue) null,   // optionalQualification
-                    this.parseArguments() // arguments
-                );
-            }
-            this.readOperator(".");
-            String name = this.readIdentifier();
-            if (this.peekOperator("(")) {
-
-                // 'super' '.' Identifier Arguments
-                return new Java.SuperclassMethodInvocation(
-                    this.location(),      // location
-                    name,                 // methodName
-                    this.parseArguments() // arguments
-                );
-            } else {
-
-                // 'super' '.' Identifier
-                return new Java.SuperclassFieldAccessExpression(
-                    this.location(),  // location
-                    (Java.Type) null, // optionalQualification
-                    name              // fieldName
-                );
-            }
-        }
-
-        // 'new'
-        if (this.peekKeyword("new")) {
-            Location location = this.location();
-            this.eatToken();
-            Java.Type type = this.parseType();
-            if (type instanceof Java.ArrayType) {
-                // 'new' ArrayType ArrayInitializer
-                return new Java.NewInitializedArray(location, (Java.ArrayType) type, this.parseArrayInitializer());
-            }
-            if (
-                type instanceof Java.ReferenceType
-                && this.peekOperator("(")
-            ) {
-                // 'new' ReferenceType Arguments [ ClassBody ]
-                Java.Rvalue[] arguments = this.parseArguments();
-                if (this.peekOperator("{")) {
-                    // 'new' ReferenceType Arguments ClassBody
-                    final Java.AnonymousClassDeclaration anonymousClassDeclaration = new Java.AnonymousClassDeclaration(
-                        this.location(), // location
-                        type             // baseType
-                    );
-                    this.parseClassBody(anonymousClassDeclaration);
-                    return new Java.NewAnonymousClassInstance(
-                        location,                  // location
-                        (Java.Rvalue) null,        // optionalQualification
-                        anonymousClassDeclaration, // anonymousClassDeclaration
-                        arguments                  // arguments
-                    );
-                } else {
-                    // 'new' ReferenceType Arguments
-                    return new Java.NewClassInstance(
-                        location,           // location
-                        (Java.Rvalue) null, // optionalQualification
-                        type,               // type
-                        arguments           // arguments
-                    );
-                }
-            }
-            // 'new' Type DimExprs { '[]' }
-            return new Java.NewArray(
-                location,               // location
-                type,                   // type
-                this.parseDimExprs(),   // dimExprs
-                this.parseBracketsOpt() // dims
-            );
-        }
-
-        // BasicType
-        if (this.peekKeyword(new String[] { "boolean", "char", "byte", "short", "int", "long", "float", "double", })) {
-            Java.Type res = this.parseType();
-            int brackets = this.parseBracketsOpt();
-            for (int i = 0; i < brackets; ++i) res = new Java.ArrayType(res);
-            if (
-                this.peekOperator(".")
-                && this.scanner.peekNextButOne().isKeyword("class")
-            ) {
-                // BasicType { '[]' } '.' 'class'
-                this.eatToken();
-                Location location = this.location();
-                this.eatToken();
-                return new Java.ClassLiteral(location, res);
-            }
-            // BasicType { '[]' }
-            return res;
-        }
-
-        // 'void'
-        if (this.peekKeyword("void")) {
-            this.eatToken();
-            if (
-                this.peekOperator(".")
-                && this.scanner.peekNextButOne().isKeyword("class")
-            ) {
-                // 'void' '.' 'class'
-                this.eatToken();
-                Location location = this.location();
-                this.eatToken();
-                return new Java.ClassLiteral(location, new Java.BasicType(location, Java.BasicType.VOID));
-            }
-            this.throwParseException("\"void\" encountered in wrong context");
-        }
-
-        this.throwParseException("Unexpected token \"" + this.scanner.peek() + "\" in primary");
-        /* NEVER REACHED */ return null;
-    }
-
-    /**
-     * <pre>
-     *   Selector :=
-     *     '.' Identifier |                       // FieldAccess 15.11.1
-     *     '.' Identifier Arguments |             // MethodInvocation
-     *     '.' 'this'                             // QualifiedThis 15.8.4
-     *     '.' 'super' Arguments                  // Qualified superclass constructor invocation (JLS 8.8.5.1)
-     *     '.' 'super' '.' Identifier |           // SuperclassFieldReference (JLS 15.11.2)
-     *     '.' 'super' '.' Identifier Arguments | // SuperclassMethodInvocation (JLS 15.12.4.9)
-     *     '.' 'new' Identifier Arguments [ ClassBody ] | // QualifiedClassInstanceCreationExpression  15.9
-     *     '.' 'class'
-     *     '[' Expression ']'                     // ArrayAccessExpression 15.13
-     * </pre>
-     */
-    public Java.Atom parseSelector(Java.Atom atom) throws ParseException, Scanner.ScanException, IOException {
-        if (this.peekOperator(".")) {
-            this.eatToken();
-            if (this.scanner.peek().isIdentifier()) {
-                String identifier = this.readIdentifier();
-                if (this.peekOperator("(")) {
-                    // '.' Identifier Arguments
-                    return new Java.MethodInvocation(
-                        this.location(),      // location
-                        atom.toRvalueOrPE(),  // optionalTarget
-                        identifier,           // methodName
-                        this.parseArguments() // arguments
-                    );
-                }
-                // '.' Identifier
-                return new Java.FieldAccessExpression(
-                    this.location(),     // location
-                    atom.toRvalueOrPE(), // lhs
-                    identifier           // fieldName
-                );
-            }
-            if (this.peekKeyword("this")) {
-                // '.' 'this'
-                Location location = this.location();
-                this.eatToken();
-                return new Java.QualifiedThisReference(
-                    location,                // location
-                    atom.toTypeOrPE()        // qualification
-                );
-            }
-            if (this.peekKeyword("super")) {
-                Location location = this.location();
-                this.eatToken();
-                if (this.peekOperator("(")) {
-
-                    // '.' 'super' Arguments
-                    // Qualified superclass constructor invocation (JLS 8.8.5.1) (LHS is an Rvalue)
-                    return new Java.SuperConstructorInvocation(
-                        location,             // location
-                        atom.toRvalueOrPE(),  // optionalQualification
-                        this.parseArguments() // arguments
-                    );
-                }
-                this.readOperator(".");
-                String identifier = this.readIdentifier();
-
-                if (this.peekOperator("(")) {
-
-                    // '.' 'super' '.' Identifier Arguments
-                    // Qualified superclass method invocation (JLS 15.12) (LHS is a ClassName)
-                    // TODO: Qualified superclass method invocation
-                    this.throwParseException("Qualified superclass method invocation NYI");
-                } else {
-
-                    // '.' 'super' '.' Identifier
-                    // Qualified superclass field access (JLS 15.11.2) (LHS is an Rvalue)
-                    return new Java.SuperclassFieldAccessExpression(
-                        location,          // location
-                        atom.toTypeOrPE(), // optionalQualification
-                        identifier         // fieldName
-                    );
-                }
-            }
-            if (this.peekKeyword("new")) {
-                // '.' 'new' Identifier Arguments [ ClassBody ]
-                Java.Rvalue lhs = atom.toRvalue();
-                Location location = this.location();
-                this.eatToken();
-                String identifier = this.readIdentifier();
-                Java.Type type = new Java.RvalueMemberType(
-                    location,  // location
-                    lhs,       // rValue
-                    identifier // identifier
-                );
-                Java.Rvalue[] arguments = this.parseArguments();
-                if (this.peekOperator("{")) {
-                    // '.' 'new' Identifier Arguments ClassBody (LHS is an Rvalue)
-                    final Java.AnonymousClassDeclaration anonymousClassDeclaration = new Java.AnonymousClassDeclaration(
-                        this.location(), // location
-                        type             // baseType
-                    );
-                    this.parseClassBody(anonymousClassDeclaration);
-                    return new Java.NewAnonymousClassInstance(
-                        location,                  // location
-                        lhs,                       // optionalQualification
-                        anonymousClassDeclaration, // anonymousClassDeclaration
-                        arguments                  // arguments
-                    );
-                } else {
-                    // '.' 'new' Identifier Arguments (LHS is an Rvalue)
-                    return new Java.NewClassInstance(
-                        location, // location
-                        lhs,      // optionalQualification
-                        type,     // referenceType
-                        arguments // arguments
-                    );
-                }
-            }
-            if (this.peekKeyword("class")) {
-                // '.' 'class'
-                Location location = this.location();
-                this.eatToken();
-                return new Java.ClassLiteral(location, atom.toTypeOrPE());
-            }
-            this.throwParseException("Unexpected selector \"" + this.scanner.peek() + "\" after \".\"");
-        }
-        if (this.peekOperator("[")) {
-            // '[' Expression ']'
-            Location location = this.location();
-            this.eatToken();
-            Java.Rvalue index = this.parseExpression().toRvalueOrPE();
-            this.readOperator("]");
-            return new Java.ArrayAccessExpression(
-                location,        // location
-                atom.toRvalueOrPE(), // lhs
-                index            // index
-            );
-        }
-        this.throwParseException("Unexpected token \"" + this.scanner.peek() + "\" in selector");
-        /* NEVER REACHED */ return null;
-    }
-
-    /**
-     * <pre>
-     *   DimExprs := DimExpr { DimExpr }
-     * </pre>
-     */
-    public Java.Rvalue[] parseDimExprs() throws ParseException, Scanner.ScanException, IOException {
-        List l = new ArrayList();
-        l.add(this.parseDimExpr());
-        while (
-            this.peekOperator("[")
-            && !this.scanner.peekNextButOne().isOperator("]")
-        ) l.add(this.parseDimExpr());
-        return (Java.Rvalue[]) l.toArray(new Java.Rvalue[l.size()]);
-    }
-
-    /**
-     * <pre>
-     *   DimExpr := '[' Expression ']'
-     * </pre>
-     */
-    public Java.Rvalue parseDimExpr() throws Scanner.ScanException, ParseException, IOException {
-        this.readOperator("[");
-        Java.Rvalue res = this.parseExpression().toRvalueOrPE();
-        this.readOperator("]");
-        return res;
-    }
-
-    /**
-     * <pre>
-     *   Arguments := '(' [ ArgumentList ] ')'
-     * </pre>
-     */
-    public Java.Rvalue[] parseArguments() throws ParseException, Scanner.ScanException, IOException {
-        this.readOperator("(");
-        if (this.peekOperator(")")) {
-            this.eatToken();
-            return new Java.Rvalue[0];
-        }
-        Java.Rvalue[] arguments = this.parseArgumentList();
-        this.readOperator(")");
-        return arguments;
-    }
-
-    /**
-     * <pre>
-     *   ArgumentList := Expression { ',' Expression }
-     * </pre>
-     */
-    public Java.Rvalue[] parseArgumentList() throws ParseException, Scanner.ScanException, IOException {
-        List l = new ArrayList();
-        for (;;) {
-            l.add(this.parseExpression().toRvalueOrPE());
-            if (!this.peekOperator(",")) break;
-            this.eatToken();
-        }
-        return (Java.Rvalue[]) l.toArray(new Java.Rvalue[l.size()]);
-    }
-
-    public Java.Atom parseLiteral() throws ParseException, Scanner.ScanException, IOException {
-        Scanner.Token t = this.scanner.read();
-        if (!t.isLiteral()) this.throwParseException("Literal expected");
-        return new Java.Literal(t.getLocation(), t.getLiteralValue());
-    }
-
-    // Simplified access to the scanner.
-
-    public Location location()                                           { return this.scanner.location(); }
-    public void     eatToken() throws Scanner.ScanException, IOException { this.scanner.read(); }
-    // Keyword-related.
-    public boolean peekKeyword()                  { return this.scanner.peek().isKeyword(); }
-    public boolean peekKeyword(String keyword)    { return this.scanner.peek().isKeyword(keyword); }
-    public boolean peekKeyword(String[] keywords) { return this.scanner.peek().isKeyword(keywords); }
-    public void    readKeyword(String keyword) throws ParseException, Scanner.ScanException, IOException {
-        if (!this.scanner.read().isKeyword(keyword)) this.throwParseException("\"" + keyword + "\" expected"); // We want a ParseException, not a ScanException
-    }
-    // Operator-related.
-    public boolean peekOperator(String operator)    { return this.scanner.peek().isOperator(operator); }
-    public boolean peekOperator(String[] operators) { return this.scanner.peek().isOperator(operators); }
-    public String  readOperator() throws ParseException, Scanner.ScanException, IOException {
-        Scanner.Token t = this.scanner.read();
-        if (!t.isOperator()) this.throwParseException("Operator expected"); // We want a ParseException, not a ScanException
-        return t.getOperator();
-    }
-    public void    readOperator(String operator) throws ParseException, Scanner.ScanException, IOException {
-        if (!this.scanner.read().isOperator(operator)) this.throwParseException("Operator \"" + operator + "\" expected"); // We want a ParseException, not a ScanException
-    }
-    // Identifier-related.
-    public boolean peekIdentifier() { return this.scanner.peek().isIdentifier(); }
-    public String readIdentifier() throws ParseException, Scanner.ScanException, IOException {
-        Scanner.Token t = this.scanner.read();
-        if (!t.isIdentifier()) this.throwParseException("Identifier expected"); // We want a ParseException, not a ScanException
-        return t.getIdentifier();
-    }
-
-    /**
-     * <pre>
-     *   ExpressionStatement := Expression ';'
-     * </pre>
-     */
-    public Java.Statement parseExpressionStatement() throws ParseException, Scanner.ScanException, IOException {
-        Java.Rvalue rv = this.parseExpression().toRvalueOrPE();
-        this.readOperator(";");
-
-        return new Java.ExpressionStatement(rv);
-    }
-
-    /**
-     * Issue a warning if the given string does not comply with the package naming conventions
-     * (JLS2 6.8.1).
-     */
-    private void verifyStringIsConventionalPackageName(String s, Location loc) {
-        if (!Character.isLowerCase(s.charAt(0))) {
-            this.warning("UPN", "Package name \"" + s + "\" does not begin with a lower-case letter (see JLS2 6.8.1)", loc);
-            return;
-        }
-
-        for (int i = 0; i < s.length(); ++i) {
-            char c = s.charAt(i);
-            if (!Character.isLowerCase(c) && c != '_' && c != '.') {
-                this.warning("PPN", "Poorly chosen package name \"" + s + "\" contains bad character '" + c + "'", loc);
-                return;
-            }
-        }
-    }
-
-    /**
-     * Issue a warning if the given identifier does not comply with the class and interface type
-     * naming conventions (JLS2 6.8.2).
-     */
-    private void verifyIdentifierIsConventionalClassOrInterfaceName(String id, Location loc) {
-        if (!Character.isUpperCase(id.charAt(0))) {
-            this.warning("UCOIN1", "Class or interface name \"" + id + "\" does not begin with an upper-case letter (see JLS2 6.8.2)", loc);
-            return;
-        } 
-        for (int i = 0; i < id.length(); ++i) {
-            char c = id.charAt(i);
-            if (!Character.isLetter(c) && !Character.isDigit(c)) {
-                this.warning("UCOIN", "Class or interface name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.2)", loc);
-                return;
-            } 
-        }
-    }
-
-    /**
-     * Issue a warning if the given identifier does not comply with the method naming conventions
-     * (JLS2 6.8.3).
-     */
-    private void verifyIdentifierIsConventionalMethodName(String id, Location loc) {
-        if (!Character.isLowerCase(id.charAt(0))) {
-            this.warning("UMN1", "Method name \"" + id + "\" does not begin with a lower-case letter (see JLS2 6.8.3)", loc);
-            return;
-        } 
-        for (int i = 0; i < id.length(); ++i) {
-            char c = id.charAt(i);
-            if (!Character.isLetter(c) && !Character.isDigit(c)) {
-                this.warning("UMN", "Method name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.3)", loc);
-                return;
-            } 
-        }
-    }
-
-    /**
-     * Issue a warning if the given identifier does not comply with the field naming conventions
-     * (JLS2 6.8.4) and constant naming conventions (JLS2 6.8.5).
-     */
-    private void verifyIdentifierIsConventionalFieldName(String id, Location loc) {
-
-        // In practice, a field is not always a constant iff it is static-final. So let's
-        // always tolerate both field and constant names.
-
-        if (Character.isUpperCase(id.charAt(0))) {
-            for (int i = 0; i < id.length(); ++i) {
-                char c = id.charAt(i);
-                if (!Character.isUpperCase(c) && !Character.isDigit(c) && c != '_') {
-                    this.warning("UCN", "Constant name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.5)", loc);
-                    return;
-                } 
-            }
-        } else
-        if (Character.isLowerCase(id.charAt(0))) {
-            for (int i = 0; i < id.length(); ++i) {
-                char c = id.charAt(i);
-                if (!Character.isLetter(c) && !Character.isDigit(c)) {
-                    this.warning("UFN", "Field name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.4)", loc);
-                    return;
-                } 
-            }
-        } else {
-            this.warning("UFN1", "\"" + id + "\" is neither a conventional field name (JLS2 6.8.4) nor a conventional constant name (JLS2 6.8.5)", loc);
-        }
-    }
-
-    /**
-     * Issue a warning if the given identifier does not comply with the local variable and
-     * parameter naming conventions (JLS2 6.8.6).
-     */
-    private void verifyIdentifierIsConventionalLocalVariableOrParameterName(String id, Location loc) {
-        if (!Character.isLowerCase(id.charAt(0))) {
-            this.warning("ULVN1", "Local variable name \"" + id + "\" does not begin with a lower-case letter (see JLS2 6.8.6)", loc);
-            return;
-        } 
-        for (int i = 0; i < id.length(); ++i) {
-            char c = id.charAt(i);
-            if (!Character.isLetter(c) && !Character.isDigit(c)) {
-                this.warning("ULVN", "Local variable name \"" + id + "\" contains unconventional character \"" + c + "\" (see JLS2 6.8.6)", loc);
-                return;
-            } 
-        }
-    }
-
-    /**
-     * By default, warnings are discarded, but an application my install a
-     * {@link WarningHandler}.
-     * <p>
-     * Notice that there is no <code>Parser.setErrorHandler()</code> method, but parse errors
-     * always throw a {@link ParseException}. The reason being is that there is no reasonable
-     * way to recover from parse errors and continue parsing, so there is no need to install
-     * a custom parse error handler.
-     *
-     * @param optionalWarningHandler <code>null</code> to indicate that no warnings be issued
-     */
-    public void setWarningHandler(WarningHandler optionalWarningHandler) {
-        this.optionalWarningHandler = optionalWarningHandler;
-    }
-
-    // Used for elaborate warning handling.
-    private WarningHandler optionalWarningHandler = null;
-
-    /**
-     * Issues a warning with the given message and location and returns. This is done through
-     * a {@link WarningHandler} that was installed through
-     * {@link #setWarningHandler(WarningHandler)}.
-     * <p>
-     * The <code>handle</code> argument qulifies the warning and is typically used by
-     * the {@link WarningHandler} to suppress individual warnings.
-     */
-    private void warning(String handle, String message, Location optionalLocation) {
-        if (this.optionalWarningHandler != null) this.optionalWarningHandler.handleWarning(handle, message, optionalLocation);
-    }
-
-    /**
-     * An exception that reflects an error during parsing.
-     *
-     * This exception is associated with a particular {@link Location
-     * Location} in the source code.
-     */
-    public static class ParseException extends LocatedException {
-        public ParseException(String message, Location location) {
-            super(message, location);
-        }
-    }
-
-    /**
-     * Convenience method for throwing a ParseException.
-     */
-    protected final void throwParseException(String message) throws ParseException {
-        throw new ParseException(message, this.location());
-    }
-
-    private static String join(String[] sa, String separator) {
-        if (sa == null) return ("(null)");
-        if (sa.length == 0) return ("(zero length array)");
-        StringBuffer sb = new StringBuffer(sa[0]);
-        for (int i = 1; i < sa.length; ++i) {
-            sb.append(separator).append(sa[i]);
-        }
-        return sb.toString();
-    }
-}
diff --git a/src/org/codehaus/janino/ReflectionIClass.java b/src/org/codehaus/janino/ReflectionIClass.java
deleted file mode 100644
index eaf8196..0000000
--- a/src/org/codehaus/janino/ReflectionIClass.java
+++ /dev/null
@@ -1,314 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.util.*;
-import java.lang.reflect.*;
-
-/**
- * Wraps a {@link java.lang.Class} in an {@link org.codehaus.janino.IClass}.
- */
-class ReflectionIClass extends IClass {
-    private /*final*/ Class        clazz;
-    private /*final*/ IClassLoader iClassLoader;
-
-    /**
-     * @param iClassLoader required to load other {@link IClass}es on <code>get...()</code>.
-     */
-    public ReflectionIClass(Class clazz, IClassLoader iClassLoader) {
-        this.clazz = clazz;
-        this.iClassLoader = iClassLoader;
-    }
-
-    protected IConstructor[] getDeclaredIConstructors2() {
-        Constructor[] constructors = this.clazz.getDeclaredConstructors();
-        IConstructor[] result = new IConstructor[constructors.length];
-        for (int i = 0; i < constructors.length; ++i) {
-            result[i] = new ReflectionIConstructor(constructors[i]);
-        }
-        return result;
-    }
-
-    protected IMethod[] getDeclaredIMethods2() {
-        Method[] methods = this.clazz.getDeclaredMethods();
-        List iMethods = new ArrayList();
-        for (int i = 0; i < methods.length; ++i) {
-            Method m = methods[i];
-
-            // Skip JDK 1.5 synthetic methods (e.g. those generated for
-            // covariant return values).
-            if ((m.getModifiers() & Mod.SYNTHETIC) != 0) continue;
-
-            // Wrap java.reflection.Method in an IMethod.
-            iMethods.add(new ReflectionIMethod(m));
-        }
-        if (methods.length == 0 && this.clazz.isArray()) {
-            iMethods.add(new IMethod() {
-                public String   getName() { return "clone"; }
-                public IClass   getReturnType() throws CompileException { return ReflectionIClass.this.iClassLoader.OBJECT; }
-                public boolean  isAbstract() { return false; }
-                public boolean  isStatic() { return false; }
-                public Access   getAccess() { return Access.PUBLIC; }
-                public IClass[] getParameterTypes() throws CompileException { return new IClass[0]; }
-                public IClass[] getThrownExceptions() throws CompileException { return new IClass[0]; }
-            });
-        }
-        return (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
-    }
-
-    protected IField[] getDeclaredIFields2() {
-        Field[] fields = this.clazz.getDeclaredFields();
-        IField[] result = new IField[fields.length];
-        for (int i = 0; i < fields.length; ++i) {
-            result[i] = new ReflectionIField(fields[i]);
-        }
-        return result;
-    }
-
-    protected IClass[] getDeclaredIClasses2() {
-        return this.classesToIClasses(this.clazz.getDeclaredClasses());
-    }
-
-    protected IClass getDeclaringIClass2() {
-        Class declaringClass = this.clazz.getDeclaringClass();
-        if (declaringClass == null) return null;
-        return this.classToIClass(declaringClass);
-    }
-    protected IClass getOuterIClass2() throws CompileException {
-        if (Modifier.isStatic(this.clazz.getModifiers())) return null;
-        return this.getDeclaringIClass();
-    }
-    protected IClass getSuperclass2() {
-        Class superclass = this.clazz.getSuperclass();
-        return superclass == null ? null : this.classToIClass(superclass);
-    }
-    protected IClass[] getInterfaces2() {
-        return this.classesToIClasses(this.clazz.getInterfaces());
-    }
-    protected String getDescriptor2() {
-        return Descriptor.fromClassName(this.clazz.getName());
-    }
-    public Access  getAccess()   { return ReflectionIClass.modifiers2Access(this.clazz.getModifiers()); }
-    public boolean isFinal()     { return Modifier.isFinal(this.clazz.getModifiers()); }
-    public boolean isInterface() { return this.clazz.isInterface(); }
-    public boolean isAbstract()  { return Modifier.isAbstract(this.clazz.getModifiers()); }
-    public boolean isArray()     { return this.clazz.isArray(); }
-    protected IClass getComponentType2() {
-        Class componentType = this.clazz.getComponentType();
-        return componentType == null ? null : this.classToIClass(componentType);
-    }
-    public boolean isPrimitive() {
-        return this.clazz.isPrimitive();
-    }
-    public boolean isPrimitiveNumeric() {
-        return (
-            this.clazz == byte.class   ||
-            this.clazz == short.class  ||
-            this.clazz == int.class    ||
-            this.clazz == long.class   ||
-            this.clazz == char.class   ||
-            this.clazz == float.class  ||
-            this.clazz == double.class
-        );
-    }
-
-    /**
-     * @return E.g. "int", "int[][]", "pkg1.pkg2.Outer$Inner[]"
-     */
-    public String toString() {
-        int brackets = 0;
-        Class c = this.clazz;
-        while (c.isArray()) {
-            ++brackets;
-            c = c.getComponentType();
-        }
-        String s = c.getName();
-        while (brackets-- > 0) s += "[]";
-        return s;
-    }
-
-    private class ReflectionIConstructor extends IConstructor {
-        public ReflectionIConstructor(Constructor constructor) { this.constructor = constructor; }
-
-        // Implement IMember.
-        public Access getAccess() {
-            int mod = this.constructor.getModifiers();
-            return ReflectionIClass.modifiers2Access(mod);
-        }
-
-        // Implement "IConstructor".
-        public IClass[] getParameterTypes() throws CompileException {
-            IClass[] parameterTypes = ReflectionIClass.this.classesToIClasses(this.constructor.getParameterTypes());
-
-            // The JAVADOC of java.lang.reflect.Constructor does not document it, but
-            // "getParameterTypes()" includes the synthetic "enclosing instance" parameter.
-            IClass outerClass = ReflectionIClass.this.getOuterIClass();
-            if (outerClass != null) {
-                if (parameterTypes.length < 1) throw new CompileException("Constructor \"" + this.constructor + "\" lacks synthetic enclosing instance parameter", null);
-                if (parameterTypes[0] != outerClass) throw new CompileException("Enclosing instance parameter of constructor \"" + this.constructor + "\" has wrong type -- \"" + parameterTypes[0] + "\" vs. \"" + outerClass + "\"", null);
-                IClass[] tmp = new IClass[parameterTypes.length - 1];
-                System.arraycopy(parameterTypes, 1, tmp, 0, tmp.length);
-                parameterTypes = tmp;
-            }
-
-            return parameterTypes;
-        }
-        public String getDescriptor() {
-            Class[] parameterTypes = this.constructor.getParameterTypes();
-            String[] parameterDescriptors = new String[parameterTypes.length];
-            for (int i = 0; i < parameterDescriptors.length; ++i) {
-                parameterDescriptors[i] = Descriptor.fromClassName(parameterTypes[i].getName());
-                }
-            return new MethodDescriptor(parameterDescriptors, Descriptor.VOID_).toString();
-        }
-        public IClass[] getThrownExceptions() {
-            return ReflectionIClass.this.classesToIClasses(this.constructor.getExceptionTypes());
-        }
-
-        final Constructor constructor;
-    };
-    private class ReflectionIMethod extends IMethod {
-        public ReflectionIMethod(Method method) { this.method = method; }
-
-        // Implement IMember.
-        public Access getAccess() {
-            return ReflectionIClass.modifiers2Access(this.method.getModifiers());
-        }
-
-        // Implement "IMethod".
-        public String getName() { return this.method.getName(); }
-        public IClass[] getParameterTypes() {
-            return ReflectionIClass.this.classesToIClasses(this.method.getParameterTypes());
-        }
-        public boolean isStatic() { return Modifier.isStatic(this.method.getModifiers()); }
-        public boolean isAbstract() { return Modifier.isAbstract(this.method.getModifiers()); }
-        public IClass getReturnType() {
-            return ReflectionIClass.this.classToIClass(this.method.getReturnType());
-        }
-        public IClass[] getThrownExceptions() {
-            return ReflectionIClass.this.classesToIClasses(this.method.getExceptionTypes());
-        }
-
-        final Method method;
-    };
-    private class ReflectionIField extends IField {
-        public ReflectionIField(Field field) { this.field = field; }
-
-        // Implement IMember.
-        public Access getAccess() {
-            return ReflectionIClass.modifiers2Access(this.field.getModifiers());
-        }
-
-        // Implement "IField".
-        public String getName() { return this.field.getName(); }
-        public boolean isStatic() {
-            return Modifier.isStatic(this.field.getModifiers());
-        }
-        public IClass getType() {
-            return ReflectionIClass.this.classToIClass(this.field.getType());
-        }
-        public String toString() {
-            return (
-                Descriptor.toString(this.getDeclaringIClass().getDescriptor()) +
-                "." +
-                this.getName()
-            );
-        }
-        /**
-         * This implementation of {@link IClass.IField#getConstantValue()} is
-         * not completely correct:
-         * <ul>
-         *   <li>
-         *   It treats non-static fields as non-constant
-         *   <li>
-         *   Even fields with a <i>non-constant</i> initializer are identified
-         *   as constant. (The value of that field may be different in a
-         *   different JVM instance -- the classical example is
-         *   {@link java.io.File#separator}.)
-         * </ul>
-         */
-        public Object getConstantValue() throws CompileException {
-            int mod = this.field.getModifiers();
-            Class clazz = this.field.getType();
-            if (
-                Modifier.isStatic(mod) &&
-                Modifier.isFinal(mod) &&
-                (clazz.isPrimitive() || clazz == String.class)
-            ) {
-                try {
-                    return this.field.get(null);
-                } catch (IllegalAccessException ex) {
-                    throw new CompileException("Field \"" + this.field.getName() + "\" is not accessible", (Location) null);
-                }
-            }
-            return null;
-        }
-
-        final Field field;
-    }
-
-    /**
-     * Load {@link Class} through {@link IClassLoader} to
-     * ensure unique {@link IClass}es.
-     */
-    private IClass classToIClass(Class c) {
-        IClass iClass;
-        try {
-            iClass = this.iClassLoader.loadIClass(Descriptor.fromClassName(c.getName()));
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException("Loading IClass \"" + c.getName() + "\": " + ex);
-        }
-        if (iClass == null) throw new RuntimeException("Cannot load class \"" + c.getName() + "\" through the given ClassLoader");
-        return iClass;
-    }
-
-    /**
-     * @see #classToIClass(Class)
-     */
-    private IClass[] classesToIClasses(Class[] cs) {
-        IClass[] result = new IClass[cs.length];
-        for (int i = 0; i < cs.length; ++i) result[i] = this.classToIClass(cs[i]);
-        return result;
-    }
-
-    private static Access modifiers2Access(int modifiers) {
-        return (
-            Modifier.isPrivate(modifiers)   ? Access.PRIVATE   :
-            Modifier.isProtected(modifiers) ? Access.PROTECTED :
-            Modifier.isPublic(modifiers)    ? Access.PUBLIC    :
-            Access.DEFAULT
-        );
-    }
-}
diff --git a/src/org/codehaus/janino/ResourceFinderIClassLoader.java b/src/org/codehaus/janino/ResourceFinderIClassLoader.java
deleted file mode 100644
index 1ec79f2..0000000
--- a/src/org/codehaus/janino/ResourceFinderIClassLoader.java
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-
-import org.codehaus.janino.util.ClassFile;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * This {@link org.codehaus.janino.IClassLoader} loads IClasses through a
- * a {@link org.codehaus.janino.util.resource.ResourceFinder} that designates
- * {@link org.codehaus.janino.util.ClassFile}s.
- */
-public class ResourceFinderIClassLoader extends IClassLoader {
-    private final ResourceFinder resourceFinder;
-
-    public ResourceFinderIClassLoader(
-        ResourceFinder resourceFinder,
-        IClassLoader   optionalParentIClassLoader
-    ) {
-        super(optionalParentIClassLoader);
-        this.resourceFinder = resourceFinder;
-        this.postConstruct();
-    }
-
-    protected IClass findIClass(String descriptor) throws ClassNotFoundException {
-        String className = Descriptor.toClassName(descriptor);
-
-        // Find the class file resource.
-        Resource classFileResource = this.resourceFinder.findResource(ClassFile.getClassFileResourceName(className));
-        if (classFileResource == null) return null;
-
-        // Open the class file resource.
-        InputStream is;
-        try {
-            is = classFileResource.open();
-        } catch (IOException ex) {
-            throw new ClassNotFoundException("Opening resource \"" + classFileResource.getFileName() + "\"", ex);
-        }
-
-        // Load the IClass from the class file.
-        ClassFile cf;
-        try {
-            cf = new ClassFile(is);
-        } catch (IOException e) {
-            throw new ClassNotFoundException("Reading resource \"" + classFileResource.getFileName() + "\"", e);
-        } finally {
-            try { is.close(); } catch (IOException e) {}
-        }
-        IClass iClass = new ClassFileIClass(cf, this);
-        this.defineIClass(iClass);
-        return iClass;
-    }
-
-}
diff --git a/src/org/codehaus/janino/Scanner.java b/src/org/codehaus/janino/Scanner.java
deleted file mode 100644
index 03251e8..0000000
--- a/src/org/codehaus/janino/Scanner.java
+++ /dev/null
@@ -1,1276 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.util.LocatedException;
-import org.codehaus.janino.util.TeeReader;
-
-
-/**
- * Splits up a character stream into tokens and returns them as
- * {@link java.lang.String String} objects.
- * <p>
- * The <code>optionalFileName</code> parameter passed to many
- * constructors should point 
- */
-
-public class Scanner {
-
-    // Public Scanners that read from a file.
-
-    /**
-     * Set up a scanner that reads tokens from the given file in the default charset.
-     * <p>
-     * <b>This method is deprecated because it leaves the input file open.</b>
-     *
-     * @deprecated
-     */
-    public Scanner(String fileName) throws ScanException, IOException {
-        this(
-            fileName,                     // optionalFileName
-            new FileInputStream(fileName) // is
-        );
-    }
-
-    /**
-     * Set up a scanner that reads tokens from the given file in the given encoding.
-     * <p>
-     * <b>This method is deprecated because it leaves the input file open.</b>
-     *
-     * @deprecated
-     */
-    public Scanner(String fileName, String encoding) throws ScanException, IOException {
-        this(
-            fileName,                      // optionalFileName
-            new FileInputStream(fileName), // is
-            encoding                       // optionalEncoding
-        );
-    }
-
-    /**
-     * Set up a scanner that reads tokens from the given file in the platform
-     * default encoding.
-     * <p>
-     * <b>This method is deprecated because it leaves the input file open.</b>
-     *
-     * @deprecated
-     */
-    public Scanner(File file) throws ScanException, IOException {
-        this(
-            file.getAbsolutePath(),    // optionalFileName
-            new FileInputStream(file), // is
-            null                       // optionalEncoding
-        );
-    }
-
-    /**
-     * Set up a scanner that reads tokens from the given file in the given encoding.
-     * <p>
-     * <b>This method is deprecated because it leaves the input file open.</b>
-     *
-     * @deprecated
-     */
-    public Scanner(File file, String optionalEncoding) throws ScanException, IOException {
-        this(
-            file.getAbsolutePath(),    // optionalFileName
-            new FileInputStream(file), // fis
-            optionalEncoding                   // optionalEncoding
-        );
-    }
-
-    // Public Scanners that read from an InputStream
-
-    /**
-     * Set up a scanner that reads tokens from the given
-     * {@link InputStream} in the platform default encoding.
-     * <p>
-     * The <code>fileName</code> is solely used for reporting in thrown
-     * exceptions.
-     */
-    public Scanner(String optionalFileName, InputStream is) throws ScanException, IOException {
-        this(
-            optionalFileName,
-            new InputStreamReader(is), // in
-            (short) 1, (short) 0       // initialLineNumber, initialColumnNumber
-        );
-    }
-
-    /**
-     * Set up a scanner that reads tokens from the given
-     * {@link InputStream} with the given <code>optionalEncoding</code>
-     * (<code>null</code> means platform default encoding).
-     * <p>
-     * The <code>optionalFileName</code> is used for reporting errors during
-     * compilation and for source level debugging, and should name an existing
-     * file. If <code>null</code> is passed, and the system property
-     * <code>org.codehaus.janino.source_debugging.enable</code> is set to "true", then
-     * a temporary file in <code>org.codehaus.janino.source_debugging.dir</code> or the
-     * system's default temp dir is created in order to make the source code
-     * available to a debugger.
-     */
-    public Scanner(
-        String      optionalFileName,
-        InputStream is,
-        String      optionalEncoding
-    ) throws ScanException, IOException {
-        this(
-            optionalFileName,                  // optionalFileName
-            (                                  // in
-                optionalEncoding == null ?
-                new InputStreamReader(is) :
-                new InputStreamReader(is, optionalEncoding)
-            ),
-            (short) 1, (short) 0               // initialLineNumber, initialColumnNumber
-        );
-    }
-
-    // Public Scanners that read from a Reader.
-
-    /**
-     * Set up a scanner that reads tokens from the given
-     * {@link Reader}.
-     * <p>
-     * The <code>optionalFileName</code> is used for reporting errors during
-     * compilation and for source level debugging, and should name an existing
-     * file. If <code>null</code> is passed, and the system property
-     * <code>org.codehaus.janino.source_debugging.enable</code> is set to "true", then
-     * a temporary file in <code>org.codehaus.janino.source_debugging.dir</code> or the
-     * system's default temp dir is created in order to make the source code
-     * available to a debugger.
-     */
-    public Scanner(String optionalFileName, Reader in) throws ScanException, IOException {
-        this(
-            optionalFileName, // optionalFileName
-            in,               // in
-            (short) 1,        // initialLineNumber
-            (short) 0         // initialColumnNumber
-        );
-    }
-
-    /**
-     * Creates a {@link Scanner} that counts lines and columns from non-default initial
-     * values.
-     */
-    public Scanner(
-        String optionalFileName,
-        Reader in,
-        short  initialLineNumber,        // "1" is a good idea
-        short  initialColumnNumber       // "0" is a good idea
-    ) throws ScanException, IOException {
-
-        // Debugging on source code level is only possible if the code comes from
-        // a "real" Java source file which the debugger can read. If this is not the
-        // case, and we absolutely want source code level debugging, then we write
-        // a verbatim copy of the source code into a temporary file in the system
-        // temp directory.
-        // This behavior is controlled by the two system properties
-        //     org.codehaus.janino.source_debugging.enable
-        //     org.codehaus.janino.source_debugging.dir
-        // JANINO is designed to compile in memory to save the overhead of disk
-        // I/O, so writing this file is only recommended for source code level
-        // debugging purposes.
-        if (optionalFileName == null && Boolean.getBoolean("org.codehaus.janino.source_debugging.enable")) {
-            String dirName = System.getProperty("org.codehaus.janino.source_debugging.dir");
-            File dir = dirName == null ? null : new File(dirName);
-            File temporaryFile = File.createTempFile("janino", ".java", dir);
-            temporaryFile.deleteOnExit();
-            in = new TeeReader(
-                in,                            // in
-                new FileWriter(temporaryFile), // out
-                true                           // closeWriterOnEOF
-            );
-            optionalFileName = temporaryFile.getAbsolutePath();
-        }
-
-        this.optionalFileName     = optionalFileName;
-        this.in                   = new UnicodeUnescapeReader(in);
-        this.nextCharLineNumber   = initialLineNumber;
-        this.nextCharColumnNumber = initialColumnNumber;
-
-        this.readNextChar();
-        this.nextToken       = this.internalRead();
-        this.nextButOneToken = null;
-    }
-
-    /**
-     * Return the file name optionally passed to the constructor.
-     */
-    public String getFileName() {
-        return this.optionalFileName;
-    }
-
-    /**
-     * Closes the character source (file, {@link InputStream}, {@link Reader}) associated
-     * with this object. The results of future calls to {@link #peek()} and
-     * {@link #read()} are undefined.
-     * <p>
-     * <b>This method is deprecated, because the concept described above is confusing. An
-     * application should close the underlying {@link InputStream} or {@link Reader} itself.</b>
-     *
-     * @deprecated
-     */
-    public void close() throws IOException {
-        this.in.close();
-    }
-
-    /**
-     * Read the next token from the input.
-     */
-    public Token read() throws ScanException, IOException {
-        Token res = this.nextToken;
-        if (this.nextButOneToken != null) {
-            this.nextToken = this.nextButOneToken;
-            this.nextButOneToken = null;
-        } else {
-            this.nextToken = this.internalRead();
-        }
-        return res;
-    }
-
-    /**
-     * Peek the next token, but don't remove it from the input.
-     */
-    public Token peek() {
-        if (Scanner.DEBUG) System.err.println("peek() => \"" + this.nextToken + "\"");
-        return this.nextToken;
-    }
-
-    /**
-     * Peek the next but one token, neither remove the next nor the next but one token from the
-     * input.
-     * <p>
-     * This makes parsing so much easier, e.g. for class literals like
-     * <code>Map.class</code>.
-     */
-    public Token peekNextButOne() throws ScanException, IOException {
-        if (this.nextButOneToken == null) this.nextButOneToken = this.internalRead();
-        return this.nextButOneToken;
-    }
-
-    /**
-     * Get the text of the doc comment (a.k.a. "JAVADOC comment") preceeding
-     * the next token.
-     * @return <code>null</code> if the next token is not preceeded by a doc comment
-     */
-    public String doc() {
-        String s = this.docComment;
-        this.docComment = null;
-        return s;
-    }
-
-    /**
-     * Returns the {@link Location} of the next token.
-     */
-    public Location location() {
-        return this.nextToken.getLocation();
-    }
-
-    public abstract class Token {
-        private /*final*/ String optionalFileName;
-        private /*final*/ short  lineNumber;
-        private /*final*/ short  columnNumber;
-        private Location location = null;
-
-        private Token() {
-            this.optionalFileName = Scanner.this.optionalFileName;
-            this.lineNumber       = Scanner.this.tokenLineNumber;
-            this.columnNumber     = Scanner.this.tokenColumnNumber;
-        }
-
-        public Location getLocation() {
-            if (this.location == null) this.location = new Location(this.optionalFileName, this.lineNumber, this.columnNumber);
-            return this.location;
-        }
-
-        public boolean isKeyword() { return false; }
-        public boolean isKeyword(String k) { return false; }
-        public boolean isKeyword(String[] ks) { return false; }
-        public String getKeyword() throws ScanException { throw new ScanException("Not a keyword token"); }
-
-        public boolean isIdentifier() { return false; }
-        public boolean isIdentifier(String id) { return false; }
-        public String getIdentifier() throws ScanException { throw new ScanException("Not an identifier token"); }
-
-        public boolean isLiteral() { return false; }
-        public Object getLiteralValue() throws ScanException { throw new ScanException("Not a literal token"); }
-
-        public boolean isOperator() { return false; }
-        public boolean isOperator(String o) { return false; }
-        public boolean isOperator(String[] os) { return false; }
-        public String getOperator() throws ScanException { throw new ScanException("Not an operator token"); }
-
-        public boolean isEOF() { return false; }
-    }
-
-    public class KeywordToken extends Token {
-        private final String keyword;
-
-        /**
-         * @param keyword Must be in interned string!
-         */
-        private KeywordToken(String keyword) {
-            this.keyword = keyword;
-        }
-
-        public boolean isKeyword() { return true; }
-        public boolean isKeyword(String k) { return this.keyword == k; }
-        public boolean isKeyword(String[] ks) {
-            for (int i = 0; i < ks.length; ++i) {
-                if (this.keyword == ks[i]) return true;
-            }
-            return false;
-        }
-        public String getKeyword() { return this.keyword; }
-
-        public String toString() { return this.keyword; }
-    }
-
-    public class IdentifierToken extends Token {
-        private final String identifier;
-
-        private IdentifierToken(String identifier) {
-            this.identifier = identifier;
-        }
-
-        public boolean isIdentifier() { return true; }
-        public boolean isIdentifier(String id) { return this.identifier.equals(id); }
-        public String getIdentifier() { return this.identifier; }
-
-        public String toString() { return this.identifier; }
-    }
-
-    /**
-     * This reference represents the "magic" literal "2147483648" which is only
-     * allowed in a negated context.
-     */
-    public static final Integer MAGIC_INTEGER = new Integer(Integer.MIN_VALUE);
-
-    /**
-     * This reference represents the "magic" literal "9223372036854775808L" which is only
-     * allowed in a negated context.
-     */
-    public static final Long MAGIC_LONG = new Long(Long.MIN_VALUE);
-
-    /**
-     * The type of the <code>value</code> parameter determines the type of the literal
-     * token:
-     * <table>
-     *   <tr><th>Type/value returned by {@link #getLiteralValue()}</th><th>Literal</th></tr>
-     *   <tr><td>{@link String}</td><td>STRING literal</td></tr>
-     *   <tr><td>{@link Character}</td><td>CHAR literal</td></tr>
-     *   <tr><td>{@link Integer}</td><td>INT literal</td></tr>
-     *   <tr><td>{@link Long}</td><td>LONG literal</td></tr>
-     *   <tr><td>{@link Float}</td><td>FLOAT literal</td></tr>
-     *   <tr><td>{@link Double}</td><td>DOUBLE literal</td></tr>
-     *   <tr><td>{@link Boolean}</td><td>BOOLEAN literal</td></tr>
-     *   <tr><td><code>null</code></td><td>NULL literal</td></tr>
-     * </table>
-     */
-    public final class LiteralToken extends Token {
-        private final Object value;
-
-        /**
-         * @param value A {@link Boolean}, {@link String}, {@link Double}, {@link Float}, {@link Character}, or <code>null</code>
-         */
-        public LiteralToken(Object value) {
-            this.value = value;
-        }
-
-        // Implement {@link Literal}.
-        public final boolean isLiteral() { return true; }
-        public Object getLiteralValue()  { return this.value; }
-
-        public String toString() {
-            return Scanner.literalValueToString(this.value);
-        }
-    }
-    public static String literalValueToString(Object v) {
-        if (v instanceof String) {
-            StringBuffer sb = new StringBuffer();
-            sb.append('"');
-            String s = (String) v;
-            for (int i = 0; i < s.length(); ++i) {
-                char c = s.charAt(i);
-
-                if (c == '"') {
-                    sb.append("\\\"");
-                } else {
-                    Scanner.escapeCharacter(c, sb);
-                }
-            }
-            sb.append('"');
-            return sb.toString();
-        }
-        if (v instanceof Character) {
-            char c = ((Character) v).charValue();
-            if (c == '\'') return "'\\''";
-            StringBuffer sb = new StringBuffer("'");
-            Scanner.escapeCharacter(c, sb);
-            return sb.append('\'').toString();
-        }
-        if (v instanceof Integer) {
-            if (v == Scanner.MAGIC_INTEGER) return "2147483648";
-            int iv = ((Integer) v).intValue();
-            return iv < 0 ? "0x" + Integer.toHexString(iv) : Integer.toString(iv);
-        }
-        if (v instanceof Long) {
-            if (v == Scanner.MAGIC_LONG) return "9223372036854775808L";
-            long lv = ((Long) v).longValue();
-            return lv < 0L ? "0x" + Long.toHexString(lv) + 'L' : Long.toString(lv) + 'L';
-        }
-        if (v instanceof Float) {
-            return v.toString() + 'F';
-        }
-        if (v instanceof Double) {
-            return v.toString() + 'D';
-        }
-        if (v instanceof Boolean) {
-            return v.toString();
-        }
-        if (v == null) {
-            return "null";
-        }
-        throw new RuntimeException("Unexpected value type \"" + v.getClass().getName() + "\"");
-    }
-
-    public class OperatorToken extends Token {
-        private final String operator;
-
-        /**
-         * 
-         * @param operator Must be an interned string!
-         */
-        private OperatorToken(String operator) {
-            this.operator = operator;
-        }
-
-        public boolean isOperator() { return true; }
-        public boolean isOperator(String o) { return this.operator == o; }
-        public boolean isOperator(String[] os) {
-            for (int i = 0; i < os.length; ++i) {
-                if (this.operator == os[i]) return true;
-            }
-            return false;
-        }
-        public String getOperator() { return this.operator; }
-
-        public String toString() { return this.operator; }
-    }
-
-    public class EOFToken extends Token {
-        public boolean isEOF() { return true; }
-        public String toString() { return "End-Of-File"; }
-    }
-
-    /**
-     * Escape unprintable characters appropriately, i.e. as
-     * backslash-letter or backslash-U-four-hex-digits.
-     * <p>
-     * Notice: Single and double quotes are not escaped!
-     */
-    private static void escapeCharacter(char c, StringBuffer sb) {
-
-        // Backslash escape sequences.
-        int idx = "\b\t\n\f\r\\".indexOf(c);
-        if (idx != -1) {
-            sb.append('\\').append("btnfr\\".charAt(idx));
-        } else
-
-        // Printable characters.
-        if (c >= ' ' && c < 255 && c != 127) {
-            sb.append(c);
-        } else
-
-        // Backslash-U escape sequences.
-        {
-            sb.append("\\u");
-            String hs = Integer.toHexString(0xffff & c);
-            for (int j = hs.length(); j < 4; ++j) sb.append('0');
-            sb.append(hs);
-        }
-    }
-
-    private Token internalRead() throws ScanException, IOException {
-        if (this.docComment != null) {
-            this.warning("MDC", "Misplaced doc comment", this.nextToken.getLocation());
-            this.docComment = null;
-        }
-
-        // Skip whitespace and process comments.
-        int          state = 0;
-        StringBuffer dcsb  = null; // For doc comment
-
-        PROCESS_COMMENTS:
-        for (;;) {
-            switch (state) {
-    
-            case 0: // Outside any comment
-                if (this.nextChar == -1) {
-                    return new EOFToken();
-                } else
-                if (Character.isWhitespace((char) this.nextChar)) {
-                    ;
-                } else
-                if (this.nextChar == '/') {
-                    state = 1;
-                } else
-                {
-                    break PROCESS_COMMENTS;
-                }
-                break;
-
-            case 1:  // After "/"
-                if (this.nextChar == -1) {
-                    return new OperatorToken("/");
-                } else
-                if (this.nextChar == '=') {
-                    this.readNextChar();
-                    return new OperatorToken("/=");
-                } else
-                if (this.nextChar == '/') {
-                    state = 2;
-                } else
-                if (this.nextChar == '*') {
-                    state = 3;
-                } else
-                {
-                    return new OperatorToken("/");
-                }
-                break;
-
-            case 2: // After "//..."
-                if (this.nextChar == -1) {
-                    return new EOFToken();
-                } else
-                if (this.nextChar == '\r' || this.nextChar == '\n') {
-                    state = 0;
-                } else
-                {
-                    ;
-                }
-                break;
-
-            case 3: // After "/*"
-                if (this.nextChar == -1) {
-                    throw new ScanException("EOF in traditional comment");
-                } else
-                if (this.nextChar == '*') {
-                    state = 4;
-                } else
-                {
-                    state = 9;
-                }
-                break;
-
-            case 4: // After "/**"
-                if (this.nextChar == -1) {
-                    throw new ScanException("EOF in doc comment");
-                } else
-                if (this.nextChar == '/') {
-                    state = 0;
-                } else
-                {
-                    if (this.docComment != null) this.warning("MDC", "Multiple doc comments", new Location(this.optionalFileName, this.nextCharLineNumber, this.nextCharColumnNumber)); 
-                    dcsb = new StringBuffer();
-                    dcsb.append((char) this.nextChar);
-                    state = (
-                        (this.nextChar == '\r' || this.nextChar == '\n') ? 6
-                        : this.nextChar == '*' ? 8
-                        : 5
-                    );
-                }
-                break;
-
-            case 5: // After "/**..."
-                if (this.nextChar == -1) {
-                    throw new ScanException("EOF in doc comment");
-                } else
-                if (this.nextChar == '*') {
-                    state = 8;
-                } else
-                if (this.nextChar == '\r' || this.nextChar == '\n') {
-                    dcsb.append((char) this.nextChar);
-                    state = 6;
-                } else
-                {
-                    dcsb.append((char) this.nextChar);
-                }
-                break;
-
-            case 6: // After "/**...\n"
-                if (this.nextChar == -1) {
-                    throw new ScanException("EOF in doc comment");
-                } else
-                if (this.nextChar == '*') {
-                    state = 7;
-                } else
-                if (this.nextChar == '\r' || this.nextChar == '\n') {
-                    dcsb.append((char) this.nextChar);
-                } else
-                if (this.nextChar == ' ' || this.nextChar == '\t') {
-                    ;
-                } else
-                {
-                    dcsb.append((char) this.nextChar);
-                    state = 5;
-                }
-                break;
-
-            case 7: // After "/**...\n *"
-                if (this.nextChar == -1) {
-                    throw new ScanException("EOF in doc comment");
-                } else
-                if (this.nextChar == '*') {
-                    ;
-                } else
-                if (this.nextChar == '/') {
-                    this.docComment = dcsb.toString();
-                    state = 0;
-                } else
-                {
-                    dcsb.append((char) this.nextChar);
-                    state = 5;
-                }
-                break;
-
-            case 8: // After "/**...*"
-                if (this.nextChar == -1) {
-                    throw new ScanException("EOF in doc comment");
-                } else
-                if (this.nextChar == '/') {
-                    this.docComment = dcsb.toString();
-                    state = 0;
-                } else
-                if (this.nextChar == '*') {
-                    dcsb.append('*');
-                } else
-                {
-                    dcsb.append('*');
-                    dcsb.append((char) this.nextChar);
-                    state = 5;
-                }
-                break;
-
-            case 9: // After "/*..."
-                if (this.nextChar == -1) {
-                    throw new ScanException("EOF in traditional comment");
-                } else
-                if (this.nextChar == '*') {
-                    state = 10;
-                } else
-                {
-                    ;
-                }
-                break;
-
-            case 10: // After "/*...*"
-                if (this.nextChar == -1) {
-                    throw new ScanException("EOF in traditional comment");
-                } else
-                if (this.nextChar == '/') {
-                    state = 0;
-                } else
-                if (this.nextChar == '*') {
-                    ;
-                } else
-                {
-                    state = 9;
-                }
-            }
-            this.readNextChar();
-        }
-
-        /*
-         * Whitespace and comments are now skipped; "nextChar" is definitely
-         * the first character of the token.
-         */
-        this.tokenLineNumber   = this.nextCharLineNumber;
-        this.tokenColumnNumber = this.nextCharColumnNumber;
-
-        // Scan identifier.
-        if (Character.isJavaIdentifierStart((char) this.nextChar)) {
-            StringBuffer sb = new StringBuffer();
-            sb.append((char) this.nextChar);
-            for (;;) {
-                this.readNextChar();
-                if (
-                    this.nextChar == -1 ||
-                    !Character.isJavaIdentifierPart((char) this.nextChar)
-                ) break;
-                sb.append((char) this.nextChar);
-            }
-            String s = sb.toString();
-            if (s.equals("true")) return new LiteralToken(Boolean.TRUE);
-            if (s.equals("false")) return new LiteralToken(Boolean.FALSE);
-            if (s.equals("null")) return new LiteralToken(null);
-            {
-                String v = (String) Scanner.JAVA_KEYWORDS.get(s);
-                if (v != null) return new KeywordToken(v);
-            }
-            return new IdentifierToken(s);
-        }
-
-        // Scan numeric literal.
-        if (Character.isDigit((char) this.nextChar)) {
-            return this.scanNumericLiteral(0);
-        }
-
-        // A "." is special: Could either be a floating-point constant like ".001", or the "."
-        // operator.
-        if (this.nextChar == '.') {
-            this.readNextChar();
-            if (Character.isDigit((char) this.nextChar)) {
-                return this.scanNumericLiteral(2);
-            } else {
-                return new OperatorToken(".");
-            }
-        }
-
-        // Scan string literal.
-        if (this.nextChar == '"') {
-            StringBuffer sb = new StringBuffer("");
-            this.readNextChar();
-            if (this.nextChar == -1) throw new ScanException("EOF in string literal");
-            if (this.nextChar == '\r' || this.nextChar == '\n') throw new ScanException("Line break in string literal");
-            while (this.nextChar != '"') {
-                sb.append(this.unescapeCharacterLiteral());
-            }
-            this.readNextChar();
-            return new LiteralToken(sb.toString());
-        }
-
-        // Scan character literal.
-        if (this.nextChar == '\'') {
-            this.readNextChar();
-            if (this.nextChar == '\'') throw new ScanException("Single quote must be backslash-escaped in character literal");
-            char lit = this.unescapeCharacterLiteral();
-            if (this.nextChar != '\'') throw new ScanException("Closing single quote missing");
-            this.readNextChar();
-
-            return new LiteralToken(new Character(lit));
-        }
-
-        // Scan separator / operator.
-        {
-            String v = (String) Scanner.JAVA_OPERATORS.get(
-                new String(new char[] { (char) this.nextChar })
-            );
-            if (v != null) {
-                for (;;) {
-                    this.readNextChar();
-                    String v2 = (String) Scanner.JAVA_OPERATORS.get(v + (char) this.nextChar);
-                    if (v2 == null) return new OperatorToken(v);
-                    v = v2;
-                }
-            }
-        }
-
-        throw new ScanException("Invalid character input \"" + (char) this.nextChar + "\" (character code " + this.nextChar + ")");
-    }
-
-    private Token scanNumericLiteral(int initialState) throws ScanException, IOException {
-        StringBuffer sb = (initialState == 2) ? new StringBuffer("0.") : new StringBuffer();
-        int state = initialState;
-        for (;;) {
-            switch (state) {
-    
-            case 0: // First character.
-                if (this.nextChar == '0') {
-                    state = 6;
-                } else
-                /* if (Character.isDigit((char) this.nextChar)) */ {
-                    sb.append((char) this.nextChar);
-                    state = 1;
-                }
-                break;
-    
-            case 1: // Decimal digits.
-                if (Character.isDigit((char) this.nextChar)) {
-                    sb.append((char) this.nextChar);
-                } else
-                if (this.nextChar == 'l' || this.nextChar == 'L') {
-                    this.readNextChar();
-                    return this.stringToLongLiteralToken(sb.toString(), 10);
-                } else
-                if (this.nextChar == 'f' || this.nextChar == 'F') {
-                    this.readNextChar();
-                    return this.stringToFloatLiteralToken(sb.toString());
-                } else
-                if (this.nextChar == 'd' || this.nextChar == 'D') {
-                    this.readNextChar();
-                    return this.stringToDoubleLiteralToken(sb.toString());
-                } else
-                if (this.nextChar == '.') {
-                    sb.append('.');
-                    state = 2;
-                } else
-                if (this.nextChar == 'E' || this.nextChar == 'e') {
-                    sb.append('E');
-                    state = 3;
-                } else
-                {
-                    return this.stringToIntegerLiteralToken(sb.toString(), 10);
-                }
-                break;
-    
-            case 2: // After decimal point.
-                if (Character.isDigit((char) this.nextChar)) {
-                    sb.append((char) this.nextChar);
-                } else
-                if (this.nextChar == 'e' || this.nextChar == 'E') {
-                    sb.append('E');
-                    state = 3;
-                } else
-                if (this.nextChar == 'f' || this.nextChar == 'F') {
-                    this.readNextChar();
-                    return this.stringToFloatLiteralToken(sb.toString());
-                } else
-                if (this.nextChar == 'd' || this.nextChar == 'D') {
-                    this.readNextChar();
-                    return this.stringToDoubleLiteralToken(sb.toString());
-                } else
-                {
-                    return this.stringToDoubleLiteralToken(sb.toString());
-                }
-                break;
-    
-            case 3: // Read exponent.
-                if (Character.isDigit((char) this.nextChar)) {
-                    sb.append((char) this.nextChar);
-                    state = 5;
-                } else
-                if (this.nextChar == '-' || this.nextChar == '+') {
-                    sb.append((char) this.nextChar);
-                    state = 4;
-                } else
-                {
-                    throw new ScanException("Exponent missing after \"E\"");
-                }
-                break;
-    
-            case 4: // After exponent sign.
-                if (Character.isDigit((char) this.nextChar)) {
-                    sb.append((char) this.nextChar);
-                    state = 5;
-                } else
-                {
-                    throw new ScanException("Exponent missing after \"E\" and sign");
-                }
-                break;
-    
-            case 5: // After first exponent digit.
-                if (Character.isDigit((char) this.nextChar)) {
-                    sb.append((char) this.nextChar);
-                } else
-                if (this.nextChar == 'f' || this.nextChar == 'F') {
-                    this.readNextChar();
-                    return this.stringToFloatLiteralToken(sb.toString());
-                } else
-                if (this.nextChar == 'd' || this.nextChar == 'D') {
-                    this.readNextChar();
-                    return this.stringToDoubleLiteralToken(sb.toString());
-                } else
-                {
-                    return this.stringToDoubleLiteralToken(sb.toString());
-                }
-                break;
-    
-            case 6: // After leading zero
-                if ("01234567".indexOf(this.nextChar) != -1) {
-                    sb.append((char) this.nextChar);
-                    state = 7;
-                } else
-                if (this.nextChar == 'l' || this.nextChar == 'L') {
-                    this.readNextChar();
-                    return this.stringToLongLiteralToken("0", 10);
-                } else
-                if (this.nextChar == 'f' || this.nextChar == 'F') {
-                    this.readNextChar();
-                    return this.stringToFloatLiteralToken("0");
-                } else
-                if (this.nextChar == 'd' || this.nextChar == 'D') {
-                    this.readNextChar();
-                    return this.stringToDoubleLiteralToken("0");
-                } else
-                if (this.nextChar == '.') {
-                    sb.append("0.");
-                    state = 2;
-                } else
-                if (this.nextChar == 'E' || this.nextChar == 'e') {
-                    sb.append('E');
-                    state = 3;
-                } else
-                if (this.nextChar == 'x' || this.nextChar == 'X') {
-                    state = 8;
-                } else
-                {
-                    return this.stringToIntegerLiteralToken("0", 10);
-                }
-                break;
-    
-            case 7: // In octal literal.
-                if ("01234567".indexOf(this.nextChar) != -1) {
-                    sb.append((char) this.nextChar);
-                } else
-                if (this.nextChar == 'l' || this.nextChar == 'L') {
-                    // Octal long literal.
-                    this.readNextChar();
-                    return this.stringToLongLiteralToken(sb.toString(), 8);
-                } else
-                {
-                    // Octal int literal
-                    return this.stringToIntegerLiteralToken(sb.toString(), 8);
-                }
-                break;
-    
-            case 8: // First hex digit
-                if (Character.digit((char) this.nextChar, 16) != -1) {
-                    sb.append((char) this.nextChar);
-                    state = 9;
-                } else
-                {
-                    throw new ScanException("Hex digit expected after \"0x\"");
-                }
-                break;
-    
-            case 9:
-                if (Character.digit((char) this.nextChar, 16) != -1) {
-                    sb.append((char) this.nextChar);
-                } else
-                if (this.nextChar == 'l' || this.nextChar == 'L') {
-                    // Hex long literal
-                    this.readNextChar();
-                    return this.stringToLongLiteralToken(sb.toString(), 16);
-                } else
-                {
-                    // Hex long literal
-                    return this.stringToIntegerLiteralToken(sb.toString(), 16);
-                }
-                break;
-            }
-            this.readNextChar();
-        }
-    }
-
-    private LiteralToken stringToIntegerLiteralToken(final String s, int radix) throws ScanException {
-        int x;
-        switch (radix) {
-
-        case 10:
-            // Special case: Decimal literal 2^31 must only appear in "negated" context, i.e.
-            // "-2147483648" is a valid long literal, but "2147483648" is not.
-            if (s.equals("2147483648")) return new LiteralToken(Scanner.MAGIC_INTEGER);
-            try {
-                x = Integer.parseInt(s);
-            } catch (NumberFormatException e) {
-                throw new ScanException("Value of decimal integer literal \"" + s + "\" is out of range");
-            }
-            break;
-
-        case 8:
-            // Cannot use "Integer.parseInt(s, 8)" because that parses SIGNED values.
-            x = 0;
-            for (int i = 0; i < s.length(); ++i) {
-                if ((x & 0xe0000000) != 0) throw new ScanException("Value of octal integer literal \"" + s + "\" is out of range");
-                x = (x << 3) + Character.digit(s.charAt(i), 8);
-            }
-            break;
-
-        case 16:
-            // Cannot use "Integer.parseInt(s, 16)" because that parses SIGNED values.
-            x = 0;
-            for (int i = 0; i < s.length(); ++i) {
-                if ((x & 0xf0000000) != 0) throw new ScanException("Value of hexadecimal integer literal \"" + s + "\" is out of range");
-                x = (x << 4) + Character.digit(s.charAt(i), 16);
-            }
-            break;
-
-        default:
-            throw new RuntimeException("Illegal radix " + radix);
-        }
-        return new LiteralToken(new Integer(x));
-    }
-
-    private LiteralToken stringToLongLiteralToken(final String s, int radix) throws ScanException {
-        long x;
-        switch (radix) {
-
-        case 10:
-            // Special case: Decimal literal 2^63 must only appear in "negated" context, i.e.
-            // "-9223372036854775808" is a valid long literal, but "9223372036854775808" is not.
-            if (s.equals("9223372036854775808")) return new LiteralToken(Scanner.MAGIC_LONG);
-    
-            try {
-                x = Long.parseLong(s);
-            } catch (NumberFormatException e) {
-                throw new ScanException("Value of decimal long literal \"" + s + "\" is out of range");
-            }
-            break;
-
-        case 8:
-            // Cannot use "Long.parseLong(s, 8)" because that parses SIGNED values.
-            x = 0L;
-            for (int i = 0; i < s.length(); ++i) {
-                if ((x & 0xe000000000000000L) != 0L) throw new ScanException("Value of octal long literal \"" + s + "\" is out of range");
-                x = (x << 3) + Character.digit(s.charAt(i), 8);
-            }
-            break;
-
-        case 16:
-            // Cannot use "Long.parseLong(s, 16)" because that parses SIGNED values.
-            x = 0L;
-            for (int i = 0; i < s.length(); ++i) {
-                if ((x & 0xf000000000000000L) != 0L) throw new ScanException("Value of hexadecimal long literal \"" + s + "\" is out of range");
-                x = (x << 4) + (long) Character.digit(s.charAt(i), 16);
-            }
-            break;
-
-        default:
-            throw new RuntimeException("Illegal radix " + radix);
-        }
-        return new LiteralToken(new Long(x));
-    }
-
-    private LiteralToken stringToFloatLiteralToken(final String s) throws ScanException {
-        float f;
-        try {
-            f = Float.parseFloat(s);
-        } catch (NumberFormatException e) {
-            throw new RuntimeException("SNO: parsing float literal \"" + s + "\" throws a \"NumberFormatException\"");
-        }
-        if (Float.isInfinite(f)) throw new ScanException("Value of float literal \"" + s + "\" is out of range");
-        if (Float.isNaN(f)) throw new RuntimeException("SNO: parsing float literal \"" + s + "\" results is NaN");
-
-        // Check for FLOAT underrun.
-        if (f == 0.0F) {
-            for (int i = 0; i < s.length(); ++i) {
-                char c = s.charAt(i);
-                if ("123456789".indexOf(c) != -1) throw new ScanException("Literal \"" + s + "\" is too small to be represented as a float");
-                if ("0.".indexOf(c) == -1) break;
-            }
-        }
-
-        return new LiteralToken(new Float(f));
-    }
-
-    private LiteralToken stringToDoubleLiteralToken(final String s) throws ScanException {
-        double d;
-        try {
-            d = Double.parseDouble(s);
-        } catch (NumberFormatException e) {
-            throw new RuntimeException("SNO: parsing double literal \"" + s + "\" throws a \"NumberFormatException\"");
-        }
-        if (Double.isInfinite(d)) throw new ScanException("Value of double literal \"" + s + "\" is out of range");
-        if (Double.isNaN(d)) throw new RuntimeException("SNO: parsing double literal \"" + s + "\" results is NaN");
-
-
-        // Check for DOUBLE underrun.
-        if (d == 0.0D) {
-            for (int i = 0; i < s.length(); ++i) {
-                char c = s.charAt(i);
-                if ("123456789".indexOf(c) != -1) throw new ScanException("Literal \"" + s + "\" is too small to be represented as a double");
-                if ("0.".indexOf(c) == -1) break;
-            }
-        }
-
-        return new LiteralToken(new Double(d));
-    }
-
-    /**
-     * Consume characters until a literal character is complete.
-     */
-    private char unescapeCharacterLiteral() throws ScanException, IOException {
-        if (this.nextChar == -1) throw new ScanException("EOF in character literal");
-
-        if (this.nextChar == '\r' || this.nextChar == '\n') throw new ScanException("Line break in literal not allowed");
-
-        if (this.nextChar != '\\') {
-            char res = (char) this.nextChar;
-            this.readNextChar();
-            return res;
-        }
-        this.readNextChar();
-        int idx = "btnfr".indexOf(this.nextChar);
-        if (idx != -1) {
-            char res = "\b\t\n\f\r".charAt(idx);
-            this.readNextChar();
-            return res;
-        }
-        idx = "01234567".indexOf(this.nextChar);
-        if (idx != -1) {
-            int code = idx;
-            this.readNextChar();
-            idx = "01234567".indexOf(this.nextChar);
-            if (idx == -1) return (char) code;
-            code = 8 * code + idx;
-            this.readNextChar();
-            idx = "01234567".indexOf(this.nextChar);
-            if (idx == -1) return (char) code;
-            code = 8 * code + idx;
-            if (code > 255) throw new ScanException("Invalid octal escape");
-            this.readNextChar();
-            return (char) code;
-        }
-
-        char res = (char) this.nextChar;
-        this.readNextChar();
-        return res;
-    }
-
-    // Read one character and store in "nextChar".
-    private void readNextChar() throws IOException, ScanException {
-        try {
-            this.nextChar = this.in.read();
-        } catch (UnicodeUnescapeException ex) {
-            throw new ScanException(ex.getMessage(), ex);
-        }
-        if (this.nextChar == '\r') {
-            ++this.nextCharLineNumber;
-            this.nextCharColumnNumber = 0;
-            this.crLfPending = true;
-        } else
-        if (this.nextChar == '\n') {
-            if (this.crLfPending) {
-                this.crLfPending = false;
-            } else {
-                ++this.nextCharLineNumber;
-                this.nextCharColumnNumber = 0;
-            }
-        } else
-        {
-            ++this.nextCharColumnNumber;
-        }
-//System.out.println("'" + (char) nextChar + "' = " + (int) nextChar);
-    }
-
-    private static final boolean DEBUG = false;
-
-    private /*final*/ String     optionalFileName;
-    private /*final*/ Reader     in;
-    private int              nextChar  = -1; // Always valid (one character read-ahead).
-    private boolean          crLfPending = false;
-    private short            nextCharLineNumber;
-    private short            nextCharColumnNumber;
-
-    private Token  nextToken;         // Is always non-null (one token read-ahead).
-    private Token  nextButOneToken;   // Is only non-null after "peekNextButOne()".
-    private short  tokenLineNumber;   // Line number of "nextToken" (typically starting at one).
-    private short  tokenColumnNumber; // Column number of first character of "nextToken" (1 if token is immediately preceeded by a line break).
-    private String docComment = null; // The optional JAVADOC comment preceeding the "nextToken".
-
-    private static final Map JAVA_KEYWORDS = new HashMap();
-    static {
-        String[] ks = {
-            "abstract", "boolean", "break", "byte", "case", "catch", "char",
-            "class", "const", "continue", "default", "do", "double", "else",
-            "extends", "final", "finally", "float", "for", "goto", "if",
-            "implements", "import", "instanceof", "int", "interface", "long",
-            "native", "new", "package", "private", "protected", "public",
-            "return", "short", "static", "strictfp", "super", "switch",
-            "synchronized", "this", "throw", "throws", "transient", "try",
-            "void", "volatile", "while"
-        };
-        for (int i = 0; i < ks.length; ++i) Scanner.JAVA_KEYWORDS.put(ks[i], ks[i]);
-    }
-    private static final Map JAVA_OPERATORS = new HashMap();
-    static {
-        String[] ops = {
-            // Separators:
-            "(", ")", "{", "}", "[", "]", ";", ",", ".",
-            // Operators:
-            "=",  ">",  "<",  "!",  "~",  "?",  ":",
-            "==", "<=", ">=", "!=", "&&", "||", "++", "--",
-            "+",  "-",  "*",  "/",  "&",  "|",  "^",  "%",  "<<",  ">>",  ">>>",
-            "+=", "-=", "*=", "/=", "&=", "|=", "^=", "%=", "<<=", ">>=", ">>>=",
-        };
-        for (int i = 0; i < ops.length; ++i) Scanner.JAVA_OPERATORS.put(ops[i], ops[i]);
-    }
-
-
-    /**
-     * An exception that reflects an error during parsing.
-     */
-    public class ScanException extends LocatedException {
-
-        public ScanException(String message) {
-            super(message, new Location(
-                Scanner.this.optionalFileName,
-                Scanner.this.nextCharLineNumber,
-                Scanner.this.nextCharColumnNumber
-            ));
-        }
-
-        public ScanException(String message, Throwable cause) {
-            super(message, new Location(
-                    Scanner.this.optionalFileName,
-                    Scanner.this.nextCharLineNumber,
-                    Scanner.this.nextCharColumnNumber
-            ), cause);
-        }
-    }
-
-    /**
-     * By default, warnings are discarded, but an application my install a
-     * {@link WarningHandler}.
-     * <p>
-     * Notice that there is no <code>Scanner.setErrorHandler()</code> method, but scan errors
-     * always throw a {@link ScanException}. The reason being is that there is no reasonable
-     * way to recover from scan errors and continue scanning, so there is no need to install
-     * a custom scan error handler.
-     *
-     * @param optionalWarningHandler <code>null</code> to indicate that no warnings be issued
-     */
-    public void setWarningHandler(WarningHandler optionalWarningHandler) {
-        this.optionalWarningHandler = optionalWarningHandler;
-    }
-
-    // Used for elaborate warning handling.
-    private WarningHandler optionalWarningHandler = null;
-
-    /**
-     * Issues a warning with the given message and location and returns. This is done through
-     * a {@link WarningHandler} that was installed through
-     * {@link #setWarningHandler(WarningHandler)}.
-     * <p>
-     * The <code>handle</code> argument qulifies the warning and is typically used by
-     * the {@link WarningHandler} to suppress individual warnings.
-     */
-    private void warning(String handle, String message, Location optionalLocation) {
-        if (this.optionalWarningHandler != null) this.optionalWarningHandler.handleWarning(handle, message, optionalLocation);
-    }
-}
diff --git a/src/org/codehaus/janino/ScriptEvaluator.java b/src/org/codehaus/janino/ScriptEvaluator.java
deleted file mode 100644
index efa93e7..0000000
--- a/src/org/codehaus/janino/ScriptEvaluator.java
+++ /dev/null
@@ -1,1045 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.codehaus.janino.Java.AmbiguousName;
-import org.codehaus.janino.Java.LocalVariableDeclarationStatement;
-import org.codehaus.janino.Parser.ParseException;
-import org.codehaus.janino.Scanner.ScanException;
-import org.codehaus.janino.util.Traverser;
-
-/**
- * An engine that executes a script in Java<sup>TM</sup> bytecode.
- * <p>
- * The syntax of the script to compile is a sequence of import declarations (not allowed if you
- * compile many scripts at a time, see below) followed by a
- * sequence of statements, as defined in the
- * <a href="http://java.sun.com/docs/books/jls/second_edition">Java Language Specification, 2nd
- * edition</a>, sections
- * <a href="http://java.sun.com/docs/books/jls/second_edition/html/packages.doc.html#70209">7.5</a>
- * and
- * <a href="http://java.sun.com/docs/books/jls/second_edition/html/statements.doc.html#101241">14</a>.
- * <p>
- * Example:
- * <pre>
- *   import java.text.*;
- * 
- *   System.out.println("HELLO");
- *   System.out.println(new DecimalFormat("####,###.##").format(a));
- * </pre>
- * (Notice that this expression refers to a parameter "a", as explained below.)
- * <p>
- * The script may complete abnormally, e.g. through a RETURN statement:
- * <pre>
- *   if (a == null) {
- *       System.out.println("Oops!");
- *       return;
- *   }
- * </pre>
- * Optionally, the script may be declared with a non-void return type. In this case, the last
- * statement of the script must be a RETURN statement (or a THROW statement), and all RETURN
- * statements in the script must return a value with the given type.
- * <p>
- * The script evaluator is implemented by creating and compiling a temporary compilation unit
- * defining one class with one method the body of which consists of the statements of the
- * script.
- * <p>
- * To set up a {@link ScriptEvaluator} object, proceed as follows:
- * <ol>
- *   <li>
- *   Create the {@link ScriptEvaluator} using {@link #ScriptEvaluator()}
- *   <li>
- *   Configure the {@link ScriptEvaluator} by calling any of the following methods:
- *   <ul>
- *      <li>{@link #setReturnType(Class)}
- *      <li>{@link #setParameters(String[], Class[])}
- *      <li>{@link #setThrownExceptions(Class[])}
- *      <li>{@link org.codehaus.janino.SimpleCompiler#setParentClassLoader(ClassLoader)}
- *      <li>{@link org.codehaus.janino.ClassBodyEvaluator#setDefaultImports(String[])}
- *   </ul>
- *   <li>
- *   Call any of the {@link org.codehaus.janino.Cookable#cook(Scanner)} methods to scan,
- *   parse, compile and load the script into the JVM.
- * </ol>
- * After the {@link ScriptEvaluator} object is created, the script can be executed as often with
- * different parameter values (see {@link #evaluate(Object[])}). This execution is very fast,
- * compared to the compilation.
- * <p>
- * Less common methods exist that allow for the specification of the name of the generated class,
- * the class it extends, the interfaces it implements, the name of the method that executes the
- * script, the exceptions that this method (i.e. the script) is allowed to throw, and the
- * {@link ClassLoader} that is used to define the generated class and to load classes referenced by
- * the script.
- * <p>
- * Alternatively, a number of "convenience constructors" exist that execute the steps described
- * above instantly. Their use is discouraged.
- * <p>
- * If you want to compile many scripts at the same time, you have the option to cook an
- * <i>array</i> of scripts in one {@link ScriptEvaluator} by using the following methods:
- * <ul>
- *   <li>{@link #setMethodNames(String[])}
- *   <li>{@link #setParameters(String[][], Class[][])}
- *   <li>{@link #setReturnTypes(Class[])}
- *   <li>{@link #setStaticMethod(boolean[])}
- *   <li>{@link #setThrownExceptions(Class[][])}
- *   <li>{@link #cook(Scanner[])}
- *   <li>{@link #evaluate(int, Object[])}
- * </ul>
- * Notice that these methods have array parameters in contrast to their one-script brethren.
- */
-public class ScriptEvaluator extends ClassBodyEvaluator {
-
-    protected boolean[]  optionalStaticMethod = null;
-    protected Class[]    optionalReturnTypes = null;
-    protected String[]   optionalMethodNames = null;
-    protected String[][] optionalParameterNames = null;
-    protected Class[][]  optionalParameterTypes = null;
-    protected Class[][]  optionalThrownExceptions = null;
-
-    private Method[]     result = null; // null=uncooked
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.cook(script);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see Cookable#cook(String)
-     */
-    public ScriptEvaluator(
-        String   script
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        this.cook(script);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.setReturnType(returnType);
-     * se.cook(script);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see #setReturnType(Class)
-     * @see Cookable#cook(String)
-     */
-    public ScriptEvaluator(
-        String   script,
-        Class    returnType
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        this.setReturnType(returnType);
-        this.cook(script);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.setReturnType(returnType);
-     * se.setParameters(parameterNames, parameterTypes);
-     * se.cook(script);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see #setReturnType(Class)
-     * @see #setParameters(String[], Class[])
-     * @see Cookable#cook(String)
-     */
-    public ScriptEvaluator(
-        String   script,
-        Class    returnType,
-        String[] parameterNames,
-        Class[]  parameterTypes
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        this.setReturnType(returnType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.cook(script);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.setReturnType(returnType);
-     * se.setParameters(parameterNames, parameterTypes);
-     * se.setThrownExceptions(thrownExceptions);
-     * se.cook(script);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see #setReturnType(Class)
-     * @see #setParameters(String[], Class[])
-     * @see #setThrownExceptions(Class[])
-     * @see Cookable#cook(String)
-     */
-    public ScriptEvaluator(
-        String   script,
-        Class    returnType,
-        String[] parameterNames,
-        Class[]  parameterTypes,
-        Class[]  thrownExceptions
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        this.setReturnType(returnType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.cook(script);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.setReturnType(returnType);
-     * se.setParameters(parameterNames, parameterTypes);
-     * se.setThrownExceptions(thrownExceptions);
-     * se.setParentClassLoader(optionalParentClassLoader);
-     * se.cook(optionalFileName, is);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see #setReturnType(Class)
-     * @see #setParameters(String[], Class[])
-     * @see #setThrownExceptions(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(String, InputStream)
-     */
-    public ScriptEvaluator(
-        String      optionalFileName,
-        InputStream is,
-        Class       returnType,
-        String[]    parameterNames,
-        Class[]     parameterTypes,
-        Class[]     thrownExceptions,
-        ClassLoader optionalParentClassLoader // null = use current thread's context class loader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.setReturnType(returnType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(optionalFileName, is);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.setReturnType(returnType);
-     * se.setParameters(parameterNames, parameterTypes);
-     * se.setThrownExceptions(thrownExceptions);
-     * se.setParentClassLoader(optionalParentClassLoader);
-     * se.cook(reader);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see #setReturnType(Class)
-     * @see #setParameters(String[], Class[])
-     * @see #setThrownExceptions(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(String, Reader)
-     */
-    public ScriptEvaluator(
-        String      optionalFileName,
-        Reader      reader,
-        Class       returnType,
-        String[]    parameterNames,
-        Class[]     parameterTypes,
-        Class[]     thrownExceptions,
-        ClassLoader optionalParentClassLoader // null = use current thread's context class loader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.setReturnType(returnType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(optionalFileName, reader);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.setReturnType(returnType);
-     * se.setParameters(parameterNames, parameterTypes);
-     * se.setThrownExceptions(thrownExceptions);
-     * se.setParentClassLoader(optionalParentClassLoader);
-     * se.cook(scanner);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see #setReturnType(Class)
-     * @see #setParameters(String[], Class[])
-     * @see #setThrownExceptions(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(Scanner)
-     */
-    public ScriptEvaluator(
-        Scanner     scanner,
-        Class       returnType,
-        String[]    parameterNames,
-        Class[]     parameterTypes,
-        Class[]     thrownExceptions,
-        ClassLoader optionalParentClassLoader // null = use current thread's context class loader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.setReturnType(returnType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(scanner);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.setExtendedType(optionalExtendedType);
-     * se.setImplementedTypes(implementedTypes);
-     * se.setReturnType(returnType);
-     * se.setParameters(parameterNames, parameterTypes);
-     * se.setThrownExceptions(thrownExceptions);
-     * se.setParentClassLoader(optionalParentClassLoader);
-     * se.cook(scanner);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see ClassBodyEvaluator#setExtendedType(Class)
-     * @see ClassBodyEvaluator#setImplementedTypes(Class[])
-     * @see #setReturnType(Class)
-     * @see #setParameters(String[], Class[])
-     * @see #setThrownExceptions(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(Scanner)
-     */
-    public ScriptEvaluator(
-        Scanner     scanner,
-        Class       optionalExtendedType,
-        Class[]     implementedTypes,
-        Class       returnType,
-        String[]    parameterNames,
-        Class[]     parameterTypes,
-        Class[]     thrownExceptions,
-        ClassLoader optionalParentClassLoader // null = use current thread's context class loader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.setExtendedType(optionalExtendedType);
-        this.setImplementedTypes(implementedTypes);
-        this.setReturnType(returnType);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(scanner);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * ScriptEvaluator se = new ScriptEvaluator();
-     * se.setClassName(className);
-     * se.setExtendedType(optionalExtendedType);
-     * se.setImplementedTypes(implementedTypes);
-     * se.setStaticMethod(staticMethod);
-     * se.setReturnType(returnType);
-     * se.setMethodName(methodName);
-     * se.setParameters(parameterNames, parameterTypes);
-     * se.setThrownExceptions(thrownExceptions);
-     * se.setParentClassLoader(optionalParentClassLoader);
-     * se.cook(scanner);</pre>
-     *
-     * @see #ScriptEvaluator()
-     * @see ClassBodyEvaluator#setClassName(String)
-     * @see ClassBodyEvaluator#setExtendedType(Class)
-     * @see ClassBodyEvaluator#setImplementedTypes(Class[])
-     * @see #setStaticMethod(boolean)
-     * @see #setReturnType(Class)
-     * @see #setMethodName(String)
-     * @see #setParameters(String[], Class[])
-     * @see #setThrownExceptions(Class[])
-     * @see SimpleCompiler#setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(Scanner)
-     */
-    public ScriptEvaluator(
-        Scanner     scanner,
-        String      className,
-        Class       optionalExtendedType,
-        Class[]     implementedTypes,
-        boolean     staticMethod,
-        Class       returnType,
-        String      methodName,
-        String[]    parameterNames,
-        Class[]     parameterTypes,
-        Class[]     thrownExceptions,
-        ClassLoader optionalParentClassLoader // null = use current thread's context class loader
-    ) throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
-        this.setClassName(className);
-        this.setExtendedType(optionalExtendedType);
-        this.setImplementedTypes(implementedTypes);
-        this.setStaticMethod(staticMethod);
-        this.setReturnType(returnType);
-        this.setMethodName(methodName);
-        this.setParameters(parameterNames, parameterTypes);
-        this.setThrownExceptions(thrownExceptions);
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(scanner);
-    }
-
-    public ScriptEvaluator() {}
-
-    /**
-     * Define whether the generated method should be STATIC or not. Defaults to <code>true</code>.
-     */
-    public void setStaticMethod(boolean staticMethod) {
-        this.setStaticMethod(new boolean[] { staticMethod });
-    }
-
-    /**
-     * Define the return type of the generated method. Defaults to <code>void.class</code>.
-     */
-    public void setReturnType(Class returnType) {
-        this.setReturnTypes(new Class[] { returnType });
-    }
-
-    /**
-     * Define the name of the generated method. Defaults to an unspecified name.
-     */
-    public void setMethodName(String methodName) {
-        this.setMethodNames(new String[] { methodName });
-    }
-
-    /**
-     * Define the names and types of the parameters of the generated method.
-     */
-    public void setParameters(String[] parameterNames, Class[] parameterTypes) {
-        this.setParameters(new String[][] { parameterNames }, new Class[][] {parameterTypes });
-    }
-
-    /**
-     * Define the exceptions that the generated method may throw.
-     */
-    public void setThrownExceptions(Class[] thrownExceptions) {
-        this.setThrownExceptions(new Class[][] { thrownExceptions });
-    }
-
-    public final void cook(Scanner scanner)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cook(new Scanner[] { scanner });
-    }
-
-    /**
-     * Calls the generated method with concrete parameter values.
-     * <p>
-     * Each parameter value must have the same type as specified through
-     * the "parameterTypes" parameter of
-     * {@link #setParameters(String[], Class[])}.
-     * <p>
-     * Parameters of primitive type must passed with their wrapper class
-     * objects.
-     * <p>
-     * The object returned has the class as specified through
-     * {@link #setReturnType(Class)}.
-     * <p>
-     * This method is thread-safe.
-     *
-     * @param parameterValues The concrete parameter values.
-     */
-    public Object evaluate(Object[] parameterValues) throws InvocationTargetException {
-        return this.evaluate(0, parameterValues);
-    }
-
-    /**
-     * Returns the loaded {@link java.lang.reflect.Method}.
-     * <p>
-     * This method must only be called after {@link #cook(Scanner)}.
-     * <p>
-     * This method must not be called for instances of derived classes.
-     */
-    public Method getMethod() {
-        return this.getMethod(0);
-    }
-
-    /**
-     * Define whether the methods implementing each script should be STATIC or not. By default
-     * all scripts are compiled into STATIC methods.
-     */
-    public void setStaticMethod(boolean[] staticMethod) {
-        assertNotCooked();
-        this.optionalStaticMethod = (boolean[]) staticMethod.clone();
-    }
-
-    /**
-     * Define the return types of the scripts. By default all scripts have VOID return type.
-     */
-    public void setReturnTypes(Class[] returnTypes) {
-        assertNotCooked();
-        this.optionalReturnTypes = (Class[]) returnTypes.clone();
-    }
-
-    /**
-     * Define the names of the generated methods. By default the methods have distinct and
-     * implementation-specific names.
-     * <p>
-     * If two scripts have the same name, then they must have different parameter types
-     * (see {@link #setParameters(String[][], Class[][])}).
-     */
-    public void setMethodNames(String[] methodNames) {
-        assertNotCooked();
-        this.optionalMethodNames = (String[]) methodNames.clone();
-    }
-
-    /**
-     * Define the names and types of the parameters of the generated methods.
-     */
-    public void setParameters(String[][] parameterNames, Class[][] parameterTypes) {
-        assertNotCooked();
-        this.optionalParameterNames = (String[][]) parameterNames.clone();
-        this.optionalParameterTypes = (Class[][]) parameterTypes.clone();
-    }
-
-    /**
-     * Define the exceptions that the generated methods may throw.
-     */
-    public void setThrownExceptions(Class[][] thrownExceptions) {
-        assertNotCooked();
-        this.optionalThrownExceptions = (Class[][]) thrownExceptions.clone();
-    }
-
-    /**
-     * Like {@link #cook(Scanner)}, but cooks a <i>set</i> of scripts into one class. Notice that
-     * if <i>any</i> of the scripts causes trouble, the entire compilation will fail. If you
-     * need to report <i>which</i> of the scripts causes the exception, you may want to use the
-     * <code>optionalFileName</code> argument of {@link Scanner#Scanner(String, Reader)} to
-     * distinguish between the individual token sources.
-     * <p>
-     * On a 2 GHz Intel Pentium Core Duo under Windows XP with an IBM 1.4.2 JDK, compiling
-     * 10000 expressions "a + b" (integer) takes about 4 seconds and 56 MB of main memory.
-     * The generated class file is 639203 bytes large.
-     * <p>
-     * The number and the complexity of the scripts is restricted by the
-     * <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#88659">Limitations
-     * of the Java Virtual Machine</a>, where the most limiting factor is the 64K entries limit
-     * of the constant pool. Since every method with a distinct name requires one entry there,
-     * you can define at best 32K (very simple) scripts.
-     *
-     * If and only if the number of scanners is one, then that single script may contain leading
-     * IMPORT directives.
-     *
-     * @throws IllegalStateException if any of the preceeding <code>set...()</code> had an array size different from that of <code>scanners</code>
-     */
-    public final void cook(Scanner[] scanners)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        if (scanners == null) throw new NullPointerException();
-
-        // The "dimension" of this ScriptEvaluator, i.e. how many scripts are cooked at the same
-        // time.
-        int count = scanners.length;
-
-        // Check array sizes.
-        if (this.optionalMethodNames      != null && this.optionalMethodNames.length      != count) throw new IllegalStateException("methodName");
-        if (this.optionalParameterNames   != null && this.optionalParameterNames.length   != count) throw new IllegalStateException("parameterNames");
-        if (this.optionalParameterTypes   != null && this.optionalParameterTypes.length   != count) throw new IllegalStateException("parameterTypes");
-        if (this.optionalReturnTypes      != null && this.optionalReturnTypes.length      != count) throw new IllegalStateException("returnTypes");
-        if (this.optionalStaticMethod     != null && this.optionalStaticMethod.length     != count) throw new IllegalStateException("staticMethod");
-        if (this.optionalThrownExceptions != null && this.optionalThrownExceptions.length != count) throw new IllegalStateException("thrownExceptions");
-
-        this.setUpClassLoaders();
-
-        // Create compilation unit.
-        Java.CompilationUnit compilationUnit = this.makeCompilationUnit(count == 1 ? scanners[0] : null);
-
-        // Create class declaration.
-        Java.ClassDeclaration cd = this.addPackageMemberClassDeclaration(scanners[0].location(), compilationUnit);
-
-        // Determine method names.
-        String[] methodNames;
-        if (this.optionalMethodNames == null) {
-            methodNames = new String[count];
-            for (int i = 0; i < count; ++i) methodNames[i] = "eval" + i;
-        } else
-        {
-            methodNames = this.optionalMethodNames;
-        }
-
-        // Create methods with one block each.
-        for (int i = 0; i < count; ++i) {
-            Scanner scanner = scanners[i];
-
-            Java.Block block = this.makeBlock(i, scanner);
-
-            // Determine the following script properties AFTER the call to "makeBlock()",
-            // because "makeBlock()" may modify these script properties on-the-fly.
-            boolean  staticMethod     = this.optionalStaticMethod     == null ? true : this.optionalStaticMethod[i];
-            Class    returnType       = this.optionalReturnTypes      == null ? this.getDefaultReturnType() : this.optionalReturnTypes[i];
-            String[] parameterNames   = this.optionalParameterNames   == null ? new String[0] : this.optionalParameterNames[i];
-            Class[]  parameterTypes   = this.optionalParameterTypes   == null ? new Class[0] : this.optionalParameterTypes[i];
-            Class[]  thrownExceptions = this.optionalThrownExceptions == null ? new Class[0] : this.optionalThrownExceptions[i];
-
-            cd.addDeclaredMethod(this.makeMethodDeclaration(
-                scanner.location(), // location
-                staticMethod,       // staticMethod
-                returnType,         // returnType
-                methodNames[i],     // methodName
-                parameterTypes,     // parameterTypes
-                parameterNames,     // parameterNames
-                thrownExceptions,   // thrownExceptions
-                block               // optionalBody
-            ));
-        }
-
-        // Compile and load the compilation unit.
-        Class c = this.compileToClass(
-            compilationUnit,                                    // compilationUnit
-            DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION, // debuggingInformation
-            this.className
-        );
-        
-        // Find the script methods by name.
-        this.result = new Method[count];
-        if (count <= 10) {
-            for (int i = 0; i < count; ++i) {
-                try {
-                    this.result[i] = c.getDeclaredMethod(methodNames[i], this.optionalParameterTypes == null ? new Class[0] : this.optionalParameterTypes[i]);
-                } catch (NoSuchMethodException ex) {
-                    throw new RuntimeException("SNO: Loaded class does not declare method \"" + methodNames[i] + "\"");
-                }
-            }
-        } else
-        {
-            class MethodWrapper {
-                private final String  name;
-                private final Class[] parameterTypes;
-                MethodWrapper(String name, Class[] parameterTypes) {
-                    this.name = name;
-                    this.parameterTypes = parameterTypes;
-                }
-                public boolean equals(Object o) {
-                    if (!(o instanceof MethodWrapper)) return false;
-                    MethodWrapper that = (MethodWrapper) o;
-                    if (!this.name.equals(that.name)) return false;
-                    int cnt = this.parameterTypes.length;
-                    if (cnt != that.parameterTypes.length) return false;
-                    for (int i = 0; i < cnt; ++i) {
-                        if (!this.parameterTypes[i].equals(that.parameterTypes[i])) return false;
-                    }
-                    return true;
-                }
-                public int hashCode() {
-                    int hc = this.name.hashCode();
-                    for (int i = 0; i < this.parameterTypes.length; ++i) {
-                        hc ^= this.parameterTypes[i].hashCode();
-                    }
-                    return hc;
-                }
-            }
-            Method[] ma = c.getDeclaredMethods();
-            Map dms = new HashMap(2 * count);
-            for (int i = 0; i < ma.length; ++i) {
-                Method m = ma[i];
-                dms.put(new MethodWrapper(m.getName(), m.getParameterTypes()), m);
-            }
-            for (int i = 0; i < count; ++i) {
-                Method m = (Method) dms.get(new MethodWrapper(methodNames[i], this.optionalParameterTypes == null ? new Class[0] : this.optionalParameterTypes[i]));
-                if (m == null) throw new RuntimeException("SNO: Loaded class does not declare method \"" + methodNames[i] + "\"");
-                this.result[i] = m;
-            }
-        }
-    }
-
-    public final void cook(Reader[] readers)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.cook(new String[readers.length], readers);
-    }
-
-    /**
-     * @param optionalFileNames Used when reporting errors and warnings.
-     */
-    public final void cook(String[] optionalFileNames, Reader[] readers)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        Scanner[] scanners = new Scanner[readers.length];
-        for (int i = 0; i < readers.length; ++i) scanners[i] = new Scanner(optionalFileNames[i], readers[i]);
-        this.cook(scanners);
-    }
-
-    /**
-     * Cook tokens from {@link java.lang.String}s.
-     */
-    public final void cook(String[] strings)
-    throws CompileException, Parser.ParseException, Scanner.ScanException {
-        Reader[] readers = new Reader[strings.length];
-        for (int i = 0; i < strings.length; ++i) readers[i] = new StringReader(strings[i]);
-        try {
-            this.cook(readers);
-        } catch (IOException ex) {
-            throw new RuntimeException("SNO: IOException despite StringReader");
-        }
-    }
-
-    protected Class getDefaultReturnType() {
-        return void.class;
-    }
-
-    /**
-     * Fill the given <code>block</code> by parsing statements until EOF and adding
-     * them to the block.
-     */
-    protected Java.Block makeBlock(int idx, Scanner scanner) throws ParseException, ScanException, IOException {
-        Java.Block block = new Java.Block(scanner.location());
-        Parser parser = new Parser(scanner);
-        while (!scanner.peek().isEOF()) {
-            block.addStatement(parser.parseBlockStatement());
-        }
-
-        return block;
-    }
-
-    protected void compileToMethods(
-        Java.CompilationUnit compilationUnit,
-        String[]             methodNames,
-        Class[][]            parameterTypes
-    ) throws CompileException {
-
-        // Compile and load the compilation unit.
-        Class c = this.compileToClass(
-            compilationUnit,                                    // compilationUnit
-            DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION, // debuggingInformation
-            this.className
-        );
-
-        // Find the script method by name.
-        this.result = new Method[methodNames.length];
-        for (int i = 0; i < this.result.length; ++i) {
-            try {
-                this.result[i] = c.getMethod(methodNames[i], parameterTypes[i]);
-            } catch (NoSuchMethodException ex) {
-                throw new RuntimeException("SNO: Loaded class does not declare method \"" + this.optionalMethodNames[i] + "\"");
-            }
-        }
-    }
-
-    /**
-     * To the given {@link Java.ClassDeclaration}, add
-     * <ul>
-     *   <li>A public method declaration with the given return type, name, parameter
-     *       names and values and thrown exceptions
-     *   <li>A block 
-     * </ul> 
-     *
-     * @param returnType Return type of the declared method
-     */
-    protected Java.MethodDeclarator makeMethodDeclaration(
-        Location   location,
-        boolean    staticMethod,
-        Class      returnType,
-        String     methodName,
-        Class[]    parameterTypes,
-        String[]   parameterNames,
-        Class[]    thrownExceptions,
-        Java.Block optionalBody
-    ) {
-        if (parameterNames.length != parameterTypes.length) throw new RuntimeException("Lengths of \"parameterNames\" (" + parameterNames.length + ") and \"parameterTypes\" (" + parameterTypes.length + ") do not match");
-
-        Java.FunctionDeclarator.FormalParameter[] fps = new Java.FunctionDeclarator.FormalParameter[parameterNames.length];
-        for (int i = 0; i < fps.length; ++i) {
-            fps[i] = new Java.FunctionDeclarator.FormalParameter(
-                location,                                      // location
-                true,                                          // finaL
-                this.classToType(location, parameterTypes[i]), // type
-                parameterNames[i]                              // name
-            );
-        }
-
-        return new Java.MethodDeclarator(
-            location,                                        // location
-            null,                                            // optionalDocComment
-            (                                                // modifiers
-                staticMethod ?
-                (short) (Mod.PUBLIC | Mod.STATIC) :
-                (short) Mod.PUBLIC
-            ),
-            this.classToType(location, returnType),          // type
-            methodName,                                      // name
-            fps,                                             // formalParameters
-            this.classesToTypes(location, thrownExceptions), // thrownExceptions
-            optionalBody                                     // optionalBody
-        );
-    }
-
-    /**
-     * Simplified version of
-     * {@link #createFastScriptEvaluator(Scanner, Class, String[], ClassLoader)}.
-     * 
-     * @param script Contains the sequence of script tokens
-     * @param interfaceToImplement Must declare exactly the one method that defines the expression's signature
-     * @param parameterNames The expression references the parameters through these names
-     * @return an object that implements the given interface and extends the <code>optionalExtendedType</code>
-     */
-    public static Object createFastScriptEvaluator(
-        String   script,
-        Class    interfaceToImplement,
-        String[] parameterNames
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        ScriptEvaluator se = new ScriptEvaluator();
-        return ScriptEvaluator.createFastEvaluator(se, script, parameterNames, interfaceToImplement);
-    }
-
-    /**
-     * If the parameter and return types of the expression are known at compile time,
-     * then a "fast" script evaluator can be instantiated through this method.
-     * <p>
-     * Script evaluation is faster than through {@link #evaluate(Object[])}, because
-     * it is not done through reflection but through direct method invocation.
-     * <p>
-     * Example:
-     * <pre>
-     * public interface Foo {
-     *     int bar(int a, int b);
-     * }
-     * ...
-     * Foo f = (Foo) ScriptEvaluator.createFastScriptEvaluator(
-     *     new Scanner(null, new StringReader("return a + b;")),
-     *     Foo.class,
-     *     new String[] { "a", "b" },
-     *     (ClassLoader) null          // Use current thread's context class loader
-     * );
-     * System.out.println("1 + 2 = " + f.bar(1, 2));
-     * </pre>
-     * Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
-     * or with package scope in the root package (i.e. "no" package).
-     * 
-     * @param scanner Source of script tokens
-     * @param interfaceToImplement Must declare exactly one method
-     * @param parameterNames
-     * @param optionalParentClassLoader
-     * @return an object that implements the given interface
-     */
-    public static Object createFastScriptEvaluator(
-        Scanner     scanner,
-        Class       interfaceToImplement,
-        String[]    parameterNames,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        ScriptEvaluator se = new ScriptEvaluator();
-        se.setParentClassLoader(optionalParentClassLoader);
-        return ScriptEvaluator.createFastEvaluator(se, scanner, parameterNames, interfaceToImplement);
-    }
-
-    /**
-     * Like {@link #createFastScriptEvaluator(Scanner, Class, String[], ClassLoader)},
-     * but gives you more control over the generated class (rarely needed in practice).
-     * <p> 
-     * Notice: The <code>interfaceToImplement</code> must either be declared <code>public</code>,
-     * or with package scope in the same package as <code>className</code>.
-     * 
-     * @param scanner                   Source of script tokens
-     * @param className                 Name of generated class
-     * @param optionalExtendedType      Class to extend
-     * @param interfaceToImplement      Must declare exactly the one method that defines the expression's signature
-     * @param parameterNames            The expression references the parameters through these names
-     * @param optionalParentClassLoader Used to load referenced classes, defaults to the current thread's "context class loader"
-     * @return an object that implements the given interface and extends the <code>optionalExtendedType</code>
-     */
-    public static Object createFastScriptEvaluator(
-        Scanner     scanner,
-        String      className,
-        Class       optionalExtendedType,
-        Class       interfaceToImplement,
-        String[]    parameterNames,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        ScriptEvaluator se = new ScriptEvaluator();
-        se.setClassName(className);
-        se.setExtendedType(optionalExtendedType);
-        se.setParentClassLoader(optionalParentClassLoader);
-        return ScriptEvaluator.createFastEvaluator(se, scanner, parameterNames, interfaceToImplement);
-    }
-
-    public static Object createFastScriptEvaluator(
-        Scanner     scanner,
-        String[]    optionalDefaultImports,
-        String      className,
-        Class       optionalExtendedType,
-        Class       interfaceToImplement,
-        String[]    parameterNames,
-        ClassLoader optionalParentClassLoader
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        ScriptEvaluator se = new ScriptEvaluator();
-        se.setClassName(className);
-        se.setExtendedType(optionalExtendedType);
-        se.setDefaultImports(optionalDefaultImports);
-        se.setParentClassLoader(optionalParentClassLoader);
-        return ScriptEvaluator.createFastEvaluator(se, scanner, parameterNames, interfaceToImplement);
-    }
-
-    public static Object createFastEvaluator(
-        ScriptEvaluator se,
-        String          s,
-        String[]        parameterNames,
-        Class           interfaceToImplement
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException {
-        try {
-            return ScriptEvaluator.createFastEvaluator(
-                se,
-                new Scanner(null, new StringReader(s)),
-                parameterNames,
-                interfaceToImplement
-            );
-        } catch (IOException ex) {
-            throw new RuntimeException("IOException despite StringReader");
-        }
-    }
-
-    /**
-     * Create and return an object that implements the exactly one method of the given
-     * <code>interfaceToImplement</code>.
-     *
-     * @param se A pre-configured {@link ScriptEvaluator} object
-     * @param scanner Source of tokens to read
-     * @param parameterNames The names of the parameters of the one abstract method of <code>interfaceToImplement</code>
-     * @param interfaceToImplement A type with exactly one abstract method
-     * @return an instance of the created {@link Object}
-     */
-    public static Object createFastEvaluator(
-        ScriptEvaluator se,
-        Scanner         scanner,
-        String[]        parameterNames,
-        Class           interfaceToImplement
-    ) throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        if (!interfaceToImplement.isInterface()) throw new RuntimeException("\"" + interfaceToImplement + "\" is not an interface");
-
-        Method[] methods = interfaceToImplement.getDeclaredMethods();
-        if (methods.length != 1) throw new RuntimeException("Interface \"" + interfaceToImplement + "\" must declare exactly one method");
-        Method methodToImplement = methods[0];
-
-        se.setImplementedTypes(new Class[] { interfaceToImplement });
-        se.setStaticMethod(false);
-        se.setReturnType(methodToImplement.getReturnType());
-        se.setMethodName(methodToImplement.getName());
-        se.setParameters(parameterNames, methodToImplement.getParameterTypes());
-        se.setThrownExceptions(methodToImplement.getExceptionTypes());
-        se.cook(scanner);
-        Class c = se.getMethod().getDeclaringClass();
-        try {
-            return c.newInstance();
-        } catch (InstantiationException e) {
-            // SNO - Declared class is always non-abstract.
-            throw new RuntimeException(e.toString());
-        } catch (IllegalAccessException e) {
-            // SNO - interface methods are always PUBLIC.
-            throw new RuntimeException(e.toString());
-        }
-    }
-
-    /**
-     * Guess the names of the parameters used in the given expression. The strategy is to look
-     * at all "ambiguous names" in the expression (e.g. in "a.b.c.d()", the ambiguous name
-     * is "a.b.c"), and then at the components of the ambiguous name.
-     * <ul>
-     *   <li>If any component starts with an upper-case letter, then ambiguous name is assumed to
-     *       be a type name.
-     *   <li>Otherwise, if the first component of the ambiguous name matches the name of a 
-     *       previously defined local variable, then the first component of the ambiguous name is
-     *       assumed to be a local variable name. (Notice that this strategy does not consider that
-     *       the scope of a local variable declaration may end before the end of the script.)
-     *   <li>Otherwise, the first component of the ambiguous name is assumed to be a parameter name.
-     * </ul>
-     *
-     * @see Scanner#Scanner(String, Reader)
-     */
-    public static String[] guessParameterNames(Scanner scanner) throws ParseException, ScanException, IOException {
-        Parser parser = new Parser(scanner);
-
-        // Eat optional leading import declarations.
-        while (scanner.peek().isKeyword("import")) parser.parseImportDeclaration();
-
-        // Parse the script statements into a block.
-        Java.Block block = new Java.Block(scanner.location());
-        while (!scanner.peek().isEOF()) block.addStatement(parser.parseBlockStatement());
-
-        // Traverse the block for ambiguous names and guess which of them are parameter names.
-        final Set localVariableNames = new HashSet();
-        final Set parameterNames = new HashSet();
-        new Traverser() {
-            public void traverseLocalVariableDeclarationStatement(LocalVariableDeclarationStatement lvds) {
-                for (int i = 0; i < lvds.variableDeclarators.length; ++i) {
-                    localVariableNames.add(lvds.variableDeclarators[i].name);
-                }
-                super.traverseLocalVariableDeclarationStatement(lvds);
-            }
-
-            public void traverseAmbiguousName(AmbiguousName an) {
-
-                // If any of the components starts with an upper-case letter, then the ambiguous
-                // name is most probably a type name, e.g. "System.out" or "java.lang.System.out".
-                for (int i = 0; i < an.identifiers.length; ++i) {
-                    if (Character.isUpperCase(an.identifiers[i].charAt(0))) return;
-                }
-
-                // Is it a local variable's name?
-                if (localVariableNames.contains(an.identifiers[0])) return;
-
-                // It's most probably a parameter name (although it could be a field name as well).
-                parameterNames.add(an.identifiers[0]);
-            }
-        }.traverseBlock(block);
-
-        return (String[]) parameterNames.toArray(new String[parameterNames.size()]);
-    }
-
-    /**
-     * Calls the generated method with concrete parameter values.
-     * <p>
-     * Each parameter value must have the same type as specified through
-     * the "parameterTypes" parameter of
-     * {@link #setParameters(String[], Class[])}.
-     * <p>
-     * Parameters of primitive type must passed with their wrapper class
-     * objects.
-     * <p>
-     * The object returned has the class as specified through
-     * {@link #setReturnType(Class)}.
-     * <p>
-     * This method is thread-safe.
-     *
-     * @param idx The index of the script (0 ... <code>scripts.length - 1</code>)
-     * @param parameterValues The concrete parameter values.
-     */
-    public Object evaluate(int idx, Object[] parameterValues) throws InvocationTargetException {
-        if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
-        try {
-            return this.result[idx].invoke(null, parameterValues);
-        } catch (IllegalAccessException ex) {
-            throw new RuntimeException(ex.toString());
-        }
-    }
-
-    /**
-     * Returns the loaded {@link java.lang.reflect.Method}.
-     * <p>
-     * This method must only be called after {@link #cook(Scanner)}.
-     * <p>
-     * This method must not be called for instances of derived classes.
-     *
-     * @param idx The index of the script (0 ... <code>scripts.length - 1</code>)
-     */
-    public Method getMethod(int idx) {
-        if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
-        return this.result[idx];
-    }
-}
diff --git a/src/org/codehaus/janino/SimpleCompiler.java b/src/org/codehaus/janino/SimpleCompiler.java
deleted file mode 100644
index f3fd349..0000000
--- a/src/org/codehaus/janino/SimpleCompiler.java
+++ /dev/null
@@ -1,462 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.codehaus.janino.tools.Disassembler;
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-
-/**
- * A simplified version of {@link Compiler} that can compile only a single
- * compilation unit. (A "compilation unit" is the characters stored in a
- * ".java" file.)
- * <p>
- * Opposed to a normal ".java" file, you can declare multiple public classes
- * here.
- * <p>
- * To set up a {@link SimpleCompiler} object, proceed as follows:
- * <ol>
- *   <li>
- *   Create the {@link SimpleCompiler} using {@link #SimpleCompiler()}
- *   <li>
- *   Optionally set an alternate parent class loader through
- *   {@link #setParentClassLoader(ClassLoader)}.
- *   <li>
- *   Call any of the {@link org.codehaus.janino.Cookable#cook(Scanner)} methods to scan,
- *   parse, compile and load the compilation unit into the JVM.
- * </ol>
- * Alternatively, a number of "convenience constructors" exist that execute the steps described
- * above instantly.
- */
-public class SimpleCompiler extends Cookable {
-    private final static boolean DEBUG = false;
-
-    private ClassLoader parentClassLoader = Thread.currentThread().getContextClassLoader();
-    private Class[]     optionalAuxiliaryClasses = null;
-
-    // Set when "cook()"ing.
-    private AuxiliaryClassLoader classLoader = null;
-    private IClassLoader         iClassLoader = null;
-
-    private ClassLoader result = null;
-
-    public static void main(String[] args) throws Exception {
-        if (args.length >= 1 && args[0].equals("-help")) {
-            System.out.println("Usage:");
-            System.out.println("    org.codehaus.janino.SimpleCompiler <source-file> <class-name> { <argument> }");
-            System.out.println("Reads a compilation unit from the given <source-file> and invokes method");
-            System.out.println("\"public static void main(String[])\" of class <class-name>, passing the.");
-            System.out.println("given <argument>s.");
-            System.exit(1);
-        }
-        
-        if (args.length < 2) {
-            System.err.println("Source file and/or class name missing; try \"-help\".");
-            System.exit(1);
-        }
-
-        // Get source file.
-        String sourceFileName = args[0];
-
-        // Get class name.
-        String className = args[1];
-
-        // Get arguments.
-        String[] arguments = new String[args.length - 2];
-        System.arraycopy(args, 2, arguments, 0, arguments.length);
-
-        // Compile the source file.
-        ClassLoader cl = new SimpleCompiler(sourceFileName, new FileInputStream(sourceFileName)).getClassLoader();
-
-        // Load the class.
-        Class c = cl.loadClass(className);
-
-        // Invoke the "public static main(String[])" method.
-        Method m = c.getMethod("main", new Class[] { String[].class });
-        m.invoke(null, new Object[] { arguments });
-    }
-
-    /**
-     * Equivalent to<pre>
-     * SimpleCompiler sc = new SimpleCompiler();
-     * sc.cook(optionalFileName, in);</pre>
-     *
-     * @see #SimpleCompiler()
-     * @see Cookable#cook(String, Reader)
-     */
-    public SimpleCompiler(
-        String optionalFileName,
-        Reader in
-    ) throws IOException, Scanner.ScanException, Parser.ParseException, CompileException {
-        this.cook(optionalFileName, in);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * SimpleCompiler sc = new SimpleCompiler();
-     * sc.cook(optionalFileName, is);</pre>
-     *
-     * @see #SimpleCompiler()
-     * @see Cookable#cook(String, InputStream)
-     */
-    public SimpleCompiler(
-        String      optionalFileName,
-        InputStream is
-    ) throws IOException, Scanner.ScanException, Parser.ParseException, CompileException {
-        this.cook(optionalFileName, is);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * SimpleCompiler sc = new SimpleCompiler();
-     * sc.cook(fileName);</pre>
-     *
-     * @see #SimpleCompiler()
-     * @see Cookable#cookFile(String)
-     */
-    public SimpleCompiler(
-        String fileName
-    ) throws IOException, Scanner.ScanException, Parser.ParseException, CompileException {
-        this.cookFile(fileName);
-    }
-
-    /**
-     * Equivalent to<pre>
-     * SimpleCompiler sc = new SimpleCompiler();
-     * sc.setParentClassLoader(optionalParentClassLoader);
-     * sc.cook(scanner);</pre>
-     *
-     * @see #SimpleCompiler()
-     * @see #setParentClassLoader(ClassLoader)
-     * @see Cookable#cook(Scanner)
-     */
-    public SimpleCompiler(
-        Scanner     scanner,
-        ClassLoader optionalParentClassLoader
-    ) throws IOException, Scanner.ScanException, Parser.ParseException, CompileException {
-        this.setParentClassLoader(optionalParentClassLoader);
-        this.cook(scanner);
-    }
-
-    public SimpleCompiler() {}
-
-    /**
-     * The "parent class loader" is used to load referenced classes. Useful values are:
-     * <table border="1"><tr>
-     *   <td><code>System.getSystemClassLoader()</code></td>
-     *   <td>The running JVM's class path</td>
-     * </tr><tr>
-     *   <td><code>Thread.currentThread().getContextClassLoader()</code> or <code>null</code></td>
-     *   <td>The class loader effective for the invoking thread</td>
-     * </tr><tr>
-     *   <td>{@link #BOOT_CLASS_LOADER}</td>
-     *   <td>The running JVM's boot class path</td>
-     * </tr></table>
-     * The parent class loader defaults to the current thread's context class loader.
-     */
-    public void setParentClassLoader(ClassLoader optionalParentClassLoader) {
-        this.setParentClassLoader(optionalParentClassLoader, null);
-    }
-
-    /**
-     * A {@link ClassLoader} that finds the classes on the JVM's <i>boot class path</i> (e.g.
-     * <code>java.io.*</code>), but not the classes on the JVM's <i>class path</i>.
-     */
-    public static final ClassLoader BOOT_CLASS_LOADER = new ClassLoader(null) {};
-
-    /**
-     * Allow references to the classes loaded through this parent class loader
-     * (@see {@link #setParentClassLoader(ClassLoader)}), plus the extra
-     * <code>auxiliaryClasses</code>.
-     * <p>
-     * Notice that the <code>auxiliaryClasses</code> must either be loadable through the
-     * <code>optionalParentClassLoader</code> (in which case they have no effect), or
-     * <b>no class with the same name</b> must be loadable through the
-     * <code>optionalParentClassLoader</code>.
-     */
-    public void setParentClassLoader(ClassLoader optionalParentClassLoader, Class[] auxiliaryClasses) {
-        assertNotCooked();
-        this.parentClassLoader = (
-            optionalParentClassLoader != null
-            ? optionalParentClassLoader
-            : Thread.currentThread().getContextClassLoader()
-        );
-        this.optionalAuxiliaryClasses = auxiliaryClasses;
-    }
-
-    public void cook(Scanner scanner)
-    throws CompileException, Parser.ParseException, Scanner.ScanException, IOException {
-        this.setUpClassLoaders();
-
-        // Parse the compilation unit.
-        Java.CompilationUnit compilationUnit = new Parser(scanner).parseCompilationUnit();
-
-        // Compile the classes and load them.
-        this.compileToClassLoader(
-            compilationUnit,
-            DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION
-        );
-    }
-    
-    /**
-     * Cook this compilation unit directly. 
-     *  See {@link Cookable#cook}
-     */
-    public void cook(Java.CompilationUnit compilationUnit) throws CompileException {
-        this.setUpClassLoaders();
-
-        // Compile the classes and load them.
-        this.compileToClassLoader(
-            compilationUnit,
-            DebuggingInformation.DEFAULT_DEBUGGING_INFORMATION
-        );
-    }
-
-    /**
-     * Initializes {@link #classLoader} and {@link #iClassLoader} from the configured
-     * {@link #parentClassLoader} and {@link #optionalAuxiliaryClasses}. These are needed by
-     * {@link #classToType(Location, Class)} and friends which are used when creating the AST.
-     */
-    protected final void setUpClassLoaders() {
-        assertNotCooked();
-
-        // Set up the ClassLoader for the compilation and the loading.
-        this.classLoader = new AuxiliaryClassLoader(this.parentClassLoader);
-        if (this.optionalAuxiliaryClasses != null) {
-            for (int i = 0; i < this.optionalAuxiliaryClasses.length; ++i) {
-                this.classLoader.addAuxiliaryClass(this.optionalAuxiliaryClasses[i]);
-            }
-        }
-
-        this.iClassLoader = new ClassLoaderIClassLoader(this.classLoader);
-    }
-
-    /**
-     * A {@link ClassLoader} that intermixes that classes loaded by its parent with a map of
-     * "auxiliary classes".
-     */
-    private static final class AuxiliaryClassLoader extends ClassLoader {
-        private final Map auxiliaryClasses = new HashMap(); // String name => Class
-
-        private AuxiliaryClassLoader(ClassLoader parent) {
-            super(parent);
-        }
-
-        protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
-            Class c = (Class) this.auxiliaryClasses.get(name);
-            if (c != null) return c;
-        
-            return super.loadClass(name, resolve);
-        }
-
-        private void addAuxiliaryClass(Class c) {
-            if (this.auxiliaryClasses.containsKey(c.getName())) return;
-
-            // Check whether the auxiliary class is conflicting with this ClassLoader.
-            try {
-                Class c2 = super.loadClass(c.getName(), false);
-                if (c2 != c) throw new RuntimeException("Trying to add an auxiliary class \"" + c.getName() + "\" while another class with the same name is already loaded");
-            } catch (ClassNotFoundException ex) {
-                ;
-            }
-
-            this.auxiliaryClasses.put(c.getName(), c);
-
-            {
-                Class sc = c.getSuperclass();
-                if (sc != null) this.addAuxiliaryClass(sc);
-            }
-
-            {
-                Class[] ifs = c.getInterfaces();
-                for (int i = 0; i < ifs.length; ++i) this.addAuxiliaryClass(ifs[i]);
-            }
-        }
-
-        public boolean equals(Object o) {
-            if (!(o instanceof AuxiliaryClassLoader)) return false;
-            AuxiliaryClassLoader that = (AuxiliaryClassLoader) o;
-
-            {
-                final ClassLoader parentOfThis = this.getParent();
-                final ClassLoader parentOfThat = that.getParent();
-                if (parentOfThis == null ? parentOfThat != null : !parentOfThis.equals(parentOfThat)) return false;
-            }
-
-            return this.auxiliaryClasses.equals(that.auxiliaryClasses);
-        }
-
-        public int hashCode() {
-            ClassLoader parent = this.getParent();
-            return (parent == null ? 0 : parent.hashCode()) ^ this.auxiliaryClasses.hashCode();
-        }
-    }
-
-    /**
-     * Returns a {@link ClassLoader} object through which the previously compiled classes can
-     * be accessed. This {@link ClassLoader} can be used for subsequent calls to
-     * {@link #SimpleCompiler(Scanner, ClassLoader)} in order to compile compilation units that
-     * use types (e.g. declare derived types) declared in the previous one.
-     * <p>
-     * This method must only be called after {@link #cook(Scanner)}.
-     * <p>
-     * This method must not be called for instances of derived classes.
-     */
-    public ClassLoader getClassLoader() {
-        if (this.getClass() != SimpleCompiler.class) throw new IllegalStateException("Must not be called on derived instances");
-        if (this.result == null) throw new IllegalStateException("Must only be called after \"cook()\"");
-        return this.result;
-    }
-
-    /**
-     * Two {@link SimpleCompiler}s are regarded equal iff
-     * <ul>
-     *   <li>Both are objects of the same class (e.g. both are {@link ScriptEvaluator}s)
-     *   <li>Both generated functionally equal classes as seen by {@link ByteArrayClassLoader#equals(Object)}
-     * </ul>
-     */
-    public boolean equals(Object o) {
-        if (!(o instanceof SimpleCompiler)) return false;
-        SimpleCompiler that = (SimpleCompiler) o;
-        if (this.getClass() != that.getClass()) return false;
-        if (this.result == null || that.result == null) throw new IllegalStateException("Equality can only be checked after cooking");
-        return this.result.equals(that.result);
-    }
-
-    public int hashCode() {
-        return this.classLoader.hashCode();
-    }
-
-    /**
-     * Wrap a reflection {@link Class} in a {@link Java.Type} object.
-     */
-    protected Java.Type classToType(
-        Location    location,
-        final Class optionalClass
-    ) {
-        if (optionalClass == null) return null;
-
-        this.classLoader.addAuxiliaryClass(optionalClass);
-
-        IClass iClass;
-        try {
-            iClass = this.iClassLoader.loadIClass(Descriptor.fromClassName(optionalClass.getName()));
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException("Loading IClass \"" + optionalClass.getName() + "\": " + ex);
-        }
-        if (iClass == null) throw new RuntimeException("Cannot load class \"" + optionalClass.getName() + "\" through the given ClassLoader");
-
-        return new Java.SimpleType(location, iClass);
-    }
-
-    /**
-     * Convert an array of {@link Class}es into an array of{@link Java.Type}s.
-     */
-    protected Java.Type[] classesToTypes(
-        Location location,
-        Class[]  classes
-    ) {
-        Java.Type[] types = new Java.Type[classes.length];
-        for (int i = 0; i < classes.length; ++i) {
-            types[i] = this.classToType(location, classes[i]);
-        }
-        return types;
-    }
-
-    /**
-     * Compile the given compilation unit. (A "compilation unit" is typically the contents
-     * of a Java<sup>TM</sup> source file.)
-     * 
-     * @param compilationUnit The parsed compilation unit
-     * @param debuggingInformation What kind of debugging information to generate in the class file
-     * @return The {@link ClassLoader} into which the compiled classes were defined
-     * @throws CompileException
-     */
-    protected final ClassLoader compileToClassLoader(
-        Java.CompilationUnit compilationUnit,
-        EnumeratorSet        debuggingInformation
-    ) throws CompileException {
-        if (SimpleCompiler.DEBUG) {
-            UnparseVisitor.unparse(compilationUnit, new OutputStreamWriter(System.out));
-        }
-
-        // Compile compilation unit to class files.
-        ClassFile[] classFiles = new UnitCompiler(
-            compilationUnit,
-            this.iClassLoader
-        ).compileUnit(debuggingInformation);
-
-        // Convert the class files to bytes and store them in a Map.
-        Map classes = new HashMap(); // String className => byte[] data
-        for (int i = 0; i < classFiles.length; ++i) {
-            ClassFile cf = classFiles[i];
-            classes.put(cf.getThisClassName(), cf.toByteArray());
-        }
-
-        // Disassemble all generated classes (for debugging).
-        if (SimpleCompiler.DEBUG) {
-            for (Iterator it = classes.entrySet().iterator(); it.hasNext();) {
-                Map.Entry me = (Map.Entry) it.next();
-                String className = (String) me.getKey();
-                byte[] bytecode = (byte[]) me.getValue();
-                System.out.println("*** Disassembly of class \"" + className + "\":");
-                try {
-                    new Disassembler().disasm(new ByteArrayInputStream(bytecode));
-                    System.out.flush();
-                } catch (IOException ex) {
-                    throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
-                }
-            }
-        }
-
-        // Create a ClassLoader that loads the generated classes.
-        this.result = new ByteArrayClassLoader(
-            classes,         // classes
-            this.classLoader // parent
-        );
-        return this.result;
-    }
-
-    /**
-     * Throw an {@link IllegalStateException} if this {@link Cookable} is already cooked.
-     */
-    protected void assertNotCooked() {
-        if (this.classLoader != null) throw new IllegalStateException("Already cooked");
-    }
-}
diff --git a/src/org/codehaus/janino/UnicodeUnescapeException.java b/src/org/codehaus/janino/UnicodeUnescapeException.java
deleted file mode 100644
index 366419c..0000000
--- a/src/org/codehaus/janino/UnicodeUnescapeException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-/**
- * Represents a problem that occurred while unescaping a unicode escape
- * sequence through a {@link org.codehaus.janino.UnicodeUnescapeReader}.
- */
-public class UnicodeUnescapeException extends RuntimeException {
-    public UnicodeUnescapeException(String message) {
-        super(message);
-    }
-}
diff --git a/src/org/codehaus/janino/UnicodeUnescapeReader.java b/src/org/codehaus/janino/UnicodeUnescapeReader.java
deleted file mode 100644
index 91e4bc8..0000000
--- a/src/org/codehaus/janino/UnicodeUnescapeReader.java
+++ /dev/null
@@ -1,136 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-
-/**
- * A {@link FilterReader} that unescapes the "Unicode Escapes"
- * as described in
- * <a href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#100850">the
- * Java Language Specification, 2nd edition</a>.
- * <p>
- * Notice that it is possible to formulate invalid escape sequences, e.g.
- * "\u123g" ("g" is not a valid hex character). This is handled by
- * throwing a {@link java.lang.RuntimeException}-derived
- * {@link org.codehaus.janino.UnicodeUnescapeException}.
- */
-public class UnicodeUnescapeReader extends FilterReader {
-
-    /**
-     * @param in
-     */
-    public UnicodeUnescapeReader(Reader in) {
-        super(in);
-    }
-
-    /**
-     * Override {@link FilterReader#read()}.
-     * 
-     * @throws UnicodeUnescapeException Invalid escape sequence encountered
-     */
-    public int read() throws IOException {
-        int c;
-
-        // Read next character.
-        if (this.unreadChar == -1) {
-            c = this.in.read();
-        } else {
-            c = this.unreadChar;
-            this.unreadChar = -1;
-        }
-
-        // Check for backslash-u escape sequence, preceeded with an even number
-        // of backslashes.
-        if (c != '\\' || this.oddPrecedingBackslashes) {
-            this.oddPrecedingBackslashes = false;
-            return c;
-        }
-
-        // Read one character ahead and check if it is a "u".
-        c = this.in.read();
-        if (c != 'u') {
-            this.unreadChar = c;
-            this.oddPrecedingBackslashes = true;
-            return '\\';
-        }
-
-        // Skip redundant "u"s.
-        do {
-            c = this.in.read();
-            if (c == -1) throw new UnicodeUnescapeException("Incomplete escape sequence");
-        } while (c == 'u');
-
-        // Decode escape sequence.
-        char[] ca = new char[4];
-        ca[0] = (char) c;
-        if (this.in.read(ca, 1, 3) != 3) throw new UnicodeUnescapeException("Incomplete escape sequence");
-        try {
-            return 0xffff & Integer.parseInt(new String(ca), 16);
-        } catch (NumberFormatException ex) {
-            throw new UnicodeUnescapeException("Invalid escape sequence \"\\u" + new String(ca) + "\"");
-        }
-    }
-
-    /**
-     * Override {@link FilterReader#read(char[], int, int)}.
-     */
-    public int read(char[] cbuf, int off, int len) throws IOException {
-        if (len == 0) return 0;
-        int res = 0;
-        do {
-            int c = this.read();
-            if (c == -1) break;
-            cbuf[off++] = (char) c;
-        } while (++res < len);
-        return res == 0 ? -1 : res;
-    }
-
-    /**
-     * Simple unit testing.
-     */
-    public static void main(String[] args) throws IOException {
-        Reader r = new UnicodeUnescapeReader(new StringReader(args[0]));
-        for (;;) {
-            int c = r.read();
-            if (c == -1) break;
-            System.out.print((char) c);
-        }
-        System.out.println();
-    }
-
-    private int     unreadChar = -1; // -1 == none
-    private boolean oddPrecedingBackslashes = false;
-}
diff --git a/src/org/codehaus/janino/UnitCompiler.java b/src/org/codehaus/janino/UnitCompiler.java
deleted file mode 100644
index 8de3dbc..0000000
--- a/src/org/codehaus/janino/UnitCompiler.java
+++ /dev/null
@@ -1,8378 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-import org.codehaus.janino.IClass.IField;
-import org.codehaus.janino.IClass.IInvocable;
-import org.codehaus.janino.IClass.IMethod;
-import org.codehaus.janino.Java.AlternateConstructorInvocation;
-import org.codehaus.janino.Java.Block;
-import org.codehaus.janino.Java.BlockStatement;
-import org.codehaus.janino.Java.BreakStatement;
-import org.codehaus.janino.Java.CatchClause;
-import org.codehaus.janino.Java.ConstructorDeclarator;
-import org.codehaus.janino.Java.ConstructorInvocation;
-import org.codehaus.janino.Java.ContinueStatement;
-import org.codehaus.janino.Java.DoStatement;
-import org.codehaus.janino.Java.EmptyStatement;
-import org.codehaus.janino.Java.ExpressionStatement;
-import org.codehaus.janino.Java.FieldAccess;
-import org.codehaus.janino.Java.FieldDeclaration;
-import org.codehaus.janino.Java.ForStatement;
-import org.codehaus.janino.Java.FunctionDeclarator;
-import org.codehaus.janino.Java.IfStatement;
-import org.codehaus.janino.Java.Initializer;
-import org.codehaus.janino.Java.Invocation;
-import org.codehaus.janino.Java.LabeledStatement;
-import org.codehaus.janino.Java.LocalClassDeclarationStatement;
-import org.codehaus.janino.Java.LocalVariable;
-import org.codehaus.janino.Java.LocalVariableDeclarationStatement;
-import org.codehaus.janino.Java.Locatable;
-import org.codehaus.janino.Java.ReturnStatement;
-import org.codehaus.janino.Java.Rvalue;
-import org.codehaus.janino.Java.SimpleType;
-import org.codehaus.janino.Java.Statement;
-import org.codehaus.janino.Java.SuperConstructorInvocation;
-import org.codehaus.janino.Java.SuperclassFieldAccessExpression;
-import org.codehaus.janino.Java.SwitchStatement;
-import org.codehaus.janino.Java.SynchronizedStatement;
-import org.codehaus.janino.Java.ThrowStatement;
-import org.codehaus.janino.Java.TryStatement;
-import org.codehaus.janino.Java.WhileStatement;
-import org.codehaus.janino.Java.CompilationUnit.ImportDeclaration;
-import org.codehaus.janino.Java.CompilationUnit.SingleStaticImportDeclaration;
-import org.codehaus.janino.Java.CompilationUnit.SingleTypeImportDeclaration;
-import org.codehaus.janino.Java.CompilationUnit.StaticImportOnDemandDeclaration;
-import org.codehaus.janino.Java.CompilationUnit.TypeImportOnDemandDeclaration;
-import org.codehaus.janino.Visitor.BlockStatementVisitor;
-import org.codehaus.janino.Visitor.ImportVisitor;
-import org.codehaus.janino.util.ClassFile;
-import org.codehaus.janino.util.enumerator.EnumeratorSet;
-
-/**
- * This class actually implements the Java<sup>TM</sup> compiler. It is
- * associated with exactly one compilation unit which it compiles.
- */
-public class UnitCompiler {
-    private static final boolean DEBUG = false;
-
-    /**
-     * This constant determines the number of operands up to which the
-     *
-     *      a.concat(b).concat(c)
-     *
-     * strategy is used to implement string concatenation. For more operands, the
-     *
-     *      new StringBuffer(a).append(b).append(c).append(d).toString()
-     *
-     * strategy is chosen.
-     *
-     * A very good article from Tom Gibara
-     *
-     *    http://www.tomgibara.com/janino-evaluation/string-concatenation-benchmark
-     *
-     * analyzes the impact of this decision and recommends a value of three.
-     */
-    private static final int STRING_CONCAT_LIMIT = 3;
-
-    public UnitCompiler(
-        Java.CompilationUnit compilationUnit,
-        IClassLoader         iClassLoader
-    ) throws CompileException {
-        this.compilationUnit = compilationUnit;
-        this.iClassLoader    = iClassLoader;
-
-        try {
-            if (iClassLoader.loadIClass(Descriptor.STRING_BUILDER) != null) {
-                this.isStringBuilderAvailable = true;
-            } else
-            if (iClassLoader.loadIClass(Descriptor.STRING_BUFFER) != null) {
-                this.isStringBuilderAvailable = false;
-            } else
-            {
-                throw new RuntimeException("SNO: Could neither load \"StringBuffer\" nor \"StringBuilder\"");
-            }
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException("SNO: Error loading \"StringBuffer\" or \"StringBuilder\": " + ex.getMessage());
-        }
-
-        // Compile non-static import declarations. (Must be done here in the constructor and not
-        // down in "compileUnit()" because otherwise "resolve()" cannot resolve type names.)
-        this.typeImportsOnDemand = new ArrayList();
-        this.typeImportsOnDemand.add(new String[] { "java", "lang" });
-        for (Iterator it = this.compilationUnit.importDeclarations.iterator(); it.hasNext();) {
-            ImportDeclaration id = (ImportDeclaration) it.next();
-            class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-            try {
-                id.accept(new ImportVisitor() {
-                    public void visitSingleTypeImportDeclaration(SingleTypeImportDeclaration stid)          { try { UnitCompiler.this.import2(stid);  } catch (CompileException e) { throw new UCE(e); } }
-                    public void visitTypeImportOnDemandDeclaration(TypeImportOnDemandDeclaration tiodd)     {       UnitCompiler.this.import2(tiodd);                                                    }
-                    public void visitSingleStaticImportDeclaration(SingleStaticImportDeclaration ssid)      {}
-                    public void visitStaticImportOnDemandDeclaration(StaticImportOnDemandDeclaration siodd) {}
-                });
-            } catch (UCE uce) { throw uce.ce; }
-        }
-    }
-
-    private void import2(SingleTypeImportDeclaration stid) throws CompileException {
-        String[] ids = stid.identifiers;
-        String name = last(ids);
-
-        String[] prev = (String[]) UnitCompiler.this.singleTypeImports.put(name, ids);
-
-        // Check for re-import of same name.
-        if (prev != null && !Arrays.equals(prev, ids)) {
-            this.compileError("Class \"" + name + "\" was previously imported as \"" + Java.join(prev, ".") + "\", now as \"" + Java.join(ids, ".") + "\"");
-        }
-    }
-    private void import2(TypeImportOnDemandDeclaration tiodd) {
-
-        // Duplicate type-imports-on-demand are not an error, so no checks here.
-        UnitCompiler.this.typeImportsOnDemand.add(tiodd.identifiers);
-    }
-    private void import2(SingleStaticImportDeclaration ssid) throws CompileException {
-        String name = last(ssid.identifiers);
-        Object importedObject;
-
-        FIND_IMPORTED_OBJECT:
-        {
-
-            // Type?
-            {
-                IClass iClass = this.loadFullyQualifiedClass(ssid.identifiers);
-                if (iClass != null) {
-                    importedObject = iClass;
-                    break FIND_IMPORTED_OBJECT;
-                }
-            }
-    
-            String[] typeName = allButLast(ssid.identifiers);
-            IClass iClass = this.loadFullyQualifiedClass(typeName);
-            if (iClass == null) {
-                this.compileError("Could not load \"" + Java.join(typeName, ".") + "\"", ssid.getLocation());
-                return;
-            }
-    
-            // Static field?
-            IField[] flds = iClass.getDeclaredIFields();
-            for (int i = 0; i < flds.length; ++i) {
-                IField iField = flds[i];
-                if (iField.getName().equals(name)) {
-                    if (!iField.isStatic()) {
-                        this.compileError("Filed \"" + name + "\" of \"" + Java.join(typeName, ".") + "\" must be static", ssid.getLocation());
-                    }
-                    importedObject = iField;
-                    break FIND_IMPORTED_OBJECT;
-                }
-            }
-    
-            // Static method?
-            IMethod[] ms = iClass.getDeclaredIMethods(name);
-            if (ms.length > 0) {
-                importedObject = Arrays.asList(ms);
-                break FIND_IMPORTED_OBJECT;
-            }
-
-            // Give up.
-            this.compileError("\"" + Java.join(typeName, ".") + "\" has no static member \"" + name + "\"", ssid.getLocation());
-            return;
-        }
-
-        Object prev = this.singleStaticImports.put(name, importedObject);
-
-        // Check for re-import of same name.
-        if (prev != null && !prev.equals(importedObject)) {
-            UnitCompiler.this.compileError("\"" + name + "\" was previously statically imported as \"" + prev.toString() + "\", now as \"" + importedObject.toString() + "\"", ssid.getLocation());
-        }
-    }
-    private void import2(StaticImportOnDemandDeclaration siodd) throws CompileException {
-        IClass iClass = this.loadFullyQualifiedClass(siodd.identifiers);
-        if (iClass == null) {
-            this.compileError("Could not load \"" + Java.join(siodd.identifiers, ".") + "\"", siodd.getLocation());
-            return;
-        }
-        UnitCompiler.this.staticImportsOnDemand.add(iClass);
-    }
-
-    /**
-     * Generates an array of {@link ClassFile} objects which represent the classes and
-     * interfaces defined in the compilation unit.
-     */
-    public ClassFile[] compileUnit(
-        EnumeratorSet debuggingInformation
-    ) throws CompileException {
-
-        // Compile static import declarations.
-        for (Iterator it = this.compilationUnit.importDeclarations.iterator(); it.hasNext();) {
-            ImportDeclaration id = (ImportDeclaration) it.next();
-            class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-            try {
-                id.accept(new ImportVisitor() {
-                    public void visitSingleTypeImportDeclaration(SingleTypeImportDeclaration stid)          {}
-                    public void visitTypeImportOnDemandDeclaration(TypeImportOnDemandDeclaration tiodd)     {}
-                    public void visitSingleStaticImportDeclaration(SingleStaticImportDeclaration ssid)      { try { UnitCompiler.this.import2(ssid);  } catch (CompileException e) { throw new UCE(e); } }
-                    public void visitStaticImportOnDemandDeclaration(StaticImportOnDemandDeclaration siodd) { try { UnitCompiler.this.import2(siodd); } catch (CompileException e) { throw new UCE(e); } }
-                });
-            } catch (UCE uce) { throw uce.ce; }
-        }
-
-        this.generatedClassFiles  = new ArrayList();
-        this.debuggingInformation = debuggingInformation;
-
-        for (Iterator it = this.compilationUnit.packageMemberTypeDeclarations.iterator(); it.hasNext();) {
-            UnitCompiler.this.compile((Java.PackageMemberTypeDeclaration) it.next());
-        }
-
-        if (this.compileErrorCount > 0) throw new CompileException(this.compileErrorCount + " error(s) while compiling unit \"" + this.compilationUnit.optionalFileName + "\"", null);
-
-        List l = this.generatedClassFiles;
-        return (ClassFile[]) l.toArray(new ClassFile[l.size()]);
-    }
-
-    // ------------ TypeDeclaration.compile() -------------
-
-    private void compile(Java.TypeDeclaration td) throws CompileException {
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.TypeDeclarationVisitor tdv = new Visitor.TypeDeclarationVisitor() {
-            public void visitAnonymousClassDeclaration        (Java.AnonymousClassDeclaration acd)          { try { UnitCompiler.this.compile2(acd                                     ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalClassDeclaration            (Java.LocalClassDeclaration lcd)              { try { UnitCompiler.this.compile2(lcd                                     ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitPackageMemberClassDeclaration    (Java.PackageMemberClassDeclaration pmcd)     { try { UnitCompiler.this.compile2((Java.PackageMemberTypeDeclaration) pmcd); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitMemberInterfaceDeclaration       (Java.MemberInterfaceDeclaration mid)         { try { UnitCompiler.this.compile2(mid                                     ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) { try { UnitCompiler.this.compile2((Java.PackageMemberTypeDeclaration) pmid); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitMemberClassDeclaration           (Java.MemberClassDeclaration mcd)             { try { UnitCompiler.this.compile2(mcd                                     ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            td.accept(tdv);
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    public void compile2(Java.PackageMemberTypeDeclaration pmtd) throws CompileException {
-        Java.CompilationUnit declaringCompilationUnit = pmtd.getDeclaringCompilationUnit();
-
-        // Check for conflict with single-type-import (7.6).
-        {
-            String[] ss = this.getSingleTypeImport(pmtd.getName());
-            if (ss != null) this.compileError("Package member type declaration \"" + pmtd.getName() + "\" conflicts with single-type-import \"" + Java.join(ss, ".") + "\"", pmtd.getLocation());
-        }
-
-        // Check for redefinition within compilation unit (7.6).
-        {
-            Java.PackageMemberTypeDeclaration otherPMTD = declaringCompilationUnit.getPackageMemberTypeDeclaration(pmtd.getName());
-            if (otherPMTD != pmtd) this.compileError("Redeclaration of type \"" + pmtd.getName() + "\", previously declared in " + otherPMTD.getLocation(), pmtd.getLocation());
-        }
-
-        if (pmtd instanceof Java.NamedClassDeclaration) {
-            this.compile2((Java.NamedClassDeclaration) pmtd);
-        } else
-        if (pmtd instanceof Java.InterfaceDeclaration) {
-            this.compile2((Java.InterfaceDeclaration) pmtd);
-        } else
-        {
-            throw new RuntimeException("PMTD of unexpected type " + pmtd.getClass().getName());
-        }
-    }
-
-    public void compile2(Java.ClassDeclaration cd) throws CompileException {
-        IClass iClass = this.resolve(cd);
-
-        // Check that all methods are implemented.
-        if ((cd.modifiers & Mod.ABSTRACT) == 0) {
-            IMethod[] ms = iClass.getIMethods();
-            for (int i = 0; i <  ms.length; ++i) {
-                if (ms[i].isAbstract()) this.compileError("Non-abstract class \"" + iClass + "\" must implement method \"" + ms[i] + "\"", cd.getLocation());
-            }
-        }
-
-        // Create "ClassFile" object.
-        ClassFile cf = new ClassFile(
-            (short) (cd.modifiers | Mod.SUPER),           // accessFlags
-            iClass.getDescriptor(),                       // thisClassFD
-            iClass.getSuperclass().getDescriptor(),       // superClassFD
-            IClass.getDescriptors(iClass.getInterfaces()) // interfaceFDs
-        );
-
-        // Add InnerClasses attribute entry for this class declaration.
-        if (cd.getEnclosingScope() instanceof Java.CompilationUnit) {
-            ;
-        } else
-        if (cd.getEnclosingScope() instanceof Java.Block) {
-            short innerClassInfoIndex = cf.addConstantClassInfo(iClass.getDescriptor());
-            short innerNameIndex = (
-                this instanceof Java.NamedTypeDeclaration ?
-                cf.addConstantUtf8Info(((Java.NamedTypeDeclaration) this).getName()) :
-                (short) 0
-            );
-            cf.addInnerClassesAttributeEntry(new ClassFile.InnerClassesAttribute.Entry(
-                innerClassInfoIndex, // innerClassInfoIndex
-                (short) 0,           // outerClassInfoIndex
-                innerNameIndex,      // innerNameIndex
-                cd.modifiers         // innerClassAccessFlags
-            ));
-        } else
-        if (cd.getEnclosingScope() instanceof Java.AbstractTypeDeclaration) {
-            short innerClassInfoIndex = cf.addConstantClassInfo(iClass.getDescriptor());
-            short outerClassInfoIndex = cf.addConstantClassInfo(this.resolve(((Java.AbstractTypeDeclaration) cd.getEnclosingScope())).getDescriptor());
-            short innerNameIndex      = cf.addConstantUtf8Info(((Java.MemberTypeDeclaration) cd).getName());
-            cf.addInnerClassesAttributeEntry(new ClassFile.InnerClassesAttribute.Entry(
-                innerClassInfoIndex, // innerClassInfoIndex
-                outerClassInfoIndex, // outerClassInfoIndex
-                innerNameIndex,      // innerNameIndex
-                cd.modifiers         // innerClassAccessFlags
-            ));
-        }
-
-        // Set "SourceFile" attribute.
-        if (this.debuggingInformation.contains(DebuggingInformation.SOURCE)) {
-            String sourceFileName;
-            {
-                String s = cd.getLocation().getFileName();
-                if (s != null) {
-                    sourceFileName = new File(s).getName();
-                } else if (cd instanceof Java.NamedTypeDeclaration) {
-                    sourceFileName = ((Java.NamedTypeDeclaration) cd).getName() + ".java";
-                } else {
-                    sourceFileName = "ANONYMOUS.java";
-                }
-            }
-            cf.addSourceFileAttribute(sourceFileName);
-        }
-
-        // Add "Deprecated" attribute (JVMS 4.7.10)
-        if (cd instanceof Java.DocCommentable) {
-            if (((Java.DocCommentable) cd).hasDeprecatedDocTag()) cf.addDeprecatedAttribute();
-        }
-
-        // Optional: Generate and compile class initialization method.
-        {
-            Java.Block b = new Java.Block(cd.getLocation());
-            for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
-                Java.TypeBodyDeclaration tbd = (Java.TypeBodyDeclaration) it.next();
-                if (tbd.isStatic()) b.addButDontEncloseStatement((Java.BlockStatement) tbd);
-            }
-
-            this.maybeCreateInitMethod(cd, cf, b);
-        }
-
-        this.compileDeclaredMethods(cd, cf);
-
-        
-        // Compile declared constructors.
-        // As a side effect of compiling methods and constructors, synthetic "class-dollar"
-        // methods (which implement class literals) are generated on-the fly. 
-        // We need to note how many we have here so we can compile the extras.
-        int declaredMethodCount = cd.declaredMethods.size();
-        {
-            int syntheticFieldCount = cd.syntheticFields.size();
-            Java.ConstructorDeclarator[] cds = cd.getConstructors();
-            for (int i = 0; i < cds.length; ++i) {
-                this.compile(cds[i], cf);
-                if (syntheticFieldCount != cd.syntheticFields.size()) throw new RuntimeException("SNO: Compilation of constructor \"" + cds[i] + "\" (" + cds[i].getLocation() +") added synthetic fields!?");
-            }
-        }
-
-        // A side effect of this call may create synthetic functions to access
-        // protected parent variables
-        this.compileDeclaredMemberTypes(cd, cf);
-
-        // Compile the aforementioned extras.
-        this.compileDeclaredMethods(cd, cf, declaredMethodCount);
-
-        // Class and instance variables.
-        for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
-            Java.TypeBodyDeclaration tbd = (Java.TypeBodyDeclaration) it.next();
-            if (!(tbd instanceof Java.FieldDeclaration)) continue;
-            this.addFields((Java.FieldDeclaration) tbd, cf);
-        }
-
-        // Synthetic fields.
-        for (Iterator it = cd.syntheticFields.values().iterator(); it.hasNext();) {
-            IClass.IField f = (IClass.IField) it.next();
-            cf.addFieldInfo(
-                Mod.PACKAGE,                 // modifiers,
-                f.getName(),                 // fieldName,
-                f.getType().getDescriptor(), // fieldTypeFD,
-                null                         // optionalConstantValue
-            );
-        }
-
-
-        // Add the generated class file to a thread-local store.
-        this.generatedClassFiles.add(cf);
-    }
-
-    /**
-     * Create {@link ClassFile.FieldInfo}s for all fields declared by the
-     * given {@link Java.FieldDeclaration}.
-     */
-    private void addFields(Java.FieldDeclaration fd, ClassFile cf) throws CompileException {
-        for (int j = 0; j < fd.variableDeclarators.length; ++j) {
-            Java.VariableDeclarator vd = fd.variableDeclarators[j];
-            Java.Type type = fd.type;
-            for (int k = 0; k < vd.brackets; ++k) type = new Java.ArrayType(type);
-
-            Object ocv = null;
-            if (
-                (fd.modifiers & Mod.FINAL) != 0 &&
-                vd.optionalInitializer != null
-            ) {
-                if (vd.optionalInitializer instanceof Java.Rvalue) ocv = this.getConstantValue((Java.Rvalue) vd.optionalInitializer);
-                if (ocv == Java.Rvalue.CONSTANT_VALUE_NULL) ocv = null;
-            }
-
-            ClassFile.FieldInfo fi;
-            if (Mod.isPrivateAccess(fd.modifiers)) {
-
-                // To make the private field accessible for enclosing types, enclosed types and types
-                // enclosed by the same type, it is modified as follows:
-                //  + Access is changed from PRIVATE to PACKAGE
-                fi = cf.addFieldInfo(
-                    Mod.changeAccess(fd.modifiers, Mod.PACKAGE), // modifiers
-                    vd.name,                                     // fieldName
-                    this.getType(type).getDescriptor(),          // fieldTypeFD
-                    ocv                                          // optionalConstantValue
-                );
-            } else
-            {
-                fi = cf.addFieldInfo(
-                    fd.modifiers,                       // modifiers
-                    vd.name,                            // fieldName
-                    this.getType(type).getDescriptor(), // fieldTypeFD
-                    ocv                                 // optionalConstantValue
-                );
-            }
-
-            // Add "Deprecated" attribute (JVMS 4.7.10)
-            if (fd.hasDeprecatedDocTag()) {
-                fi.addAttribute(new ClassFile.DeprecatedAttribute(cf.addConstantUtf8Info("Deprecated")));
-            }
-        }
-    }
-
-    public void compile2(Java.AnonymousClassDeclaration acd) throws CompileException {
-        this.compile2((Java.InnerClassDeclaration) acd);
-    }
-
-    public void compile2(Java.LocalClassDeclaration lcd) throws CompileException {
-        this.compile2((Java.InnerClassDeclaration) lcd);
-    }
-
-    public void compile2(Java.InnerClassDeclaration icd) throws CompileException {
-
-        // Define a synthetic "this$..." field if there is an enclosing instance.
-        {
-            List ocs = UnitCompiler.getOuterClasses(icd);
-            final int nesting = ocs.size();
-            if (nesting >= 2) {
-                icd.defineSyntheticField(new SimpleIField(
-                    this.resolve(icd),
-                    "this$" + (nesting - 2),
-                    this.resolve((Java.AbstractTypeDeclaration) ocs.get(1))
-                ));
-            }
-        }
-
-        this.compile2((Java.ClassDeclaration) icd);
-    }
-
-    public void compile2(final Java.MemberClassDeclaration mcd) throws CompileException {
-        this.compile2((Java.InnerClassDeclaration) mcd);
-    }
-
-    public void compile2(Java.InterfaceDeclaration id) throws CompileException {
-        IClass iClass = this.resolve(id);
-
-        // Determine extended interfaces.
-        id.interfaces = new IClass[id.extendedTypes.length];
-        String[] interfaceDescriptors = new String[id.interfaces.length];
-        for (int i = 0; i < id.extendedTypes.length; ++i) {
-            id.interfaces[i] = this.getType(id.extendedTypes[i]);
-            interfaceDescriptors[i] = id.interfaces[i].getDescriptor();
-        }
-
-        // Create "ClassFile" object.
-        ClassFile cf = new ClassFile(
-            (short) (                         // accessFlags
-                id.modifiers |
-                Mod.SUPER |
-                Mod.INTERFACE |
-                Mod.ABSTRACT
-            ),
-            iClass.getDescriptor(),           // thisClassFD
-            Descriptor.OBJECT,                // superClassFD
-            interfaceDescriptors              // interfaceFDs
-        );
-
-        // Set "SourceFile" attribute.
-        if (this.debuggingInformation.contains(DebuggingInformation.SOURCE)) {
-            String sourceFileName;
-            {
-                String s = id.getLocation().getFileName();
-                if (s != null) {
-                    sourceFileName = new File(s).getName();
-                } else {
-                    sourceFileName = id.getName() + ".java";
-                }
-            }
-            cf.addSourceFileAttribute(sourceFileName);
-        }
-
-        // Add "Deprecated" attribute (JVMS 4.7.10)
-        if (id.hasDeprecatedDocTag()) cf.addDeprecatedAttribute();
-
-        // Interface initialization method.
-        if (!id.constantDeclarations.isEmpty()) {
-            Java.Block b = new Java.Block(id.getLocation());
-            b.addButDontEncloseStatements(id.constantDeclarations);
-
-            maybeCreateInitMethod(id, cf, b);
-        }
-
-        compileDeclaredMethods(id, cf);
-
-        // Class variables.
-        for (int i = 0; i < id.constantDeclarations.size(); ++i) {
-            Java.BlockStatement bs = (Java.BlockStatement) id.constantDeclarations.get(i);
-            if (!(bs instanceof Java.FieldDeclaration)) continue;
-            this.addFields((Java.FieldDeclaration) bs, cf);
-        }
-
-        compileDeclaredMemberTypes(id, cf);
-
-        // Add the generated class file to a thread-local store.
-        this.generatedClassFiles.add(cf);
-    }
-
-    /**
-     * Create class initialization method iff there is any initialization code.
-     * @param decl  The type declaration
-     * @param cf    The class file into which to put the method
-     * @param b     The block for the method (possibly empty)
-     * @throws CompileException
-     */
-    private void maybeCreateInitMethod(Java.AbstractTypeDeclaration decl,
-            ClassFile cf, Java.Block b) throws CompileException {
-        // Create interface initialization method iff there is any initialization code.
-        if (this.generatesCode(b)) {
-            Java.MethodDeclarator md = new Java.MethodDeclarator(
-                decl.getLocation(),                               // location
-                null,                                           // optionalDocComment
-                (short) (Mod.STATIC | Mod.PUBLIC),              // modifiers
-                new Java.BasicType(                             // type
-                    decl.getLocation(),
-                    Java.BasicType.VOID
-                ),
-                "<clinit>",                                     // name
-                new Java.FunctionDeclarator.FormalParameter[0], // formalParameters
-                new Java.ReferenceType[0],                      // thrownExcaptions
-                b                                               // optionalBody
-            );
-            md.setDeclaringType(decl);
-            this.compile(md, cf);
-        }
-    }
-
-    /**
-     * Compile all of the types for this declaration
-     * <p>
-     * NB: as a side effect this will fill in the sythetic field map
-     * @throws CompileException
-     */
-    private void compileDeclaredMemberTypes(
-        Java.AbstractTypeDeclaration decl,
-        ClassFile                    cf
-    ) throws CompileException {
-        for (Iterator it = decl.getMemberTypeDeclarations().iterator(); it.hasNext();) {
-            Java.AbstractTypeDeclaration atd = ((Java.AbstractTypeDeclaration) it.next());
-            this.compile(atd);
-
-            // Add InnerClasses attribute entry for member type declaration.
-            short innerClassInfoIndex = cf.addConstantClassInfo(this.resolve(atd).getDescriptor());
-            short outerClassInfoIndex = cf.addConstantClassInfo(this.resolve(decl).getDescriptor());
-            short innerNameIndex      = cf.addConstantUtf8Info(((Java.MemberTypeDeclaration) atd).getName());
-            cf.addInnerClassesAttributeEntry(new ClassFile.InnerClassesAttribute.Entry(
-                innerClassInfoIndex, // innerClassInfoIndex
-                outerClassInfoIndex, // outerClassInfoIndex
-                innerNameIndex,      // innerNameIndex
-                decl.modifiers         // innerClassAccessFlags
-            ));
-        }
-    }
-    
-    /**
-     * Compile all of the methods for this declaration
-     * <p>
-     * NB: as a side effect this will fill in the sythetic field map
-     * @throws CompileException
-     */
-    private void compileDeclaredMethods(
-        Java.AbstractTypeDeclaration typeDeclaration,
-        ClassFile                    cf
-    ) throws CompileException {
-        compileDeclaredMethods(typeDeclaration, cf, 0);
-    }
-
-    /**
-     * Compile methods for this declaration starting at startPos
-     * @param startPos starting param to fill in
-     * @throws CompileException
-     */
-    private void compileDeclaredMethods(
-        Java.AbstractTypeDeclaration typeDeclaration,
-        ClassFile                    cf,
-        int                          startPos
-    ) throws CompileException {
-
-        // Notice that as a side effect of compiling methods, synthetic "class-dollar"
-        // methods (which implement class literals) are generated on-the fly. Hence, we
-        // must not use an Iterator here.
-        for (int i = startPos; i < typeDeclaration.declaredMethods.size(); ++i) {
-            this.compile(((Java.MethodDeclarator) typeDeclaration.declaredMethods.get(i)), cf);
-        }
-    }
-
-    /**
-     * @return <tt>false</tt> if this statement cannot complete normally (JLS2
-     * 14.20)
-     */
-    private boolean compile(Java.BlockStatement bs) throws CompileException {
-        final boolean[] res = new boolean[1];
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.BlockStatementVisitor bsv = new Visitor.BlockStatementVisitor() {
-            public void visitInitializer                      (Java.Initializer                       i   ) { try { res[0] = UnitCompiler.this.compile2(i   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldDeclaration                 (Java.FieldDeclaration                  fd  ) { try { res[0] = UnitCompiler.this.compile2(fd  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLabeledStatement                 (Java.LabeledStatement                  ls  ) { try { res[0] = UnitCompiler.this.compile2(ls  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBlock                            (Java.Block                             b   ) { try { res[0] = UnitCompiler.this.compile2(b   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitExpressionStatement              (Java.ExpressionStatement               es  ) { try { res[0] = UnitCompiler.this.compile2(es  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitIfStatement                      (Java.IfStatement                       is  ) { try { res[0] = UnitCompiler.this.compile2(is  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitForStatement                     (Java.ForStatement                      fs  ) { try { res[0] = UnitCompiler.this.compile2(fs  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitWhileStatement                   (Java.WhileStatement                    ws  ) { try { res[0] = UnitCompiler.this.compile2(ws  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitTryStatement                     (Java.TryStatement                      ts  ) { try { res[0] = UnitCompiler.this.compile2(ts  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSwitchStatement                  (Java.SwitchStatement                   ss  ) { try { res[0] = UnitCompiler.this.compile2(ss  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSynchronizedStatement            (Java.SynchronizedStatement             ss  ) { try { res[0] = UnitCompiler.this.compile2(ss  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitDoStatement                      (Java.DoStatement                       ds  ) { try { res[0] = UnitCompiler.this.compile2(ds  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) { try { res[0] = UnitCompiler.this.compile2(lvds); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitReturnStatement                  (Java.ReturnStatement                   rs  ) { try { res[0] = UnitCompiler.this.compile2(rs  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitThrowStatement                   (Java.ThrowStatement                    ts  ) { try { res[0] = UnitCompiler.this.compile2(ts  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBreakStatement                   (Java.BreakStatement                    bs  ) { try { res[0] = UnitCompiler.this.compile2(bs  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitContinueStatement                (Java.ContinueStatement                 cs  ) { try { res[0] = UnitCompiler.this.compile2(cs  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitEmptyStatement                   (Java.EmptyStatement                    es  ) {       res[0] = UnitCompiler.this.compile2(es  );                                                                }
-            public void visitLocalClassDeclarationStatement   (Java.LocalClassDeclarationStatement    lcds) { try { res[0] = UnitCompiler.this.compile2(lcds); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitAlternateConstructorInvocation   (Java.AlternateConstructorInvocation    aci ) { try { res[0] = UnitCompiler.this.compile2(aci ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperConstructorInvocation       (Java.SuperConstructorInvocation        sci ) { try { res[0] = UnitCompiler.this.compile2(sci ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            bs.accept(bsv);
-            return res[0];
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private boolean compile2(Java.Initializer i) throws CompileException {
-        return this.compile(i.block);
-    }
-    private boolean compile2(Java.Block b) throws CompileException {
-        this.codeContext.saveLocalVariables();
-        try {
-            boolean previousStatementCanCompleteNormally = true;
-            for (int i = 0; i < b.statements.size(); ++i) {
-                Java.BlockStatement bs = (Java.BlockStatement) b.statements.get(i);
-                if (!previousStatementCanCompleteNormally && this.generatesCode(bs)) {
-                    this.compileError("Statement is unreachable", bs.getLocation());
-                    break;
-                }
-                previousStatementCanCompleteNormally = this.compile(bs);
-            }
-            return previousStatementCanCompleteNormally;
-        } finally {
-            this.codeContext.restoreLocalVariables();
-        }
-    }
-    private boolean compile2(Java.DoStatement ds) throws CompileException {
-        Object cvc = this.getConstantValue(ds.condition);
-        if (cvc != null) {
-            if (Boolean.TRUE.equals(cvc)) {
-                this.warning("DSTC", "Condition of DO statement is always TRUE; the proper way of declaring an unconditional loop is \"for (;;)\"", ds.getLocation());
-                return this.compileUnconditionalLoop(ds, ds.body, null);
-            } else
-            {
-                this.warning("DSNR", "DO statement never repeats", ds.getLocation());
-            }
-        }
-
-        ds.whereToContinue = this.codeContext.new Offset();
-        ds.bodyHasContinue = false;
-
-        CodeContext.Offset bodyOffset = this.codeContext.newOffset();
-
-        // Compile body.
-        if (!this.compile(ds.body) && !ds.bodyHasContinue) {
-            this.warning("DSNTC", "\"do\" statement never tests its condition", ds.getLocation());
-            if (ds.whereToBreak == null) return false;
-            ds.whereToBreak.set();
-            return true;
-        }
-
-        // Compile condition.
-        ds.whereToContinue.set();
-        this.compileBoolean(ds.condition, bodyOffset, Java.Rvalue.JUMP_IF_TRUE);
-
-        if (ds.whereToBreak != null) ds.whereToBreak.set();
-
-        return true;
-    }
-    private boolean compile2(Java.ForStatement fs) throws CompileException {
-        this.codeContext.saveLocalVariables();
-        try {
-
-            // Compile init.
-            if (fs.optionalInit != null) this.compile(fs.optionalInit);
-
-            if (fs.optionalCondition == null) {
-                return this.compileUnconditionalLoop(fs, fs.body, fs.optionalUpdate);
-            } else
-            {
-                Object cvc = this.getConstantValue(fs.optionalCondition);
-                if (cvc != null) {
-                    if (Boolean.TRUE.equals(cvc)) {
-                        this.warning("FSTC", "Condition of FOR statement is always TRUE; the proper way of declaring an unconditional loop is \"for (;;)\"", fs.getLocation());
-                        return this.compileUnconditionalLoop(fs, fs.body, fs.optionalUpdate);
-                    } else
-                    {
-                        this.warning("FSNR", "FOR statement never repeats", fs.getLocation());
-                    }
-                }
-            }
-
-            CodeContext.Offset toCondition = this.codeContext.new Offset();
-            this.writeBranch(fs, Opcode.GOTO, toCondition);
-
-            // Compile body.
-            fs.whereToContinue = this.codeContext.new Offset();
-            fs.bodyHasContinue = false;
-            CodeContext.Offset bodyOffset = this.codeContext.newOffset();
-            boolean bodyCCN = this.compile(fs.body);
-
-            // Compile update.
-            fs.whereToContinue.set();
-            if (fs.optionalUpdate != null) {
-                if (!bodyCCN && !fs.bodyHasContinue) {
-                    this.warning("FUUR", "For update is unreachable", fs.getLocation());
-                } else
-                {
-                    for (int i = 0; i < fs.optionalUpdate.length; ++i) {
-                        this.compile(fs.optionalUpdate[i]);
-                    }
-                }
-            }
-
-            // Compile condition.
-            toCondition.set();
-            this.compileBoolean(fs.optionalCondition, bodyOffset, Java.Rvalue.JUMP_IF_TRUE);
-        } finally {
-            this.codeContext.restoreLocalVariables();
-        }
-
-        if (fs.whereToBreak != null) fs.whereToBreak.set();
-
-        return true;
-    }
-    private boolean compile2(Java.WhileStatement ws) throws CompileException {
-        Object cvc = this.getConstantValue(ws.condition);
-        if (cvc != null) {
-            if (Boolean.TRUE.equals(cvc)) {
-                this.warning("WSTC", "Condition of WHILE statement is always TRUE; the proper way of declaring an unconditional loop is \"for (;;)\"", ws.getLocation());
-                return this.compileUnconditionalLoop(ws, ws.body, null);
-            } else
-            {
-                this.warning("WSNR", "WHILE statement never repeats", ws.getLocation());
-            }
-        }
-
-        ws.whereToContinue = this.codeContext.new Offset();
-        ws.bodyHasContinue = false;
-        this.writeBranch(ws, Opcode.GOTO, ws.whereToContinue);
-
-        // Compile body.
-        CodeContext.Offset bodyOffset = this.codeContext.newOffset();
-        this.compile(ws.body); // Return value (CCN) is ignored.
-
-        // Compile condition.
-        ws.whereToContinue.set();
-        this.compileBoolean(ws.condition, bodyOffset, Java.Rvalue.JUMP_IF_TRUE);
-
-        if (ws.whereToBreak != null) ws.whereToBreak.set();
-        return true;
-    }
-    private boolean compileUnconditionalLoop(
-        Java.ContinuableStatement cs,
-        Java.BlockStatement       body,
-        Java.Rvalue[]             optionalUpdate
-    ) throws CompileException {
-        if (optionalUpdate != null) return this.compileUnconditionalLoopWithUpdate(cs, body, optionalUpdate);
-
-        cs.whereToContinue = this.codeContext.newOffset();
-        cs.bodyHasContinue = false;
-
-        // Compile body.
-        if (this.compile(body)) this.writeBranch(cs, Opcode.GOTO, cs.whereToContinue);
-
-        if (cs.whereToBreak == null) return false;
-        cs.whereToBreak.set();
-        return true;
-    }
-    private boolean compileUnconditionalLoopWithUpdate(
-        Java.ContinuableStatement cs,
-        Java.BlockStatement       body,
-        Java.Rvalue[]             update
-    ) throws CompileException {
-        cs.whereToContinue = this.codeContext.new Offset();
-        cs.bodyHasContinue = false;
-
-        // Compile body.
-        CodeContext.Offset bodyOffset = this.codeContext.newOffset();
-        boolean bodyCCN = this.compile(body);
-
-        // Compile the "update".
-        cs.whereToContinue.set();
-        if (!bodyCCN && !cs.bodyHasContinue) {
-            this.warning("LUUR", "Loop update is unreachable", update[0].getLocation());
-        } else
-        {
-            for (int i = 0; i < update.length; ++i) this.compile(update[i]);
-            this.writeBranch(cs, Opcode.GOTO, bodyOffset);
-        }
-
-        if (cs.whereToBreak == null) return false;
-        cs.whereToBreak.set();
-        return true;
-    }
-
-    private final boolean compile2(Java.LabeledStatement ls) throws CompileException {
-        boolean canCompleteNormally = this.compile(ls.body);
-        if (ls.whereToBreak != null) {
-            ls.whereToBreak.set();
-            canCompleteNormally = true;
-        }
-        return canCompleteNormally;
-    }
-    private boolean compile2(Java.SwitchStatement ss) throws CompileException {
-
-        // Compute condition.
-        IClass switchExpressionType = this.compileGetValue(ss.condition);
-        this.assignmentConversion(
-            (Locatable) ss,       // l
-            switchExpressionType, // sourceType
-            IClass.INT,           // targetType
-            null                  // optionalConstantValue
-        );
-
-        // Prepare the map of case labels to code offsets.
-        TreeMap              caseLabelMap = new TreeMap(); // Integer => Offset
-        CodeContext.Offset   defaultLabelOffset = null;
-        CodeContext.Offset[] sbsgOffsets = new CodeContext.Offset[ss.sbsgs.size()];
-        for (int i = 0; i < ss.sbsgs.size(); ++i) {
-            Java.SwitchStatement.SwitchBlockStatementGroup sbsg = (Java.SwitchStatement.SwitchBlockStatementGroup) ss.sbsgs.get(i);
-            sbsgOffsets[i] = this.codeContext.new Offset();
-            for (int j = 0; j < sbsg.caseLabels.size(); ++j) {
-
-                // Verify that case label value is a constant.
-                Java.Rvalue rv = (Java.Rvalue) sbsg.caseLabels.get(j);
-                Object cv = this.getConstantValue(rv);
-                if (cv == null) {
-                    this.compileError("Value of \"case\" label does not pose a constant value", rv.getLocation());
-                    cv = new Integer(99);
-                }
-
-                // Verify that case label is assignable to the type of the switch expression.
-                IClass rvType = this.getType(rv);
-                this.assignmentConversion(
-                    (Locatable) ss,       // l
-                    rvType,               // sourceType
-                    switchExpressionType, // targetType
-                    cv                    // optionalConstantValue
-                );
-
-                // Convert char, byte, short, int to "Integer".
-                Integer civ;
-                if (cv instanceof Integer) {
-                    civ = (Integer) cv;
-                } else
-                if (cv instanceof Number) {
-                    civ = new Integer(((Number) cv).intValue());
-                } else
-                if (cv instanceof Character) {
-                    civ = new Integer(((Character) cv).charValue());
-                } else {
-                    this.compileError("Value of case label must be a char, byte, short or int constant", rv.getLocation());
-                    civ = new Integer(99);
-                }
-
-                // Store in case label map.
-                if (caseLabelMap.containsKey(civ)) this.compileError("Duplicate \"case\" switch label value", rv.getLocation());
-                caseLabelMap.put(civ, sbsgOffsets[i]);
-            }
-            if (sbsg.hasDefaultLabel) {
-                if (defaultLabelOffset != null) this.compileError("Duplicate \"default\" switch label", sbsg.getLocation());
-                defaultLabelOffset = sbsgOffsets[i];
-            }
-        }
-        if (defaultLabelOffset == null) defaultLabelOffset = this.getWhereToBreak(ss);
-
-        // Generate TABLESWITCH or LOOKUPSWITCH instruction.
-        CodeContext.Offset switchOffset = this.codeContext.newOffset();
-        if (caseLabelMap.isEmpty()) {
-            // Special case: SWITCH statement without CASE labels (but maybe a DEFAULT label).
-            ;
-        } else
-        if (
-            ((Integer) caseLabelMap.firstKey()).intValue() + caseLabelMap.size() >= // Beware of INT overflow!
-            ((Integer) caseLabelMap.lastKey()).intValue() - caseLabelMap.size()
-        ) {
-            int low = ((Integer) caseLabelMap.firstKey()).intValue();
-            int high = ((Integer) caseLabelMap.lastKey()).intValue();
-
-            this.writeOpcode(ss, Opcode.TABLESWITCH);
-            new Java.Padder(this.codeContext).set();
-            this.writeOffset(switchOffset, defaultLabelOffset);
-            this.writeInt(low);
-            this.writeInt(high);
-            Iterator si = caseLabelMap.entrySet().iterator();
-            int cur = low;
-            while (si.hasNext()) {
-                Map.Entry me = (Map.Entry) si.next();
-                int val = ((Integer) me.getKey()).intValue();
-                while (cur < val) {
-                    this.writeOffset(switchOffset, defaultLabelOffset);
-                    ++cur;
-                }
-                this.writeOffset(switchOffset, (CodeContext.Offset) me.getValue());
-                ++cur;
-            }
-        } else {
-            this.writeOpcode(ss, Opcode.LOOKUPSWITCH);
-            new Java.Padder(this.codeContext).set();
-            this.writeOffset(switchOffset, defaultLabelOffset);
-            this.writeInt(caseLabelMap.size());
-            Iterator si = caseLabelMap.entrySet().iterator();
-            while (si.hasNext()) {
-                Map.Entry me = (Map.Entry) si.next();
-                this.writeInt(((Integer) me.getKey()).intValue());
-                this.writeOffset(switchOffset, (CodeContext.Offset) me.getValue());
-            }
-        }
-
-        // Compile statement groups.
-        boolean canCompleteNormally = true;
-        for (int i = 0; i < ss.sbsgs.size(); ++i) {
-            Java.SwitchStatement.SwitchBlockStatementGroup sbsg = (Java.SwitchStatement.SwitchBlockStatementGroup) ss.sbsgs.get(i);
-            sbsgOffsets[i].set();
-            canCompleteNormally = true;
-            for (int j = 0; j < sbsg.blockStatements.size(); ++j) {
-                Java.BlockStatement bs = (Java.BlockStatement) sbsg.blockStatements.get(j);
-                if (!canCompleteNormally) {
-                    this.compileError("Statement is unreachable", bs.getLocation());
-                    break;
-                }
-                canCompleteNormally = this.compile(bs);
-            }
-        }
-        if (ss.whereToBreak != null) {
-            ss.whereToBreak.set();
-            canCompleteNormally = true;
-        }
-        return canCompleteNormally;
-    }
-    private boolean compile2(Java.BreakStatement bs) throws CompileException {
-
-        // Find the broken statement.
-        Java.BreakableStatement brokenStatement = null;
-        if (bs.optionalLabel == null) {
-            for (
-                Java.Scope s = bs.getEnclosingScope();
-                s instanceof Java.Statement || s instanceof Java.CatchClause;
-                s = s.getEnclosingScope()
-            ) {
-                if (s instanceof Java.BreakableStatement) {
-                    brokenStatement = (Java.BreakableStatement) s;
-                    break;
-                }
-            }
-            if (brokenStatement == null) {
-                this.compileError("\"break\" statement is not enclosed by a breakable statement", bs.getLocation());
-                return false;
-            }
-        } else {
-            for (
-                Java.Scope s = bs.getEnclosingScope();
-                s instanceof Java.Statement || s instanceof Java.CatchClause;
-                s = s.getEnclosingScope()
-            ) {
-                if (s instanceof Java.LabeledStatement) {
-                    Java.LabeledStatement ls = (Java.LabeledStatement) s;
-                    if (ls.label.equals(bs.optionalLabel)) {
-                        brokenStatement = ls;
-                        break;
-                    }
-                }
-            }
-            if (brokenStatement == null) {
-                this.compileError("Statement \"break " + bs.optionalLabel + "\" is not enclosed by a breakable statement with label \"" + bs.optionalLabel + "\"", bs.getLocation());
-                return false;
-            }
-        }
-
-        this.leaveStatements(
-            bs.getEnclosingScope(),              // from
-            brokenStatement.getEnclosingScope(), // to
-            null                                 // optionalStackValueType
-        );
-        this.writeBranch(bs, Opcode.GOTO, this.getWhereToBreak(brokenStatement));
-        return false;
-    }
-    private boolean compile2(Java.ContinueStatement cs) throws CompileException {
-
-        // Find the continued statement.
-        Java.ContinuableStatement continuedStatement = null;
-        if (cs.optionalLabel == null) {
-            for (
-                Java.Scope s = cs.getEnclosingScope();
-                s instanceof Java.Statement || s instanceof Java.CatchClause;
-                s = s.getEnclosingScope()
-            ) {
-                if (s instanceof Java.ContinuableStatement) {
-                    continuedStatement = (Java.ContinuableStatement) s;
-                    break;
-                }
-            }
-            if (continuedStatement == null) {
-                this.compileError("\"continue\" statement is not enclosed by a continuable statement", cs.getLocation());
-                return false;
-            }
-        } else {
-            for (
-                Java.Scope s = cs.getEnclosingScope();
-                s instanceof Java.Statement || s instanceof Java.CatchClause;
-                s = s.getEnclosingScope()
-            ) {
-                if (s instanceof Java.LabeledStatement) {
-                    Java.LabeledStatement ls = (Java.LabeledStatement) s;
-                    if (ls.label.equals(cs.optionalLabel)) {
-                        Java.Statement st = ls.body;
-                        while (st instanceof Java.LabeledStatement) st = ((Java.LabeledStatement) st).body;
-                        if (!(st instanceof Java.ContinuableStatement)) {
-                            this.compileError("Labeled statement is not continuable", st.getLocation());
-                            return false;
-                        }
-                        continuedStatement = (Java.ContinuableStatement) st;
-                        break;
-                    }
-                }
-            }
-            if (continuedStatement == null) {
-                this.compileError("Statement \"continue " + cs.optionalLabel + "\" is not enclosed by a continuable statement with label \"" + cs.optionalLabel + "\"", cs.getLocation());
-                return false;
-            }
-        }
-
-        continuedStatement.bodyHasContinue = true;
-        this.leaveStatements(
-            cs.getEnclosingScope(),                 // from
-            continuedStatement.getEnclosingScope(), // to
-            null                                    // optionalStackValueType
-        );
-        this.writeBranch(cs, Opcode.GOTO, continuedStatement.whereToContinue);
-        return false;
-    }
-    private boolean compile2(Java.EmptyStatement es) {
-        return true;
-    }
-    private boolean compile2(Java.ExpressionStatement ee) throws CompileException {
-        this.compile(ee.rvalue);
-        return true;
-    }
-    private boolean compile2(Java.FieldDeclaration fd) throws CompileException {
-        for (int i = 0; i < fd.variableDeclarators.length; ++i) {
-            Java.VariableDeclarator vd = fd.variableDeclarators[i];
-
-            Java.ArrayInitializerOrRvalue initializer = this.getNonConstantFinalInitializer(fd, vd);
-            if (initializer == null) continue;
-
-            if ((fd.modifiers & Mod.STATIC) == 0) {
-                this.writeOpcode(fd, Opcode.ALOAD_0);
-            }
-            IClass fieldType = this.getType(fd.type);
-            if (initializer instanceof Java.Rvalue) {
-                Java.Rvalue rvalue = (Java.Rvalue) initializer;
-                IClass initializerType = this.compileGetValue(rvalue);
-                fieldType = fieldType.getArrayIClass(vd.brackets, this.iClassLoader.OBJECT);
-                this.assignmentConversion(
-                    (Locatable) fd,               // l
-                    initializerType,              // sourceType
-                    fieldType,                    // destinationType
-                    this.getConstantValue(rvalue) // optionalConstantValue
-                );
-            } else
-            if (initializer instanceof Java.ArrayInitializer) {
-                this.compileGetValue((Java.ArrayInitializer) initializer, fieldType);
-            } else
-            {
-                throw new RuntimeException("Unexpected array initializer or rvalue class " + initializer.getClass().getName());
-            }
-
-            // No need to check accessibility here.
-            ;
-
-            if ((fd.modifiers & Mod.STATIC) != 0) {
-                this.writeOpcode(fd, Opcode.PUTSTATIC);
-            } else {
-                this.writeOpcode(fd, Opcode.PUTFIELD);
-            }
-            this.writeConstantFieldrefInfo(
-                this.resolve(fd.getDeclaringType()).getDescriptor(),
-                vd.name, // classFD
-                fieldType.getDescriptor()                            // fieldFD
-            );
-        }
-        return true;
-    }
-    private boolean compile2(Java.IfStatement is) throws CompileException {
-        Object cv = this.getConstantValue(is.condition);
-        Java.BlockStatement es = (
-            is.optionalElseStatement != null
-            ? is.optionalElseStatement
-            : new Java.EmptyStatement(is.thenStatement.getLocation())
-        );
-        if (cv instanceof Boolean) {
-
-            // Constant condition.
-            this.fakeCompile(is.condition);
-            Java.BlockStatement seeingStatement, blindStatement;
-            if (((Boolean) cv).booleanValue()) {
-                seeingStatement = is.thenStatement;
-                blindStatement  = es;
-            } else {
-                seeingStatement = es;
-                blindStatement  = is.thenStatement;
-            }
-
-            // Compile the seeing statement.
-            CodeContext.Inserter ins = this.codeContext.newInserter();
-            boolean ssccn = this.compile(seeingStatement);
-            if (ssccn) return true;
-
-            // Hm... the "seeing statement" cannot complete normally. Things are getting
-            // complicated here! The robust solution is to compile the constant-condition-IF
-            // statement as a non-constant-condition-IF statement. As an optimization, iff the
-            // IF-statement is enclosed ONLY by blocks, then the remaining bytecode can be
-            // written to a "fake" code context, i.e. be thrown away.
-
-            // Constant-condition-IF statement only enclosed by blocks?
-            Java.Scope s = is.getEnclosingScope();
-            while (s instanceof Java.Block) s = s.getEnclosingScope();
-            if (s instanceof Java.FunctionDeclarator) {
-
-                // Yes, compile rest of method to /dev/null.
-                throw UnitCompiler.STOP_COMPILING_CODE;
-            } else
-            {
-
-                // Compile constant-condition-IF statement as non-constant-condition-IF statement.
-                CodeContext.Offset off = this.codeContext.newOffset();
-                this.codeContext.pushInserter(ins);
-                try {
-                    this.pushConstant(is, new Integer(0));
-                    this.writeBranch((Locatable) is, Opcode.IFNE, off);
-                } finally {
-                    this.codeContext.popInserter();
-                }
-            }
-            return this.compile(blindStatement);
-        }
-
-        // Non-constant condition.
-        if (this.generatesCode(is.thenStatement)) {
-            if (this.generatesCode(es)) {
-
-                // if (expr) stmt else stmt
-                CodeContext.Offset eso = this.codeContext.new Offset();
-                CodeContext.Offset end = this.codeContext.new Offset();
-                this.compileBoolean(is.condition, eso, Java.Rvalue.JUMP_IF_FALSE);
-                boolean tsccn = this.compile(is.thenStatement);
-                if (tsccn) this.writeBranch((Locatable) is, Opcode.GOTO, end);
-                eso.set();
-                boolean esccn = this.compile(es);
-                end.set();
-                return tsccn || esccn;
-            } else {
-
-                // if (expr) stmt else ;
-                CodeContext.Offset end = this.codeContext.new Offset();
-                this.compileBoolean(is.condition, end, Java.Rvalue.JUMP_IF_FALSE);
-                this.compile(is.thenStatement);
-                end.set();
-                return true;
-            }
-        } else {
-            if (this.generatesCode(es)) {
-
-                // if (expr) ; else stmt
-                CodeContext.Offset end = this.codeContext.new Offset();
-                this.compileBoolean(is.condition, end, Java.Rvalue.JUMP_IF_TRUE);
-                this.compile(es);
-                end.set();
-                return true;
-            } else {
-
-                // if (expr) ; else ;
-                IClass conditionType = this.compileGetValue(is.condition);
-                if (conditionType != IClass.BOOLEAN) this.compileError("Not a boolean expression", is.getLocation());
-                this.pop((Locatable) is, conditionType);
-                return true;
-            }
-        }
-    }
-    private static final RuntimeException STOP_COMPILING_CODE = new RuntimeException("SNO: This exception should have been caught and processed");
-
-    private boolean compile2(Java.LocalClassDeclarationStatement lcds) throws CompileException {
-
-        // Check for redefinition.
-        Java.LocalClassDeclaration otherLCD = this.findLocalClassDeclaration(lcds, lcds.lcd.name);
-        if (otherLCD != lcds.lcd) this.compileError("Redeclaration of local class \"" + lcds.lcd.name + "\"; previously declared in " + otherLCD.getLocation());
-
-        this.compile(lcds.lcd);
-        return true;
-    }
-
-    /**
-     * Find a local class declared in any block enclosing the given block statement.
-     */
-    private Java.LocalClassDeclaration findLocalClassDeclaration(Java.Scope s, String name) {
-        for (;;) {
-            Java.Scope es = s.getEnclosingScope();
-            if (es instanceof Java.CompilationUnit) break;
-            if (s instanceof Java.BlockStatement && es instanceof Java.Block) {
-                Java.BlockStatement bs = (Java.BlockStatement) s;
-                Java.Block          b = (Java.Block) es;
-                for (Iterator it = b.statements.iterator(); it.hasNext();) {
-                    Java.BlockStatement bs2 = (Java.BlockStatement) it.next();
-                    if (bs2 instanceof Java.LocalClassDeclarationStatement) {
-                        Java.LocalClassDeclarationStatement lcds = ((Java.LocalClassDeclarationStatement) bs2);
-                        if (lcds.lcd.name.equals(name)) return lcds.lcd;
-                    }
-                    if (bs2 == bs) break;
-                }
-            }
-            s = es;
-        }
-        return null;
-    }
-
-    private boolean compile2(Java.LocalVariableDeclarationStatement lvds) throws CompileException {
-        if ((lvds.modifiers & ~Mod.FINAL) != 0) this.compileError("The only allowed modifier in local variable declarations is \"final\"", lvds.getLocation());
-
-        for (int j = 0; j < lvds.variableDeclarators.length; ++j) {
-            Java.VariableDeclarator vd = lvds.variableDeclarators[j];
-
-            Java.LocalVariable lv = this.getLocalVariable(lvds, vd);
-            lv.localVariableArrayIndex = this.codeContext.allocateLocalVariable(Descriptor.size(lv.type.getDescriptor()));
-
-            if (vd.optionalInitializer != null) {
-                if (vd.optionalInitializer instanceof Java.Rvalue) {
-                    Java.Rvalue rhs = (Java.Rvalue) vd.optionalInitializer;
-                    this.assignmentConversion(
-                        (Locatable) lvds,          // l
-                        this.compileGetValue(rhs), // sourceType
-                        lv.type,                   // targetType
-                        this.getConstantValue(rhs) // optionalConstantValue
-                    );
-                } else
-                if (vd.optionalInitializer instanceof Java.ArrayInitializer) {
-                    this.compileGetValue((Java.ArrayInitializer) vd.optionalInitializer, lv.type);
-                } else
-                {
-                    throw new RuntimeException("Unexpected rvalue or array initialized class " + vd.optionalInitializer.getClass().getName());
-                }
-                this.store(
-                    (Locatable) lvds, // l
-                    lv.type,          // valueType
-                    lv                // localVariable
-                );
-            }
-        }
-        return true;
-    }
-
-    public Java.LocalVariable getLocalVariable(
-        Java.LocalVariableDeclarationStatement lvds,
-        Java.VariableDeclarator                vd
-    ) throws CompileException {
-        if (vd.localVariable == null) {
-
-            // Determine variable type.
-            Java.Type variableType = lvds.type;
-            for (int k = 0; k < vd.brackets; ++k) variableType = new Java.ArrayType(variableType);
-
-            vd.localVariable = new Java.LocalVariable((lvds.modifiers & Mod.FINAL) != 0, this.getType(variableType));
-        }
-        return vd.localVariable;
-    }
-
-    private boolean compile2(Java.ReturnStatement rs) throws CompileException {
-
-        // Determine enclosing block, function and compilation Unit.
-        Java.FunctionDeclarator enclosingFunction = null;
-        {
-            Java.Scope s = rs.getEnclosingScope();
-            for (s = s.getEnclosingScope(); s instanceof Java.Statement || s instanceof Java.CatchClause; s = s.getEnclosingScope());
-            enclosingFunction = (Java.FunctionDeclarator) s;
-        }
-
-        IClass returnType = this.getReturnType(enclosingFunction);
-        if (returnType == IClass.VOID) {
-            if (rs.optionalReturnValue != null) this.compileError("Method must not return a value", rs.getLocation());
-            this.leaveStatements(
-                rs.getEnclosingScope(), // from
-                enclosingFunction,      // to
-                null                    // optionalStackValueType
-            );
-            this.writeOpcode(rs, Opcode.RETURN);
-            return false;
-        }
-        if (rs.optionalReturnValue == null) {
-            this.compileError("Method must return a value", rs.getLocation());
-            return false;
-        }
-        IClass type = this.compileGetValue(rs.optionalReturnValue);
-        this.assignmentConversion(
-            (Locatable) rs,                               // l
-            type,                                         // sourceType
-            returnType,                                   // targetType
-            this.getConstantValue(rs.optionalReturnValue) // optionalConstantValue
-        );
-
-        this.leaveStatements(
-            rs.getEnclosingScope(), // from
-            enclosingFunction,      // to
-            returnType              // optionalStackValueType
-        );
-        this.writeOpcode(rs, Opcode.IRETURN + this.ilfda(returnType));
-        return false;
-    }
-    private boolean compile2(Java.SynchronizedStatement ss) throws CompileException {
-
-        // Evaluate monitor object expression.
-        if (!this.iClassLoader.OBJECT.isAssignableFrom(this.compileGetValue(ss.expression))) this.compileError("Monitor object of \"synchronized\" statement is not a subclass of \"Object\"", ss.getLocation());
-
-        this.codeContext.saveLocalVariables();
-        boolean canCompleteNormally = false;
-        try {
-
-            // Allocate a local variable for the monitor object.
-            ss.monitorLvIndex = this.codeContext.allocateLocalVariable((short) 1);
-
-            // Store the monitor object.
-            this.writeOpcode(ss, Opcode.DUP);
-            this.store((Locatable) ss, this.iClassLoader.OBJECT, ss.monitorLvIndex);
-
-            // Create lock on the monitor object.
-            this.writeOpcode(ss, Opcode.MONITORENTER);
-
-            // Compile the statement body.
-            CodeContext.Offset monitorExitOffset = this.codeContext.new Offset();
-            CodeContext.Offset beginningOfBody = this.codeContext.newOffset();
-            canCompleteNormally = this.compile(ss.body);
-            if (canCompleteNormally) {
-                this.writeBranch(ss, Opcode.GOTO, monitorExitOffset);
-            }
-
-            // Generate the exception handler.
-            CodeContext.Offset here = this.codeContext.newOffset();
-            this.codeContext.addExceptionTableEntry(
-                beginningOfBody, // startPC
-                here,            // endPC
-                here,            // handlerPC
-                null             // catchTypeFD
-            );
-            this.leave(ss, this.iClassLoader.THROWABLE);
-            this.writeOpcode(ss, Opcode.ATHROW);
-
-            // Unlock monitor object.
-            if (canCompleteNormally) {
-                monitorExitOffset.set();
-                this.leave(ss, null);
-            }
-        } finally {
-            this.codeContext.restoreLocalVariables();
-        }
-
-        return canCompleteNormally;
-    }
-    private boolean compile2(Java.ThrowStatement ts) throws CompileException {
-        IClass expressionType = this.compileGetValue(ts.expression);
-        this.checkThrownException(
-            (Locatable) ts,        // l
-            expressionType,        // type
-            ts.getEnclosingScope() // scope
-        );
-        this.writeOpcode(ts, Opcode.ATHROW);
-        return false;
-    }
-    private boolean compile2(Java.TryStatement ts) throws CompileException {
-        if (ts.optionalFinally != null) ts.finallyOffset = this.codeContext.new Offset();
-
-        CodeContext.Offset beginningOfBody = this.codeContext.newOffset();
-        CodeContext.Offset afterStatement = this.codeContext.new Offset();
-
-        this.codeContext.saveLocalVariables();
-        try {
-
-            // Allocate a LV for the JSR of the FINALLY clause.
-            //
-            // Notice:
-            //   For unclear reasons, this variable must not overlap with any of the body's
-            //   variables (although the body's variables are out of scope when it comes to the
-            //   FINALLY clause!?), otherwise you get
-            //     java.lang.VerifyError: ... Accessing value from uninitialized localvariable 4
-            //   See bug #56.
-            short pcLVIndex = ts.optionalFinally != null ? this.codeContext.allocateLocalVariable((short) 1) : (short) 0;
-
-            boolean canCompleteNormally = this.compile(ts.body);
-            CodeContext.Offset afterBody = this.codeContext.newOffset();
-            if (canCompleteNormally) {
-                this.writeBranch(ts, Opcode.GOTO, afterStatement);
-            }
-
-            if (beginningOfBody.offset != afterBody.offset) { // Avoid zero-length exception table entries.
-                this.codeContext.saveLocalVariables();
-                try {
-
-                    // Allocate the "exception variable".
-                    short evi = this.codeContext.allocateLocalVariable((short) 1);
-
-                    for (int i = 0; i < ts.catchClauses.size(); ++i) {
-                        Java.CatchClause cc = (Java.CatchClause) ts.catchClauses.get(i);
-                        IClass caughtExceptionType = this.getType(cc.caughtException.type);
-                        this.codeContext.addExceptionTableEntry(
-                            beginningOfBody,                    // startPC
-                            afterBody,                          // endPC
-                            this.codeContext.newOffset(),       // handlerPC
-                            caughtExceptionType.getDescriptor() // catchTypeFD
-                        );
-                        this.store(
-                            (Locatable) cc,      // l
-                            caughtExceptionType, // lvType
-                            evi                  // lvIndex
-                        );
-        
-                        // Kludge: Treat the exception variable like a local
-                        // variable of the catch clause body.
-                        UnitCompiler.this.getLocalVariable(cc.caughtException).localVariableArrayIndex = evi;
-        
-                        if (this.compile(cc.body)) {
-                            canCompleteNormally = true;
-                            if (
-                                i < ts.catchClauses.size() - 1 ||
-                                ts.optionalFinally != null
-                            ) this.writeBranch(cc, Opcode.GOTO, afterStatement);
-                        }
-                    }
-                } finally {
-                    this.codeContext.restoreLocalVariables();
-                }
-            }
-
-            if (ts.optionalFinally != null) {
-                CodeContext.Offset here = this.codeContext.newOffset();
-                this.codeContext.addExceptionTableEntry(
-                    beginningOfBody, // startPC
-                    here,            // endPC
-                    here,            // handlerPC
-                    null             // catchTypeFD
-                );
-
-                this.codeContext.saveLocalVariables();
-                try {
-
-                    // Save the exception object in an anonymous local variable.
-                    short evi = this.codeContext.allocateLocalVariable((short) 1);
-                    this.store(
-                        (Locatable) ts.optionalFinally, // l
-                        this.iClassLoader.OBJECT,       // valueType
-                        evi                             // localVariableIndex
-                    );
-                    this.writeBranch(ts.optionalFinally, Opcode.JSR, ts.finallyOffset);
-                    this.load(
-                        (Locatable) ts.optionalFinally, // l
-                        this.iClassLoader.OBJECT,       // valueType
-                        evi                             // localVariableIndex
-                    );
-                    this.writeOpcode(ts.optionalFinally, Opcode.ATHROW);
-    
-                    // Compile the "finally" body.
-                    ts.finallyOffset.set();
-                    this.store(
-                        (Locatable) ts.optionalFinally, // l
-                        this.iClassLoader.OBJECT,       // valueType
-                        pcLVIndex                       // localVariableIndex
-                    );
-                    if (this.compile(ts.optionalFinally)) {
-                        this.writeOpcode(ts.optionalFinally, Opcode.RET);
-                        this.writeByte(pcLVIndex);
-                    }
-                } finally {
-
-                    // The exception object local variable allocated above MUST NOT BE RELEASED
-                    // until after the FINALLY block is compiled, for otherwise you get
-                    //   java.lang.VerifyError: ... Accessing value from uninitialized register 7
-                    this.codeContext.restoreLocalVariables();
-                }
-            }
-
-            afterStatement.set();
-            if (canCompleteNormally) this.leave(ts, null);
-            return canCompleteNormally;
-        } finally {
-            this.codeContext.restoreLocalVariables();
-        }
-    }
-
-    // ------------ FunctionDeclarator.compile() -------------
-
-    private void compile(Java.FunctionDeclarator fd, final ClassFile classFile) throws CompileException {
-        ClassFile.MethodInfo mi;
-
-        if (Mod.isPrivateAccess(fd.modifiers)) {
-            if (fd instanceof Java.MethodDeclarator && !fd.isStatic()){
-
-                // To make the non-static private method invocable for enclosing types, enclosed types
-                // and types enclosed by the same type, it is modified as follows:
-                //  + Access is changed from PRIVATE to PACKAGE
-                //  + The name is appended with "$"
-                //  + It is made static
-                //  + A parameter of type "declaring class" is prepended to the signature
-                mi = classFile.addMethodInfo(
-                    (short) (Mod.changeAccess(fd.modifiers, Mod.PACKAGE) | Mod.STATIC), // accessFlags
-                    fd.name + '$',                               // name
-                    MethodDescriptor.prependParameter(           // methodMD
-                        this.toIMethod((Java.MethodDeclarator) fd).getDescriptor(),
-                        this.resolve(fd.getDeclaringType()).getDescriptor()
-                    )
-                );
-            } else
-            {
-
-                // To make the static private method or private constructor invocable for enclosing
-                // types, enclosed types and types enclosed by the same type, it is modified as
-                // follows:
-                //  + Access is changed from PRIVATE to PACKAGE
-                mi = classFile.addMethodInfo(
-                    Mod.changeAccess(fd.modifiers, Mod.PACKAGE), // accessFlags
-                    fd.name,                                     // name
-                    this.toIInvocable(fd).getDescriptor()        // methodMD
-                );
-            }
-        } else
-        {
-            mi = classFile.addMethodInfo(
-                fd.modifiers,                         // accessFlags
-                fd.name,                              // name
-                this.toIInvocable(fd).getDescriptor() // methodMD
-            );
-        }
-
-        // Add "Exceptions" attribute (JVMS 4.7.4).
-        {
-            final short eani = classFile.addConstantUtf8Info("Exceptions");
-            short[] tecciis = new short[fd.thrownExceptions.length];
-            for (int i = 0; i < fd.thrownExceptions.length; ++i) {
-                tecciis[i] = classFile.addConstantClassInfo(this.getType(fd.thrownExceptions[i]).getDescriptor());
-            }
-            mi.addAttribute(new ClassFile.ExceptionsAttribute(eani, tecciis));
-        }
-
-        // Add "Deprecated" attribute (JVMS 4.7.10)
-        if (fd.hasDeprecatedDocTag()) {
-            mi.addAttribute(new ClassFile.DeprecatedAttribute(classFile.addConstantUtf8Info("Deprecated")));
-        }
-
-        if ((fd.modifiers & (Mod.ABSTRACT | Mod.NATIVE)) != 0) return;
-
-        // Create CodeContext.
-        final CodeContext codeContext = new CodeContext(mi.getClassFile());
-
-        CodeContext savedCodeContext = this.replaceCodeContext(codeContext);
-        try {
-
-            // Define special parameter "this".
-            if ((fd.modifiers & Mod.STATIC) == 0) {
-                this.codeContext.allocateLocalVariable((short) 1);
-            }
-
-            if (fd instanceof Java.ConstructorDeclarator) {
-                Java.ConstructorDeclarator constructorDeclarator = (Java.ConstructorDeclarator) fd;
-
-                // Reserve space for synthetic parameters ("this$...", "val$...").
-                for (Iterator it = constructorDeclarator.getDeclaringClass().syntheticFields.values().iterator(); it.hasNext();) {
-                    IClass.IField sf = (IClass.IField) it.next();
-                    Java.LocalVariable lv = new Java.LocalVariable(true, sf.getType());
-                    lv.localVariableArrayIndex = this.codeContext.allocateLocalVariable(Descriptor.size(sf.getDescriptor()));
-                    constructorDeclarator.syntheticParameters.put(sf.getName(), lv);
-                }
-            }
-
-            this.buildLocalVariableMap(fd);
-
-            // Compile the constructor preamble.
-            if (fd instanceof Java.ConstructorDeclarator) {
-                Java.ConstructorDeclarator cd = (Java.ConstructorDeclarator) fd;
-                if (cd.optionalConstructorInvocation != null) {
-                    this.compile(cd.optionalConstructorInvocation);
-                    if (cd.optionalConstructorInvocation instanceof Java.SuperConstructorInvocation) {
-                        this.assignSyntheticParametersToSyntheticFields(cd);
-                        this.initializeInstanceVariablesAndInvokeInstanceInitializers(cd);
-                    }
-                } else {
-
-                    // Determine qualification for superconstructor invocation.
-                    Java.QualifiedThisReference qualification = null;
-                    IClass outerClassOfSuperclass = this.resolve(cd.getDeclaringClass()).getSuperclass().getOuterIClass();
-                    if (outerClassOfSuperclass != null) {
-//                        qualification = new Java.QualifiedThisReference(
-//                            cd.getLocation(),        // location
-//                            cd.getDeclaringClass(),  // declaringClass
-//                            cd,                      // declaringTypeBodyDeclaration
-//                            outerClassOfSuperclass   // targetIClass
-//                        );
-                        qualification = new Java.QualifiedThisReference(
-                            cd.getLocation(),    // location
-                            new Java.SimpleType( // qualification
-                                cd.getLocation(),
-                                outerClassOfSuperclass
-                            )
-                        );
-                    }
-
-                    // Invoke the superconstructor.
-                    Java.SuperConstructorInvocation sci = new Java.SuperConstructorInvocation(
-                        cd.getLocation(),       // location
-                        qualification,          // optionalQualification
-                        new Java.Rvalue[0]      // arguments
-                    );
-                    sci.setEnclosingScope(fd);
-                    this.compile(sci);
-                    this.assignSyntheticParametersToSyntheticFields(cd);
-                    this.initializeInstanceVariablesAndInvokeInstanceInitializers(cd);
-                }
-            }
-
-            // Compile the function body.
-            try {
-                if (fd.optionalBody == null) {
-                    this.compileError("Method must have a body", fd.getLocation());
-                }
-                boolean canCompleteNormally = this.compile(fd.optionalBody);
-                if (canCompleteNormally) {
-                    if (this.getReturnType(fd) != IClass.VOID) this.compileError("Method must return a value", fd.getLocation());
-                    this.writeOpcode(fd, Opcode.RETURN);
-                }
-            } catch (RuntimeException ex) {
-                if (ex != UnitCompiler.STOP_COMPILING_CODE) throw ex;
-
-                // In very special circumstances (e.g. "if (true) return;"), code generation is
-                // terminated abruptly by throwing STOP_COMPILING_CODE.
-                ;
-            }
-        } finally {
-            this.replaceCodeContext(savedCodeContext);
-        }
-
-        // Don't continue code attribute generation if we had compile errors.
-        if (this.compileErrorCount > 0) return;
-
-        // Fix up and reallocate as needed.
-        codeContext.fixUpAndRelocate();
-
-        // Do flow analysis.
-        if (UnitCompiler.DEBUG) {
-            try {
-                codeContext.flowAnalysis(fd.toString());
-            } catch (RuntimeException ex) {
-                ex.printStackTrace();
-                ;
-            }
-        } else {
-            codeContext.flowAnalysis(fd.toString());
-        }
-
-        // Add the code context as a code attribute to the MethodInfo.
-        final short lntani = (
-            this.debuggingInformation.contains(DebuggingInformation.LINES) ?
-            classFile.addConstantUtf8Info("LineNumberTable") :
-            (short) 0
-        );
-        mi.addAttribute(new ClassFile.AttributeInfo(classFile.addConstantUtf8Info("Code")) {
-            protected void storeBody(DataOutputStream dos) throws IOException {
-                codeContext.storeCodeAttributeBody(dos, lntani);
-            }
-        });
-    }
-
-    private void buildLocalVariableMap(FunctionDeclarator fd) throws CompileException {
-        Map localVars = new HashMap();
-
-        // Add function parameters.
-        for (int i = 0; i < fd.formalParameters.length; ++i) {
-            Java.FunctionDeclarator.FormalParameter fp = fd.formalParameters[i];
-            if (localVars.containsKey(fp.name)) this.compileError("Redefinition of formal parameter \"" + fp.name + "\"", fd.getLocation());
-            Java.LocalVariable lv = this.getLocalVariable(fp);
-            lv.localVariableArrayIndex = this.codeContext.allocateLocalVariable(Descriptor.size(lv.type.getDescriptor()));
-            
-            localVars.put(fp.name, lv);
-        }
-
-        fd.localVariables = localVars;
-        if (fd instanceof ConstructorDeclarator) {
-            ConstructorDeclarator cd = (ConstructorDeclarator) fd;
-            if (cd.optionalConstructorInvocation != null) {
-                buildLocalVariableMap(cd.optionalConstructorInvocation, localVars);
-            }
-        }
-        if (fd.optionalBody != null) this.buildLocalVariableMap(fd.optionalBody, localVars);
-    }
-
-    private Map buildLocalVariableMap(BlockStatement bs, final Map localVars) throws CompileException {
-        final Map[] resVars = new Map[] { localVars };
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        BlockStatementVisitor bsv = new BlockStatementVisitor() {
-            // basic statements that use the default handlers
-            public void visitAlternateConstructorInvocation(AlternateConstructorInvocation aci) { UnitCompiler.this.buildLocalVariableMap(aci, localVars); }
-            public void visitBreakStatement(BreakStatement bs)                                  { UnitCompiler.this.buildLocalVariableMap(bs, localVars); }
-            public void visitContinueStatement(ContinueStatement cs)                            { UnitCompiler.this.buildLocalVariableMap(cs, localVars); }
-            public void visitEmptyStatement(EmptyStatement es)                                  { UnitCompiler.this.buildLocalVariableMap(es, localVars); }
-            public void visitExpressionStatement(ExpressionStatement es)                        { UnitCompiler.this.buildLocalVariableMap(es, localVars); }
-            public void visitFieldDeclaration(FieldDeclaration fd)                              { UnitCompiler.this.buildLocalVariableMap(fd, localVars); }
-            public void visitReturnStatement(ReturnStatement rs)                                { UnitCompiler.this.buildLocalVariableMap(rs, localVars); }
-            public void visitSuperConstructorInvocation(SuperConstructorInvocation sci)         { UnitCompiler.this.buildLocalVariableMap(sci, localVars); }
-            public void visitThrowStatement(ThrowStatement ts)                                  { UnitCompiler.this.buildLocalVariableMap(ts, localVars); }
-            public void visitLocalClassDeclarationStatement(LocalClassDeclarationStatement lcds){ UnitCompiler.this.buildLocalVariableMap(lcds, localVars); }
-            
-            // more complicated statements with specialized handlers, but don't add new variables in this scope
-            public void visitBlock(Block b)              					 { try { UnitCompiler.this.buildLocalVariableMap(b , localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitDoStatement(DoStatement ds)                     { try { UnitCompiler.this.buildLocalVariableMap(ds, localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitForStatement(ForStatement fs)                   { try { UnitCompiler.this.buildLocalVariableMap(fs, localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitIfStatement(IfStatement is)                     { try { UnitCompiler.this.buildLocalVariableMap(is, localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitInitializer(Initializer i)                      { try { UnitCompiler.this.buildLocalVariableMap(i , localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSwitchStatement(SwitchStatement ss)             { try { UnitCompiler.this.buildLocalVariableMap(ss, localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSynchronizedStatement(SynchronizedStatement ss) { try { UnitCompiler.this.buildLocalVariableMap(ss, localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitTryStatement(TryStatement ts)                   { try { UnitCompiler.this.buildLocalVariableMap(ts, localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitWhileStatement(WhileStatement ws)               { try { UnitCompiler.this.buildLocalVariableMap(ws, localVars); } catch (CompileException e) { throw new UCE(e); } }
-            
-            // more complicated statements with specialized handlers, that can add variables in this scope
-            public void visitLabeledStatement(LabeledStatement ls)                                     { try { resVars[0] = UnitCompiler.this.buildLocalVariableMap(ls  , localVars); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalVariableDeclarationStatement(LocalVariableDeclarationStatement lvds) { try { resVars[0] = UnitCompiler.this.buildLocalVariableMap(lvds, localVars); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try { bs.accept(bsv); } catch(UCE uce) { throw uce.ce; }
-        return resVars[0];
-    }
-    // default handlers
-    private Map buildLocalVariableMap(Statement s, final Map localVars)              { return s.localVariables = localVars; }
-    private Map buildLocalVariableMap(ConstructorInvocation ci, final Map localVars) { return ci.localVariables = localVars; }
-    
-    // specialized handlers
-    private void buildLocalVariableMap(Block block, Map localVars) throws CompileException {
-        block.localVariables = localVars;
-        for (Iterator it = block.statements.iterator(); it.hasNext();) {
-            BlockStatement bs = (BlockStatement)it.next();
-            localVars = this.buildLocalVariableMap(bs, localVars);
-        }
-    }
-    private void buildLocalVariableMap(DoStatement ds, final Map localVars) throws CompileException {
-        ds.localVariables = localVars;
-        this.buildLocalVariableMap(ds.body, localVars);
-    }
-    private void buildLocalVariableMap(ForStatement fs, final Map localVars) throws CompileException {
-        Map inner = localVars;
-        if(fs.optionalInit != null) {
-            inner = UnitCompiler.this.buildLocalVariableMap(fs.optionalInit, localVars);
-        }
-        fs.localVariables = inner;
-        UnitCompiler.this.buildLocalVariableMap(fs.body, inner);
-    }
-    private void buildLocalVariableMap(IfStatement is, final Map localVars) throws CompileException {
-        is.localVariables = localVars;
-        UnitCompiler.this.buildLocalVariableMap(is.thenStatement, localVars);
-        if(is.optionalElseStatement != null) {
-            UnitCompiler.this.buildLocalVariableMap(is.optionalElseStatement, localVars);
-        }
-    }
-    private void buildLocalVariableMap(Initializer i, final Map localVars) throws CompileException {
-        UnitCompiler.this.buildLocalVariableMap(i.block, localVars);
-    }
-    private void buildLocalVariableMap(SwitchStatement ss, final Map localVars) throws CompileException {
-        ss.localVariables = localVars;
-        Map vars = localVars;
-        for (Iterator cases = ss.sbsgs.iterator(); cases.hasNext();) {
-            SwitchStatement.SwitchBlockStatementGroup sbsg = (SwitchStatement.SwitchBlockStatementGroup) cases.next();
-            for (Iterator stmts = sbsg.blockStatements.iterator(); stmts.hasNext();) {
-                BlockStatement bs = (BlockStatement) stmts.next();
-                vars = UnitCompiler.this.buildLocalVariableMap(bs, vars);
-            }
-        }
-    }
-    private void buildLocalVariableMap(SynchronizedStatement ss, final Map localVars) throws CompileException {
-        ss.localVariables = localVars;
-        UnitCompiler.this.buildLocalVariableMap(ss.body, localVars);
-    }
-    private void buildLocalVariableMap(TryStatement ts, final Map localVars) throws CompileException {
-        ts.localVariables = localVars;
-        UnitCompiler.this.buildLocalVariableMap(ts.body, localVars);
-        for (Iterator it = ts.catchClauses.iterator(); it.hasNext();) {
-            Java.CatchClause cc = (Java.CatchClause) it.next();
-            UnitCompiler.this.buildLocalVariableMap(cc, localVars);
-        }
-        if(ts.optionalFinally != null) {
-            UnitCompiler.this.buildLocalVariableMap(ts.optionalFinally, localVars);
-        }
-    }
-    private void buildLocalVariableMap(WhileStatement ws, final Map localVars) throws CompileException {
-        ws.localVariables = localVars;
-        UnitCompiler.this.buildLocalVariableMap(ws.body, localVars);
-    }
-    
-    private Map buildLocalVariableMap(LabeledStatement ls, final Map localVars) throws CompileException {
-        ls.localVariables = localVars;
-        return UnitCompiler.this.buildLocalVariableMap((BlockStatement)ls.body, localVars);
-    }
-    private Map buildLocalVariableMap(LocalVariableDeclarationStatement lvds, final Map localVars) throws CompileException {
-        Map newVars = new HashMap();
-        newVars.putAll(localVars);
-        for(int i = 0; i < lvds.variableDeclarators.length; ++i) {
-            Java.VariableDeclarator vd = lvds.variableDeclarators[i];
-            Java.LocalVariable lv = UnitCompiler.this.getLocalVariable(lvds, vd);
-            if(newVars.containsKey(vd.name)) this.compileError("Redefinition of local variable \"" + vd.name + "\" ", vd.getLocation());
-            newVars.put(vd.name, lv);
-        }
-        lvds.localVariables = newVars;
-        return newVars;
-    }
-    protected void buildLocalVariableMap(CatchClause cc, Map localVars) throws CompileException {
-        Map vars = new HashMap();
-        vars.putAll(localVars);
-        LocalVariable lv = this.getLocalVariable(cc.caughtException);
-        vars.put(cc.caughtException.name, lv);
-        this.buildLocalVariableMap(cc.body, vars);
-    }
-
-
-
-    public Java.LocalVariable getLocalVariable(Java.FunctionDeclarator.FormalParameter fp) throws CompileException {
-        if (fp.localVariable == null) {
-            fp.localVariable = new Java.LocalVariable(fp.finaL, this.getType(fp.type));
-        }
-        return fp.localVariable;
-    }
-
-    // ------------------ Rvalue.compile() ----------------
-
-    /**
-     * Call to check whether the given {@link Java.Rvalue} compiles or not.
-     */
-    private void fakeCompile(Java.Rvalue rv) throws CompileException {
-        CodeContext savedCodeContext = this.replaceCodeContext(this.createDummyCodeContext());
-        try {
-            this.compileContext(rv);
-            this.compileGet(rv);
-        } finally {
-            this.replaceCodeContext(savedCodeContext);
-        }
-    }
-
-    /**
-     * Some {@link Java.Rvalue}s compile more efficiently when their value
-     * is not needed, e.g. "i++".
-     */
-    private void compile(Java.Rvalue rv) throws CompileException {
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
-            public void visitArrayLength                   (Java.ArrayLength                    al  ) { try { UnitCompiler.this.compile2(al  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitAssignment                    (Java.Assignment                     a   ) { try { UnitCompiler.this.compile2(a   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitUnaryOperation                (Java.UnaryOperation                 uo  ) { try { UnitCompiler.this.compile2(uo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBinaryOperation               (Java.BinaryOperation                bo  ) { try { UnitCompiler.this.compile2(bo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCast                          (Java.Cast                           c   ) { try { UnitCompiler.this.compile2(c   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitClassLiteral                  (Java.ClassLiteral                   cl  ) { try { UnitCompiler.this.compile2(cl  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitConditionalExpression         (Java.ConditionalExpression          ce  ) { try { UnitCompiler.this.compile2(ce  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCrement                       (Java.Crement                        c   ) { try { UnitCompiler.this.compile2(c   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitInstanceof                    (Java.Instanceof                     io  ) { try { UnitCompiler.this.compile2(io  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitMethodInvocation              (Java.MethodInvocation               mi  ) { try { UnitCompiler.this.compile2(mi  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassMethodInvocation    (Java.SuperclassMethodInvocation     smi ) { try { UnitCompiler.this.compile2(smi ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLiteral                       (Java.Literal                        l   ) { try { UnitCompiler.this.compile2(l   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewAnonymousClassInstance     (Java.NewAnonymousClassInstance      naci) { try { UnitCompiler.this.compile2(naci); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewArray                      (Java.NewArray                       na  ) { try { UnitCompiler.this.compile2(na  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewInitializedArray           (Java.NewInitializedArray            nia ) { try { UnitCompiler.this.compile2(nia ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewClassInstance              (Java.NewClassInstance               nci ) { try { UnitCompiler.this.compile2(nci ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitParameterAccess               (Java.ParameterAccess                pa  ) { try { UnitCompiler.this.compile2(pa  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitQualifiedThisReference        (Java.QualifiedThisReference         qtr ) { try { UnitCompiler.this.compile2(qtr ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitThisReference                 (Java.ThisReference                  tr  ) { try { UnitCompiler.this.compile2(tr  ); } catch (CompileException e) { throw new UCE(e); } }
-
-            public void visitAmbiguousName                  (Java.AmbiguousName              an   ) { try { UnitCompiler.this.compile2(an   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression      aae  ) { try { UnitCompiler.this.compile2(aae  ); } catch (CompileException e) { throw new UCE(e); } };
-            public void visitFieldAccess                    (Java.FieldAccess                fa   ) { try { UnitCompiler.this.compile2(fa   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression      fae  ) { try { UnitCompiler.this.compile2(fae  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassFieldAccessExpression(SuperclassFieldAccessExpression scfae) { try { UnitCompiler.this.compile2(scfae); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess        lva  ) { try { UnitCompiler.this.compile2(lva  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression    pe   ) { try { UnitCompiler.this.compile2(pe   ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            rv.accept(rvv);
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private void compile2(Java.Rvalue rv) throws CompileException {
-        this.pop((Locatable) rv, this.compileGetValue(rv));
-    }
-    private void compile2(Java.Assignment a) throws CompileException {
-        if (a.operator == "=") {
-            this.compileContext(a.lhs);
-            this.assignmentConversion(
-                (Locatable) a,               // l
-                this.compileGetValue(a.rhs), // sourceType
-                this.getType(a.lhs),         // targetType
-                this.getConstantValue(a.rhs) // optionalConstantValue
-            );
-            this.compileSet(a.lhs);
-            return;
-        }
-
-        // Implement "|= ^= &= *= /= %= += -= <<= >>= >>>=".
-        int lhsCS = this.compileContext(a.lhs);
-        this.dup((Locatable) a, lhsCS);
-        IClass lhsType = this.compileGet(a.lhs);
-        IClass resultType = this.compileArithmeticBinaryOperation(
-            (Locatable) a,        // l
-            lhsType,              // lhsType
-            a.operator.substring( // operator
-                0,
-                a.operator.length() - 1
-            ).intern(), // <= IMPORTANT!
-            a.rhs                 // rhs
-        );
-        // Convert the result to LHS type (JLS2 15.26.2).
-        if (
-            !this.tryIdentityConversion(resultType, lhsType) &&
-            !this.tryNarrowingPrimitiveConversion(
-                (Locatable) a,   // l
-                resultType,      // sourceType
-                lhsType          // destinationType
-            )
-        ) throw new RuntimeException("SNO: \"" + a.operator + "\" reconversion failed");
-        this.compileSet(a.lhs);
-    }
-    private void compile2(Java.Crement c) throws CompileException {
-
-        // Optimized crement of integer local variable.
-        Java.LocalVariable lv = this.isIntLV(c);
-        if (lv != null) {
-            this.writeOpcode(c, Opcode.IINC);
-            this.writeByte(lv.localVariableArrayIndex);
-            this.writeByte(c.operator == "++" ? 1 : -1);
-            return;
-        }
-
-        int cs = this.compileContext(c.operand);
-        this.dup((Locatable) c, cs);
-        IClass type = this.compileGet(c.operand);
-        IClass promotedType = this.unaryNumericPromotion((Locatable) c, type);
-        this.writeOpcode(c, UnitCompiler.ilfd(
-            promotedType,
-            Opcode.ICONST_1,
-            Opcode.LCONST_1,
-            Opcode.FCONST_1,
-            Opcode.DCONST_1
-        ));
-        if (c.operator == "++") {
-            this.writeOpcode(c, Opcode.IADD + UnitCompiler.ilfd(promotedType));
-        } else
-        if (c.operator == "--") {
-            this.writeOpcode(c, Opcode.ISUB + UnitCompiler.ilfd(promotedType));
-        } else {
-            this.compileError("Unexpected operator \"" + c.operator + "\"", c.getLocation());
-        }
-
-        this.reverseUnaryNumericPromotion((Locatable) c, promotedType, type);
-        this.compileSet(c.operand);
-    }
-    private void compile2(Java.ParenthesizedExpression pe) throws CompileException {
-        this.compile(pe.value);
-    }
-
-    private boolean compile2(Java.AlternateConstructorInvocation aci) throws CompileException {
-        Java.ConstructorDeclarator declaringConstructor = (Java.ConstructorDeclarator) aci.getEnclosingScope();
-        IClass                     declaringIClass = this.resolve(declaringConstructor.getDeclaringClass());
-
-        this.writeOpcode(aci, Opcode.ALOAD_0);
-        if (declaringIClass.getOuterIClass() != null) this.writeOpcode(aci, Opcode.ALOAD_1);
-        this.invokeConstructor(
-            (Locatable) aci,                   // l
-            (Java.Scope) declaringConstructor, // scope
-            (Java.Rvalue) null,                // optionalEnclosingInstance
-            declaringIClass,                   // targetClass
-            aci.arguments                      // arguments
-        );
-        return true;
-    }
-    private boolean compile2(Java.SuperConstructorInvocation sci) throws CompileException {
-        Java.ConstructorDeclarator declaringConstructor = (Java.ConstructorDeclarator) sci.getEnclosingScope();
-        this.writeOpcode(sci, Opcode.ALOAD_0);
-        Java.ClassDeclaration declaringClass = declaringConstructor.getDeclaringClass();
-        IClass superclass = this.resolve(declaringClass).getSuperclass();
-
-        Java.Rvalue optionalEnclosingInstance;
-        if (sci.optionalQualification != null) {
-            optionalEnclosingInstance = sci.optionalQualification;
-        } else {
-            IClass outerIClassOfSuperclass = superclass.getOuterIClass();
-            if (outerIClassOfSuperclass == null) {
-                optionalEnclosingInstance = null;
-            } else {
-//                optionalEnclosingInstance = new Java.QualifiedThisReference(
-//                    sci.getLocation(),      // location
-//                    declaringClass,         // declaringClass
-//                    declaringConstructor,   // declaringTypeBodyDeclaration
-//                    outerIClassOfSuperclass // targetClass
-//                );
-                optionalEnclosingInstance = new Java.QualifiedThisReference(
-                    sci.getLocation(),   // location
-                    new Java.SimpleType( // qualification
-                        sci.getLocation(),
-                        outerIClassOfSuperclass
-                    )
-                );
-                optionalEnclosingInstance.setEnclosingBlockStatement(sci);
-            }
-        }
-        this.invokeConstructor(
-            (Locatable) sci,                   // l
-            (Java.Scope) declaringConstructor, // scope
-            optionalEnclosingInstance,         // optionalEnclosingInstance
-            superclass,                        // targetClass
-            sci.arguments                      // arguments
-        );
-        return true;
-    }
-
-    /**
-     * Some {@link Java.Rvalue}s compile more efficiently when their value is the
-     * condition for a branch.<br>
-     *
-     * Notice that if "this" is a constant, then either "dst" is never
-     * branched to, or it is unconditionally branched to. "Unexamined code"
-     * errors may result during bytecode validation.
-     */
-    private void compileBoolean(
-        Java.Rvalue              rv,
-        final CodeContext.Offset dst,        // Where to jump.
-        final boolean            orientation // JUMP_IF_TRUE or JUMP_IF_FALSE.
-    ) throws CompileException {
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
-            public void visitArrayLength                   (Java.ArrayLength                    al  ) { try { UnitCompiler.this.compileBoolean2(al  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitAssignment                    (Java.Assignment                     a   ) { try { UnitCompiler.this.compileBoolean2(a   , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitUnaryOperation                (Java.UnaryOperation                 uo  ) { try { UnitCompiler.this.compileBoolean2(uo  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBinaryOperation               (Java.BinaryOperation                bo  ) { try { UnitCompiler.this.compileBoolean2(bo  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCast                          (Java.Cast                           c   ) { try { UnitCompiler.this.compileBoolean2(c   , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitClassLiteral                  (Java.ClassLiteral                   cl  ) { try { UnitCompiler.this.compileBoolean2(cl  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitConditionalExpression         (Java.ConditionalExpression          ce  ) { try { UnitCompiler.this.compileBoolean2(ce  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCrement                       (Java.Crement                        c   ) { try { UnitCompiler.this.compileBoolean2(c   , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitInstanceof                    (Java.Instanceof                     io  ) { try { UnitCompiler.this.compileBoolean2(io  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitMethodInvocation              (Java.MethodInvocation               mi  ) { try { UnitCompiler.this.compileBoolean2(mi  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassMethodInvocation    (Java.SuperclassMethodInvocation     smi ) { try { UnitCompiler.this.compileBoolean2(smi , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLiteral                       (Java.Literal                        l   ) { try { UnitCompiler.this.compileBoolean2(l   , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewAnonymousClassInstance     (Java.NewAnonymousClassInstance      naci) { try { UnitCompiler.this.compileBoolean2(naci, dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewArray                      (Java.NewArray                       na  ) { try { UnitCompiler.this.compileBoolean2(na  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewInitializedArray           (Java.NewInitializedArray            nia ) { try { UnitCompiler.this.compileBoolean2(nia , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewClassInstance              (Java.NewClassInstance               nci ) { try { UnitCompiler.this.compileBoolean2(nci , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitParameterAccess               (Java.ParameterAccess                pa  ) { try { UnitCompiler.this.compileBoolean2(pa  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitQualifiedThisReference        (Java.QualifiedThisReference         qtr ) { try { UnitCompiler.this.compileBoolean2(qtr , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitThisReference                 (Java.ThisReference                  tr  ) { try { UnitCompiler.this.compileBoolean2(tr  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-
-            public void visitAmbiguousName                  (Java.AmbiguousName                   an   ) { try { UnitCompiler.this.compileBoolean2(an   , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression           aae  ) { try { UnitCompiler.this.compileBoolean2(aae  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } };
-            public void visitFieldAccess                    (Java.FieldAccess                     fa   ) { try { UnitCompiler.this.compileBoolean2(fa   , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression           fae  ) { try { UnitCompiler.this.compileBoolean2(fae  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { UnitCompiler.this.compileBoolean2(scfae, dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess             lva  ) { try { UnitCompiler.this.compileBoolean2(lva  , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression         pe   ) { try { UnitCompiler.this.compileBoolean2(pe   , dst, orientation); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            rv.accept(rvv);
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private void compileBoolean2(
-        Java.Rvalue        rv,
-        CodeContext.Offset dst,        // Where to jump.
-        boolean            orientation // JUMP_IF_TRUE or JUMP_IF_FALSE.
-    ) throws CompileException {
-        IClass type = this.compileGetValue(rv);
-        IClassLoader icl = this.iClassLoader;
-        if (type == icl.BOOLEAN) {
-            this.unboxingConversion((Locatable) rv, icl.BOOLEAN, IClass.BOOLEAN);
-        } else
-        if (type != IClass.BOOLEAN) {
-            this.compileError("Not a boolean expression", rv.getLocation());
-        }
-        this.writeBranch(rv, orientation == Java.Rvalue.JUMP_IF_TRUE ? Opcode.IFNE : Opcode.IFEQ, dst);
-    }
-    private void compileBoolean2(
-        Java.UnaryOperation ue,
-        CodeContext.Offset dst,        // Where to jump.
-        boolean            orientation // JUMP_IF_TRUE or JUMP_IF_FALSE.
-    ) throws CompileException {
-        if (ue.operator == "!") {
-            this.compileBoolean(ue.operand, dst, !orientation);
-            return;
-        }
-
-        this.compileError("Boolean expression expected", ue.getLocation());
-    }
-    private void compileBoolean2(
-        Java.BinaryOperation bo,
-        CodeContext.Offset   dst,        // Where to jump.
-        boolean              orientation // JUMP_IF_TRUE or JUMP_IF_FALSE.
-    ) throws CompileException {
-
-        if (bo.op == "|" || bo.op == "^" || bo.op == "&") {
-            this.compileBoolean2((Java.Rvalue) bo, dst, orientation);
-            return;
-        }
-
-        if (bo.op == "||" || bo.op == "&&") {
-            Object lhsCV = this.getConstantValue(bo.lhs);
-            if (lhsCV instanceof Boolean) {
-                if (((Boolean) lhsCV).booleanValue() ^ bo.op == "||") {
-                    // "true && a", "false || a"
-                    this.compileBoolean(bo.rhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
-                } else {
-                    // "false && a", "true || a"
-                    this.compileBoolean(bo.lhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
-                    this.fakeCompile(bo.rhs);
-                }
-                return;
-            }
-            Object rhsCV = this.getConstantValue(bo.rhs);
-            if (rhsCV instanceof Boolean) {
-                if (((Boolean) rhsCV).booleanValue() ^ bo.op == "||") {
-                    // "a && true", "a || false"
-                    this.compileBoolean(bo.lhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
-                } else {
-                    // "a && false", "a || true"
-                    this.pop((Locatable) bo.lhs, this.compileGetValue(bo.lhs));
-                    this.compileBoolean(bo.rhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
-                }
-                return;
-            }
-            if (bo.op == "||" ^ orientation == Java.Rvalue.JUMP_IF_FALSE) {
-                this.compileBoolean(bo.lhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
-                this.compileBoolean(bo.rhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
-            } else {
-                CodeContext.Offset end = this.codeContext.new Offset();
-                this.compileBoolean(bo.lhs, end, Java.Rvalue.JUMP_IF_FALSE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
-                this.compileBoolean(bo.rhs, dst, Java.Rvalue.JUMP_IF_TRUE ^ orientation == Java.Rvalue.JUMP_IF_FALSE);
-                end.set();
-            }
-            return;
-        }
-
-        if (
-            bo.op == "==" ||
-            bo.op == "!=" ||
-            bo.op == "<=" ||
-            bo.op == ">=" ||
-            bo.op == "<"  ||
-            bo.op == ">"
-        ) {
-            int opIdx = (
-                bo.op == "==" ? 0 :
-                bo.op == "!=" ? 1 :
-                bo.op == "<"  ? 2 :
-                bo.op == ">=" ? 3 :
-                bo.op == ">"  ? 4 :
-                bo.op == "<=" ? 5 : Integer.MIN_VALUE
-            );
-            if (orientation == Java.Rvalue.JUMP_IF_FALSE) opIdx ^= 1;
-
-            // Comparison with "null".
-            {
-                boolean lhsIsNull = this.getConstantValue(bo.lhs) == Java.Rvalue.CONSTANT_VALUE_NULL;
-                boolean rhsIsNull = this.getConstantValue(bo.rhs) == Java.Rvalue.CONSTANT_VALUE_NULL;
-
-                if (lhsIsNull || rhsIsNull) {
-                    if (bo.op != "==" && bo.op != "!=") this.compileError("Operator \"" + bo.op + "\" not allowed on operand \"null\"", bo.getLocation());
-
-                    // null == x
-                    // x == null
-                    IClass ohsType = this.compileGetValue(lhsIsNull ? bo.rhs : bo.lhs);
-                    if (ohsType.isPrimitive()) this.compileError("Cannot compare \"null\" with primitive type \"" + ohsType.toString() + "\"", bo.getLocation());
-                    this.writeBranch(bo, Opcode.IFNULL + opIdx, dst);
-                    return;
-                }
-            }
-
-            IClass lhsType = this.compileGetValue(bo.lhs);
-            CodeContext.Inserter convertLhsInserter = this.codeContext.newInserter();
-            IClass rhsType = this.compileGetValue(bo.rhs);
-
-            // 15.20.1 Numerical comparison.
-            if (
-                this.getUnboxedType(lhsType).isPrimitiveNumeric() &&
-                this.getUnboxedType(rhsType).isPrimitiveNumeric() &&
-                !((bo.op == "==" || bo.op == "!=") && !lhsType.isPrimitive() && !rhsType.isPrimitive())
-            ) {
-                IClass promotedType = this.binaryNumericPromotion((Locatable) bo, lhsType, convertLhsInserter, rhsType);
-                if (promotedType == IClass.INT) {
-                    this.writeBranch(bo, Opcode.IF_ICMPEQ + opIdx, dst);
-                } else
-                if (promotedType == IClass.LONG) {
-                    this.writeOpcode(bo, Opcode.LCMP);
-                    this.writeBranch(bo, Opcode.IFEQ + opIdx, dst);
-                } else
-                if (promotedType == IClass.FLOAT) {
-                    this.writeOpcode(bo, Opcode.FCMPG);
-                    this.writeBranch(bo, Opcode.IFEQ + opIdx, dst);
-                } else
-                if (promotedType == IClass.DOUBLE) {
-                    this.writeOpcode(bo, Opcode.DCMPG);
-                    this.writeBranch(bo, Opcode.IFEQ + opIdx, dst);
-                } else
-                {
-                    throw new RuntimeException("Unexpected promoted type \"" + promotedType + "\"");
-                }
-                return;
-            }
-
-            // JLS3 15.21.2 Boolean Equality Operators == and !=
-            if (
-                (lhsType == IClass.BOOLEAN && this.getUnboxedType(rhsType) == IClass.BOOLEAN) ||
-                (rhsType == IClass.BOOLEAN && this.getUnboxedType(lhsType) == IClass.BOOLEAN)
-            ) {
-                if (bo.op != "==" && bo.op != "!=") this.compileError("Operator \"" + bo.op + "\" not allowed on boolean operands", bo.getLocation());
-                IClassLoader icl = this.iClassLoader;
-
-                // Unbox LHS if necessary.
-                if (lhsType == icl.BOOLEAN) {
-                    this.codeContext.pushInserter(convertLhsInserter);
-                    try {
-                        this.unboxingConversion((Locatable) bo, icl.BOOLEAN, IClass.BOOLEAN);
-                    } finally {
-                        this.codeContext.popInserter();
-                    }
-                }
-
-                // Unbox RHS if necessary.
-                if (rhsType == icl.BOOLEAN) {
-                    this.unboxingConversion((Locatable) bo, icl.BOOLEAN, IClass.BOOLEAN);
-                }
-
-                this.writeBranch(bo, Opcode.IF_ICMPEQ + opIdx, dst);
-                return;
-            }
-
-            // Reference comparison.
-            // Note: Comparison with "null" is already handled above.
-            if (
-                !lhsType.isPrimitive() &&
-                !rhsType.isPrimitive()
-            ) {
-                if (bo.op != "==" && bo.op != "!=") this.compileError("Operator \"" + bo.op + "\" not allowed on reference operands", bo.getLocation());
-                this.writeBranch(bo, Opcode.IF_ACMPEQ + opIdx, dst);
-                return;
-            }
-
-            this.compileError("Cannot compare types \"" + lhsType + "\" and \"" + rhsType + "\"", bo.getLocation());
-        }
-
-        this.compileError("Boolean expression expected", bo.getLocation());
-    }
-    private void compileBoolean2(
-        Java.ParenthesizedExpression pe,
-        CodeContext.Offset dst,
-        boolean orientation
-    ) throws CompileException {
-        this.compileBoolean(pe.value, dst, orientation);
-    }
-
-    /**
-     * Generates code that determines the context of the {@link
-     * Java.Rvalue} and puts it on the operand stack. Most expressions
-     * do not have a "context", but some do. E.g. for "x[y]", the context
-     * is "x, y". The bottom line is that for statements like "x[y] += 3"
-     * the context is only evaluated once.
-     *
-     * @return The size of the context on the operand stack
-     */
-    private int compileContext(Java.Rvalue rv) throws CompileException {
-        final int[] res = new int[1];
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
-            public void visitArrayLength                   (Java.ArrayLength                    al  ) { try { res[0] = UnitCompiler.this.compileContext2(al  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitAssignment                    (Java.Assignment                     a   ) {       res[0] = UnitCompiler.this.compileContext2(a   );                                                                }
-            public void visitUnaryOperation                (Java.UnaryOperation                 uo  ) {       res[0] = UnitCompiler.this.compileContext2(uo  );                                                                }
-            public void visitBinaryOperation               (Java.BinaryOperation                bo  ) {       res[0] = UnitCompiler.this.compileContext2(bo  );                                                                }
-            public void visitCast                          (Java.Cast                           c   ) {       res[0] = UnitCompiler.this.compileContext2(c   );                                                                }
-            public void visitClassLiteral                  (Java.ClassLiteral                   cl  ) {       res[0] = UnitCompiler.this.compileContext2(cl  );                                                                }
-            public void visitConditionalExpression         (Java.ConditionalExpression          ce  ) {       res[0] = UnitCompiler.this.compileContext2(ce  );                                                                }
-            public void visitCrement                       (Java.Crement                        c   ) {       res[0] = UnitCompiler.this.compileContext2(c   );                                                                }
-            public void visitInstanceof                    (Java.Instanceof                     io  ) {       res[0] = UnitCompiler.this.compileContext2(io  );                                                                }
-            public void visitMethodInvocation              (Java.MethodInvocation               mi  ) {       res[0] = UnitCompiler.this.compileContext2(mi  );                                                                }
-            public void visitSuperclassMethodInvocation    (Java.SuperclassMethodInvocation     smi ) {       res[0] = UnitCompiler.this.compileContext2(smi );                                                                }
-            public void visitLiteral                       (Java.Literal                        l   ) {       res[0] = UnitCompiler.this.compileContext2(l   );                                                                }
-            public void visitNewAnonymousClassInstance     (Java.NewAnonymousClassInstance      naci) {       res[0] = UnitCompiler.this.compileContext2(naci);                                                                }
-            public void visitNewArray                      (Java.NewArray                       na  ) {       res[0] = UnitCompiler.this.compileContext2(na  );                                                                }
-            public void visitNewInitializedArray           (Java.NewInitializedArray            nia ) {       res[0] = UnitCompiler.this.compileContext2(nia );                                                                }
-            public void visitNewClassInstance              (Java.NewClassInstance               nci ) {       res[0] = UnitCompiler.this.compileContext2(nci );                                                                }
-            public void visitParameterAccess               (Java.ParameterAccess                pa  ) {       res[0] = UnitCompiler.this.compileContext2(pa  );                                                                }
-            public void visitQualifiedThisReference        (Java.QualifiedThisReference         qtr ) {       res[0] = UnitCompiler.this.compileContext2(qtr );                                                                }
-            public void visitThisReference                 (Java.ThisReference                  tr  ) {       res[0] = UnitCompiler.this.compileContext2(tr  );                                                                }
-
-            public void visitAmbiguousName                  (Java.AmbiguousName                   an   ) { try { res[0] = UnitCompiler.this.compileContext2(an   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression           aae  ) { try { res[0] = UnitCompiler.this.compileContext2(aae  ); } catch (CompileException e) { throw new UCE(e); } };
-            public void visitFieldAccess                    (Java.FieldAccess                     fa   ) { try { res[0] = UnitCompiler.this.compileContext2(fa   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression           fae  ) { try { res[0] = UnitCompiler.this.compileContext2(fae  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { res[0] = UnitCompiler.this.compileContext2(scfae); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess             lva  ) {       res[0] = UnitCompiler.this.compileContext2(lva  );                                                                }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression         pe   ) { try { res[0] = UnitCompiler.this.compileContext2(pe   ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            rv.accept(rvv);
-            return res[0];
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private int compileContext2(Java.Rvalue rv) {
-        return 0;
-    }
-    private int compileContext2(Java.AmbiguousName an) throws CompileException {
-        return this.compileContext(this.toRvalueOrCE(this.reclassify(an)));
-    }
-    private int compileContext2(Java.FieldAccess fa) throws CompileException {
-        if (fa.field.isStatic()) {
-            this.getType(this.toTypeOrCE(fa.lhs));
-            return 0;
-        } else {
-            this.compileGetValue(this.toRvalueOrCE(fa.lhs));
-            return 1;
-        }
-    }
-    private int compileContext2(Java.ArrayLength al) throws CompileException {
-        if (!this.compileGetValue(al.lhs).isArray()) this.compileError("Cannot determine length of non-array type", al.getLocation());
-        return 1;
-    }
-    private int compileContext2(Java.ArrayAccessExpression aae) throws CompileException {
-        IClass lhsType = this.compileGetValue(aae.lhs);
-        if (!lhsType.isArray()) this.compileError("Subscript not allowed on non-array type \"" + lhsType.toString() + "\"", aae.getLocation());
-
-        IClass indexType = this.compileGetValue(aae.index);
-        if (
-            !this.tryIdentityConversion(indexType, IClass.INT) &&
-            !this.tryWideningPrimitiveConversion(
-                (Locatable) aae, // l
-                indexType,       // sourceType
-                IClass.INT       // targetType
-            )
-        ) this.compileError("Index expression of type \"" + indexType + "\" cannot be widened to \"int\"", aae.getLocation());
-
-        return 2;
-    }
-    private int compileContext2(Java.FieldAccessExpression fae) throws CompileException {
-        this.determineValue(fae);
-        return this.compileContext(fae.value);
-    }
-    private int compileContext2(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
-        this.determineValue(scfae);
-        return this.compileContext(scfae.value);
-    }
-    private int compileContext2(Java.ParenthesizedExpression pe) throws CompileException {
-        return this.compileContext(pe.value);
-    }
-
-    /**
-     * Generates code that determines the value of the {@link Java.Rvalue}
-     * and puts it on the operand stack. This method relies on that the
-     * "context" of the {@link Java.Rvalue} is on top of the operand stack
-     * (see {@link #compileContext(Java.Rvalue)}).
-     *
-     * @return The type of the {@link Java.Rvalue}
-     */
-    private IClass compileGet(Java.Rvalue rv) throws CompileException {
-        final IClass[] res = new IClass[1];
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
-            public void visitArrayLength                   (Java.ArrayLength                    al  ) {       res[0] = UnitCompiler.this.compileGet2(al  );                                                                }
-            public void visitAssignment                    (Java.Assignment                     a   ) { try { res[0] = UnitCompiler.this.compileGet2(a   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitUnaryOperation                (Java.UnaryOperation                 uo  ) { try { res[0] = UnitCompiler.this.compileGet2(uo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBinaryOperation               (Java.BinaryOperation                bo  ) { try { res[0] = UnitCompiler.this.compileGet2(bo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCast                          (Java.Cast                           c   ) { try { res[0] = UnitCompiler.this.compileGet2(c   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitClassLiteral                  (Java.ClassLiteral                   cl  ) { try { res[0] = UnitCompiler.this.compileGet2(cl  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitConditionalExpression         (Java.ConditionalExpression          ce  ) { try { res[0] = UnitCompiler.this.compileGet2(ce  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCrement                       (Java.Crement                        c   ) { try { res[0] = UnitCompiler.this.compileGet2(c   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitInstanceof                    (Java.Instanceof                     io  ) { try { res[0] = UnitCompiler.this.compileGet2(io  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitMethodInvocation              (Java.MethodInvocation               mi  ) { try { res[0] = UnitCompiler.this.compileGet2(mi  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassMethodInvocation    (Java.SuperclassMethodInvocation     smi ) { try { res[0] = UnitCompiler.this.compileGet2(smi ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLiteral                       (Java.Literal                        l   ) { try { res[0] = UnitCompiler.this.compileGet2(l   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewAnonymousClassInstance     (Java.NewAnonymousClassInstance      naci) { try { res[0] = UnitCompiler.this.compileGet2(naci); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewArray                      (Java.NewArray                       na  ) { try { res[0] = UnitCompiler.this.compileGet2(na  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewInitializedArray           (Java.NewInitializedArray            nia ) { try { res[0] = UnitCompiler.this.compileGet2(nia ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewClassInstance              (Java.NewClassInstance               nci ) { try { res[0] = UnitCompiler.this.compileGet2(nci ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitParameterAccess               (Java.ParameterAccess                pa  ) { try { res[0] = UnitCompiler.this.compileGet2(pa  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitQualifiedThisReference        (Java.QualifiedThisReference         qtr ) { try { res[0] = UnitCompiler.this.compileGet2(qtr ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitThisReference                 (Java.ThisReference                  tr  ) { try { res[0] = UnitCompiler.this.compileGet2(tr  ); } catch (CompileException e) { throw new UCE(e); } }
-
-            public void visitAmbiguousName                  (Java.AmbiguousName                   an   ) { try { res[0] = UnitCompiler.this.compileGet2(an   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression           aae  ) { try { res[0] = UnitCompiler.this.compileGet2(aae  ); } catch (CompileException e) { throw new UCE(e); } };
-            public void visitFieldAccess                    (Java.FieldAccess                     fa   ) { try { res[0] = UnitCompiler.this.compileGet2(fa   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression           fae  ) { try { res[0] = UnitCompiler.this.compileGet2(fae  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { res[0] = UnitCompiler.this.compileGet2(scfae); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess             lva  ) {       res[0] = UnitCompiler.this.compileGet2(lva  );                                                                }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression         pe   ) { try { res[0] = UnitCompiler.this.compileGet2(pe   ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            rv.accept(rvv);
-            return res[0];
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private IClass compileGet2(Java.BooleanRvalue brv) throws CompileException {
-        CodeContext.Offset isTrue = this.codeContext.new Offset();
-        this.compileBoolean(brv, isTrue, Java.Rvalue.JUMP_IF_TRUE);
-        this.writeOpcode(brv, Opcode.ICONST_0);
-        CodeContext.Offset end = this.codeContext.new Offset();
-        this.writeBranch(brv, Opcode.GOTO, end);
-        isTrue.set();
-        this.writeOpcode(brv, Opcode.ICONST_1);
-        end.set();
-
-        return IClass.BOOLEAN;
-    }
-    private IClass compileGet2(Java.AmbiguousName an) throws CompileException {
-        return this.compileGet(this.toRvalueOrCE(this.reclassify(an)));
-    }
-    private IClass compileGet2(Java.LocalVariableAccess lva) {
-        return this.load((Locatable) lva, lva.localVariable);
-    }
-    private IClass compileGet2(Java.FieldAccess fa) throws CompileException {
-        this.checkAccessible(fa.field, fa.getEnclosingBlockStatement());
-        if (fa.field.isStatic()) {
-            this.writeOpcode(fa, Opcode.GETSTATIC);
-        } else {
-            this.writeOpcode(fa, Opcode.GETFIELD);
-        }
-        this.writeConstantFieldrefInfo(
-            fa.field.getDeclaringIClass().getDescriptor(),
-            fa.field.getName(), // classFD
-            fa.field.getType().getDescriptor()             // fieldFD
-        );
-        return fa.field.getType();
-    }
-    private IClass compileGet2(Java.ArrayLength al) {
-        this.writeOpcode(al, Opcode.ARRAYLENGTH);
-        return IClass.INT;
-    }
-    private IClass compileGet2(Java.ThisReference tr) throws CompileException {
-        this.referenceThis((Locatable) tr);
-        return this.getIClass(tr);
-    }
-    private IClass compileGet2(Java.QualifiedThisReference qtr) throws CompileException {
-        this.referenceThis(
-            (Locatable) qtr,                           // l
-            this.getDeclaringClass(qtr),               // declaringClass
-            this.getDeclaringTypeBodyDeclaration(qtr), // declaringTypeBodyDeclaration
-            this.getTargetIClass(qtr)                  // targetIClass
-        );
-        return this.getTargetIClass(qtr);
-    }
-    private IClass compileGet2(Java.ClassLiteral cl) throws CompileException {
-        Location loc = cl.getLocation();
-        final IClassLoader icl = this.iClassLoader;
-        IClass iClass = this.getType(cl.type);
-
-        if (iClass.isPrimitive()) {
-
-            // Primitive class literal.
-            this.writeOpcode(cl, Opcode.GETSTATIC);
-            String wrapperClassDescriptor = (
-                iClass == IClass.VOID    ? "Ljava/lang/Void;"      :
-                iClass == IClass.BYTE    ? "Ljava/lang/Byte;"      :
-                iClass == IClass.CHAR    ? "Ljava/lang/Character;" :
-                iClass == IClass.DOUBLE  ? "Ljava/lang/Double;"    :
-                iClass == IClass.FLOAT   ? "Ljava/lang/Float;"     :
-                iClass == IClass.INT     ? "Ljava/lang/Integer;"   :
-                iClass == IClass.LONG    ? "Ljava/lang/Long;"      :
-                iClass == IClass.SHORT   ? "Ljava/lang/Short;"     :
-                iClass == IClass.BOOLEAN ? "Ljava/lang/Boolean;"   :
-                null
-            );
-            if (wrapperClassDescriptor == null) throw new RuntimeException("SNO: Unidentifiable primitive type \"" + iClass + "\"");
-
-            this.writeConstantFieldrefInfo(
-                wrapperClassDescriptor,
-                "TYPE", // classFD
-                "Ljava/lang/Class;"     // fieldFD
-            );
-            return icl.CLASS;
-        }
-
-        // Non-primitive class literal.
-
-        Java.AbstractTypeDeclaration declaringType;
-        for (Java.Scope s = cl.getEnclosingBlockStatement();; s = s.getEnclosingScope()) {
-            if (s instanceof Java.TypeDeclaration) {
-                declaringType = (Java.AbstractTypeDeclaration) s;
-                break;
-            }
-        }
-
-        // Check if synthetic method "static Class class$(String className)" is already
-        // declared.
-        if (declaringType.getMethodDeclaration("class$") == null) this.declareClassDollarMethod(cl);
-
-        // Determine the statics of the declaring class (this is where static fields
-        // declarations are found).
-        List statics; // TypeBodyDeclaration
-        if (declaringType instanceof Java.ClassDeclaration) {
-            statics = ((Java.ClassDeclaration) declaringType).variableDeclaratorsAndInitializers;
-        } else
-        if (declaringType instanceof Java.InterfaceDeclaration) {
-            statics = ((Java.InterfaceDeclaration) declaringType).constantDeclarations;
-        } else {
-            throw new RuntimeException("SNO: AbstractTypeDeclaration is neither ClassDeclaration nor InterfaceDeclaration");
-        }
-
-        String className = Descriptor.toClassName(iClass.getDescriptor());
-
-        // Compose the "class-dollar" field name. This i done as follows:
-        //   Type         Class-name           Field-name
-        //   String       java.lang.String     class$java$lang$String
-        //   String[]     [Ljava.lang.String;  array$Ljava$lang$String
-        //   String[][]   [[Ljava.lang.String; array$$Ljava$lang$String
-        //   String[][][] [[[java.lang.String; array$$$Ljava$lang$String
-        //   int[]        [I                   array$I
-        //   int[][]      [[I                  array$$I
-        String classDollarFieldName;
-        {
-            if (className.startsWith("[")) {
-                classDollarFieldName = "array" + className.replace('.', '$').replace('[', '$');
-                if (classDollarFieldName.endsWith(";")) classDollarFieldName = classDollarFieldName.substring(0, classDollarFieldName.length() - 1);
-            } else
-            {
-                classDollarFieldName = "class$" + className.replace('.', '$');
-            }
-        }
-
-        // Declare the static "class dollar field" if not already done.
-        {
-            boolean hasClassDollarField = false;
-            BLOCK_STATEMENTS: for (Iterator it = statics.iterator(); it.hasNext();) {
-                Java.TypeBodyDeclaration tbd = (Java.TypeBodyDeclaration) it.next();
-                if (!tbd.isStatic()) continue;
-                if (tbd instanceof Java.FieldDeclaration) {
-                    Java.FieldDeclaration fd = (Java.FieldDeclaration) tbd;
-                    IClass.IField[] fds = this.getIFields(fd);
-                    for (int j = 0; j < fds.length; ++j) {
-                        if (fds[j].getName().equals(classDollarFieldName)) {
-                            hasClassDollarField = true;
-                            break BLOCK_STATEMENTS;
-                        }
-                    }
-                }
-            }
-            if (!hasClassDollarField) {
-                Java.Type classType = new Java.SimpleType(loc, icl.CLASS);
-                Java.FieldDeclaration fd = new Java.FieldDeclaration(
-                    loc,                            // location
-                    null,                           // optionalDocComment
-                    Mod.STATIC,                     // modifiers
-                    classType,                      // type
-                    new Java.VariableDeclarator[] { // variableDeclarators
-                        new Java.VariableDeclarator(
-                            loc,                  // location
-                            classDollarFieldName, // name
-                            0,                    // brackets
-                            (Java.Rvalue) null    // optionalInitializer
-                        )
-                    }
-                );
-                if (declaringType instanceof Java.ClassDeclaration) {
-                    ((Java.ClassDeclaration) declaringType).addVariableDeclaratorOrInitializer(fd);
-                } else
-                if (declaringType instanceof Java.InterfaceDeclaration) {
-                    ((Java.InterfaceDeclaration) declaringType).addConstantDeclaration(fd);
-                } else {
-                    throw new RuntimeException("SNO: AbstractTypeDeclaration is neither ClassDeclaration nor InterfaceDeclaration");
-                }
-            }
-        }
-
-        // return (class$X != null) ? class$X : (class$X = class$("X"));
-        Java.Type declaringClassOrInterfaceType = new Java.SimpleType(loc, this.resolve(declaringType));
-        Java.Lvalue classDollarFieldAccess = new Java.FieldAccessExpression(
-            loc,                           // location
-            declaringClassOrInterfaceType, // lhs
-            classDollarFieldName           // fieldName
-        );
-        Java.ConditionalExpression ce = new Java.ConditionalExpression(
-            loc,                            // location
-            new Java.BinaryOperation(       // lhs
-                loc,                        // location
-                classDollarFieldAccess,     // lhs
-                "!=",                       // op
-                new Java.Literal(loc, null) // rhs
-            ),
-            classDollarFieldAccess,        // mhs
-            new Java.Assignment(           // rhs
-                loc,                       // location
-                classDollarFieldAccess,    // lhs
-                "=",                       // operator
-                new Java.MethodInvocation( // rhs
-                    loc,                           // location
-                    declaringClassOrInterfaceType, // optionalTarget
-                    "class$",                      // methodName
-                    new Java.Rvalue[] {            // arguments
-                        new Java.Literal(
-                            loc,      // location
-                            className // constantValue
-                        )
-                    }
-                )
-            )
-        );
-        ce.setEnclosingBlockStatement(cl.getEnclosingBlockStatement());
-        return this.compileGet(ce);
-    }
-    private IClass compileGet2(Java.Assignment a) throws CompileException {
-        if (a.operator == "=") {
-            int lhsCS = this.compileContext(a.lhs);
-            IClass rhsType = this.compileGetValue(a.rhs);
-            IClass lhsType = this.getType(a.lhs);
-            Object rhsCV = this.getConstantValue(a.rhs);
-            this.assignmentConversion(
-                (Locatable) a, // l
-                rhsType,       // sourceType
-                lhsType,       // targetType
-                rhsCV          // optionalConstantValue
-            );
-            this.dupx(
-                (Locatable) a, // l
-                lhsType,       // type
-                lhsCS          // x
-            );
-            this.compileSet(a.lhs);
-            return lhsType;
-        }
-
-        // Implement "|= ^= &= *= /= %= += -= <<= >>= >>>=".
-        int lhsCS = this.compileContext(a.lhs);
-        this.dup((Locatable) a, lhsCS);
-        IClass lhsType = this.compileGet(a.lhs);
-        IClass resultType = this.compileArithmeticBinaryOperation(
-            (Locatable) a,        // l
-            lhsType,              // lhsType
-            a.operator.substring( // operator
-                0,
-                a.operator.length() - 1
-            ).intern(), // <= IMPORTANT!
-            a.rhs                 // rhs
-        );
-        // Convert the result to LHS type (JLS2 15.26.2).
-        if (
-            !this.tryIdentityConversion(resultType, lhsType) &&
-            !this.tryNarrowingPrimitiveConversion(
-                (Locatable) a, // l
-                resultType,    // sourceType
-                lhsType        // destinationType
-            )
-        ) throw new RuntimeException("SNO: \"" + a.operator + "\" reconversion failed");
-        this.dupx(
-            (Locatable) a, // l
-            lhsType,       // type
-            lhsCS          // x
-        );
-        this.compileSet(a.lhs);
-        return lhsType;
-    }
-    private IClass compileGet2(Java.ConditionalExpression ce) throws CompileException {
-        IClass mhsType, rhsType;
-        CodeContext.Inserter mhsConvertInserter, rhsConvertInserter;
-        CodeContext.Offset toEnd = this.codeContext.new Offset();
-        Object cv = this.getConstantValue(ce.lhs);
-        if (cv instanceof Boolean) {
-            if (((Boolean) cv).booleanValue()) {
-                mhsType = this.compileGetValue(ce.mhs);
-                mhsConvertInserter = this.codeContext.newInserter();
-                rhsType = this.getType(ce.rhs);
-                rhsConvertInserter = null;
-            } else {
-                mhsType = this.getType(ce.mhs);
-                mhsConvertInserter = null;
-                rhsType = this.compileGetValue(ce.rhs);
-                rhsConvertInserter = this.codeContext.currentInserter();
-            }
-        } else {
-            CodeContext.Offset toRhs = this.codeContext.new Offset();
-
-            this.compileBoolean(ce.lhs, toRhs, Java.Rvalue.JUMP_IF_FALSE);
-            mhsType = this.compileGetValue(ce.mhs);
-            mhsConvertInserter = this.codeContext.newInserter();
-            this.writeBranch(ce, Opcode.GOTO, toEnd);
-            toRhs.set();
-            rhsType = this.compileGetValue(ce.rhs);
-            rhsConvertInserter = this.codeContext.currentInserter();
-        }
-
-        IClass expressionType;
-        if (mhsType == rhsType) {
-
-            // JLS 15.25.1.1
-            expressionType = mhsType;
-        } else
-        if (mhsType.isPrimitiveNumeric() && rhsType.isPrimitiveNumeric()) {
-
-            // JLS 15.25.1.2
-
-            // TODO JLS 15.25.1.2.1
-
-            // TODO JLS 15.25.1.2.2
-
-            // JLS 15.25.1.2.3
-            expressionType = this.binaryNumericPromotion(
-                (Locatable) ce,     // l
-                mhsType,            // type1
-                mhsConvertInserter, // convertInserter1
-                rhsType,            // type2
-                rhsConvertInserter  // convertInserter2
-            );
-        } else
-        if (this.getConstantValue(ce.mhs) == Java.Rvalue.CONSTANT_VALUE_NULL && !rhsType.isPrimitive()) {
-
-            // JLS 15.25.1.3 (null : ref)
-            expressionType = rhsType;
-        } else
-        if (!mhsType.isPrimitive() && this.getConstantValue(ce.rhs) == Java.Rvalue.CONSTANT_VALUE_NULL) {
-
-            // JLS 15.25.1.3 (ref : null)
-            expressionType = mhsType;
-        } else
-        if (!mhsType.isPrimitive() && !rhsType.isPrimitive()) {
-            if (mhsType.isAssignableFrom(rhsType)) {
-                expressionType = mhsType;
-            } else
-            if (rhsType.isAssignableFrom(mhsType)) {
-                expressionType = rhsType;
-            } else {
-                this.compileError("Reference types \"" + mhsType + "\" and \"" + rhsType + "\" don't match", ce.getLocation());
-                return this.iClassLoader.OBJECT;
-            }
-        } else
-        {
-            this.compileError("Incompatible expression types \"" + mhsType + "\" and \"" + rhsType + "\"", ce.getLocation());
-            return this.iClassLoader.OBJECT;
-        }
-        toEnd.set();
-
-        return expressionType;
-    }
-    private IClass compileGet2(Java.Crement c) throws CompileException {
-
-        // Optimized crement of integer local variable.
-        Java.LocalVariable lv = this.isIntLV(c);
-        if (lv != null) {
-            if (!c.pre) this.load((Locatable) c, lv);
-            this.writeOpcode(c, Opcode.IINC);
-            this.writeByte(lv.localVariableArrayIndex);
-            this.writeByte(c.operator == "++" ? 1 : -1);
-            if (c.pre) this.load((Locatable) c, lv);
-            return lv.type;
-        }
-
-        // Compile operand context.
-        int cs = this.compileContext(c.operand);
-        // DUP operand context.
-        this.dup((Locatable) c, cs);
-        // Get operand value.
-        IClass type = this.compileGet(c.operand);
-        // DUPX operand value.
-        if (!c.pre) this.dupx((Locatable) c, type, cs);
-        // Apply "unary numeric promotion".
-        IClass promotedType = this.unaryNumericPromotion((Locatable) c, type);
-        // Crement.
-        this.writeOpcode(c, UnitCompiler.ilfd(
-            promotedType,
-            Opcode.ICONST_1,
-            Opcode.LCONST_1,
-            Opcode.FCONST_1,
-            Opcode.DCONST_1
-        ));
-        if (c.operator == "++") {
-            this.writeOpcode(c, Opcode.IADD + UnitCompiler.ilfd(promotedType));
-        } else
-        if (c.operator == "--") {
-            this.writeOpcode(c, Opcode.ISUB + UnitCompiler.ilfd(promotedType));
-        } else {
-            this.compileError("Unexpected operator \"" + c.operator + "\"", c.getLocation());
-        }
-        this.reverseUnaryNumericPromotion((Locatable) c, promotedType, type);
-        // DUPX cremented operand value.
-        if (c.pre) this.dupx((Locatable) c, type, cs);
-        // Set operand.
-        this.compileSet(c.operand);
-
-        return type;
-    }
-    private IClass compileGet2(Java.ArrayAccessExpression aae) throws CompileException {
-        IClass lhsComponentType = this.getType(aae);
-        this.writeOpcode(aae, Opcode.IALOAD + UnitCompiler.ilfdabcs(lhsComponentType));
-        return lhsComponentType;
-    }
-    private IClass compileGet2(Java.FieldAccessExpression fae) throws CompileException {
-        this.determineValue(fae);
-        return this.compileGet(fae.value);
-    }
-    private IClass compileGet2(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
-        this.determineValue(scfae);
-        return this.compileGet(scfae.value);
-    }
-    private IClass compileGet2(Java.UnaryOperation uo) throws CompileException {
-        if (uo.operator == "!") {
-            return this.compileGet2((Java.BooleanRvalue) uo);
-        }
-
-        if (uo.operator == "+") {
-            return this.unaryNumericPromotion(
-                (Locatable) uo,
-                this.convertToPrimitiveNumericType((Locatable) uo, this.compileGetValue(uo.operand))
-            );
-        }
-
-        if (uo.operator == "-") {
-
-            // Special handling for negated literals.
-            if (uo.operand instanceof Java.Literal) {
-                Java.Literal l = (Java.Literal) uo.operand;
-                this.pushConstant((Locatable) uo, this.getNegatedConstantValue2(l));
-                return this.unaryNumericPromotion((Locatable) uo, this.getType2(l));
-            }
-
-            IClass promotedType = this.unaryNumericPromotion(
-                (Locatable) uo,
-                this.convertToPrimitiveNumericType((Locatable) uo, this.compileGetValue(uo.operand))
-            );
-            this.writeOpcode(uo, Opcode.INEG + UnitCompiler.ilfd(promotedType));
-            return promotedType;
-        }
-
-        if (uo.operator == "~") {
-            IClass operandType = this.compileGetValue(uo.operand);
-
-            IClass promotedType = this.unaryNumericPromotion((Locatable) uo, operandType);
-            if (promotedType == IClass.INT) {
-                this.writeOpcode(uo, Opcode.ICONST_M1);
-                this.writeOpcode(uo, Opcode.IXOR);
-                return IClass.INT;
-            }
-            if (promotedType == IClass.LONG) {
-                this.writeOpcode(uo, Opcode.LDC2_W);
-                this.writeConstantLongInfo(-1L);
-                this.writeOpcode(uo, Opcode.LXOR);
-                return IClass.LONG;
-            }
-            this.compileError("Operator \"~\" not applicable to type \"" + promotedType + "\"", uo.getLocation());
-        }
-
-        this.compileError("Unexpected operator \"" + uo.operator + "\"", uo.getLocation());
-        return this.iClassLoader.OBJECT;
-    }
-    private IClass compileGet2(Java.Instanceof io) throws CompileException {
-        IClass lhsType = this.compileGetValue(io.lhs);
-        IClass rhsType = this.getType(io.rhs);
-
-        if (rhsType.isAssignableFrom(lhsType)) {
-            this.pop((Locatable) io, lhsType);
-            this.writeOpcode(io, Opcode.ICONST_1);
-        } else
-        if (
-            lhsType.isInterface() ||
-            rhsType.isInterface() ||
-            lhsType.isAssignableFrom(rhsType)
-        ) {
-            this.writeOpcode(io, Opcode.INSTANCEOF);
-            this.writeConstantClassInfo(rhsType.getDescriptor());
-        } else {
-            this.compileError("\"" + lhsType + "\" can never be an instance of \"" + rhsType + "\"", io.getLocation());
-        }
-        return IClass.BOOLEAN;
-    }
-    private IClass compileGet2(Java.BinaryOperation bo) throws CompileException {
-        if (
-            bo.op == "||" ||
-            bo.op == "&&" ||
-            bo.op == "==" ||
-            bo.op == "!=" ||
-            bo.op == "<"  ||
-            bo.op == ">"  ||
-            bo.op == "<=" ||
-            bo.op == ">="
-        ) {
-            // Eventually calls "compileBoolean()".
-            return this.compileGet2((Java.BooleanRvalue) bo);
-        }
-
-        // Implements "| ^ & * / % + - << >> >>>".
-        return this.compileArithmeticOperation(
-            (Locatable) bo,             // l
-            null,                       // type
-            bo.unrollLeftAssociation(), // operands
-            bo.op                       // operator
-        );
-    }
-    private IClass compileGet2(Java.Cast c) throws CompileException {
-
-        // JLS3 5.5 Casting Conversion
-        IClass tt = this.getType(c.targetType);
-        IClass vt = this.compileGetValue(c.value);
-        if (
-            !this.tryIdentityConversion(vt, tt) &&
-            !this.tryWideningPrimitiveConversion((Locatable) c, vt, tt) &&
-            !this.tryNarrowingPrimitiveConversion((Locatable) c, vt, tt) &&
-            !this.tryWideningReferenceConversion(vt, tt) &&
-            !this.tryNarrowingReferenceConversion((Locatable) c, vt, tt) &&
-            !this.tryBoxingConversion((Locatable) c, vt, tt) &&
-            !this.tryUnboxingConversion((Locatable) c, vt, tt)
-        ) this.compileError("Cannot cast \"" + vt + "\" to \"" + tt + "\"", c.getLocation());
-        return tt;
-    }
-    private IClass compileGet2(Java.ParenthesizedExpression pe) throws CompileException {
-        return this.compileGet(pe.value);
-    }
-    private IClass compileGet2(Java.MethodInvocation mi) throws CompileException {
-        IClass.IMethod iMethod = this.findIMethod(mi);
-
-        if (mi.optionalTarget == null) {
-
-            // JLS2 6.5.7.1, 15.12.4.1.1.1
-            Java.TypeBodyDeclaration scopeTBD;
-            Java.ClassDeclaration    scopeClassDeclaration;
-            {
-                Java.Scope s;
-                for (s = mi.getEnclosingBlockStatement(); !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
-                scopeTBD = (Java.TypeBodyDeclaration) s;
-                if (!(s instanceof Java.ClassDeclaration)) s = s.getEnclosingScope();
-                scopeClassDeclaration = (Java.ClassDeclaration) s;
-            }
-            if (iMethod.isStatic()) {
-                this.warning("IASM", "Implicit access to static method \"" + iMethod.toString() + "\"", mi.getLocation());
-                // JLS2 15.12.4.1.1.1.1
-                ;
-            } else {
-                this.warning("IANSM", "Implicit access to non-static method \"" + iMethod.toString() + "\"", mi.getLocation());
-                // JLS2 15.12.4.1.1.1.2
-                if (scopeTBD.isStatic()) this.compileError("Instance method \"" + iMethod.toString() + "\" cannot be invoked in static context", mi.getLocation());
-                this.referenceThis(
-                    (Locatable) mi,              // l
-                    scopeClassDeclaration,       // declaringClass
-                    scopeTBD,                    // declaringTypeBodyDeclaration
-                    iMethod.getDeclaringIClass() // targetIClass
-                );
-            }
-        } else {
-
-            // 6.5.7.2
-            boolean staticContext = this.isType(mi.optionalTarget);
-            if (staticContext) {
-                this.getType(this.toTypeOrCE(mi.optionalTarget));
-            } else
-            {
-                this.compileGetValue(this.toRvalueOrCE(mi.optionalTarget));
-            }
-            if (iMethod.isStatic()) {
-                if (!staticContext) {
-                    // JLS2 15.12.4.1.2.1
-                    this.pop((Locatable) mi.optionalTarget, this.getType(mi.optionalTarget));
-                }
-            } else {
-                if (staticContext) this.compileError("Instance method \"" + mi.methodName + "\" cannot be invoked in static context", mi.getLocation());
-            }
-        }
-
-        // Evaluate method parameters.
-        IClass[] parameterTypes = iMethod.getParameterTypes();
-        for (int i = 0; i < mi.arguments.length; ++i) {
-            this.assignmentConversion(
-                (Locatable) mi,                        // l
-                this.compileGetValue(mi.arguments[i]), // sourceType
-                parameterTypes[i],                     // targetType
-                this.getConstantValue(mi.arguments[i]) // optionalConstantValue
-            );
-        }
-
-        // Invoke!
-        this.checkAccessible(iMethod, mi.getEnclosingBlockStatement());
-        if (iMethod.getDeclaringIClass().isInterface()) {
-            this.writeOpcode(mi, Opcode.INVOKEINTERFACE);
-            this.writeConstantInterfaceMethodrefInfo(
-                iMethod.getDeclaringIClass().getDescriptor(),                                           // locatable
-                iMethod.getName(), // classFD
-                iMethod.getDescriptor()                       // methodMD
-            );
-            IClass[] pts = iMethod.getParameterTypes();
-            int count = 1;
-            for (int i = 0; i < pts.length; ++i) count += Descriptor.size(pts[i].getDescriptor());
-            this.writeByte(count);
-            this.writeByte(0);
-        } else {
-            if (!iMethod.isStatic() && iMethod.getAccess() == Access.PRIVATE) {
-
-                // In order to make a non-static private method invocable for enclosing types,
-                // enclosed types and types enclosed by the same type, "compile(FunctionDeclarator)"
-                // modifies it on-the-fly as follows:
-                //  + Access is changed from PRIVATE to PACKAGE
-                //  + The name is appended with "$"
-                //  + It is made static
-                //  + A parameter of type "declaring class" is prepended to the signature
-                // Hence, the invocation of such a method must be modified accordingly.
-                this.writeOpcode(mi, Opcode.INVOKESTATIC);
-                this.writeConstantMethodrefInfo(
-                    iMethod.getDeclaringIClass().getDescriptor(),                                           // locatable
-                    iMethod.getName() + '$', // classFD
-                    MethodDescriptor.prependParameter(            // methodMD
-                        iMethod.getDescriptor(),
-                        iMethod.getDeclaringIClass().getDescriptor()
-                    )
-                );
-            } else
-            {
-                byte opcode = iMethod.isStatic() ? Opcode.INVOKESTATIC : Opcode.INVOKEVIRTUAL;
-                this.writeOpcode(mi, opcode);
-                this.writeConstantMethodrefInfo(
-                    iMethod.getDeclaringIClass().getDescriptor(), // classFD
-                    iMethod.getName(),                            // methodName
-                    iMethod.getDescriptor()                       // methodMD
-                );
-            }
-        }
-        return iMethod.getReturnType();
-    }
-    private IClass compileGet2(Java.SuperclassMethodInvocation scmi) throws CompileException {
-        IClass.IMethod iMethod = this.findIMethod(scmi);
-
-        Java.Scope s;
-        for (s = scmi.getEnclosingBlockStatement(); s instanceof Java.Statement || s instanceof Java.CatchClause; s = s.getEnclosingScope());
-        Java.FunctionDeclarator fd = s instanceof Java.FunctionDeclarator ? (Java.FunctionDeclarator) s : null;
-        if (fd == null) {
-            this.compileError("Cannot invoke superclass method in non-method scope", scmi.getLocation());
-            return IClass.INT;
-        }
-        if ((fd.modifiers & Mod.STATIC) != 0) this.compileError("Cannot invoke superclass method in static context", scmi.getLocation());
-        this.load((Locatable) scmi, this.resolve(fd.getDeclaringType()), 0);
-
-        // Evaluate method parameters.
-        IClass[] parameterTypes = iMethod.getParameterTypes();
-        for (int i = 0; i < scmi.arguments.length; ++i) {
-            this.assignmentConversion(
-                (Locatable) scmi,                        // l
-                this.compileGetValue(scmi.arguments[i]), // sourceType
-                parameterTypes[i],                       // targetType
-                this.getConstantValue(scmi.arguments[i]) // optionalConstantValue
-            );
-        }
-
-        // Invoke!
-        this.writeOpcode(scmi, Opcode.INVOKESPECIAL);
-        this.writeConstantMethodrefInfo(
-            iMethod.getDeclaringIClass().getDescriptor(), // classFD
-            scmi.methodName,                              // methodName
-            iMethod.getDescriptor()                       // methodMD
-        );
-        return iMethod.getReturnType();
-    }
-    private IClass compileGet2(Java.NewClassInstance nci) throws CompileException {
-        if (nci.iClass == null) nci.iClass = this.getType(nci.type);
-
-        this.writeOpcode(nci, Opcode.NEW);
-        this.writeConstantClassInfo(nci.iClass.getDescriptor());
-        this.writeOpcode(nci, Opcode.DUP);
-
-        if (nci.iClass.isInterface()) this.compileError("Cannot instantiate \"" + nci.iClass + "\"", nci.getLocation());
-        this.checkAccessible(nci.iClass, nci.getEnclosingBlockStatement());
-        if (nci.iClass.isAbstract()) this.compileError("Cannot instantiate abstract \"" + nci.iClass + "\"", nci.getLocation());
-
-        // Determine the enclosing instance for the new object.
-        Java.Rvalue optionalEnclosingInstance;
-        if (nci.optionalQualification != null) {
-            if (nci.iClass.getOuterIClass() == null) this.compileError("Static member class cannot be instantiated with qualified NEW");
-
-            // Enclosing instance defined by qualification (JLS 15.9.2.BL1.B3.B2).
-            optionalEnclosingInstance = nci.optionalQualification;
-        } else {
-            Java.Scope s = nci.getEnclosingBlockStatement();
-            for (; !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
-            Java.TypeBodyDeclaration enclosingTypeBodyDeclaration = (Java.TypeBodyDeclaration) s;
-            Java.TypeDeclaration enclosingTypeDeclaration = (Java.TypeDeclaration) s.getEnclosingScope();
-
-            if (
-                !(enclosingTypeDeclaration instanceof Java.ClassDeclaration)
-                || enclosingTypeBodyDeclaration.isStatic()
-            ) {
-
-                // No enclosing instance in
-                //  + interface method declaration or
-                //  + static type body declaration (here: method or initializer or field declarator)
-                // context (JLS 15.9.2.BL1.B3.B1.B1).
-                if (nci.iClass.getOuterIClass() != null) this.compileError("Instantiation of \"" + nci.type + "\" requires an enclosing instance", nci.getLocation());
-                optionalEnclosingInstance = null;
-            } else {
-
-                // Determine the type of the enclosing instance for the new object.
-                IClass optionalOuterIClass = nci.iClass.getDeclaringIClass();
-                if (optionalOuterIClass == null) {
-
-                    // No enclosing instance needed for a top-level class object.
-                    optionalEnclosingInstance = null;
-                } else {
-
-                    // Find an appropriate enclosing instance for the new inner class object among
-                    // the enclosing instances of the current object (JLS
-                    // 15.9.2.BL1.B3.B1.B2).
-//                    Java.ClassDeclaration outerClassDeclaration = (Java.ClassDeclaration) enclosingTypeDeclaration;
-//                    optionalEnclosingInstance = new Java.QualifiedThisReference(
-//                        nci.getLocation(),            // location
-//                        outerClassDeclaration,        // declaringClass
-//                        enclosingTypeBodyDeclaration, // declaringTypeBodyDeclaration
-//                        optionalOuterIClass           // targetIClass
-//                    );
-                    optionalEnclosingInstance = new Java.QualifiedThisReference(
-                        nci.getLocation(),   // location
-                        new Java.SimpleType( // qualification
-                            nci.getLocation(),
-                            optionalOuterIClass
-                        )
-                    );
-                    optionalEnclosingInstance.setEnclosingBlockStatement(nci.getEnclosingBlockStatement());
-                }
-            }
-        }
-
-        this.invokeConstructor(
-            (Locatable) nci,                  // l
-            nci.getEnclosingBlockStatement(), // scope
-            optionalEnclosingInstance,        // optionalEnclosingInstance
-            nci.iClass,                       // targetClass
-            nci.arguments                     // arguments
-        );
-        return nci.iClass;
-    }
-    private IClass compileGet2(Java.NewAnonymousClassInstance naci) throws CompileException {
-
-        // Find constructors.
-        Java.AnonymousClassDeclaration acd = naci.anonymousClassDeclaration;
-        IClass sc = this.resolve(acd).getSuperclass();
-        IClass.IConstructor[] iConstructors = sc.getDeclaredIConstructors();
-        if (iConstructors.length == 0) throw new RuntimeException("SNO: Base class has no constructors");
-
-        // Determine most specific constructor.
-        IClass.IConstructor iConstructor = (IClass.IConstructor) this.findMostSpecificIInvocable(
-            (Locatable) naci, // l
-            iConstructors,    // iInvocables
-            naci.arguments    // arguments
-        );
-
-        IClass[] pts = iConstructor.getParameterTypes();
-
-        // Determine formal parameters of anonymous constructor.
-        Java.FunctionDeclarator.FormalParameter[] fps;
-        Location loc = naci.getLocation();
-        {
-            List l = new ArrayList(); // FormalParameter
-
-            // Pass the enclosing instance of the base class as parameter #1.
-            if (naci.optionalQualification != null) l.add(new Java.FunctionDeclarator.FormalParameter(
-                loc,                                                                // location
-                true,                                                               // finaL
-                new Java.SimpleType(loc, this.getType(naci.optionalQualification)), // type
-                "this$base"                                                         // name
-            ));
-            for (int i = 0; i < pts.length; ++i) l.add(new Java.FunctionDeclarator.FormalParameter(
-                loc,                              // location
-                true,                             // finaL
-                new Java.SimpleType(loc, pts[i]), // type
-                "p" + i                           // name
-            ));
-            fps = (Java.FunctionDeclarator.FormalParameter[]) l.toArray(new Java.FunctionDeclarator.FormalParameter[l.size()]);
-        }
-
-        // Determine thrown exceptions of anonymous constructor.
-        IClass[] tes = iConstructor.getThrownExceptions();
-        Java.Type[]   tets = new Java.Type[tes.length];
-        for (int i = 0; i < tes.length; ++i) tets[i] = new Java.SimpleType(loc, tes[i]);
-
-        // The anonymous constructor merely invokes the constructor of its superclass.
-        int j = 0;
-        Java.Rvalue optionalQualificationAccess;
-        if (naci.optionalQualification == null) {
-            optionalQualificationAccess = null;
-        } else
-        {
-            optionalQualificationAccess = new Java.ParameterAccess(loc, fps[j++]);
-        }
-        Java.Rvalue[] parameterAccesses = new Java.Rvalue[pts.length];
-        for (int i = 0; i < pts.length; ++i) {
-            parameterAccesses[i] = new Java.ParameterAccess(loc, fps[j++]);
-        }
-
-        // Generate the anonymous constructor for the anonymous class (JLS 15.9.5.1).
-        acd.addConstructor(new Java.ConstructorDeclarator(
-            loc,                                 // location
-            null,                                // optionalDocComment
-            Mod.PACKAGE,                         // modifiers
-            fps,                                 // formalParameters
-            tets,                                // thrownExceptions
-            new Java.SuperConstructorInvocation( // optionalExplicitConstructorInvocation
-                loc,                         // location
-                optionalQualificationAccess, // optionalQualification
-                parameterAccesses            // arguments
-            ),
-            new Java.Block(loc)                  // optionalBody
-        ));
-
-        // Compile the anonymous class.
-        this.compile(acd);
-
-        // Instantiate the anonymous class.
-        this.writeOpcode(naci, Opcode.NEW);
-        this.writeConstantClassInfo(this.resolve(naci.anonymousClassDeclaration).getDescriptor());
-
-        // Invoke the anonymous constructor.
-        this.writeOpcode(naci, Opcode.DUP);
-        Java.Rvalue[] arguments2;
-        if (naci.optionalQualification == null) {
-            arguments2 = naci.arguments;
-        } else {
-            arguments2 = new Java.Rvalue[naci.arguments.length + 1];
-            arguments2[0] = naci.optionalQualification;
-            System.arraycopy(naci.arguments, 0, arguments2, 1, naci.arguments.length);
-        }
-
-        // Notice: The enclosing instance of the anonymous class is "this", not the
-        // qualification of the NewAnonymousClassInstance.
-        Java.Scope s;
-        for (s = naci.getEnclosingBlockStatement(); !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
-        Java.ThisReference oei;
-        if (((Java.TypeBodyDeclaration) s).isStatic()) {
-            oei = null;
-        } else
-        {
-            oei = new Java.ThisReference(loc);
-            oei.setEnclosingBlockStatement(naci.getEnclosingBlockStatement());
-        }
-        this.invokeConstructor(
-            (Locatable) naci,                               // l
-            (Java.Scope) naci.getEnclosingBlockStatement(), // scope
-            oei,                                            // optionalEnclosingInstance
-            this.resolve(naci.anonymousClassDeclaration),   // targetClass
-            arguments2                                      // arguments
-        );
-        return this.resolve(naci.anonymousClassDeclaration);
-    }
-    private IClass compileGet2(Java.ParameterAccess pa) throws CompileException {
-        Java.LocalVariable lv = this.getLocalVariable(pa.formalParameter);
-        this.load((Locatable) pa, lv);
-        return lv.type;
-    }
-    private IClass compileGet2(Java.NewArray na) throws CompileException {
-        for (int i = 0; i < na.dimExprs.length; ++i) {
-            IClass dimType = this.compileGetValue(na.dimExprs[i]);
-            if (dimType != IClass.INT && this.unaryNumericPromotion(
-                (Locatable) na, // l
-                dimType         // type
-            ) != IClass.INT) this.compileError("Invalid array size expression type", na.getLocation());
-        }
-
-        return this.newArray(
-            (Locatable) na,       // l
-            na.dimExprs.length,   // dimExprCount
-            na.dims,              // dims
-            this.getType(na.type) // componentType
-        );
-    }
-    private IClass compileGet2(Java.NewInitializedArray nia) throws CompileException {
-        IClass at = this.getType(nia.arrayType);
-        this.compileGetValue(nia.arrayInitializer, at);
-        return at;
-    }
-    private void compileGetValue(Java.ArrayInitializer ai, IClass arrayType) throws CompileException {
-        if (!arrayType.isArray()) this.compileError("Array initializer not allowed for non-array type \"" + arrayType.toString() + "\"");
-        IClass ct = arrayType.getComponentType();
-
-        this.pushConstant((Locatable) ai, new Integer(ai.values.length));
-        this.newArray(
-            (Locatable) ai, // l
-            1,              // dimExprCount,
-            0,              // dims,
-            ct              // componentType
-        );
-
-        for (int i = 0; i < ai.values.length; ++i) {
-            this.writeOpcode(ai, Opcode.DUP);
-            this.pushConstant((Locatable) ai, new Integer(i));
-            Java.ArrayInitializerOrRvalue aiorv = ai.values[i];
-            if (aiorv instanceof Java.Rvalue) {
-                Java.Rvalue rv = (Java.Rvalue) aiorv;
-                this.assignmentConversion(
-                    (Locatable) ai,           // l
-                    this.compileGetValue(rv), // sourceType
-                    ct,                       // targetType
-                    this.getConstantValue(rv) // optionalConstantValue
-                );
-            } else
-            if (aiorv instanceof Java.ArrayInitializer) {
-                this.compileGetValue((Java.ArrayInitializer) aiorv, ct);
-            } else
-            {
-                throw new RuntimeException("Unexpected array initializer or rvalue class " + aiorv.getClass().getName());
-            }
-            this.writeOpcode(ai, Opcode.IASTORE + UnitCompiler.ilfdabcs(ct));
-        }
-    }
-    private IClass compileGet2(Java.Literal l) throws CompileException {
-        if (
-            l.value == Scanner.MAGIC_INTEGER ||
-            l.value == Scanner.MAGIC_LONG
-        ) this.compileError("This literal value may only appear in a negated context", l.getLocation());
-        return this.pushConstant((Locatable) l, l.value == null ? Java.Rvalue.CONSTANT_VALUE_NULL : l.value);
-    }
-
-    /**
-     * Convenience function that calls {@link #compileContext(Java.Rvalue)}
-     * and {@link #compileGet(Java.Rvalue)}.
-     * @return The type of the Rvalue
-     */
-    private IClass compileGetValue(Java.Rvalue rv) throws CompileException {
-        Object cv = this.getConstantValue(rv);
-        if (cv != null) {
-            this.fakeCompile(rv); // To check that, e.g., "a" compiles in "true || a".
-            this.pushConstant((Locatable) rv, cv);
-            return this.getType(rv);
-        }
-
-        this.compileContext(rv);
-        return this.compileGet(rv);
-    }
-
-    // -------------------- Rvalue.getConstantValue() -----------------
-
-    /**
-     * Attempts to evaluate as a constant expression.
-     * <p>
-     * <table>
-     *   <tr><th>Expression type</th><th>Return value type</th></tr>
-     *   <tr><td>String</td><td>String</td></tr>
-     *   <tr><td>byte</td><td>Byte</td></tr>
-     *   <tr><td>short</td><td>Chort</td></tr>
-     *   <tr><td>int</td><td>Integer</td></tr>
-     *   <tr><td>boolean</td><td>Boolean</td></tr>
-     *   <tr><td>char</td><td>Character</td></tr>
-     *   <tr><td>float</td><td>Float</td></tr>
-     *   <tr><td>long</td><td>Long</td></tr>
-     *   <tr><td>double</td><td>Double</td></tr>
-     *   <tr><td>null</td><td>{@link Java.Rvalue#CONSTANT_VALUE_NULL}</td></tr>
-     * </table>
-     *
-     * @return <code>null</code> iff the rvalue is not a constant value
-     */
-    public final Object getConstantValue(Java.Rvalue rv) throws CompileException {
-        if (rv.constantValue != Java.Rvalue.CONSTANT_VALUE_UNKNOWN) return rv.constantValue;
-
-        final Object[] res = new Object[1];
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
-            public void visitArrayLength               (Java.ArrayLength                al  ) {       res[0] = UnitCompiler.this.getConstantValue2(al  );                                                    }
-            public void visitAssignment                (Java.Assignment                 a   ) {       res[0] = UnitCompiler.this.getConstantValue2(a   );                                                    }
-            public void visitUnaryOperation            (Java.UnaryOperation             uo  ) { try { res[0] = UnitCompiler.this.getConstantValue2(uo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBinaryOperation           (Java.BinaryOperation            bo  ) { try { res[0] = UnitCompiler.this.getConstantValue2(bo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCast                      (Java.Cast                       c   ) { try { res[0] = UnitCompiler.this.getConstantValue2(c   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitClassLiteral              (Java.ClassLiteral               cl  ) {       res[0] = UnitCompiler.this.getConstantValue2(cl  );                                                    }
-            public void visitConditionalExpression     (Java.ConditionalExpression      ce  ) {       res[0] = UnitCompiler.this.getConstantValue2(ce  );                                                    }
-            public void visitCrement                   (Java.Crement                    c   ) {       res[0] = UnitCompiler.this.getConstantValue2(c   );                                                    }
-            public void visitInstanceof                (Java.Instanceof                 io  ) {       res[0] = UnitCompiler.this.getConstantValue2(io  );                                                    }
-            public void visitMethodInvocation          (Java.MethodInvocation           mi  ) {       res[0] = UnitCompiler.this.getConstantValue2(mi  );                                                    }
-            public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi ) {       res[0] = UnitCompiler.this.getConstantValue2(smi );                                                    }
-            public void visitLiteral                   (Java.Literal                    l   ) { try { res[0] = UnitCompiler.this.getConstantValue2(l   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance  naci) {       res[0] = UnitCompiler.this.getConstantValue2(naci);                                                    }
-            public void visitNewArray                  (Java.NewArray                   na  ) {       res[0] = UnitCompiler.this.getConstantValue2(na  );                                                    }
-            public void visitNewInitializedArray       (Java.NewInitializedArray        nia ) {       res[0] = UnitCompiler.this.getConstantValue2(nia );                                                    }
-            public void visitNewClassInstance          (Java.NewClassInstance           nci ) {       res[0] = UnitCompiler.this.getConstantValue2(nci );                                                    }
-            public void visitParameterAccess           (Java.ParameterAccess            pa  ) {       res[0] = UnitCompiler.this.getConstantValue2(pa  );                                                    }
-            public void visitQualifiedThisReference    (Java.QualifiedThisReference     qtr ) {       res[0] = UnitCompiler.this.getConstantValue2(qtr );                                                    }
-            public void visitThisReference             (Java.ThisReference              tr  ) {       res[0] = UnitCompiler.this.getConstantValue2(tr  );                                                    }
-
-            public void visitAmbiguousName                  (Java.AmbiguousName                   an   ) { try { res[0] = UnitCompiler.this.getConstantValue2(an   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression           aae  ) {       res[0] = UnitCompiler.this.getConstantValue2(aae  );                                                    }
-            public void visitFieldAccess                    (Java.FieldAccess                     fa   ) { try { res[0] = UnitCompiler.this.getConstantValue2(fa   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression           fae  ) {       res[0] = UnitCompiler.this.getConstantValue2(fae  );                                                    }
-            public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) {       res[0] = UnitCompiler.this.getConstantValue2(scfae);                                                    }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess             lva  ) {       res[0] = UnitCompiler.this.getConstantValue2(lva  );                                                    }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression         pe   ) { try { res[0] = UnitCompiler.this.getConstantValue2(pe   ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            rv.accept(rvv);
-            rv.constantValue = res[0];
-            return rv.constantValue;
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private Object getConstantValue2(Java.Rvalue rv) {
-        return null;
-    }
-    private Object getConstantValue2(Java.AmbiguousName an) throws CompileException {
-        return this.getConstantValue(this.toRvalueOrCE(this.reclassify(an)));
-    }
-    private Object getConstantValue2(Java.FieldAccess fa) throws CompileException {
-        return fa.field.getConstantValue();
-    }
-    private Object getConstantValue2(Java.UnaryOperation uo) throws CompileException {
-        if (uo.operator.equals("+")) return this.getConstantValue(uo.operand);
-        if (uo.operator.equals("-")) return this.getNegatedConstantValue(uo.operand);
-        if (uo.operator.equals("!")) {
-            Object cv = this.getConstantValue(uo.operand);
-            return cv instanceof Boolean ? (
-                ((Boolean) cv).booleanValue() ? Boolean.FALSE : Boolean.TRUE
-            ) : null;
-        }
-        return null;
-    }
-    private Object getConstantValue2(Java.BinaryOperation bo) throws CompileException {
-
-        // null == null
-        // null != null
-        if (
-            (bo.op == "==" || bo.op == "!=") &&
-            this.getConstantValue(bo.lhs) == Java.Rvalue.CONSTANT_VALUE_NULL &&
-            this.getConstantValue(bo.rhs) == Java.Rvalue.CONSTANT_VALUE_NULL
-        ) return bo.op == "==" ? Boolean.TRUE : Boolean.FALSE;
-
-        // "|", "^", "&", "*", "/", "%", "+", "-".
-        if (
-            bo.op == "|" ||
-            bo.op == "^" ||
-            bo.op == "&" ||
-            bo.op == "*" ||
-            bo.op == "/" ||
-            bo.op == "%" ||
-            bo.op == "+" ||
-            bo.op == "-"
-        ) {
-
-            // Unroll the constant operands.
-            List cvs = new ArrayList();
-            for (Iterator it = bo.unrollLeftAssociation(); it.hasNext();) {
-                Object cv = this.getConstantValue(((Java.Rvalue) it.next()));
-                if (cv == null) return null;
-                cvs.add(cv);
-            }
-
-            // Compute the constant value of the unrolled binary operation.
-            Iterator it = cvs.iterator();
-            Object lhs = it.next();
-            while (it.hasNext()) {
-                Object rhs = it.next();
-
-                // String concatenation?
-                if (bo.op == "+" && (lhs instanceof String || rhs instanceof String)) {
-                    StringBuffer sb = new StringBuffer();
-                    sb.append(lhs.toString()).append(rhs.toString());
-                    while (it.hasNext()) sb.append(it.next().toString());
-                    return sb.toString();
-                }
-
-                if (!(lhs instanceof Number) || !(rhs instanceof Number)) return null;
-
-                try {
-                    // Numeric binary operation.
-                    if (lhs instanceof Double || rhs instanceof Double) {
-                        double lhsD = ((Number) lhs).doubleValue();
-                        double rhsD = ((Number) rhs).doubleValue();
-                        double cvD;
-                        if (bo.op == "*") cvD = lhsD * rhsD; else
-                        if (bo.op == "/") cvD = lhsD / rhsD; else
-                        if (bo.op == "%") cvD = lhsD % rhsD; else
-                        if (bo.op == "+") cvD = lhsD + rhsD; else
-                        if (bo.op == "-") cvD = lhsD - rhsD; else return null;
-                        lhs = new Double(cvD);
-                    } else
-                    if (lhs instanceof Float || rhs instanceof Float) {
-                        float lhsF = ((Number) lhs).floatValue();
-                        float rhsF = ((Number) rhs).floatValue();
-                        float cvF;
-                        if (bo.op == "*") cvF = lhsF * rhsF; else
-                        if (bo.op == "/") cvF = lhsF / rhsF; else
-                        if (bo.op == "%") cvF = lhsF % rhsF; else
-                        if (bo.op == "+") cvF = lhsF + rhsF; else
-                        if (bo.op == "-") cvF = lhsF - rhsF; else return null;
-                        lhs = new Float(cvF);
-                    } else
-                    if (lhs instanceof Long || rhs instanceof Long) {
-                        long lhsL = ((Number) lhs).longValue();
-                        long rhsL = ((Number) rhs).longValue();
-                        long cvL;
-                        if (bo.op == "|") cvL = lhsL | rhsL; else
-                        if (bo.op == "^") cvL = lhsL ^ rhsL; else
-                        if (bo.op == "&") cvL = lhsL & rhsL; else
-                        if (bo.op == "*") cvL = lhsL * rhsL; else
-                        if (bo.op == "/") cvL = lhsL / rhsL; else
-                        if (bo.op == "%") cvL = lhsL % rhsL; else
-                        if (bo.op == "+") cvL = lhsL + rhsL; else
-                        if (bo.op == "-") cvL = lhsL - rhsL; else return null;
-                        lhs = new Long(cvL);
-                    } else
-                    {
-                        int lhsI = ((Number) lhs).intValue();
-                        int rhsI = ((Number) rhs).intValue();
-                        int cvI;
-                        if (bo.op == "|") cvI = lhsI | rhsI; else
-                        if (bo.op == "^") cvI = lhsI ^ rhsI; else
-                        if (bo.op == "&") cvI = lhsI & rhsI; else
-                        if (bo.op == "*") cvI = lhsI * rhsI; else
-                        if (bo.op == "/") cvI = lhsI / rhsI; else
-                        if (bo.op == "%") cvI = lhsI % rhsI; else
-                        if (bo.op == "+") cvI = lhsI + rhsI; else
-                        if (bo.op == "-") cvI = lhsI - rhsI; else return null;
-                        lhs = new Integer(cvI);
-                    }
-                } catch (ArithmeticException ae) {
-                    // Most likely a div by zero or mod by zero.
-                    // Guess we can't make this expression into a constant.
-                    return null;
-                }
-            }
-            return lhs;
-        }
-
-        // "&&" and "||" with constant LHS operand.
-        if (
-            bo.op == "&&" ||
-            bo.op == "||"
-        ) {
-            Object lhsValue = this.getConstantValue(bo.lhs);
-            if (lhsValue instanceof Boolean) {
-                boolean lhsBV = ((Boolean) lhsValue).booleanValue();
-                return (
-                    bo.op == "&&" ?
-                    (lhsBV ? this.getConstantValue(bo.rhs) : Boolean.FALSE) :
-                    (lhsBV ? Boolean.TRUE : this.getConstantValue(bo.rhs))
-                );
-            }
-        }
-
-        return null;
-    }
-    private Object getConstantValue2(Java.Cast c) throws CompileException {
-        Object cv = this.getConstantValue(c.value);
-        if (cv == null) return null;
-
-        if (cv instanceof Number) {
-            IClass tt = this.getType(c.targetType);
-            if (tt == IClass.BYTE  ) return new Byte(((Number) cv).byteValue());
-            if (tt == IClass.SHORT ) return new Short(((Number) cv).shortValue());
-            if (tt == IClass.INT   ) return new Integer(((Number) cv).intValue());
-            if (tt == IClass.LONG  ) return new Long(((Number) cv).longValue());
-            if (tt == IClass.FLOAT ) return new Float(((Number) cv).floatValue());
-            if (tt == IClass.DOUBLE) return new Double(((Number) cv).doubleValue());
-        }
-
-        return null;
-    }
-    private Object getConstantValue2(Java.ParenthesizedExpression pe) throws CompileException {
-        return this.getConstantValue(pe.value);
-    }
-    private Object getConstantValue2(Java.Literal l) throws CompileException {
-        if (
-            l.value == Scanner.MAGIC_INTEGER ||
-            l.value == Scanner.MAGIC_LONG
-        ) this.compileError("This literal value may only appear in a negated context", l.getLocation());
-        return l.value == null ? Java.Rvalue.CONSTANT_VALUE_NULL : l.value;
-    }
-
-    /**
-     * Attempts to evaluate the negated value of a constant {@link Java.Rvalue}.
-     * This is particularly relevant for the smallest value of an integer or
-     * long literal.
-     *
-     * @return null if value is not constant; otherwise a String, Byte,
-     * Short, Integer, Boolean, Character, Float, Long or Double
-     */
-    private final Object getNegatedConstantValue(Java.Rvalue rv) throws CompileException {
-        final Object[] res = new Object[1];
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.RvalueVisitor rvv = new Visitor.RvalueVisitor() {
-            public void visitArrayLength               (Java.ArrayLength                al  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(al  );                                                                }
-            public void visitAssignment                (Java.Assignment                 a   ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(a   );                                                                }
-            public void visitUnaryOperation            (Java.UnaryOperation             uo  ) { try { res[0] = UnitCompiler.this.getNegatedConstantValue2(uo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBinaryOperation           (Java.BinaryOperation            bo  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(bo  );                                                                }
-            public void visitCast                      (Java.Cast                       c   ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(c   );                                                                }
-            public void visitClassLiteral              (Java.ClassLiteral               cl  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(cl  );                                                                }
-            public void visitConditionalExpression     (Java.ConditionalExpression      ce  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(ce  );                                                                }
-            public void visitCrement                   (Java.Crement                    c   ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(c   );                                                                }
-            public void visitInstanceof                (Java.Instanceof                 io  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(io  );                                                                }
-            public void visitMethodInvocation          (Java.MethodInvocation           mi  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(mi  );                                                                }
-            public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(smi );                                                                }
-            public void visitLiteral                   (Java.Literal                    l   ) { try { res[0] = UnitCompiler.this.getNegatedConstantValue2(l   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance  naci) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(naci);                                                                }
-            public void visitNewArray                  (Java.NewArray                   na  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(na  );                                                                }
-            public void visitNewInitializedArray       (Java.NewInitializedArray        nia ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(nia );                                                                }
-            public void visitNewClassInstance          (Java.NewClassInstance           nci ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(nci );                                                                }
-            public void visitParameterAccess           (Java.ParameterAccess            pa  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(pa  );                                                                }
-            public void visitQualifiedThisReference    (Java.QualifiedThisReference     qtr ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(qtr );                                                                }
-            public void visitThisReference             (Java.ThisReference              tr  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(tr  );                                                                }
-
-            public void visitAmbiguousName                  (Java.AmbiguousName                   an   ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(an   );                                                    }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression           aae  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(aae  );                                                    }
-            public void visitFieldAccess                    (Java.FieldAccess                     fa   ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(fa   );                                                    }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression           fae  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(fae  );                                                    }
-            public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(scfae);                                                    }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess             lva  ) {       res[0] = UnitCompiler.this.getNegatedConstantValue2(lva  );                                                    }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression         pe   ) { try { res[0] = UnitCompiler.this.getNegatedConstantValue2(pe   ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            rv.accept(rvv);
-            return res[0];
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private Object getNegatedConstantValue2(Java.Rvalue rv) {
-        return null;
-    }
-    private Object getNegatedConstantValue2(Java.UnaryOperation uo) throws CompileException {
-        return (
-            uo.operator.equals("+") ? this.getNegatedConstantValue(uo.operand) :
-            uo.operator.equals("-") ? this.getConstantValue(uo.operand) :
-            null
-        );
-    }
-    private Object getNegatedConstantValue2(Java.ParenthesizedExpression pe) throws CompileException {
-        return this.getNegatedConstantValue(pe.value);
-    }
-    private Object getNegatedConstantValue2(Java.Literal l) throws CompileException {
-        if (l.value instanceof Integer) return new Integer(-((Integer) l.value).intValue()   );
-        if (l.value instanceof Long   ) return new Long   (-((Long   ) l.value).longValue()  );
-        if (l.value instanceof Float  ) return new Float  (-((Float  ) l.value).floatValue() );
-        if (l.value instanceof Double ) return new Double (-((Double ) l.value).doubleValue());
-
-        this.compileError("Cannot negate this literal", l.getLocation());
-        return null;
-    }
-
-    // ------------ BlockStatement.generatesCode() -------------
-
-    /**
-     * Check whether invocation of {@link #compile(Java.BlockStatement)} would
-     * generate more than zero code bytes.
-     */
-    private boolean generatesCode(Java.BlockStatement bs) throws CompileException {
-        final boolean[] res = new boolean[1];
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.BlockStatementVisitor bsv = new Visitor.BlockStatementVisitor() {
-            public void visitInitializer                      (Java.Initializer                       i   ) { try { res[0] = UnitCompiler.this.generatesCode2(i   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldDeclaration                 (Java.FieldDeclaration                  fd  ) { try { res[0] = UnitCompiler.this.generatesCode2(fd  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLabeledStatement                 (Java.LabeledStatement                  ls  ) {       res[0] = UnitCompiler.this.generatesCode2(ls  );                                                                }
-            public void visitBlock                            (Java.Block                             b   ) { try { res[0] = UnitCompiler.this.generatesCode2(b   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitExpressionStatement              (Java.ExpressionStatement               es  ) {       res[0] = UnitCompiler.this.generatesCode2(es  );                                                                }
-            public void visitIfStatement                      (Java.IfStatement                       is  ) {       res[0] = UnitCompiler.this.generatesCode2(is  );                                                                }
-            public void visitForStatement                     (Java.ForStatement                      fs  ) {       res[0] = UnitCompiler.this.generatesCode2(fs  );                                                                }
-            public void visitWhileStatement                   (Java.WhileStatement                    ws  ) {       res[0] = UnitCompiler.this.generatesCode2(ws  );                                                                }
-            public void visitTryStatement                     (Java.TryStatement                      ts  ) {       res[0] = UnitCompiler.this.generatesCode2(ts  );                                                                }
-            public void visitSwitchStatement                  (Java.SwitchStatement                   ss  ) {       res[0] = UnitCompiler.this.generatesCode2(ss  );                                                                }
-            public void visitSynchronizedStatement            (Java.SynchronizedStatement             ss  ) {       res[0] = UnitCompiler.this.generatesCode2(ss  );                                                                }
-            public void visitDoStatement                      (Java.DoStatement                       ds  ) {       res[0] = UnitCompiler.this.generatesCode2(ds  );                                                                }
-            public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {       res[0] = UnitCompiler.this.generatesCode2(lvds);                                                                }
-            public void visitReturnStatement                  (Java.ReturnStatement                   rs  ) {       res[0] = UnitCompiler.this.generatesCode2(rs  );                                                                }
-            public void visitThrowStatement                   (Java.ThrowStatement                    ts  ) {       res[0] = UnitCompiler.this.generatesCode2(ts  );                                                                }
-            public void visitBreakStatement                   (Java.BreakStatement                    bs  ) {       res[0] = UnitCompiler.this.generatesCode2(bs  );                                                                }
-            public void visitContinueStatement                (Java.ContinueStatement                 cs  ) {       res[0] = UnitCompiler.this.generatesCode2(cs  );                                                                }
-            public void visitEmptyStatement                   (Java.EmptyStatement                    es  ) {       res[0] = UnitCompiler.this.generatesCode2(es  );                                                                }
-            public void visitLocalClassDeclarationStatement   (Java.LocalClassDeclarationStatement    lcds) {       res[0] = UnitCompiler.this.generatesCode2(lcds);                                                                }
-            public void visitAlternateConstructorInvocation   (Java.AlternateConstructorInvocation    aci ) {       res[0] = UnitCompiler.this.generatesCode2(aci );                                                                }
-            public void visitSuperConstructorInvocation       (Java.SuperConstructorInvocation        sci ) {       res[0] = UnitCompiler.this.generatesCode2(sci );                                                                }
-        };
-        try {
-            bs.accept(bsv);
-            return res[0];
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    public boolean generatesCode2(Java.BlockStatement bs) { return true; }
-    public boolean generatesCode2(Java.EmptyStatement es) { return false; }
-    public boolean generatesCode2(Java.LocalClassDeclarationStatement lcds) { return false; }
-    public boolean generatesCode2(Java.Initializer i) throws CompileException { return this.generatesCode(i.block); }
-    // Takes a List<Java.BlockStatement>.
-    public boolean generatesCode2ListStatements(List l) throws CompileException {
-        for (int i = 0; i < l.size(); ++i) {
-            if (this.generatesCode(((Java.BlockStatement) l.get(i)))) return true;
-        }
-        return false;
-    }
-    public boolean generatesCode2(Java.Block b) throws CompileException {
-        return generatesCode2ListStatements(b.statements);
-    }
-    public boolean generatesCode2(Java.FieldDeclaration fd) throws CompileException {
-        // Code is only generated if at least one of the declared variables has a
-        // non-constant-final initializer.
-        for (int i = 0; i < fd.variableDeclarators.length; ++i) {
-            Java.VariableDeclarator vd = fd.variableDeclarators[i];
-            if (this.getNonConstantFinalInitializer(fd, vd) != null) return true;
-        }
-        return false;
-    }
-
-    // ------------ BlockStatement.leave() -------------
-
-    /**
-     * Clean up the statement context. This is currently relevant for
-     * "try ... catch ... finally" statements (execute "finally" clause)
-     * and "synchronized" statements (monitorexit).
-     * <p>
-     * Statements like "return", "break", "continue" must call this method
-     * for all the statements they terminate.
-     * <p>
-     * Notice: If <code>optionalStackValueType</code> is <code>null</code>,
-     * then the operand stack is empty; otherwise exactly one operand with that
-     * type is on the stack. This information is vital to implementations of
-     * {@link #leave(Java.BlockStatement, IClass)} that require a specific
-     * operand stack state (e.g. an empty operand stack for JSR).
-     */
-    private void leave(Java.BlockStatement bs, final IClass optionalStackValueType) {
-        Visitor.BlockStatementVisitor bsv = new Visitor.BlockStatementVisitor() {
-            public void visitInitializer                      (Java.Initializer                       i   ) { UnitCompiler.this.leave2(i,    optionalStackValueType); }
-            public void visitFieldDeclaration                 (Java.FieldDeclaration                  fd  ) { UnitCompiler.this.leave2(fd,   optionalStackValueType); }
-            public void visitLabeledStatement                 (Java.LabeledStatement                  ls  ) { UnitCompiler.this.leave2(ls,   optionalStackValueType); }
-            public void visitBlock                            (Java.Block                             b   ) { UnitCompiler.this.leave2(b,    optionalStackValueType); }
-            public void visitExpressionStatement              (Java.ExpressionStatement               es  ) { UnitCompiler.this.leave2(es,   optionalStackValueType); }
-            public void visitIfStatement                      (Java.IfStatement                       is  ) { UnitCompiler.this.leave2(is,   optionalStackValueType); }
-            public void visitForStatement                     (Java.ForStatement                      fs  ) { UnitCompiler.this.leave2(fs,   optionalStackValueType); }
-            public void visitWhileStatement                   (Java.WhileStatement                    ws  ) { UnitCompiler.this.leave2(ws,   optionalStackValueType); }
-            public void visitTryStatement                     (Java.TryStatement                      ts  ) { UnitCompiler.this.leave2(ts,   optionalStackValueType); }
-            public void visitSwitchStatement                  (Java.SwitchStatement                   ss  ) { UnitCompiler.this.leave2(ss,   optionalStackValueType); }
-            public void visitSynchronizedStatement            (Java.SynchronizedStatement             ss  ) { UnitCompiler.this.leave2(ss,   optionalStackValueType); }
-            public void visitDoStatement                      (Java.DoStatement                       ds  ) { UnitCompiler.this.leave2(ds,   optionalStackValueType); }
-            public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) { UnitCompiler.this.leave2(lvds, optionalStackValueType); }
-            public void visitReturnStatement                  (Java.ReturnStatement                   rs  ) { UnitCompiler.this.leave2(rs,   optionalStackValueType); }
-            public void visitThrowStatement                   (Java.ThrowStatement                    ts  ) { UnitCompiler.this.leave2(ts,   optionalStackValueType); }
-            public void visitBreakStatement                   (Java.BreakStatement                    bs  ) { UnitCompiler.this.leave2(bs,   optionalStackValueType); }
-            public void visitContinueStatement                (Java.ContinueStatement                 cs  ) { UnitCompiler.this.leave2(cs,   optionalStackValueType); }
-            public void visitEmptyStatement                   (Java.EmptyStatement                    es  ) { UnitCompiler.this.leave2(es,   optionalStackValueType); }
-            public void visitLocalClassDeclarationStatement   (Java.LocalClassDeclarationStatement    lcds) { UnitCompiler.this.leave2(lcds, optionalStackValueType); }
-            public void visitAlternateConstructorInvocation   (Java.AlternateConstructorInvocation    aci ) { UnitCompiler.this.leave2(aci,  optionalStackValueType); }
-            public void visitSuperConstructorInvocation       (Java.SuperConstructorInvocation        sci ) { UnitCompiler.this.leave2(sci,  optionalStackValueType); }
-        };
-        bs.accept(bsv);
-    }
-    public void leave2(Java.BlockStatement bs, IClass optionalStackValueType) { ; }
-    public void leave2(Java.SynchronizedStatement ss, IClass optionalStackValueType) {
-        this.load((Locatable) ss, this.iClassLoader.OBJECT, ss.monitorLvIndex);
-        this.writeOpcode(ss, Opcode.MONITOREXIT);
-    }
-    public void leave2(Java.TryStatement ts, IClass optionalStackValueType) {
-        if (ts.finallyOffset != null) {
-
-            this.codeContext.saveLocalVariables();
-            try {
-                short sv = 0;
-
-                // Obviously, JSR must always be executed with the operand stack being
-                // empty; otherwise we get "java.lang.VerifyError: Inconsistent stack height
-                // 1 != 2"
-                if (optionalStackValueType != null) {
-                    sv = this.codeContext.allocateLocalVariable(Descriptor.size(optionalStackValueType.getDescriptor()));
-                    this.store((Locatable) ts, optionalStackValueType, sv);
-                }
-    
-                this.writeBranch(ts, Opcode.JSR, ts.finallyOffset);
-    
-                if (optionalStackValueType != null) {
-                    this.load((Locatable) ts, optionalStackValueType, sv);
-                }
-            } finally {
-                this.codeContext.restoreLocalVariables();
-            }
-        }
-    }
-
-    // ---------------- Lvalue.compileSet() -----------------
-
-    /**
-     * Generates code that stores a value in the {@link Java.Lvalue}.
-     * Expects the {@link Java.Lvalue}'s context (see {@link
-     * #compileContext}) and a value of the {@link Java.Lvalue}'s type
-     * on the operand stack.
-     */
-    private void compileSet(Java.Lvalue lv) throws CompileException {
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.LvalueVisitor lvv = new Visitor.LvalueVisitor() {
-            public void visitAmbiguousName                  (Java.AmbiguousName                   an   ) { try { UnitCompiler.this.compileSet2(an   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression           aae  ) { try { UnitCompiler.this.compileSet2(aae  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccess                    (Java.FieldAccess                     fa   ) { try { UnitCompiler.this.compileSet2(fa   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression           fae  ) { try { UnitCompiler.this.compileSet2(fae  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { UnitCompiler.this.compileSet2(scfae); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess             lva  ) {       UnitCompiler.this.compileSet2(lva  );                                                    }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression         pe   ) { try { UnitCompiler.this.compileSet2(pe   ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            lv.accept(lvv);
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private void compileSet2(Java.AmbiguousName an) throws CompileException {
-        this.compileSet(this.toLvalueOrCE(this.reclassify(an)));
-    }
-    private void compileSet2(Java.LocalVariableAccess lva) {
-        this.store(
-            (Locatable) lva,
-            lva.localVariable.type,
-            lva.localVariable
-        );
-    }
-    private void compileSet2(Java.FieldAccess fa) throws CompileException {
-        this.checkAccessible(fa.field, fa.getEnclosingBlockStatement());
-        this.writeOpcode(fa, (
-            fa.field.isStatic() ?
-            Opcode.PUTSTATIC :
-            Opcode.PUTFIELD
-        ));
-        this.writeConstantFieldrefInfo(
-            fa.field.getDeclaringIClass().getDescriptor(),
-            fa.field.getName(), // classFD
-            fa.field.getDescriptor()                       // fieldFD
-        );
-    }
-    private void compileSet2(Java.ArrayAccessExpression aae) throws CompileException {
-        this.writeOpcode(aae, Opcode.IASTORE + UnitCompiler.ilfdabcs(this.getType(aae)));
-    }
-    private void compileSet2(Java.FieldAccessExpression fae) throws CompileException {
-        this.determineValue(fae);
-        this.compileSet(this.toLvalueOrCE(fae.value));
-    }
-    private void compileSet2(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
-        this.determineValue(scfae);
-        this.compileSet(this.toLvalueOrCE(scfae.value));
-    }
-    private void compileSet2(Java.ParenthesizedExpression pe) throws CompileException {
-        this.compileSet(this.toLvalueOrCE(pe.value));
-    }
-
-    // ---------------- Atom.getType() ----------------
-
-    private IClass getType(Java.Atom a) throws CompileException {
-        final IClass[] res = new IClass[1];
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.AtomVisitor av = new Visitor.AtomVisitor() {
-            // AtomVisitor
-            public void visitPackage                       (Java.Package                        p   ) { try { res[0] = UnitCompiler.this.getType2(p   ); } catch (CompileException e) { throw new UCE(e); } }
-            // TypeVisitor
-            public void visitArrayType                     (Java.ArrayType                      at  ) { try { res[0] = UnitCompiler.this.getType2(at  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBasicType                     (Java.BasicType                      bt  ) {       res[0] = UnitCompiler.this.getType2(bt  );                                                                }
-            public void visitReferenceType                 (Java.ReferenceType                  rt  ) { try { res[0] = UnitCompiler.this.getType2(rt  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitRvalueMemberType              (Java.RvalueMemberType               rmt ) { try { res[0] = UnitCompiler.this.getType2(rmt ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSimpleType                    (Java.SimpleType                     st  ) {       res[0] = UnitCompiler.this.getType2(st  );                                                                }
-            // RvalueVisitor
-            public void visitArrayLength                   (Java.ArrayLength                    al  ) {       res[0] = UnitCompiler.this.getType2(al  );                                                                }
-            public void visitAssignment                    (Java.Assignment                     a   ) { try { res[0] = UnitCompiler.this.getType2(a   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitUnaryOperation                (Java.UnaryOperation                 uo  ) { try { res[0] = UnitCompiler.this.getType2(uo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitBinaryOperation               (Java.BinaryOperation                bo  ) { try { res[0] = UnitCompiler.this.getType2(bo  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCast                          (Java.Cast                           c   ) { try { res[0] = UnitCompiler.this.getType2(c   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitClassLiteral                  (Java.ClassLiteral                   cl  ) {       res[0] = UnitCompiler.this.getType2(cl  );                                                                }
-            public void visitConditionalExpression         (Java.ConditionalExpression          ce  ) { try { res[0] = UnitCompiler.this.getType2(ce  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitCrement                       (Java.Crement                        c   ) { try { res[0] = UnitCompiler.this.getType2(c   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitInstanceof                    (Java.Instanceof                     io  ) {       res[0] = UnitCompiler.this.getType2(io  );                                                                }
-            public void visitMethodInvocation              (Java.MethodInvocation               mi  ) { try { res[0] = UnitCompiler.this.getType2(mi  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassMethodInvocation    (Java.SuperclassMethodInvocation     smi ) { try { res[0] = UnitCompiler.this.getType2(smi ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLiteral                       (Java.Literal                        l   ) {       res[0] = UnitCompiler.this.getType2(l   );                                                                }
-            public void visitNewAnonymousClassInstance     (Java.NewAnonymousClassInstance      naci) {       res[0] = UnitCompiler.this.getType2(naci);                                                                }
-            public void visitNewArray                      (Java.NewArray                       na  ) { try { res[0] = UnitCompiler.this.getType2(na  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewInitializedArray           (Java.NewInitializedArray            nia ) { try { res[0] = UnitCompiler.this.getType2(nia ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitNewClassInstance              (Java.NewClassInstance               nci ) { try { res[0] = UnitCompiler.this.getType2(nci ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitParameterAccess               (Java.ParameterAccess                pa  ) { try { res[0] = UnitCompiler.this.getType2(pa  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitQualifiedThisReference        (Java.QualifiedThisReference         qtr ) { try { res[0] = UnitCompiler.this.getType2(qtr ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitThisReference                 (Java.ThisReference                  tr  ) { try { res[0] = UnitCompiler.this.getType2(tr  ); } catch (CompileException e) { throw new UCE(e); } }
-            // LvalueVisitor
-            public void visitAmbiguousName                  (Java.AmbiguousName                   an   ) { try { res[0] = UnitCompiler.this.getType2(an   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression           aae  ) { try { res[0] = UnitCompiler.this.getType2(aae  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccess                    (Java.FieldAccess                     fa   ) { try { res[0] = UnitCompiler.this.getType2(fa   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression           fae  ) { try { res[0] = UnitCompiler.this.getType2(fae  ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) { try { res[0] = UnitCompiler.this.getType2(scfae); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess             lva  ) {       res[0] = UnitCompiler.this.getType2(lva  );                                                                }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression         pe   ) { try { res[0] = UnitCompiler.this.getType2(pe   ); } catch (CompileException e) { throw new UCE(e); } }
-        };
-        try {
-            a.accept(av);
-            return res[0] != null ? res[0] : this.iClassLoader.OBJECT;
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private IClass getType2(Java.SimpleType st) { return st.iClass; }
-    private IClass getType2(Java.BasicType bt) {
-        switch (bt.index) {
-            case Java.BasicType.VOID:    return IClass.VOID;
-            case Java.BasicType.BYTE:    return IClass.BYTE;
-            case Java.BasicType.SHORT:   return IClass.SHORT;
-            case Java.BasicType.CHAR:    return IClass.CHAR;
-            case Java.BasicType.INT:     return IClass.INT;
-            case Java.BasicType.LONG:    return IClass.LONG;
-            case Java.BasicType.FLOAT:   return IClass.FLOAT;
-            case Java.BasicType.DOUBLE:  return IClass.DOUBLE;
-            case Java.BasicType.BOOLEAN: return IClass.BOOLEAN;
-            default: throw new RuntimeException("Invalid index " + bt.index);
-        }
-    }
-    private IClass getType2(Java.ReferenceType rt) throws CompileException {
-        Java.BlockStatement  scopeBlockStatement = null;
-        Java.TypeDeclaration scopeTypeDeclaration = null;
-        Java.CompilationUnit scopeCompilationUnit;
-        for (Java.Scope s = rt.getEnclosingScope();; s = s.getEnclosingScope()) {
-            if (s instanceof Java.BlockStatement && scopeBlockStatement == null) {
-                scopeBlockStatement = (Java.BlockStatement) s;
-            }
-            if (s instanceof Java.TypeDeclaration && scopeTypeDeclaration == null) {
-                scopeTypeDeclaration = (Java.TypeDeclaration) s;
-            }
-            if (s instanceof Java.CompilationUnit) {
-                scopeCompilationUnit = (Java.CompilationUnit) s;
-                break;
-            }
-        }
-
-        if (rt.identifiers.length == 1) {
-
-            // 6.5.5.1 Simple type name (single identifier).
-            String simpleTypeName = rt.identifiers[0];
-
-            // 6.5.5.1.1 Local class.
-            {
-                Java.LocalClassDeclaration lcd = this.findLocalClassDeclaration(rt.getEnclosingScope(), simpleTypeName);
-                if (lcd != null) return this.resolve(lcd);
-            }
-
-            // 6.5.5.1.2 Member type.
-            if (scopeTypeDeclaration != null) { // If enclosed by another type declaration...
-                for (Java.Scope s = scopeTypeDeclaration; !(s instanceof Java.CompilationUnit); s = s.getEnclosingScope()) {
-                    if (s instanceof Java.TypeDeclaration) {
-                        IClass mt = this.findMemberType(this.resolve((Java.AbstractTypeDeclaration) s), simpleTypeName, rt.getLocation());
-                        if (mt != null) return mt;
-                    }
-                }
-            }
-
-            {
-
-                // 6.5.5.1.4a Single-type import.
-                {
-                    IClass importedClass = this.importSingleType(simpleTypeName, rt.getLocation());
-                    if (importedClass != null) return importedClass;
-                }
-
-                // 6.5.5.1.4b Type declared in same compilation unit.
-                {
-                    Java.PackageMemberTypeDeclaration pmtd = scopeCompilationUnit.getPackageMemberTypeDeclaration(simpleTypeName);
-                    if (pmtd != null) return this.resolve((Java.AbstractTypeDeclaration) pmtd);
-                }
-            }
-
-            // 6.5.5.1.5 Type declared in other compilation unit of same
-            // package.
-            {
-                String pkg = (
-                    scopeCompilationUnit.optionalPackageDeclaration == null ? null :
-                    scopeCompilationUnit.optionalPackageDeclaration.packageName
-                );
-                String className = pkg == null ? simpleTypeName : pkg + "." + simpleTypeName;
-                IClass result = findClassByName(rt.getLocation(), className);
-                if (result != null) return result;
-            }
-
-            // 6.5.5.1.6 Type-import-on-demand declaration.
-            {
-                IClass importedClass = this.importTypeOnDemand(simpleTypeName, rt.getLocation());
-                if (importedClass != null) return importedClass;
-            }
-
-            // JLS3 ???:  Type imported through single static import.
-            {
-                Object o = this.singleStaticImports.get(simpleTypeName);
-                if (o instanceof IClass) return (IClass) o;
-            }
-
-            // JLS3 ???: Type imported through static-import-on-demand.
-            {
-                IClass importedMemberType = null;
-                for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
-                    IClass ic = (IClass) it.next();
-                    IClass[] memberTypes = ic.getDeclaredIClasses();
-                    for (int i = 0; i < memberTypes.length; ++i) {
-                        IClass mt = memberTypes[i];
-                        if (!UnitCompiler.this.isAccessible(mt, scopeBlockStatement)) continue;
-                        if (mt.getDescriptor().endsWith('$' + simpleTypeName + ';')) {
-                            if (importedMemberType != null) UnitCompiler.this.compileError("Ambiguous static imports: \"" + importedMemberType.toString() + "\" vs. \"" + mt.toString() + "\"");
-                            importedMemberType = mt;
-                        }
-                    }
-                }
-                if (importedMemberType != null) return importedMemberType;
-            }
-
-            // 6.5.5.1.8 Give up.
-            this.compileError("Cannot determine simple type name \"" + simpleTypeName + "\"", rt.getLocation());
-            return this.iClassLoader.OBJECT;
-        } else {
-
-            // 6.5.5.2 Qualified type name (two or more identifiers).
-            Java.Atom q = this.reclassifyName(rt.getLocation(), rt.getEnclosingScope(), rt.identifiers, rt.identifiers.length - 1);
-
-            // 6.5.5.2.1 PACKAGE.CLASS
-            if (q instanceof Java.Package) {
-                String className = Java.join(rt.identifiers, ".");
-                IClass result = findClassByName(rt.getLocation(), className);
-                if (result != null) return result;
-
-                this.compileError("Class \"" + className + "\" not found", rt.getLocation());
-                return this.iClassLoader.OBJECT;
-            }
-
-            // 6.5.5.2.2 CLASS.CLASS (member type)
-            String memberTypeName = rt.identifiers[rt.identifiers.length - 1];
-            IClass[] types = this.getType(this.toTypeOrCE(q)).findMemberType(memberTypeName);
-            if (types.length == 1) return types[0];
-            if (types.length == 0) {
-                this.compileError("\"" + q + "\" declares no member type \"" + memberTypeName + "\"", rt.getLocation());
-            } else
-            {
-                this.compileError("\"" + q + "\" and its supertypes declare more than one member type \"" + memberTypeName + "\"", rt.getLocation());
-            }
-            return this.iClassLoader.OBJECT;
-        }
-    }
-
-    private IClass getType2(Java.RvalueMemberType rvmt) throws CompileException {
-        IClass rvt = this.getType(rvmt.rvalue);
-        IClass memberType = this.findMemberType(rvt, rvmt.identifier, rvmt.getLocation());
-        if (memberType == null) this.compileError("\"" + rvt + "\" has no member type \"" + rvmt.identifier + "\"", rvmt.getLocation());
-        return memberType;
-    }
-    private IClass getType2(Java.ArrayType at) throws CompileException {
-        return this.getType(at.componentType).getArrayIClass(this.iClassLoader.OBJECT);
-    }
-    private IClass getType2(Java.AmbiguousName an) throws CompileException {
-        return this.getType(this.reclassify(an));
-    }
-    private IClass getType2(Java.Package p) throws CompileException {
-        this.compileError("Unknown variable or type \"" + p.name + "\"", p.getLocation());
-        return this.iClassLoader.OBJECT;
-    }
-    private IClass getType2(Java.LocalVariableAccess lva) {
-        return lva.localVariable.type;
-    }
-    private IClass getType2(Java.FieldAccess fa) throws CompileException {
-        return fa.field.getType();
-    }
-    private IClass getType2(Java.ArrayLength al) {
-        return IClass.INT;
-    }
-    private IClass getType2(Java.ThisReference tr) throws CompileException {
-        return this.getIClass(tr);
-    }
-    private IClass getType2(Java.QualifiedThisReference qtr) throws CompileException {
-        return this.getTargetIClass(qtr);
-    }
-    private IClass getType2(Java.ClassLiteral cl) {
-        return this.iClassLoader.CLASS;
-    }
-    private IClass getType2(Java.Assignment a) throws CompileException {
-        return this.getType(a.lhs);
-    }
-    private IClass getType2(Java.ConditionalExpression ce) throws CompileException {
-        IClass mhsType = this.getType(ce.mhs);
-        IClass rhsType = this.getType(ce.rhs);
-
-        if (mhsType == rhsType) {
-
-            // JLS 15.25.1.1
-            return mhsType;
-        } else
-        if (mhsType.isPrimitiveNumeric() && rhsType.isPrimitiveNumeric()) {
-
-            // JLS 15.25.1.2
-
-            // TODO JLS 15.25.1.2.1
-
-            // TODO JLS 15.25.1.2.2
-
-            // JLS 15.25.1.2.3
-            return this.binaryNumericPromotionType((Java.Locatable) ce, mhsType, rhsType);
-        } else
-        if (this.getConstantValue(ce.mhs) == Java.Rvalue.CONSTANT_VALUE_NULL && !rhsType.isPrimitive()) {
-
-            // JLS 15.25.1.3 (null : ref)
-            return rhsType;
-        } else
-        if (!mhsType.isPrimitive() && this.getConstantValue(ce.rhs) == Java.Rvalue.CONSTANT_VALUE_NULL) {
-
-            // JLS 15.25.1.3 (ref : null)
-            return mhsType;
-        } else
-        if (!mhsType.isPrimitive() && !rhsType.isPrimitive()) {
-            if (mhsType.isAssignableFrom(rhsType)) {
-                return mhsType;
-            } else
-            if (rhsType.isAssignableFrom(mhsType)) {
-                return rhsType;
-            } else {
-                this.compileError("Reference types \"" + mhsType + "\" and \"" + rhsType + "\" don't match", ce.getLocation());
-                return this.iClassLoader.OBJECT;
-            }
-        } else
-        {
-            this.compileError("Incompatible expression types \"" + mhsType + "\" and \"" + rhsType + "\"", ce.getLocation());
-            return this.iClassLoader.OBJECT;
-        }
-    }
-    private IClass getType2(Java.Crement c) throws CompileException {
-        return this.getType(c.operand);
-    }
-    private IClass getType2(Java.ArrayAccessExpression aae) throws CompileException {
-        return this.getType(aae.lhs).getComponentType();
-    }
-    private IClass getType2(Java.FieldAccessExpression fae) throws CompileException {
-        this.determineValue(fae);
-        return this.getType(fae.value);
-    }
-    private IClass getType2(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
-        this.determineValue(scfae);
-        return this.getType(scfae.value);
-    }
-    private IClass getType2(Java.UnaryOperation uo) throws CompileException {
-        if (uo.operator == "!") return IClass.BOOLEAN;
-
-        if (
-            uo.operator == "+" ||
-            uo.operator == "-" ||
-            uo.operator == "~"
-        ) return this.unaryNumericPromotionType((Locatable) uo, this.getUnboxedType(this.getType(uo.operand)));
-
-        this.compileError("Unexpected operator \"" + uo.operator + "\"", uo.getLocation());
-        return IClass.BOOLEAN;
-    }
-    private IClass getType2(Java.Instanceof io) {
-        return IClass.BOOLEAN;
-    }
-    private IClass getType2(Java.BinaryOperation bo) throws CompileException {
-        if (
-            bo.op == "||" ||
-            bo.op == "&&" ||
-            bo.op == "==" ||
-            bo.op == "!=" ||
-            bo.op == "<"  ||
-            bo.op == ">"  ||
-            bo.op == "<=" ||
-            bo.op == ">="
-        ) return IClass.BOOLEAN;
-
-        if (
-            bo.op == "|" ||
-            bo.op == "^" ||
-            bo.op == "&"
-        ) {
-            IClass lhsType = this.getType(bo.lhs);
-            return (
-                lhsType == IClass.BOOLEAN || lhsType == this.iClassLoader.BOOLEAN ?
-                IClass.BOOLEAN :
-                this.binaryNumericPromotionType(
-                    (Java.Locatable) bo,
-                    lhsType,
-                    this.getType(bo.rhs)
-                )
-            );
-        }
-
-        if (
-            bo.op == "*"   ||
-            bo.op == "/"   ||
-            bo.op == "%"   ||
-            bo.op == "+"   ||
-            bo.op == "-"
-        ) {
-            IClassLoader icl = this.iClassLoader;
-
-            // Unroll the operands of this binary operation.
-            Iterator ops = bo.unrollLeftAssociation();
-
-            // Check the far left operand type.
-            IClass lhsType = this.getUnboxedType(this.getType(((Java.Rvalue) ops.next())));
-            if (bo.op == "+" && lhsType == icl.STRING) return icl.STRING;
-
-            // Determine the expression type.
-            do {
-                IClass rhsType = this.getUnboxedType(this.getType(((Java.Rvalue) ops.next())));
-                if (bo.op == "+" && rhsType == icl.STRING) return icl.STRING;
-                lhsType = this.binaryNumericPromotionType((Java.Locatable) bo, lhsType, rhsType);
-            } while (ops.hasNext());
-            return lhsType;
-        }
-
-        if (
-            bo.op == "<<"  ||
-            bo.op == ">>"  ||
-            bo.op == ">>>"
-        ) {
-            IClass lhsType = this.getType(bo.lhs);
-            return this.unaryNumericPromotionType((Locatable) bo, lhsType);
-        }
-
-        this.compileError("Unexpected operator \"" + bo.op + "\"", bo.getLocation());
-        return this.iClassLoader.OBJECT;
-    }
-    private IClass getUnboxedType(IClass type) {
-        IClass c = this.isUnboxingConvertible(type);
-        return c != null ? c : type;
-    }
-    private IClass getType2(Java.Cast c) throws CompileException {
-        return this.getType(c.targetType);
-    }
-    private IClass getType2(Java.ParenthesizedExpression pe) throws CompileException {
-        return this.getType(pe.value);
-    }
-//    private IClass getType2(Java.ConstructorInvocation ci) {
-//        throw new RuntimeException();
-//    }
-    private IClass getType2(Java.MethodInvocation mi) throws CompileException {
-        if (mi.iMethod == null) {
-            mi.iMethod = this.findIMethod(mi);
-        }
-        return mi.iMethod.getReturnType();
-    }
-    private IClass getType2(Java.SuperclassMethodInvocation scmi) throws CompileException {
-        return this.findIMethod(scmi).getReturnType();
-    }
-    private IClass getType2(Java.NewClassInstance nci) throws CompileException {
-        if (nci.iClass == null) nci.iClass = this.getType(nci.type);
-        return nci.iClass;
-    }
-    private IClass getType2(Java.NewAnonymousClassInstance naci) {
-        return this.resolve(naci.anonymousClassDeclaration);
-    }
-    private IClass getType2(Java.ParameterAccess pa) throws CompileException {
-        return this.getLocalVariable(pa.formalParameter).type;
-    }
-    private IClass getType2(Java.NewArray na) throws CompileException {
-        IClass res = this.getType(na.type);
-        return res.getArrayIClass(na.dimExprs.length + na.dims, this.iClassLoader.OBJECT);
-    }
-    private IClass getType2(Java.NewInitializedArray nia) throws CompileException {
-        return this.getType(nia.arrayType);
-    }
-    private IClass getType2(Java.Literal l) {
-        if (l.value instanceof Integer  ) return IClass.INT;
-        if (l.value instanceof Long     ) return IClass.LONG;
-        if (l.value instanceof Float    ) return IClass.FLOAT;
-        if (l.value instanceof Double   ) return IClass.DOUBLE;
-        if (l.value instanceof String   ) return this.iClassLoader.STRING;
-        if (l.value instanceof Character) return IClass.CHAR;
-        if (l.value instanceof Boolean  ) return IClass.BOOLEAN;
-        if (l.value == null             ) return IClass.VOID;
-        throw new RuntimeException("SNO: Unidentifiable literal type \"" + l.value.getClass().getName() + "\"");
-    }
-
-    // ---------------- Atom.isType() ---------------
-
-    private boolean isType(Java.Atom a) throws CompileException {
-        final boolean[] res = new boolean[1];
-        class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-        Visitor.AtomVisitor av = new Visitor.AtomVisitor() {
-            // AtomVisitor
-            public void visitPackage(Java.Package p) { res[0] = UnitCompiler.this.isType2(p); }
-            // TypeVisitor
-            public void visitArrayType       (Java.ArrayType        at  ) { res[0] = UnitCompiler.this.isType2(at ); }
-            public void visitBasicType       (Java.BasicType        bt  ) { res[0] = UnitCompiler.this.isType2(bt ); }
-            public void visitReferenceType   (Java.ReferenceType    rt  ) { res[0] = UnitCompiler.this.isType2(rt ); }
-            public void visitRvalueMemberType(Java.RvalueMemberType rmt ) { res[0] = UnitCompiler.this.isType2(rmt); }
-            public void visitSimpleType      (Java.SimpleType       st  ) { res[0] = UnitCompiler.this.isType2(st ); }
-            // RvalueVisitor
-            public void visitArrayLength               (Java.ArrayLength                al  ) { res[0] = UnitCompiler.this.isType2(al  ); }
-            public void visitAssignment                (Java.Assignment                 a   ) { res[0] = UnitCompiler.this.isType2(a   ); }
-            public void visitUnaryOperation            (Java.UnaryOperation             uo  ) { res[0] = UnitCompiler.this.isType2(uo  ); }
-            public void visitBinaryOperation           (Java.BinaryOperation            bo  ) { res[0] = UnitCompiler.this.isType2(bo  ); }
-            public void visitCast                      (Java.Cast                       c   ) { res[0] = UnitCompiler.this.isType2(c   ); }
-            public void visitClassLiteral              (Java.ClassLiteral               cl  ) { res[0] = UnitCompiler.this.isType2(cl  ); }
-            public void visitConditionalExpression     (Java.ConditionalExpression      ce  ) { res[0] = UnitCompiler.this.isType2(ce  ); }
-            public void visitCrement                   (Java.Crement                    c   ) { res[0] = UnitCompiler.this.isType2(c   ); }
-            public void visitInstanceof                (Java.Instanceof                 io  ) { res[0] = UnitCompiler.this.isType2(io  ); }
-            public void visitMethodInvocation          (Java.MethodInvocation           mi  ) { res[0] = UnitCompiler.this.isType2(mi  ); }
-            public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi ) { res[0] = UnitCompiler.this.isType2(smi ); }
-            public void visitLiteral                   (Java.Literal                    l   ) { res[0] = UnitCompiler.this.isType2(l   ); }
-            public void visitNewAnonymousClassInstance (Java.NewAnonymousClassInstance  naci) { res[0] = UnitCompiler.this.isType2(naci); }
-            public void visitNewArray                  (Java.NewArray                   na  ) { res[0] = UnitCompiler.this.isType2(na  ); }
-            public void visitNewInitializedArray       (Java.NewInitializedArray        nia ) { res[0] = UnitCompiler.this.isType2(nia ); }
-            public void visitNewClassInstance          (Java.NewClassInstance           nci ) { res[0] = UnitCompiler.this.isType2(nci ); }
-            public void visitParameterAccess           (Java.ParameterAccess            pa  ) { res[0] = UnitCompiler.this.isType2(pa  ); }
-            public void visitQualifiedThisReference    (Java.QualifiedThisReference     qtr ) { res[0] = UnitCompiler.this.isType2(qtr ); }
-            public void visitThisReference             (Java.ThisReference              tr  ) { res[0] = UnitCompiler.this.isType2(tr  ); }
-            // LvalueVisitor
-            public void visitAmbiguousName                  (Java.AmbiguousName                   an   ) { try { res[0] = UnitCompiler.this.isType2(an   ); } catch (CompileException e) { throw new UCE(e); } }
-            public void visitArrayAccessExpression          (Java.ArrayAccessExpression           aae  ) {       res[0] = UnitCompiler.this.isType2(aae  );                                                    }
-            public void visitFieldAccess                    (Java.FieldAccess                     fa   ) {       res[0] = UnitCompiler.this.isType2(fa   );                                                    }
-            public void visitFieldAccessExpression          (Java.FieldAccessExpression           fae  ) {       res[0] = UnitCompiler.this.isType2(fae  );                                                    }
-            public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) {       res[0] = UnitCompiler.this.isType2(scfae);                                                    }
-            public void visitLocalVariableAccess            (Java.LocalVariableAccess             lva  ) {       res[0] = UnitCompiler.this.isType2(lva  );                                                    }
-            public void visitParenthesizedExpression        (Java.ParenthesizedExpression         pe   ) {       res[0] = UnitCompiler.this.isType2(pe   );                                                    }
-        };
-        try {
-            a.accept(av);
-            return res[0];
-        } catch (UCE uce) {
-            throw uce.ce;
-        }
-    }
-    private boolean isType2(Java.Atom a) {
-        return a instanceof Java.Type;
-    }
-    private boolean isType2(Java.AmbiguousName an) throws CompileException {
-        return this.isType(this.reclassify(an));
-    }
-
-    /**
-     * Determine whether the given {@link IClass.IMember} is accessible in the given context,
-     * according to JLS 6.6.1.4. Issues a {@link #compileError(String)} if not.
-     */
-    private boolean isAccessible(
-        IClass.IMember      member,
-        Java.BlockStatement contextBlockStatement
-    ) throws CompileException {
-        return this.isAccessible(member.getDeclaringIClass(), member.getAccess(), contextBlockStatement);
-    }
-    
-    /**
-     * Check whether the given {@link IClass.IMember} is accessible in the given context,
-     * according to JLS 6.6.1.4. Issue a {@link #compileError(String)} if not.
-     */
-    private void checkAccessible(
-        IClass.IMember      member,
-        Java.BlockStatement contextBlockStatement
-    ) throws CompileException {
-        this.checkAccessible(member.getDeclaringIClass(), member.getAccess(), contextBlockStatement);
-    }
-
-    /**
-     * Determine whether a member (class, interface, field or method) declared in a
-     * given class is accessible from a given block statement context, according
-     * to JLS2 6.6.1.4.
-     */
-    private boolean isAccessible(
-        IClass              iClassDeclaringMember,
-        Access              memberAccess,
-        Java.BlockStatement contextBlockStatement
-    ) throws CompileException {
-        return null == this.internalCheckAccessible(iClassDeclaringMember, memberAccess, contextBlockStatement);
-    }
-    
-    /**
-     * Verify that a member (class, interface, field or method) declared in a
-     * given class is accessible from a given block statement context, according
-     * to JLS2 6.6.1.4. Issue a {@link #compileError(String)} if not.
-     */
-    private void checkAccessible(
-        IClass              iClassDeclaringMember,
-        Access              memberAccess,
-        Java.BlockStatement contextBlockStatement
-    ) throws CompileException {
-        String message = this.internalCheckAccessible(iClassDeclaringMember, memberAccess, contextBlockStatement);
-        if (message != null) this.compileError(message, contextBlockStatement.getLocation());
-    }
-
-    /**
-     * @return a descriptive text iff a member declared in that {@link IClass} with that {@link Access} is inaccessible
-     */
-    private String internalCheckAccessible(
-        IClass              iClassDeclaringMember,
-        Access              memberAccess,
-        Java.BlockStatement contextBlockStatement
-    ) throws CompileException {
-        
-        // At this point, memberAccess is PUBLIC, DEFAULT, PROECTEDED or PRIVATE.
-
-        // PUBLIC members are always accessible.
-        if (memberAccess == Access.PUBLIC) return null;
-
-        // At this point, the member is DEFAULT, PROECTEDED or PRIVATE accessible.
-
-        // Determine the class declaring the context block statement.
-        IClass iClassDeclaringContextBlockStatement;
-        for (Java.Scope s = contextBlockStatement.getEnclosingScope();; s = s.getEnclosingScope()) {
-            if (s instanceof Java.TypeDeclaration) {
-                iClassDeclaringContextBlockStatement = this.resolve((Java.TypeDeclaration) s);
-                break;
-            }
-        }
-
-        // Access is always allowed for block statements declared in the same class as the member.
-        if (iClassDeclaringContextBlockStatement == iClassDeclaringMember) return null;
-
-        // Check whether the member and the context block statement are enclosed by the same
-        // top-level type.
-        {
-            IClass topLevelIClassEnclosingMember = iClassDeclaringMember;
-                for (IClass c = iClassDeclaringMember.getDeclaringIClass(); c != null; c = c.getDeclaringIClass()) {
-                topLevelIClassEnclosingMember = c;
-            }
-            IClass topLevelIClassEnclosingContextBlockStatement = iClassDeclaringContextBlockStatement;
-            for (IClass c = iClassDeclaringContextBlockStatement.getDeclaringIClass(); c != null; c = c.getDeclaringIClass()) {
-                topLevelIClassEnclosingContextBlockStatement = c;
-            }
-
-            if (topLevelIClassEnclosingMember == topLevelIClassEnclosingContextBlockStatement) return null;
-        }
-
-        if (memberAccess == Access.PRIVATE) {
-            return "Private member cannot be accessed from type \"" + iClassDeclaringContextBlockStatement + "\".";
-        }
-
-        // At this point, the member is DEFAULT or PROTECTED accessible.
-
-        // Check whether the member and the context block statement are declared in the same
-        // package.
-        if (Descriptor.areInSamePackage(
-            iClassDeclaringMember.getDescriptor(),
-            iClassDeclaringContextBlockStatement.getDescriptor()
-        )) return null;
-
-        if (memberAccess == Access.DEFAULT) {
-            return "Member with \"" + memberAccess + "\" access cannot be accessed from type \"" + iClassDeclaringContextBlockStatement + "\".";
-        }
-
-        // At this point, the member is PROTECTED accessible.
-
-        // Check whether the class declaring the context block statement is a subclass of the
-        // class declaring the member or a nested class whose parent is a subclass
-        IClass parentClass = iClassDeclaringContextBlockStatement;
-        do {
-            if (iClassDeclaringMember.isAssignableFrom(parentClass)) {
-                return null;
-            }
-            parentClass = parentClass.getOuterIClass();
-        } while(parentClass != null);
-
-        return "Protected member cannot be accessed from type \"" + iClassDeclaringContextBlockStatement + "\", which is neither declared in the same package as nor is a subclass of \"" + iClassDeclaringMember + "\".";
-    }
-
-    /**
-     * Determine whether the given {@link IClass} is accessible in the given context,
-     * according to JLS2 6.6.1.2 and 6.6.1.4.
-     */
-    private boolean isAccessible(
-        IClass              type,
-        Java.BlockStatement contextBlockStatement
-    ) throws CompileException {
-        return null == this.internalCheckAccessible(type, contextBlockStatement);
-    }
-    
-    /**
-     * Check whether the given {@link IClass} is accessible in the given context,
-     * according to JLS2 6.6.1.2 and 6.6.1.4. Issues a {@link #compileError(String)} if not.
-     */
-    private void checkAccessible(
-        IClass              type,
-        Java.BlockStatement contextBlockStatement
-    ) throws CompileException {
-        String message = this.internalCheckAccessible(type, contextBlockStatement);
-        if (message != null) this.compileError(message, contextBlockStatement.getLocation());
-    }
-
-    private String internalCheckAccessible(
-        IClass              type,
-        Java.BlockStatement contextBlockStatement
-    ) throws CompileException {
-
-        // Determine the type declaring the type.
-        IClass iClassDeclaringType = type.getDeclaringIClass();
-
-        // Check accessibility of package member type.
-        if (iClassDeclaringType == null) {
-            if (type.getAccess() == Access.PUBLIC) {
-                return null;
-            } else
-            if (type.getAccess() == Access.DEFAULT) {
-    
-                // Determine the type declaring the context block statement.
-                IClass iClassDeclaringContextBlockStatement;
-                for (Java.Scope s = contextBlockStatement.getEnclosingScope();; s = s.getEnclosingScope()) {
-                    if (s instanceof Java.TypeDeclaration) {
-                        iClassDeclaringContextBlockStatement = this.resolve((Java.TypeDeclaration) s);
-                        break;
-                    }
-                }
-    
-                // Check whether the type is accessed from within the same package.
-                String packageDeclaringType = Descriptor.getPackageName(type.getDescriptor());
-                String contextPackage = Descriptor.getPackageName(iClassDeclaringContextBlockStatement.getDescriptor());
-                if (!(packageDeclaringType == null ? contextPackage == null : packageDeclaringType.equals(contextPackage))) return "\"" + type + "\" is inaccessible from this package";
-                return null;
-            } else
-            {
-                throw new RuntimeException("\"" + type + "\" has unexpected access \"" + type.getAccess() + "\"");
-            }
-        }
-
-        // "type" is a member type at this point.
-
-        return this.internalCheckAccessible(iClassDeclaringType, type.getAccess(), contextBlockStatement);
-    }
-
-    private final Java.Type toTypeOrCE(Java.Atom a) throws CompileException {
-        Java.Type result = a.toType();
-        if (result == null) {
-            this.compileError("Expression \"" + a.toString() + "\" is not a type", a.getLocation());
-            return new Java.SimpleType(a.getLocation(), this.iClassLoader.OBJECT);
-        }
-        return result;
-    }
-    private final Java.Rvalue toRvalueOrCE(final Java.Atom a) throws CompileException {
-        Java.Rvalue result = a.toRvalue();
-        if (result == null) {
-            this.compileError("Expression \"" + a.toString() + "\" is not an rvalue", a.getLocation());
-            return new Java.Literal(a.getLocation(), "X");
-        }
-        return result;
-    }
-    public final Java.Lvalue toLvalueOrCE(final Java.Atom a) throws CompileException {
-        Java.Lvalue result = a.toLvalue();
-        if (result == null) {
-            this.compileError("Expression \"" + a.toString() + "\" is not an lvalue", a.getLocation());
-            return new Java.Lvalue(a.getLocation()) {
-                public String toString() { return a.toString(); }
-                public void accept(Visitor.AtomVisitor visitor) {}
-                public void accept(Visitor.RvalueVisitor visitor) {}
-                public void accept(Visitor.LvalueVisitor visitor) {}
-            };
-        }
-        return result;
-    }
-
-    /**
-     * Copies the values of the synthetic parameters of this constructor ("this$..." and
-     * "val$...") to the synthetic fields of the object ("this$..." and "val$...").
-     */
-    void assignSyntheticParametersToSyntheticFields(Java.ConstructorDeclarator cd) throws CompileException {
-        for (Iterator it = cd.getDeclaringClass().syntheticFields.values().iterator(); it.hasNext();) {
-            IClass.IField sf = (IClass.IField) it.next();
-            Java.LocalVariable syntheticParameter = (Java.LocalVariable) cd.syntheticParameters.get(sf.getName());
-            if (syntheticParameter == null) throw new RuntimeException("SNO: Synthetic parameter for synthetic field \"" + sf.getName() + "\" not found");
-            try {
-                Java.ExpressionStatement es = new Java.ExpressionStatement(new Java.Assignment(
-                    cd.getLocation(),             // location
-                    new Java.FieldAccess(         // lhs
-                        cd.getLocation(),                         // location
-                        new Java.ThisReference(cd.getLocation()), // lhs
-                        sf                                        // field
-                    ),
-                    "=",                          // operator
-                    new Java.LocalVariableAccess( // rhs
-                        cd.getLocation(),  // location
-                        syntheticParameter // localVariable
-                    )
-                ));
-                es.setEnclosingScope(cd);
-                this.compile(es);
-            } catch (Parser.ParseException e) {
-                throw new RuntimeException("S.N.O.");
-            }
-        }
-    }
-
-    /**
-     * Compiles the instance variable initializers and the instance initializers in their
-     * lexical order.
-     */
-    void initializeInstanceVariablesAndInvokeInstanceInitializers(Java.ConstructorDeclarator cd) throws CompileException {
-        for (int i = 0; i < cd.getDeclaringClass().variableDeclaratorsAndInitializers.size(); ++i) {
-            Java.TypeBodyDeclaration tbd = (Java.TypeBodyDeclaration) cd.getDeclaringClass().variableDeclaratorsAndInitializers.get(i);
-            if (!tbd.isStatic()) {
-                Java.BlockStatement bs = (Java.BlockStatement) tbd;
-                if (!this.compile(bs)) this.compileError("Instance variable declarator or instance initializer does not complete normally", bs.getLocation());
-            }
-        }
-    }
-
-    /**
-     * Statements that jump out of blocks ("return", "break", "continue")
-     * must call this method to make sure that the "finally" clauses of all
-     * "try...catch" statements are executed.
-     */
-    private void leaveStatements(
-        Java.Scope  from,
-        Java.Scope  to,
-        IClass optionalStackValueType
-    ) {
-        for (Java.Scope s = from; s != to; s = s.getEnclosingScope()) {
-            if (s instanceof Java.BlockStatement) {
-                this.leave((Java.BlockStatement) s, optionalStackValueType);
-            }
-        }
-    }
-
-    /**
-     * The LHS operand of type <code>lhsType</code> is expected on the stack.
-     * <p>
-     * The following operators are supported:
-     * <code>  | ^ & * / % + - << >> >>></code>
-     */
-    private IClass compileArithmeticBinaryOperation(
-        Locatable   l,
-        IClass      lhsType,
-        String      operator,
-        Java.Rvalue rhs
-    ) throws CompileException {
-        return this.compileArithmeticOperation(
-            l,
-            lhsType,
-            Arrays.asList(new Java.Rvalue[] { rhs }).iterator(),
-            operator
-        );
-    }
-
-    /**
-     * Execute an arithmetic operation on a sequence of <code>operands</code>. If
-     * <code>type</code> is non-null, the first operand with that type is already on the stack.
-     * <p>
-     * The following operators are supported:
-     * <code>  | ^ & * / % + - << >> >>></code>
-     */
-    private IClass compileArithmeticOperation(
-        final Locatable l,
-        IClass          type,
-        Iterator        operands,
-        String          operator
-    ) throws CompileException {
-        if (
-            operator == "|" ||
-            operator == "^" ||
-            operator == "&"
-        ) {
-            final int iopcode = (
-                operator == "&" ? Opcode.IAND :
-                operator == "|" ? Opcode.IOR  :
-                operator == "^" ? Opcode.IXOR : Integer.MAX_VALUE
-            );
-
-            do {
-                Java.Rvalue operand = (Java.Rvalue) operands.next();
-
-                if (type == null) {
-                    type = this.compileGetValue(operand);
-                } else {
-                    CodeContext.Inserter convertLhsInserter = this.codeContext.newInserter();
-                    IClass rhsType = this.compileGetValue(operand);
-
-                    if (
-                        type.isPrimitiveNumeric() &&
-                        rhsType.isPrimitiveNumeric()
-                    ) {
-                        IClass promotedType = this.binaryNumericPromotion(l, type, convertLhsInserter, rhsType);
-                        if (promotedType == IClass.INT) {
-                            this.writeOpcode(l, iopcode);
-                        } else
-                        if (promotedType == IClass.LONG) {
-                            this.writeOpcode(l, iopcode + 1);
-                        } else
-                        {
-                            this.compileError("Operator \"" + operator + "\" not defined on types \"" + type + "\" and \"" + rhsType + "\"", l.getLocation());
-                        }
-                        type = promotedType;
-                    } else
-                    if (
-                        (type == IClass.BOOLEAN && this.getUnboxedType(rhsType) == IClass.BOOLEAN) ||
-                        (this.getUnboxedType(type) == IClass.BOOLEAN && rhsType == IClass.BOOLEAN)
-                    ) {
-                        IClassLoader icl = this.iClassLoader;
-                        if (type == icl.BOOLEAN) {
-                            this.codeContext.pushInserter(convertLhsInserter);
-                            try {
-                                this.unboxingConversion(l, icl.BOOLEAN, IClass.BOOLEAN);
-                            } finally {
-                                this.codeContext.popInserter();
-                            }
-                        }
-                        if (rhsType == icl.BOOLEAN) {
-                            this.unboxingConversion(l, icl.BOOLEAN, IClass.BOOLEAN);
-                        }
-                        this.writeOpcode(l, iopcode);
-                        type = IClass.BOOLEAN;
-                    } else
-                    {
-                        this.compileError("Operator \"" + operator + "\" not defined on types \"" + type + "\" and \"" + rhsType + "\"", l.getLocation());
-                        type = IClass.INT;
-                    }
-                }
-            } while (operands.hasNext());
-            return type;
-        }
-
-        if (
-            operator == "*"   ||
-            operator == "/"   ||
-            operator == "%"   ||
-            operator == "+"   ||
-            operator == "-"
-        ) {
-            final int iopcode = (
-                operator == "*"   ? Opcode.IMUL  :
-                operator == "/"   ? Opcode.IDIV  :
-                operator == "%"   ? Opcode.IREM  :
-                operator == "+"   ? Opcode.IADD  :
-                operator == "-"   ? Opcode.ISUB  : Integer.MAX_VALUE
-            );
-
-            do {
-                Java.Rvalue operand = (Java.Rvalue) operands.next();
-
-                IClass operandType = this.getType(operand);
-                IClassLoader icl = this.iClassLoader;
-
-                // String concatenation?
-                if (operator == "+" && (type == icl.STRING || operandType == icl.STRING)) {
-                    return this.compileStringConcatenation(l, type, operand, operands);
-                }
-
-                if (type == null) {
-                    type = this.compileGetValue(operand);
-                } else {
-                    CodeContext.Inserter convertLhsInserter = this.codeContext.newInserter();
-                    IClass rhsType = this.compileGetValue(operand);
-
-                    type = this.binaryNumericPromotion(l, type, convertLhsInserter, rhsType);
-
-                    int opcode;
-                    if (type == IClass.INT) {
-                        opcode = iopcode;
-                    } else
-                    if (type == IClass.LONG) {
-                        opcode = iopcode + 1;
-                    } else
-                    if (type == IClass.FLOAT) {
-                        opcode = iopcode + 2;
-                    } else
-                    if (type == IClass.DOUBLE) {
-                        opcode = iopcode + 3;
-                    } else
-                    {
-                        this.compileError("Unexpected promoted type \"" + type + "\"", l.getLocation());
-                        opcode = iopcode;
-                    }
-                    this.writeOpcode(l, opcode);
-                }
-            } while (operands.hasNext());
-            return type;
-        }
-
-        if (
-            operator == "<<"  ||
-            operator == ">>"  ||
-            operator == ">>>"
-        ) {
-            final int iopcode = (
-                operator == "<<"  ? Opcode.ISHL  :
-                operator == ">>"  ? Opcode.ISHR  :
-                operator == ">>>" ? Opcode.IUSHR : Integer.MAX_VALUE
-            );
-
-            do {
-                Java.Rvalue operand = (Java.Rvalue) operands.next();
-
-                if (type == null) {
-                    type = this.compileGetValue(operand);
-                } else {
-                    CodeContext.Inserter convertLhsInserter = this.codeContext.newInserter();
-                    IClass rhsType = this.compileGetValue(operand);
-
-                    IClass promotedLhsType;
-                    this.codeContext.pushInserter(convertLhsInserter);
-                    try {
-                        promotedLhsType = this.unaryNumericPromotion(l, type);
-                    } finally {
-                        this.codeContext.popInserter();
-                    }
-                    if (promotedLhsType != IClass.INT && promotedLhsType != IClass.LONG) this.compileError("Shift operation not allowed on operand type \"" + type + "\"", l.getLocation());
-
-                    IClass promotedRhsType = this.unaryNumericPromotion(l, rhsType);
-                    if (promotedRhsType != IClass.INT && promotedRhsType != IClass.LONG) this.compileError("Shift distance of type \"" + rhsType + "\" is not allowed", l.getLocation());
-
-                    if (promotedRhsType == IClass.LONG) this.writeOpcode(l, Opcode.L2I);
-
-                    this.writeOpcode(l, promotedLhsType == IClass.LONG ? iopcode + 1 : iopcode);
-                    type = promotedLhsType;
-                }
-            } while (operands.hasNext());
-            return type;
-        }
-
-        throw new RuntimeException("Unexpected operator \"" + operator + "\"");
-    }
-
-    /**
-     * @param type If non-null, the first operand with that type is already on the stack
-     * @param operand The next operand
-     * @param operands All following operands ({@link Iterator} over {@link Java.Rvalue}s)
-     */
-    private IClass compileStringConcatenation(
-        final Locatable l,
-        IClass          type,
-        Java.Rvalue     operand,
-        Iterator        operands
-    ) throws CompileException {
-        boolean operandOnStack;
-        if (type != null) {
-            this.stringConversion(l, type);
-            operandOnStack = true;
-        } else
-        {
-            operandOnStack = false;
-        }
-
-        // Compute list of operands and merge consecutive constant operands.
-        List tmp = new ArrayList(); // Compilable
-        do {
-            Object cv = this.getConstantValue(operand);
-            if (cv == null) {
-                // Non-constant operand.
-                final Java.Rvalue final_operand = operand;
-                tmp.add(new Compilable() {
-                    public void compile() throws CompileException {
-                        UnitCompiler.this.stringConversion(l, UnitCompiler.this.compileGetValue(final_operand));
-                    }
-                });
-
-                operand = operands.hasNext() ? (Java.Rvalue) operands.next() : null;
-            } else
-            {
-                // Constant operand. Check to see whether the next operand is also constant.
-                if (operands.hasNext()) {
-                    operand = (Java.Rvalue) operands.next();
-                    Object cv2 = this.getConstantValue(operand);
-                    if (cv2 != null) {
-                        StringBuffer sb = new StringBuffer(cv.toString()).append(cv2);
-                        for (;;) {
-                            if (!operands.hasNext()) {
-                                operand = null;
-                                break;
-                            }
-                            operand = (Java.Rvalue) operands.next();
-                            Object cv3 = this.getConstantValue(operand);
-                            if (cv3 == null) break;
-                            sb.append(cv3);
-                        }
-                        cv = sb.toString();
-                    }
-                } else
-                {
-                    operand = null;
-                }
-                // Break long string constants up into UTF8-able chunks.
-                final String[] ss = UnitCompiler.makeUTF8Able(cv.toString());
-                for (int i = 0; i < ss.length; ++i) {
-                    final String s = ss[i];
-                    tmp.add(new Compilable() {
-                        public void compile() throws CompileException {
-                            UnitCompiler.this.pushConstant(l, s);
-                        }
-                    });
-                }
-            }
-        } while (operand != null);
-
-        // At this point "tmp" contains an optimized sequence of Strings (representing constant
-        // portions) and Rvalues (non-constant portions).
-
-        if (tmp.size() <= (operandOnStack ? STRING_CONCAT_LIMIT - 1: STRING_CONCAT_LIMIT)) {
-
-            // String concatenation through "a.concat(b).concat(c)".
-            for (Iterator it = tmp.iterator(); it.hasNext();) {
-                Compilable c = (Compilable) it.next();
-                c.compile();
-                
-                // Concatenate.
-                if (operandOnStack) {
-                    this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
-                    this.writeConstantMethodrefInfo(
-                        Descriptor.STRING,
-                        "concat",                                // classFD
-                        "(" + Descriptor.STRING + ")" + Descriptor.STRING // methodMD
-                    );
-                } else
-                {
-                    operandOnStack = true;
-                }
-            }
-            return this.iClassLoader.STRING;
-        }
-
-        // String concatenation through "new StringBuffer(a).append(b).append(c).append(d).toString()".
-        Iterator it = tmp.iterator();
-
-        String stringBuilferFD = this.isStringBuilderAvailable ? Descriptor.STRING_BUILDER : Descriptor.STRING_BUFFER;
-        // "new StringBuffer(a)":
-        if (operandOnStack) {
-            this.writeOpcode(l, Opcode.NEW);
-            this.writeConstantClassInfo(stringBuilferFD);
-            this.writeOpcode(l, Opcode.DUP_X1);
-            this.writeOpcode(l, Opcode.SWAP);
-        } else
-        {
-            this.writeOpcode(l, Opcode.NEW);
-            this.writeConstantClassInfo(stringBuilferFD);
-            this.writeOpcode(l, Opcode.DUP);
-            ((Compilable) it.next()).compile();
-        }
-        this.writeOpcode(l, Opcode.INVOKESPECIAL);
-        this.writeConstantMethodrefInfo(
-            stringBuilferFD,
-            "<init>",                                // classFD
-            "(" + Descriptor.STRING + ")" + Descriptor.VOID_ // methodMD
-        );
-        while (it.hasNext()) {
-            ((Compilable) it.next()).compile();
-            
-            // "StringBuffer.append(b)":
-            this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
-            this.writeConstantMethodrefInfo(
-                stringBuilferFD,
-                "append",                                // classFD
-                "(" + Descriptor.STRING + ")" + stringBuilferFD // methodMD
-            );
-        }
-
-        // "StringBuffer.toString()":
-        this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
-        this.writeConstantMethodrefInfo(
-            stringBuilferFD,
-            "toString",           // classFD
-            "()" + Descriptor.STRING   // methodMD
-        );
-        return this.iClassLoader.STRING;
-    }
-    interface Compilable { void compile() throws CompileException; }
-
-    /**
-     * Convert object of type "sourceType" to type "String". JLS2 15.18.1.1
-     */
-    private void stringConversion(
-        Locatable l,
-        IClass    sourceType
-    ) {
-        this.writeOpcode(l, Opcode.INVOKESTATIC);
-        this.writeConstantMethodrefInfo(
-            Descriptor.STRING,
-            "valueOf", // classFD
-            "(" + (            // methodMD
-                sourceType == IClass.BOOLEAN ||
-                sourceType == IClass.CHAR    ||
-                sourceType == IClass.LONG    ||
-                sourceType == IClass.FLOAT   ||
-                sourceType == IClass.DOUBLE ? sourceType.getDescriptor() :
-                sourceType == IClass.BYTE  ||
-                sourceType == IClass.SHORT ||
-                sourceType == IClass.INT ? Descriptor.INT_ :
-                Descriptor.OBJECT
-            ) + ")" + Descriptor.STRING
-        );
-    }
-
-    /**
-     * Expects the object to initialize on the stack.
-     * <p>
-     * Notice: This method is used both for explicit constructor invocation (first statement of
-     * a constructor body) and implicit constructor invocation (right after NEW).
-     *
-     * @param optionalEnclosingInstance Used if the target class is an inner class
-     */
-    private void invokeConstructor(
-        Locatable     l,
-        Java.Scope    scope,
-        Java.Rvalue   optionalEnclosingInstance,
-        IClass        targetClass,
-        Java.Rvalue[] arguments
-    ) throws CompileException {
-
-        // Find constructors.
-        IClass.IConstructor[] iConstructors = targetClass.getDeclaredIConstructors();
-        if (iConstructors.length == 0) throw new RuntimeException("SNO: Target class \"" + targetClass.getDescriptor() + "\" has no constructors");
-
-        IClass.IConstructor iConstructor = (IClass.IConstructor) this.findMostSpecificIInvocable(
-            l,
-            iConstructors, // iInvocables
-            arguments      // arguments
-        );
-
-        // Check exceptions that the constructor may throw.
-        IClass[] thrownExceptions = iConstructor.getThrownExceptions();
-        for (int i = 0; i < thrownExceptions.length; ++i) {
-            this.checkThrownException(
-                l,
-                thrownExceptions[i],
-                scope
-            );
-        }
-
-        // Pass enclosing instance as a synthetic parameter.
-        if (optionalEnclosingInstance != null) {
-            IClass outerIClass = targetClass.getOuterIClass();
-            if (outerIClass != null) {
-                IClass eiic = this.compileGetValue(optionalEnclosingInstance);
-                if (!outerIClass.isAssignableFrom(eiic)) this.compileError("Type of enclosing instance (\"" + eiic + "\") is not assignable to \"" + outerIClass + "\"", l.getLocation());
-            }
-        }
-
-        // Pass local variables to constructor as synthetic parameters.
-        {
-            IClass.IField[] syntheticFields = targetClass.getSyntheticIFields();
-
-            // Determine enclosing function declarator and type declaration.
-            Java.TypeBodyDeclaration scopeTBD;
-            Java.TypeDeclaration     scopeTypeDeclaration;
-            {
-                Java.Scope s = scope;
-                for (; !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
-                scopeTBD             = (Java.TypeBodyDeclaration) s;
-                scopeTypeDeclaration = scopeTBD.getDeclaringType();
-            }
-
-            if (!(scopeTypeDeclaration instanceof Java.ClassDeclaration)) {
-                if (syntheticFields.length > 0) throw new RuntimeException("SNO: Target class has synthetic fields");
-            } else {
-                Java.ClassDeclaration scopeClassDeclaration = (Java.ClassDeclaration) scopeTypeDeclaration;
-                for (int i = 0; i < syntheticFields.length; ++i) {
-                    IClass.IField sf = syntheticFields[i];
-                    if (!sf.getName().startsWith("val$")) continue;
-                    IClass.IField eisf = (IClass.IField) scopeClassDeclaration.syntheticFields.get(sf.getName());
-                    if (eisf != null) {
-                        if (scopeTBD instanceof Java.MethodDeclarator) {
-                            this.load(l, this.resolve(scopeClassDeclaration), 0);
-                            this.writeOpcode(l, Opcode.GETFIELD);
-                            this.writeConstantFieldrefInfo(
-                                this.resolve(scopeClassDeclaration).getDescriptor(),
-                                sf.getName(), // classFD
-                                sf.getDescriptor()                                   // fieldFD
-                            );
-                        } else
-                        if (scopeTBD instanceof Java.ConstructorDeclarator) {
-                            Java.ConstructorDeclarator constructorDeclarator = (Java.ConstructorDeclarator) scopeTBD;
-                            Java.LocalVariable syntheticParameter = (Java.LocalVariable) constructorDeclarator.syntheticParameters.get(sf.getName());
-                            if (syntheticParameter == null) {
-                                this.compileError("Compiler limitation: Constructor cannot access local variable \"" + sf.getName().substring(4) + "\" declared in an enclosing block because none of the methods accesses it. As a workaround, declare a dummy method that accesses the local variable.", l.getLocation());
-                                this.writeOpcode(l, Opcode.ACONST_NULL);
-                            } else {
-                                this.load(l, syntheticParameter);
-                            }
-                        } else {
-                            this.compileError("Compiler limitation: Initializers cannot access local variables declared in an enclosing block.", l.getLocation());
-                            this.writeOpcode(l, Opcode.ACONST_NULL);
-                        }
-                    } else {
-                        String localVariableName = sf.getName().substring(4);
-                        Java.LocalVariable lv;
-                        DETERMINE_LV: {
-                            Java.Scope s;
-
-                            // Does one of the enclosing blocks declare a local variable with that name?
-                            for (s = scope; s instanceof Java.BlockStatement; s = s.getEnclosingScope()) {
-                                Java.BlockStatement bs = (Java.BlockStatement) s;
-                                Java.Scope es = bs.getEnclosingScope();
-                                if (!(es instanceof Java.Block)) continue;
-                                Java.Block b = (Java.Block) es;
-    
-                                for (Iterator it = b.statements.iterator();;) {
-                                    Java.BlockStatement bs2 = (Java.BlockStatement) it.next();
-                                    if (bs2 == bs) break;
-                                    if (bs2 instanceof Java.LocalVariableDeclarationStatement) {
-                                        Java.LocalVariableDeclarationStatement lvds = ((Java.LocalVariableDeclarationStatement) bs2);
-                                        Java.VariableDeclarator[] vds = lvds.variableDeclarators;
-                                        for (int j = 0; j < vds.length; ++j) {
-                                            if (vds[j].name.equals(localVariableName)) {
-                                                lv = this.getLocalVariable(lvds, vds[j]);
-                                                break DETERMINE_LV;
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-
-                            // Does the declaring function declare a parameter with that name?
-                            while (!(s instanceof Java.FunctionDeclarator)) s = s.getEnclosingScope();
-                            Java.FunctionDeclarator fd = (Java.FunctionDeclarator) s;
-                            for (int j = 0; j < fd.formalParameters.length; ++j) {
-                                Java.FunctionDeclarator.FormalParameter fp = fd.formalParameters[j];
-                                if (fp.name.equals(localVariableName)) {
-                                    lv = this.getLocalVariable(fp);
-                                    break DETERMINE_LV;
-                                }
-                            }
-                            throw new RuntimeException("SNO: Synthetic field \"" + sf.getName() + "\" neither maps a synthetic field of an enclosing instance nor a local variable");
-                        }
-                        this.load(l, lv);
-                    }
-                }
-            }
-        }
-
-        // Evaluate constructor arguments.
-        IClass[] parameterTypes = iConstructor.getParameterTypes();
-        for (int i = 0; i < arguments.length; ++i) {
-            this.assignmentConversion(
-                l,                                  // l
-                this.compileGetValue(arguments[i]), // sourceType
-                parameterTypes[i],                  // targetType
-                this.getConstantValue(arguments[i]) // optionalConstantValue
-            );
-        }
-
-        // Invoke!
-        // Notice that the method descriptor is "iConstructor.getDescriptor()" prepended with the
-        // synthetic parameters.
-        this.writeOpcode(l, Opcode.INVOKESPECIAL);
-        this.writeConstantMethodrefInfo(
-            targetClass.getDescriptor(),
-            "<init>", // classFD
-            iConstructor.getDescriptor() // methodMD
-        );
-    }
-
-    /*package*/ IClass.IField[] getIFields(final Java.FieldDeclaration fd) {
-        IClass.IField[] res = new IClass.IField[fd.variableDeclarators.length];
-        for (int i = 0; i < res.length; ++i) {
-            final Java.VariableDeclarator vd = fd.variableDeclarators[i];
-            res[i] = this.resolve(fd.getDeclaringType()).new IField() {
-
-                // Implement IMember.
-                public Access getAccess() {
-                    switch (fd.modifiers & Mod.PPP) {
-                    case Mod.PRIVATE:
-                        return Access.PRIVATE;
-                    case Mod.PROTECTED:
-                        return Access.PROTECTED;
-                    case Mod.PACKAGE:
-                        return Access.DEFAULT;
-                    case Mod.PUBLIC:
-                        return Access.PUBLIC;
-                    default:
-                        throw new RuntimeException("Invalid access");
-                    }
-                }
-
-                // Implement "IField".
-                public boolean isStatic() { return (fd.modifiers & Mod.STATIC) != 0; }
-                public IClass getType() throws CompileException {
-                    return UnitCompiler.this.getType(fd.type).getArrayIClass(vd.brackets, UnitCompiler.this.iClassLoader.OBJECT);
-                }
-                public String getName() { return vd.name; }
-                public Object getConstantValue() throws CompileException {
-                    if (
-                        (fd.modifiers & Mod.FINAL) != 0 &&
-                        vd.optionalInitializer instanceof Java.Rvalue
-                    ) {
-                        Object constantInitializerValue = UnitCompiler.this.getConstantValue((Java.Rvalue) vd.optionalInitializer);
-                        if (constantInitializerValue != null) return UnitCompiler.this.assignmentConversion(
-                            (Locatable) vd.optionalInitializer, // l
-                            constantInitializerValue,           // value
-                            this.getType()                      // targetType
-                        );
-                    }
-                    return null;
-                }
-            };
-        }
-        return res;
-    }
-
-    /**
-     * Determine the non-constant-final initializer of the given {@link Java.VariableDeclarator}.
-     * @return <code>null</code> if the variable is declared without an initializer or if the initializer is constant-final
-     */
-    Java.ArrayInitializerOrRvalue getNonConstantFinalInitializer(Java.FieldDeclaration fd, Java.VariableDeclarator vd) throws CompileException {
-
-        // Check if optional initializer exists.
-        if (vd.optionalInitializer == null) return null;
-
-        // Check if initializer is constant-final.
-        if (
-            (fd.modifiers & Mod.STATIC) != 0 &&
-            (fd.modifiers & Mod.FINAL) != 0 &&
-            vd.optionalInitializer instanceof Java.Rvalue &&
-            this.getConstantValue((Java.Rvalue) vd.optionalInitializer) != null
-        ) return null;
-
-        return vd.optionalInitializer;
-    }
-
-    private Java.Atom reclassify(Java.AmbiguousName an) throws CompileException {
-        if (an.reclassified == null) {
-            an.reclassified = this.reclassifyName(
-                an.getLocation(),
-                (Java.Scope) an.getEnclosingBlockStatement(),
-                an.identifiers, an.n
-            );
-        }
-        return an.reclassified;
-    }
-
-    /**
-     * JLS 6.5.2.2
-     * <p>
-     * Reclassify the ambiguous name consisting of the first <code>n</code> of the
-     * <code>identifers</code>.
-     * @param location
-     * @param scope
-     * @param identifiers
-     * @param n
-     * @throws CompileException
-     */
-    private Java.Atom reclassifyName(
-        Location       location,
-        Java.Scope     scope,
-        final String[] identifiers,
-        int            n
-    ) throws CompileException {
-
-        if (n == 1) return this.reclassifyName(
-            location,
-            scope,
-            identifiers[0]
-        );
-
-        // 6.5.2.2
-        Java.Atom lhs = this.reclassifyName(
-            location,
-            scope,
-            identifiers, n - 1
-        );
-        String rhs = identifiers[n - 1];
-
-        // 6.5.2.2.1
-        if (UnitCompiler.DEBUG) System.out.println("lhs = " + lhs);
-        if (lhs instanceof Java.Package) {
-            String className = ((Java.Package) lhs).name + '.' + rhs;
-            IClass result = findClassByName(location, className);
-            if (result != null) return new Java.SimpleType(location, result);
-
-            return new Java.Package(location, className);
-        }
-
-        // 6.5.2.2.3.2 EXPRESSION.length
-        if (rhs.equals("length") && this.getType(lhs).isArray()) {
-            Java.ArrayLength al = new Java.ArrayLength(location, this.toRvalueOrCE(lhs));
-            if (!(scope instanceof Java.BlockStatement)) {
-                this.compileError("\".length\" only allowed in expression context");
-                return al;
-            }
-            al.setEnclosingBlockStatement((Java.BlockStatement) scope);
-            return al;
-        }
-
-        IClass lhsType = this.getType(lhs);
-
-        // Notice: Don't need to check for 6.5.2.2.2.1 TYPE.METHOD and 6.5.2.2.3.1
-        // EXPRESSION.METHOD here because that has been done before.
-
-        {
-            IClass.IField field = this.findIField(lhsType, rhs, location);
-            if (field != null) {
-                // 6.5.2.2.2.2 TYPE.FIELD
-                // 6.5.2.2.3.2 EXPRESSION.FIELD
-                Java.FieldAccess fa = new Java.FieldAccess(
-                    location,
-                    lhs,
-                    field
-                );
-                fa.setEnclosingBlockStatement((Java.BlockStatement) scope);
-                return fa;
-            }
-        }
-
-        IClass[] classes = lhsType.getDeclaredIClasses();
-        for (int i = 0; i < classes.length; ++i) {
-            final IClass memberType = classes[i];
-            String name = Descriptor.toClassName(memberType.getDescriptor());
-            name = name.substring(name.lastIndexOf('$') + 1);
-            if (name.equals(rhs)) {
-
-                // 6.5.2.2.2.3 TYPE.TYPE
-                // 6.5.2.2.3.3 EXPRESSION.TYPE
-                return new Java.SimpleType(location, memberType);
-            }
-        }
-
-        this.compileError("\"" + rhs + "\" is neither a method, a field, nor a member class of \"" + lhsType + "\"", location);
-        return new Java.Atom(location) {
-            public String toString() { return Java.join(identifiers, "."); }
-            public final void accept(Visitor.AtomVisitor visitor) {}
-        };
-    }
-
-    private IClass findClassByName(Location location, String className) throws CompileException {
-        IClass res = this.findClass(className);
-        if(res != null) return res;
-        try {
-            return this.iClassLoader.loadIClass(Descriptor.fromClassName(className));
-        } catch (ClassNotFoundException ex) {
-            if (ex.getException() instanceof CompileException) throw (CompileException) ex.getException();
-            throw new CompileException(className, location, ex);
-        }
-    }
-
-    /**
-     * JLS 6.5.2.1
-     * @param location
-     * @param scope
-     * @param identifier
-     * @throws CompileException
-     */
-    private Java.Atom reclassifyName(
-        Location     location,
-        Java.Scope   scope,
-        final String identifier
-    ) throws CompileException {
-
-        // Determine scope block statement, type body declaration, type and compilation unit.
-        Java.BlockStatement          scopeBlockStatement = null;
-        Java.TypeBodyDeclaration     scopeTBD = null;
-        Java.AbstractTypeDeclaration scopeTypeDeclaration = null;
-        Java.CompilationUnit         scopeCompilationUnit;
-        {
-            Java.Scope s = scope;
-            if (s instanceof Java.BlockStatement) scopeBlockStatement = (Java.BlockStatement) s;
-            while (
-                (s instanceof Java.BlockStatement || s instanceof Java.CatchClause)
-                && !(s instanceof Java.TypeBodyDeclaration)
-            ) s = s.getEnclosingScope();
-            if (s instanceof Java.TypeBodyDeclaration) {
-                scopeTBD = (Java.TypeBodyDeclaration) s;
-                s = s.getEnclosingScope();
-            }
-            if (s instanceof Java.TypeDeclaration) {
-                scopeTypeDeclaration = (Java.AbstractTypeDeclaration) s;
-                s = s.getEnclosingScope();
-            }
-            while (!(s instanceof Java.CompilationUnit)) s = s.getEnclosingScope();
-            scopeCompilationUnit = (Java.CompilationUnit) s;
-        }
-
-        // 6.5.2.1.BL1
-
-        // 6.5.2.BL1.B1.B1.1 (JLS3: 6.5.2.BL1.B1.B1.1) / 6.5.6.1.1 Local variable.
-        // 6.5.2.BL1.B1.B1.2 (JLS3: 6.5.2.BL1.B1.B1.2) / 6.5.6.1.1 Parameter.
-        {
-            Java.Scope s = scope;
-            if (s instanceof Java.BlockStatement) {
-                Java.LocalVariable lv = ((Java.BlockStatement) s).findLocalVariable(identifier);
-                if (lv != null) {
-                    Java.LocalVariableAccess lva = new Java.LocalVariableAccess(location, lv);
-                    if (!(scope instanceof Java.BlockStatement)) throw new RuntimeException("SNO: Local variable access in non-block statement context!?");
-                    lva.setEnclosingBlockStatement((Java.BlockStatement) scope);
-                    return lva;
-                }
-                s = s.getEnclosingScope();
-            }
-            while (s instanceof Java.BlockStatement || s instanceof Java.CatchClause) s = s.getEnclosingScope();
-            if (s instanceof Java.FunctionDeclarator) {
-                s = s.getEnclosingScope();
-                if (s instanceof Java.InnerClassDeclaration) {
-                    Java.InnerClassDeclaration icd = (Java.InnerClassDeclaration) s;
-                    s = s.getEnclosingScope();
-                    if (s instanceof Java.AnonymousClassDeclaration) s = s.getEnclosingScope();
-                    while (s instanceof Java.BlockStatement) {
-                        Java.LocalVariable lv = ((Java.BlockStatement) s).findLocalVariable(identifier);
-                        if (lv != null) {
-                            if (!lv.finaL) this.compileError("Cannot access non-final local variable \"" + identifier + "\" from inner class");
-                            final IClass lvType = lv.type;
-                            IClass.IField iField = new SimpleIField(
-                                this.resolve(icd),
-                                "val$" + identifier,
-                                lvType
-                            );
-                            icd.defineSyntheticField(iField);
-                            Java.FieldAccess fa = new Java.FieldAccess(
-                                location,                        // location
-                                new Java.QualifiedThisReference( // lhs
-                                    location,                                        // location
-                                    new Java.SimpleType(location, this.resolve(icd)) // qualification
-                                ),
-                                iField                           // field
-                            );
-                            fa.setEnclosingBlockStatement((Java.BlockStatement) scope);
-                            return fa;
-                        }
-                        s = s.getEnclosingScope();
-                        while (s instanceof Java.BlockStatement) s = s.getEnclosingScope();
-                        if (!(s instanceof Java.FunctionDeclarator)) break;
-                        s = s.getEnclosingScope();
-                        if (!(s instanceof Java.InnerClassDeclaration)) break;
-                        icd = (Java.InnerClassDeclaration) s;
-                        s = s.getEnclosingScope();
-                    }
-                }
-            }
-        }
-
-        // 6.5.2.BL1.B1.B1.3 (JLS3: 6.5.2.BL1.B1.B1.3) / 6.5.6.1.2.1 Field.
-        Java.BlockStatement enclosingBlockStatement = null;
-        for (Java.Scope s = scope; !(s instanceof Java.CompilationUnit); s = s.getEnclosingScope()) {
-            if (s instanceof Java.BlockStatement && enclosingBlockStatement == null) enclosingBlockStatement = (Java.BlockStatement) s;
-            if (s instanceof Java.TypeDeclaration) {
-                final Java.AbstractTypeDeclaration enclosingTypeDecl = (Java.AbstractTypeDeclaration)s;
-                final IClass etd = UnitCompiler.this.resolve(enclosingTypeDecl);
-                final IClass.IField f = this.findIField(etd, identifier, location);
-                if (f != null) {
-                    if (f.isStatic()) {
-                        this.warning("IASF", "Implicit access to static field \"" + identifier + "\" of declaring class (better write \"" + f.getDeclaringIClass() + '.' + f.getName() + "\")", location);
-                    } else
-                    if (f.getDeclaringIClass() == etd) {
-                        this.warning("IANSF", "Implicit access to non-static field \"" + identifier + "\" of declaring class (better write \"this." + f.getName() + "\")", location);
-                    } else {
-                        this.warning("IANSFEI", "Implicit access to non-static field \"" + identifier + "\" of enclosing instance (better write \"" + f.getDeclaringIClass() + ".this." + f.getName() + "\")", location);
-                    }
-
-                    Java.SimpleType ct = new Java.SimpleType(scopeTypeDeclaration.getLocation(), (IClass) etd);
-                    Java.Atom lhs;
-                    if (scopeTBD.isStatic()) {
-
-                        // Field access in static method context.
-                        lhs = ct;
-                    } else
-                    {
-
-                        // Field access in non-static method context.
-                        if (f.isStatic()) {
-
-                            // Access to static field.
-                            lhs = ct;
-                        } else {
-
-                            // Access to non-static field.
-                            lhs = new Java.QualifiedThisReference(location, ct);
-                        }
-                    }
-                    Java.Rvalue res = new Java.FieldAccess(
-                        location,
-                        lhs,
-                        f
-                    );
-                    res.setEnclosingBlockStatement(enclosingBlockStatement);
-                    return res;
-                }
-            }
-        }
-
-        // JLS3 6.5.2.BL1.B1.B2.1 Static field imported through single static import.
-        {
-            Object o = this.singleStaticImports.get(identifier);
-            if (o instanceof IField) {
-                FieldAccess fieldAccess = new FieldAccess(location, new SimpleType(location, ((IField) o).getDeclaringIClass()), (IField) o);
-                fieldAccess.setEnclosingBlockStatement(enclosingBlockStatement);
-                return fieldAccess;
-            }
-        }
-
-        // JLS3 6.5.2.BL1.B1.B2.2 Static field imported through static-import-on-demand.
-        {
-            IField importedField = null;
-            for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
-                IClass iClass = (IClass) it.next();
-                IField[] flds = iClass.getDeclaredIFields();
-                for (int i = 0 ; i < flds.length; ++i) {
-                    IField f = flds[i];
-                    if (f.getName().equals(identifier)) {
-                        if (!UnitCompiler.this.isAccessible(f, enclosingBlockStatement)) continue; // JLS3 7.5.4 Static-Import-on-Demand Declaration
-                        if (importedField != null) UnitCompiler.this.compileError("Ambiguous static field import: \"" + importedField.toString() + "\" vs. \"" + f.toString() + "\"");
-                        importedField = f;
-                    }
-                }
-            }
-            if (importedField != null) {
-                if (!importedField.isStatic()) UnitCompiler.this.compileError("Cannot static-import non-static field");
-                FieldAccess fieldAccess = new FieldAccess(location, new SimpleType(location, importedField.getDeclaringIClass()), importedField);
-                fieldAccess.setEnclosingBlockStatement(enclosingBlockStatement);
-                return fieldAccess;
-            }
-        }
-
-        // Hack: "java" MUST be a package, not a class.
-        if (identifier.equals("java")) return new Java.Package(location, identifier);
-
-        // 6.5.2.BL1.B1.B2.1 (JLS3: 6.5.2.BL1.B1.B3.2) Local class.
-        {
-            Java.LocalClassDeclaration lcd = this.findLocalClassDeclaration(scope, identifier);
-            if (lcd != null) return new Java.SimpleType(location, this.resolve(lcd));
-        }
-
-        // 6.5.2.BL1.B1.B2.2 (JLS3: 6.5.2.BL1.B1.B3.3) Member type.
-        if (scopeTypeDeclaration != null) {
-            IClass memberType = this.findMemberType(UnitCompiler.this.resolve(scopeTypeDeclaration), identifier, location);
-            if (memberType != null) return new Java.SimpleType(location, memberType);
-        }
-
-        // 6.5.2.BL1.B1.B3.1 (JLS3: 6.5.2.BL1.B1.B4.1) Single type import.
-        {
-            IClass iClass = this.importSingleType(identifier, location);
-            if (iClass != null) return new Java.SimpleType(location, iClass);
-        }
-
-        // 6.5.2.BL1.B1.B3.2 (JLS3: 6.5.2.BL1.B1.B3.1) Package member class/interface declared in this compilation unit.
-        // Notice that JLS2 looks this up AFTER local class, member type, single type import, while
-        // JLS3 looks this up BEFORE local class, member type, single type import.
-        {
-            Java.PackageMemberTypeDeclaration pmtd = scopeCompilationUnit.getPackageMemberTypeDeclaration(identifier);
-            if (pmtd != null) return new Java.SimpleType(location, this.resolve((Java.AbstractTypeDeclaration) pmtd));
-        }
-
-        // 6.5.2.BL1.B1.B4 Class or interface declared in same package.
-        // Notice: Why is this missing in JLS3?
-        {
-            String className = (
-                scopeCompilationUnit.optionalPackageDeclaration == null ?
-                identifier :
-                scopeCompilationUnit.optionalPackageDeclaration.packageName + '.' + identifier
-            );
-            IClass result = findClassByName(location, className);
-            if (result != null) return new Java.SimpleType(location, result);
-        }
-
-        // 6.5.2.BL1.B1.B5 (JLS3: 6.5.2.BL1.B1.B4.2), 6.5.2.BL1.B1.B6 Type-import-on-demand.
-        {
-            IClass importedClass = this.importTypeOnDemand(identifier, location);
-            if (importedClass != null) {
-                return new Java.SimpleType(location, importedClass);
-            }
-        }
-
-        // JLS3 6.5.2.BL1.B1.B4.3 Type imported through single static import.
-        {
-            Object o = this.singleStaticImports.get(identifier);
-            if (o instanceof IClass) return new SimpleType(null, (IClass) o);
-        }
-
-        // JLS3 6.5.2.BL1.B1.B4.4 Type imported through static-import-on-demand.
-        {
-            IClass importedType = null;
-            for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
-                IClass ic = (IClass) it.next();
-                IClass[] memberTypes = ic.getDeclaredIClasses();
-                for (int i = 0; i < memberTypes.length; ++i) {
-                    IClass mt = memberTypes[i];
-                    if (!UnitCompiler.this.isAccessible(mt, scopeBlockStatement)) continue;
-                    if (mt.getDescriptor().endsWith('$' + identifier + ';')) {
-                        if (importedType != null) UnitCompiler.this.compileError("Ambiguous static type import: \"" + importedType.toString() + "\" vs. \"" + mt.toString() + "\"");
-                        importedType = mt;
-                    }
-                }
-            }
-            if (importedType != null) return new Java.SimpleType(null, importedType);
-        }
-        
-        // 6.5.2.BL1.B1.B7 Package name
-        return new Java.Package(location, identifier);
-    }
-
-    private void determineValue(Java.FieldAccessExpression fae) throws CompileException {
-        if (fae.value != null) return;
-
-        IClass lhsType = this.getType(fae.lhs);
-
-        if (fae.fieldName.equals("length") && lhsType.isArray()) {
-            fae.value = new Java.ArrayLength(
-                fae.getLocation(),
-                this.toRvalueOrCE(fae.lhs)
-            );
-        } else {
-            IClass.IField iField = this.findIField(lhsType, fae.fieldName, fae.getLocation());
-            if (iField == null) {
-                this.compileError("\"" + this.getType(fae.lhs).toString() + "\" has no field \"" + fae.fieldName + "\"", fae.getLocation());
-                fae.value = new Java.Rvalue(fae.getLocation()) {
-//                    public IClass compileGet() throws CompileException { return this.iClassLoader.OBJECT; }
-                    public String toString() { return "???"; }
-                    public final void accept(Visitor.AtomVisitor visitor) {}
-                    public final void accept(Visitor.RvalueVisitor visitor) {}
-                };
-                return;
-            }
-
-            fae.value = new Java.FieldAccess(
-                fae.getLocation(),
-                fae.lhs,
-                iField
-            );
-        }
-        fae.value.setEnclosingBlockStatement(fae.getEnclosingBlockStatement());
-    }
-
-    /** "super.fld", "Type.super.fld" */
-    private void determineValue(Java.SuperclassFieldAccessExpression scfae) throws CompileException {
-        if (scfae.value != null) return;
-
-        Rvalue lhs;
-        {
-            Java.ThisReference tr = new Java.ThisReference(scfae.getLocation());
-            tr.setEnclosingBlockStatement(scfae.getEnclosingBlockStatement());
-            IClass type;
-            if (scfae.optionalQualification != null) {
-                type = UnitCompiler.this.getType(scfae.optionalQualification);
-            } else
-            {
-                type = this.getType(tr);
-            }
-            lhs = new Java.Cast(scfae.getLocation(), new SimpleType(scfae.getLocation(), type.getSuperclass()), tr);
-        }
-
-        IClass.IField iField = this.findIField(this.getType(lhs), scfae.fieldName, scfae.getLocation());
-        if (iField == null) {
-            this.compileError("Class has no field \"" + scfae.fieldName + "\"", scfae.getLocation());
-            scfae.value = new Java.Rvalue(scfae.getLocation()) {
-                public String toString() { return "???"; }
-                public final void accept(Visitor.AtomVisitor visitor) {}
-                public final void accept(Visitor.RvalueVisitor visitor) {}
-            };
-            return;
-        }
-        scfae.value = new Java.FieldAccess(
-            scfae.getLocation(),
-            lhs,
-            iField
-        );
-        scfae.value.setEnclosingBlockStatement(scfae.getEnclosingBlockStatement());
-    }
-    
-    /**
-     * Find named methods of "targetType", examine the argument types and choose the
-     * most specific method. Check that only the allowed exceptions are thrown.
-     * <p>
-     * Notice that the returned {@link IClass.IMethod} may be declared in an enclosing type.
-     *
-     * @return The selected {@link IClass.IMethod} or <code>null</code>
-     */
-    public IClass.IMethod findIMethod(Java.MethodInvocation mi) throws CompileException {
-        IClass.IMethod iMethod;
-        FIND_METHOD: {
-
-            // Method declared by enclosing type declarations?
-            if (mi.optionalTarget == null) {
-                for (Java.Scope s = mi.getEnclosingBlockStatement(); !(s instanceof Java.CompilationUnit); s = s.getEnclosingScope()) {
-                    if (s instanceof Java.TypeDeclaration) {
-                        Java.TypeDeclaration td = (Java.TypeDeclaration) s;
-        
-                        // Find methods with specified name.
-                        iMethod = this.findIMethod(
-                            (Locatable) mi,    // loc
-                            this.resolve(td),  // targetType
-                            mi.methodName,     // methodName
-                            mi.arguments       // arguments
-                        );
-                        if (iMethod != null) break FIND_METHOD;
-                    }
-                }
-            }
-
-            // Method declared by the target's type?
-            if (mi.optionalTarget != null) {
-
-                // Find methods with specified name.
-                iMethod = this.findIMethod(
-                        (Locatable) mi,                  // loc
-                        this.getType(mi.optionalTarget), // targetType
-                        mi.methodName,                   // methodName
-                        mi.arguments                     // arguments
-                );
-                if (iMethod != null) break FIND_METHOD;
-            }
-            
-            // Static method declared through single static import?
-            {
-                Object o = this.singleStaticImports.get(mi.methodName);
-                if (o instanceof List) {
-                    IClass declaringIClass = ((IMethod) ((List) o).get(0)).getDeclaringIClass();
-                    iMethod = this.findIMethod(
-                        (Locatable) mi,  // l
-                        declaringIClass, // targetType
-                        mi.methodName,   // methodName
-                        mi.arguments     // arguments
-                    );
-                    if (iMethod != null) break FIND_METHOD;
-                }
-            }
-
-            // Static method declared through static-import-on-demand?
-            iMethod = null;
-            for (Iterator it = this.staticImportsOnDemand.iterator(); it.hasNext();) {
-                IClass iClass = (IClass) it.next();
-                IMethod im = this.findIMethod(
-                    (Locatable) mi, // l
-                    iClass,         // targetType
-                    mi.methodName,  // methodName
-                    mi.arguments    // arguments
-                );
-                if (im != null) {
-                    if (iMethod != null) UnitCompiler.this.compileError("Ambiguous static method import: \"" + iMethod.toString() + "\" vs. \"" + im.toString() + "\"");
-                    iMethod = im;
-                }
-            }
-            if (iMethod != null) break FIND_METHOD;
-
-            this.compileError("A method named \"" + mi.methodName + "\" is not declared in any enclosing class nor any supertype, nor through a static import", mi.getLocation());
-            return fakeIMethod(this.iClassLoader.OBJECT, mi.methodName, mi.arguments);
-        }
-
-        this.checkThrownExceptions(mi, iMethod);
-        return iMethod;
-    }
-
-    /**
-     * Find a {@link IClass.IMethod} in the given <code>targetType</code>, its superclasses or
-     * superinterfaces with the given <code>name</code> and for the given <code>arguments</code>.
-     * If more than one such method exists, choose the most specific one (JLS 15.11.2).
-     *
-     * @return <code>null</code> if no appropriate method could be found
-     */
-    private IClass.IMethod findIMethod(
-        Locatable loc,
-        IClass    targetType,
-        String    methodName,
-        Rvalue[]  arguments
-    ) throws CompileException {
-
-        // Get all methods 
-        List ms = new ArrayList();
-        this.getIMethods(targetType, methodName, ms);
-        if (ms.size() == 0) return null;
-
-        // Determine arguments' types, choose the most specific method
-        return (IClass.IMethod) this.findMostSpecificIInvocable(
-            loc,                                                          // loc
-            (IClass.IMethod[]) ms.toArray(new IClass.IMethod[ms.size()]), // iInvocables
-            arguments                                                     // arguments
-        );
-    }
-
-    private IMethod fakeIMethod(IClass targetType, final String name, Rvalue[] arguments) throws CompileException {
-        final IClass[] pts = new IClass[arguments.length];
-        for (int i = 0; i < arguments.length; ++i) pts[i] = this.getType(arguments[i]);
-        return targetType.new IMethod() {
-            public String   getName()                                     { return name; }
-            public IClass   getReturnType() throws CompileException       { return IClass.INT; }
-            public boolean  isStatic()                                    { return false; }
-            public boolean  isAbstract()                                  { return false; }
-            public IClass[] getParameterTypes() throws CompileException   { return pts; }
-            public IClass[] getThrownExceptions() throws CompileException { return new IClass[0]; }
-            public Access   getAccess()                                   { return Access.PUBLIC; }
-        };
-    }
-
-    /**
-     * Add all methods with the given <code>methodName</code> that are declared
-     * by the <code>type</code>, its superclasses and all their superinterfaces
-     * to the result list <code>v</code>.
-     * @param type
-     * @param methodName
-     * @param v
-     * @throws CompileException
-     */
-    public void getIMethods(
-        IClass type,
-        String methodName,
-        List   v // IMethod
-    ) throws CompileException {
-
-        // Check methods declared by this type.
-        {
-            IClass.IMethod[] ims = type.getDeclaredIMethods(methodName);
-            for (int i = 0; i < ims.length; ++i) v.add(ims[i]);
-        }
-
-        // Check superclass.
-        IClass superclass = type.getSuperclass();
-        if (superclass != null) this.getIMethods(superclass, methodName, v);
-
-        // Check superinterfaces.
-        IClass[] interfaces = type.getInterfaces();
-        for (int i = 0; i < interfaces.length; ++i) this.getIMethods(interfaces[i], methodName, v);
-
-        // JLS2 6.4.3
-        if (superclass == null && interfaces.length == 0 && type.isInterface()) {
-            IClass.IMethod[] oms = this.iClassLoader.OBJECT.getDeclaredIMethods(methodName);
-            for (int i = 0; i < oms.length; ++i) {
-                IClass.IMethod om = oms[i];
-                if (!om.isStatic() && om.getAccess() == Access.PUBLIC) v.add(om);
-            }
-        }
-    }
-
-    public IClass.IMethod findIMethod(Java.SuperclassMethodInvocation scmi) throws CompileException {
-        Java.ClassDeclaration declaringClass;
-        for (Java.Scope s = scmi.getEnclosingBlockStatement();; s = s.getEnclosingScope()) {
-            if (s instanceof Java.FunctionDeclarator) {
-                Java.FunctionDeclarator fd = (Java.FunctionDeclarator) s;
-                if ((fd.modifiers & Mod.STATIC) != 0) this.compileError("Superclass method cannot be invoked in static context", scmi.getLocation());
-            }
-            if (s instanceof Java.ClassDeclaration) {
-                declaringClass = (Java.ClassDeclaration) s;
-                break;
-            }
-        }
-        IClass superclass = this.resolve(declaringClass).getSuperclass();
-        IMethod iMethod = this.findIMethod(
-            (Locatable) scmi, // l
-            superclass,       // targetType
-            scmi.methodName,  // methodName
-            scmi.arguments    // arguments
-        );
-        if (iMethod == null) {
-            this.compileError("Class \"" + superclass + "\" has no method named \"" + scmi.methodName + "\"", scmi.getLocation());
-            return fakeIMethod(superclass, scmi.methodName, scmi.arguments);
-        }
-        this.checkThrownExceptions(scmi, iMethod);
-        return iMethod;
-    }
-
-    /**
-     * Determine the arguments' types, determine the applicable invocables and choose the most
-     * specific invocable.
-     *
-     * @param iInvocables Length must be greater than zero
-     *
-     * @return The selected {@link IClass.IInvocable}
-     * @throws CompileException
-     */
-    private IClass.IInvocable findMostSpecificIInvocable(
-        Locatable          l,
-        final IInvocable[] iInvocables,
-        Rvalue[]           arguments
-    ) throws CompileException {
-
-        // Determine arguments' types.
-        final IClass[] argumentTypes = new IClass[arguments.length];
-        for (int i = 0; i < arguments.length; ++i) {
-            argumentTypes[i] = this.getType(arguments[i]);
-        }
-
-        IInvocable ii = this.findMostSpecificIInvocable(l, iInvocables, argumentTypes, false);
-        if (ii != null) return ii;
-
-        ii = this.findMostSpecificIInvocable(l, iInvocables, argumentTypes, true);
-        if (ii != null) return ii;
-        
-        // Report a nice compile error.
-        StringBuffer sb = new StringBuffer("No applicable constructor/method found for ");
-        if (argumentTypes.length == 0) {
-            sb.append("zero actual parameters");
-        } else {
-            sb.append("actual parameters \"").append(argumentTypes[0]);
-            for (int i = 1; i < argumentTypes.length; ++i) {
-                sb.append(", ").append(argumentTypes[i]);
-            }
-            sb.append("\"");
-        }
-        sb.append("; candidates are: ").append('"' + iInvocables[0].toString() + '"');
-        for (int i = 1; i < iInvocables.length; ++i) {
-            sb.append(", ").append('"' + iInvocables[i].toString() + '"');
-        }
-        this.compileError(sb.toString(), l.getLocation());
-
-        // Well, returning a "fake" IInvocable is a bit tricky, because the iInvocables
-        // can be of different types.
-        if (iInvocables[0] instanceof IClass.IConstructor) {
-            return iInvocables[0].getDeclaringIClass().new IConstructor() {
-                public IClass[] getParameterTypes()   { return argumentTypes; }
-                public Access   getAccess()           { return Access.PUBLIC; }
-                public IClass[] getThrownExceptions() { return new IClass[0]; }
-            };
-        } else
-        if (iInvocables[0] instanceof IClass.IMethod) {
-            return iInvocables[0].getDeclaringIClass().new IMethod() {
-                public boolean  isStatic()            { return true; }
-                public boolean  isAbstract()          { return false; }
-                public IClass   getReturnType()       { return IClass.INT; }
-                public String   getName()             { return ((IClass.IMethod) iInvocables[0]).getName(); }
-                public Access   getAccess()           { return Access.PUBLIC; }
-                public IClass[] getParameterTypes()   { return argumentTypes; }
-                public IClass[] getThrownExceptions() { return new IClass[0]; }
-            };
-        } else
-        {
-            return iInvocables[0];
-        }
-    }
-
-    /**
-     * Determine the applicable invocables and choose the most specific invocable.
-     * 
-     * @return the maximally specific {@link IClass.IInvocable} or <code>null</code> if no {@link IClass.IInvocable} is applicable
-     *
-     * @throws CompileException
-     */
-    public IClass.IInvocable findMostSpecificIInvocable(
-        Locatable          l,
-        final IInvocable[] iInvocables,
-        final IClass[]     argumentTypes,
-        boolean            boxingPermitted
-    ) throws CompileException {
-        if (UnitCompiler.DEBUG) {
-            System.out.println("Argument types:");
-            for (int i = 0; i < argumentTypes.length; ++i) {
-                System.out.println(argumentTypes[i]);
-            }
-        }
-
-        // Select applicable methods (15.12.2.1).
-        List applicableIInvocables = new ArrayList();
-        NEXT_METHOD:
-        for (int i = 0; i < iInvocables.length; ++i) {
-            IClass.IInvocable ii = iInvocables[i];
-
-            // Check parameter count.
-            IClass[] parameterTypes = ii.getParameterTypes();
-            if (parameterTypes.length != argumentTypes.length) continue;
-
-            // Check argument types vs. parameter types.
-            if (UnitCompiler.DEBUG) System.out.println("Parameter / argument type check:");
-            for (int j = 0; j < argumentTypes.length; ++j) {
-                // Is method invocation conversion possible (5.3)?
-                if (UnitCompiler.DEBUG) System.out.println(parameterTypes[j] + " <=> " + argumentTypes[j]);
-                if (!this.isMethodInvocationConvertible(argumentTypes[j], parameterTypes[j], boxingPermitted)) continue NEXT_METHOD;
-            }
-
-            // Applicable!
-            if (UnitCompiler.DEBUG) System.out.println("Applicable!");
-            applicableIInvocables.add(ii);
-        }
-        if (applicableIInvocables.size() == 0) return null;
-
-        // Choose the most specific invocable (15.12.2.2).
-        if (applicableIInvocables.size() == 1) {
-            return (IClass.IInvocable) applicableIInvocables.get(0);
-        }
-
-        // Determine the "maximally specific invocables".
-        List maximallySpecificIInvocables = new ArrayList();
-        for (int i = 0; i < applicableIInvocables.size(); ++i) {
-            IClass.IInvocable applicableIInvocable = (IClass.IInvocable) applicableIInvocables.get(i);
-            int moreSpecific = 0, lessSpecific = 0;
-            for (int j = 0; j < maximallySpecificIInvocables.size(); ++j) {
-                IClass.IInvocable mostSpecificIInvocable = (IClass.IInvocable) maximallySpecificIInvocables.get(j);
-                if (applicableIInvocable.isMoreSpecificThan(mostSpecificIInvocable)) {
-                    ++moreSpecific;
-                } else
-                if (applicableIInvocable.isLessSpecificThan(mostSpecificIInvocable)) {
-                    ++lessSpecific;
-                }
-            }
-            if (moreSpecific == maximallySpecificIInvocables.size()) {
-                maximallySpecificIInvocables.clear();
-                maximallySpecificIInvocables.add(applicableIInvocable);
-            } else
-            if (lessSpecific < maximallySpecificIInvocables.size()) {
-                maximallySpecificIInvocables.add(applicableIInvocable);
-            } else
-            {
-                ;
-            }
-            if (UnitCompiler.DEBUG) System.out.println("maximallySpecificIInvocables=" + maximallySpecificIInvocables);
-        }
-
-        if (maximallySpecificIInvocables.size() == 1) return (IClass.IInvocable) maximallySpecificIInvocables.get(0);
-
-        ONE_NON_ABSTRACT_INVOCABLE:
-        if (maximallySpecificIInvocables.size() > 1 && iInvocables[0] instanceof IClass.IMethod) {
-            final IClass.IMethod im = (IClass.IMethod) maximallySpecificIInvocables.get(0);
-
-            // Check if all methods have the same signature (i.e. the types of all their
-            // parameters are identical) and exactly one of the methods is non-abstract
-            // (JLS 15.12.2.2.BL2.B1).
-            IClass.IMethod theNonAbstractMethod = null;
-            {
-                Iterator it = maximallySpecificIInvocables.iterator();
-                IClass.IMethod m = (IClass.IMethod) it.next();
-                IClass[] parameterTypesOfFirstMethod = m.getParameterTypes();
-                for (;;) {
-                    if (!m.isAbstract()) {
-                        if (theNonAbstractMethod != null) {
-                            IClass declaringIClass = m.getDeclaringIClass();
-                            IClass theNonAbstractMethodDeclaringIClass = theNonAbstractMethod.getDeclaringIClass();
-                            if (declaringIClass.isAssignableFrom(theNonAbstractMethodDeclaringIClass)) {
-                                ;
-                            } else
-                            if (theNonAbstractMethodDeclaringIClass.isAssignableFrom(declaringIClass)) {
-                                theNonAbstractMethod = m;
-                            } else
-                            {
-                                throw new RuntimeException("SNO: More than one non-abstract method with same signature and same declaring class!?");
-                            }
-                        }
-                    }
-                    if (!it.hasNext()) break;
-
-                    m = (IClass.IMethod) it.next();
-                    IClass[] pts = m.getParameterTypes();
-                    for (int i = 0; i < pts.length; ++i) {
-                        if (pts[i] != parameterTypesOfFirstMethod[i]) break ONE_NON_ABSTRACT_INVOCABLE;
-                    }
-                }
-            }
-
-            // JLS 15.12.2.2.BL2.B1.B1
-            if (theNonAbstractMethod != null) return theNonAbstractMethod;
-
-            // JLS 15.12.2.2.BL2.B1.B2
-            Set s = new HashSet();
-            {
-                IClass[][] tes = new IClass[maximallySpecificIInvocables.size()][];
-                Iterator it = maximallySpecificIInvocables.iterator();
-                for (int i = 0; i < tes.length; ++i) {
-                    tes[i] = ((IClass.IMethod) it.next()).getThrownExceptions();
-                }
-                for (int i = 0; i < tes.length; ++i) {
-                    EACH_EXCEPTION:
-                    for (int j = 0; j < tes[i].length; ++j) {
-
-                        // Check whether "that exception [te1] is declared in the THROWS
-                        // clause of each of the maximally specific methods".
-                        IClass te1 = tes[i][j];
-                        EACH_METHOD:
-                        for (int k = 0; k < tes.length; ++k) {
-                            if (k == i) continue;
-                            for (int m = 0; m < tes[k].length; ++m) {
-                                IClass te2 = tes[k][m];
-                                if (te2.isAssignableFrom(te1)) continue EACH_METHOD;
-                            }
-                            continue EACH_EXCEPTION;
-                        }
-                        s.add(te1);
-                    }
-                }
-            }
-
-            final IClass[] tes = (IClass[]) s.toArray(new IClass[s.size()]);
-            return im.getDeclaringIClass().new IMethod() {
-                public String   getName()                                   { return im.getName(); }
-                public IClass   getReturnType() throws CompileException     { return im.getReturnType(); }
-                public boolean  isAbstract()                                { return im.isAbstract(); }
-                public boolean  isStatic()                                  { return im.isStatic(); }
-                public Access   getAccess()                                 { return im.getAccess(); }
-                public IClass[] getParameterTypes() throws CompileException { return im.getParameterTypes(); }
-                public IClass[] getThrownExceptions()                       { return tes; }
-            };
-        }
-
-        // JLS 15.12.2.2.BL2.B2
-        {
-            StringBuffer sb = new StringBuffer("Invocation of constructor/method with actual parameter type(s) \"");
-            for (int i = 0; i < argumentTypes.length; ++i) {
-                if (i > 0) sb.append(", ");
-                sb.append(Descriptor.toString(argumentTypes[i].getDescriptor()));
-            }
-            sb.append("\" is ambiguous: ");
-            for (int i = 0; i < maximallySpecificIInvocables.size(); ++i) {
-                if (i > 0) sb.append(" vs. ");
-                sb.append("\"" + maximallySpecificIInvocables.get(i) + "\"");
-            }
-            this.compileError(sb.toString(), l.getLocation());
-        }
-
-        return (IClass.IMethod) iInvocables[0];
-    }
-
-    /**
-     * Check if "method invocation conversion" (5.3) is possible.
-     */
-    private boolean isMethodInvocationConvertible(
-        IClass  sourceType,
-        IClass  targetType,
-        boolean boxingPermitted
-    ) throws CompileException {
-
-        // 5.3 Identity conversion.
-        if (sourceType == targetType) return true;
-
-        // 5.3 Widening primitive conversion.
-        if (this.isWideningPrimitiveConvertible(sourceType, targetType)) return true;
-
-        // 5.3 Widening reference conversion.
-        if (this.isWideningReferenceConvertible(sourceType, targetType)) return true;
-
-        // JLS3 5.3 A boxing conversion (JLS3 5.1.7) optionally followed by widening reference conversion.
-        if (boxingPermitted) {
-            IClass boxedType = this.isBoxingConvertible(sourceType);
-            if (boxedType != null) {
-                return (
-                    this.isIdentityConvertible(boxedType, targetType) ||
-                    this.isWideningReferenceConvertible(boxedType, targetType)
-                );
-            }
-        }
-
-        // JLS3 5.3 An unboxing conversion (JLS3 5.1.8) optionally followed by a widening primitive conversion.
-        if (boxingPermitted) {
-            IClass unboxedType = this.isUnboxingConvertible(sourceType);
-            if (unboxedType != null) {
-                return (
-                    this.isIdentityConvertible(unboxedType, targetType) ||
-                    this.isWideningPrimitiveConvertible(unboxedType, targetType)
-                );
-            }
-        }
-
-        // 5.3 TODO: FLOAT or DOUBLE value set conversion
-
-        return false;
-    }
-
-    /**
-     * @throws CompileException if the {@link Invocation} throws exceptions that are disallowed in the given scope
-     */
-    private void checkThrownExceptions(Invocation in, IMethod iMethod) throws CompileException {
-        IClass[] thrownExceptions = iMethod.getThrownExceptions();
-        for (int i = 0; i < thrownExceptions.length; ++i) {
-            this.checkThrownException(
-                (Locatable) in,                              // l
-                thrownExceptions[i],                         // type
-                (Java.Scope) in.getEnclosingBlockStatement() // scope
-            );
-        }
-    }
-
-    /**
-     * @throws CompileException if the exception with the given type must not be thrown in the given scope
-     */
-    private void checkThrownException(
-        Locatable  l,
-        IClass     type,
-        Java.Scope scope
-    ) throws CompileException {
-
-        // Thrown object must be assignable to "Throwable".
-        if (!this.iClassLoader.THROWABLE.isAssignableFrom(type)) this.compileError("Thrown object of type \"" + type + "\" is not assignable to \"Throwable\"", l.getLocation());
-
-        // "RuntimeException" and "Error" are never checked.
-        if (
-            this.iClassLoader.RUNTIME_EXCEPTION.isAssignableFrom(type) ||
-            this.iClassLoader.ERROR.isAssignableFrom(type)
-        ) return;
-
-        for (;; scope = scope.getEnclosingScope()) {
-
-            // Match against enclosing "try...catch" blocks.
-            if (scope instanceof Java.TryStatement) {
-                Java.TryStatement ts = (Java.TryStatement) scope;
-                for (int i = 0; i < ts.catchClauses.size(); ++i) {
-                    Java.CatchClause cc = (Java.CatchClause) ts.catchClauses.get(i);
-                    IClass caughtType = this.getType(cc.caughtException.type);
-                    if (caughtType.isAssignableFrom(type)) return;
-                }
-            } else
-
-            // Match against "throws" clause of declaring function.
-            if (scope instanceof Java.FunctionDeclarator) {
-                Java.FunctionDeclarator fd = (Java.FunctionDeclarator) scope;
-                for (int i = 0; i < fd.thrownExceptions.length; ++i) {
-                    IClass te = this.getType(fd.thrownExceptions[i]);
-                    if (te.isAssignableFrom(type)) return;
-                }
-                break;
-            } else
-
-            if (scope instanceof Java.TypeBodyDeclaration) {
-                break;
-            }
-        }
-
-        this.compileError("Thrown exception of type \"" + type + "\" is neither caught by a \"try...catch\" block nor declared in the \"throws\" clause of the declaring function", l.getLocation());
-    }
-
-    private IClass getTargetIClass(Java.QualifiedThisReference qtr) throws CompileException {
-
-        // Determine target type.
-        if (qtr.targetIClass == null) {
-            qtr.targetIClass = this.getType(qtr.qualification);
-        }
-        return qtr.targetIClass;
-    }
-
-    /**
-     * Checks whether the operand is an integer-like local variable.
-     */
-    Java.LocalVariable isIntLV(Java.Crement c) throws CompileException {
-        if (!(c.operand instanceof Java.AmbiguousName)) return null;
-        Java.AmbiguousName an = (Java.AmbiguousName) c.operand;
-
-        Java.Atom rec = this.reclassify(an);
-        if (!(rec instanceof Java.LocalVariableAccess)) return null;
-        Java.LocalVariableAccess lva = (Java.LocalVariableAccess) rec;
-
-        Java.LocalVariable lv = lva.localVariable;
-        if (lv.finaL) this.compileError("Must not increment or decrement \"final\" local variable", lva.getLocation());
-        if (
-            lv.type == IClass.BYTE  ||
-            lv.type == IClass.SHORT ||
-            lv.type == IClass.INT   ||
-            lv.type == IClass.CHAR
-        ) return lv;
-        return null;
-    }
-
-    private IClass resolve(final Java.TypeDeclaration td) {
-        final Java.AbstractTypeDeclaration atd = (Java.AbstractTypeDeclaration) td;
-        if (atd.resolvedType == null) atd.resolvedType = new IClass() {
-            protected IClass.IMethod[] getDeclaredIMethods2() {
-                IClass.IMethod[] res = new IClass.IMethod[atd.declaredMethods.size()];
-                int i = 0;
-                for (Iterator it = atd.declaredMethods.iterator(); it.hasNext();) {
-                    res[i++] = UnitCompiler.this.toIMethod((Java.MethodDeclarator) it.next());
-                }
-                return res;
-            }
-            private IClass[] declaredClasses = null;
-            protected IClass[] getDeclaredIClasses2() {
-                if (this.declaredClasses == null) {
-                    IClass[] mts = new IClass[atd.declaredClassesAndInterfaces.size()];
-                    int i = 0;
-                    for (Iterator it = atd.declaredClassesAndInterfaces.iterator(); it.hasNext();) {
-                        mts[i++] = UnitCompiler.this.resolve((Java.AbstractTypeDeclaration) it.next());
-                    }
-                    this.declaredClasses = mts;
-                }
-                return this.declaredClasses;
-            }
-            protected IClass getDeclaringIClass2() {
-                Java.Scope s = atd;
-                for (; !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope()) {
-                    if (s instanceof Java.CompilationUnit) return null;
-                }
-                return UnitCompiler.this.resolve((Java.AbstractTypeDeclaration) s.getEnclosingScope());
-            }
-            protected IClass getOuterIClass2() throws CompileException {
-                Java.AbstractTypeDeclaration oc = (Java.AbstractTypeDeclaration) UnitCompiler.getOuterClass(atd);
-                if (oc == null) return null;
-                return UnitCompiler.this.resolve(oc);
-            }
-            protected final String getDescriptor2() {
-                return Descriptor.fromClassName(atd.getClassName());
-            }
-        
-            public boolean isArray() { return false; }
-            protected IClass  getComponentType2() { throw new RuntimeException("SNO: Non-array type has no component type"); }
-            public boolean isPrimitive() { return false; }
-            public boolean isPrimitiveNumeric() { return false; }
-            protected IConstructor[] getDeclaredIConstructors2() {
-                if (atd instanceof Java.ClassDeclaration) {
-                    Java.ConstructorDeclarator[] cs = ((Java.ClassDeclaration) atd).getConstructors();
-    
-                    IClass.IConstructor[] res = new IClass.IConstructor[cs.length];
-                    for (int i = 0; i < cs.length; ++i) res[i] = UnitCompiler.this.toIConstructor(cs[i]);
-                    return res;
-                }
-                return new IClass.IConstructor[0];
-            }
-            protected IField[] getDeclaredIFields2() {
-                if (atd instanceof Java.ClassDeclaration) {
-                    Java.ClassDeclaration cd = (Java.ClassDeclaration) atd;
-                    List l = new ArrayList(); // IClass.IField
-
-                    // Determine variable declarators of type declaration.
-                    for (int i = 0; i < cd.variableDeclaratorsAndInitializers.size(); ++i) {
-                        Java.BlockStatement vdoi = (Java.BlockStatement) cd.variableDeclaratorsAndInitializers.get(i);
-                        if (vdoi instanceof Java.FieldDeclaration) {
-                            Java.FieldDeclaration fd = (Java.FieldDeclaration) vdoi;
-                            IClass.IField[] flds = UnitCompiler.this.getIFields(fd);
-                            for (int j = 0; j < flds.length; ++j) l.add(flds[j]);
-                        }
-                    }
-                    return (IClass.IField[]) l.toArray(new IClass.IField[l.size()]);
-                } else
-                if (atd instanceof Java.InterfaceDeclaration) {
-                    Java.InterfaceDeclaration id = (Java.InterfaceDeclaration) atd;
-                    List l = new ArrayList();
-
-                    // Determine static fields.
-                    for (int i = 0; i < id.constantDeclarations.size(); ++i) {
-                        Java.BlockStatement bs = (Java.BlockStatement) id.constantDeclarations.get(i);
-                        if (bs instanceof Java.FieldDeclaration) {
-                            Java.FieldDeclaration fd = (Java.FieldDeclaration) bs;
-                            IClass.IField[] flds = UnitCompiler.this.getIFields(fd);
-                            for (int j = 0; j < flds.length; ++j) l.add(flds[j]);
-                        }
-                    }
-                    return (IClass.IField[]) l.toArray(new IClass.IField[l.size()]);
-                } else {
-                    throw new RuntimeException("SNO: AbstractTypeDeclaration is neither ClassDeclaration nor InterfaceDeclaration");
-                }
-            }
-            public IField[] getSyntheticIFields() {
-                if (atd instanceof Java.ClassDeclaration) {
-                    Collection c = ((Java.ClassDeclaration) atd).syntheticFields.values();
-                    return (IField[]) c.toArray(new IField[c.size()]);
-                }
-                return new IField[0];
-            }
-            protected IClass getSuperclass2() throws CompileException {
-                if (atd instanceof Java.AnonymousClassDeclaration) {
-                    IClass bt = UnitCompiler.this.getType(((Java.AnonymousClassDeclaration) atd).baseType);
-                    return bt.isInterface() ? UnitCompiler.this.iClassLoader.OBJECT : bt;
-                }
-                if (atd instanceof Java.NamedClassDeclaration) {
-                    Java.NamedClassDeclaration ncd = (Java.NamedClassDeclaration) atd;
-                    if (ncd.optionalExtendedType == null) return UnitCompiler.this.iClassLoader.OBJECT;
-                    IClass superclass = UnitCompiler.this.getType(ncd.optionalExtendedType);
-                    if (superclass.isInterface()) UnitCompiler.this.compileError("\"" + superclass.toString() + "\" is an interface; classes can only extend a class", td.getLocation());
-                    return superclass;
-                }
-                return null;
-            }
-            public Access getAccess() { return UnitCompiler.modifiers2Access(atd.modifiers); }
-            public boolean isFinal() { return (atd.modifiers & Mod.FINAL) != 0;  }
-            protected IClass[] getInterfaces2() throws CompileException {
-                if (atd instanceof Java.AnonymousClassDeclaration) {
-                    IClass bt = UnitCompiler.this.getType(((Java.AnonymousClassDeclaration) atd).baseType);
-                    return bt.isInterface() ? new IClass[] { bt } : new IClass[0];
-                } else
-                if (atd instanceof Java.NamedClassDeclaration) {
-                    Java.NamedClassDeclaration ncd = (Java.NamedClassDeclaration) atd;
-                    IClass[] res = new IClass[ncd.implementedTypes.length];
-                    for (int i = 0; i < res.length; ++i) {
-                        res[i] = UnitCompiler.this.getType(ncd.implementedTypes[i]);
-                        if (!res[i].isInterface()) UnitCompiler.this.compileError("\"" + res[i].toString() + "\" is not an interface; classes can only implement interfaces", td.getLocation());
-                    }
-                    return res;
-                } else
-                if (atd instanceof Java.InterfaceDeclaration) {
-                    Java.InterfaceDeclaration id = (Java.InterfaceDeclaration) atd;
-                    IClass[] res = new IClass[id.extendedTypes.length];
-                    for (int i = 0; i < res.length; ++i) {
-                        res[i] = UnitCompiler.this.getType(id.extendedTypes[i]);
-                        if (!res[i].isInterface()) UnitCompiler.this.compileError("\"" + res[i].toString() + "\" is not an interface; interfaces can only extend interfaces", td.getLocation());
-                    }
-                    return res;
-                } else {
-                    throw new RuntimeException("SNO: AbstractTypeDeclaration is neither ClassDeclaration nor InterfaceDeclaration");
-                }
-            }
-            public boolean isAbstract() {
-                return (
-                    (atd instanceof Java.InterfaceDeclaration)
-                    || (atd.modifiers & Mod.ABSTRACT) != 0
-                );
-            }
-            public boolean isInterface() { return atd instanceof Java.InterfaceDeclaration; }
-        };
-
-        return atd.resolvedType;
-    }
-
-    private void referenceThis(
-        Locatable                l,
-        Java.ClassDeclaration    declaringClass,
-        Java.TypeBodyDeclaration declaringTypeBodyDeclaration,
-        IClass                   targetIClass
-    ) throws CompileException {
-        List path = UnitCompiler.getOuterClasses(declaringClass);
-
-        if (declaringTypeBodyDeclaration.isStatic()) this.compileError("No current instance available in static context", l.getLocation());
-
-        int j;
-        TARGET_FOUND: {
-            for (j = 0; j < path.size(); ++j) {
-
-                // Notice: JLS 15.9.2.BL1.B3.B1.B2 seems to be wrong: Obviously, JAVAC does not
-                // only allow
-                //
-                //    O is the nth lexically enclosing class
-                //
-                // , but also
-                //
-                //    O is assignable from the nth lexically enclosing class
-                //
-                // However, this strategy bears the risk of ambiguities, because "O" may be
-                // assignable from more than one enclosing class.
-                if (targetIClass.isAssignableFrom(this.resolve((Java.AbstractTypeDeclaration) path.get(j)))) break TARGET_FOUND;
-            }
-            this.compileError("\"" + declaringClass + "\" is not enclosed by \"" + targetIClass + "\"", l.getLocation());
-        }
-
-        int i;
-        if (declaringTypeBodyDeclaration instanceof Java.ConstructorDeclarator) {
-            if (j == 0) {
-                this.writeOpcode(l, Opcode.ALOAD_0);
-                return;
-            }
-
-            Java.ConstructorDeclarator constructorDeclarator = (Java.ConstructorDeclarator) declaringTypeBodyDeclaration;
-            String spn = "this$" + (path.size() - 2);
-            Java.LocalVariable syntheticParameter = (Java.LocalVariable) constructorDeclarator.syntheticParameters.get(spn);
-            if (syntheticParameter == null) throw new RuntimeException("SNO: Synthetic parameter \""+ spn + "\" not found");
-            this.load(l, syntheticParameter);
-            i = 1;
-        } else {
-            this.writeOpcode(l, Opcode.ALOAD_0);
-            i = 0;
-        }
-        for (; i < j; ++i) {
-            final String fieldName = "this$" + (path.size() - i - 2);
-            final Java.InnerClassDeclaration inner = (Java.InnerClassDeclaration) path.get(i);
-            IClass iic = this.resolve((Java.AbstractTypeDeclaration) inner);
-            final Java.TypeDeclaration outer = (Java.TypeDeclaration) path.get(i + 1);
-            final IClass oic = this.resolve((Java.AbstractTypeDeclaration) outer);
-            inner.defineSyntheticField(new SimpleIField(
-                iic,
-                fieldName,
-                oic
-            ));
-            this.writeOpcode(l, Opcode.GETFIELD);
-            this.writeConstantFieldrefInfo(
-                iic.getDescriptor(),
-                fieldName, // classFD
-                oic.getDescriptor()  // fieldFD
-            );
-        }
-    }
-
-    /**
-     * Return a list consisting of the given <code>inner</code> class and all its outer classes.
-     * @return {@link List} of {@link Java.TypeDeclaration}
-     */
-    private static List getOuterClasses(Java.TypeDeclaration inner) {
-        List path = new ArrayList();
-        for (Java.TypeDeclaration ic = inner; ic != null; ic = UnitCompiler.getOuterClass(ic)) path.add(ic);
-        return path;
-    }
-
-    /*package*/ static Java.TypeDeclaration getOuterClass(Java.TypeDeclaration atd) {
-
-        // Package member class declaration.
-        if (atd instanceof Java.PackageMemberClassDeclaration) return null;
-
-        // Local class declaration.
-        if (atd instanceof Java.LocalClassDeclaration) {
-            Java.Scope s = atd.getEnclosingScope();
-            for (; !(s instanceof Java.FunctionDeclarator); s = s.getEnclosingScope());
-            if ((s instanceof Java.MethodDeclarator) && (((Java.FunctionDeclarator) s).modifiers & Mod.STATIC) != 0) return null;
-            for (; !(s instanceof Java.TypeDeclaration); s = s.getEnclosingScope());
-            Java.TypeDeclaration immediatelyEnclosingTypeDeclaration = (Java.TypeDeclaration) s;
-            return (
-                immediatelyEnclosingTypeDeclaration instanceof Java.ClassDeclaration
-            ) ? immediatelyEnclosingTypeDeclaration : null;
-        }
-
-        // Member class declaration.
-        if (
-            atd instanceof Java.MemberClassDeclaration &&
-            (((Java.MemberClassDeclaration) atd).modifiers & Mod.STATIC) != 0
-        ) return null;
-
-        // Anonymous class declaration, interface declaration
-        Java.Scope s = atd;
-        for (; !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope()) {
-            if (s instanceof Java.ConstructorInvocation) return null;
-            if (s instanceof Java.CompilationUnit) return null;
-        }
-        //if (!(s instanceof Java.ClassDeclaration)) return null;
-        if (((Java.TypeBodyDeclaration) s).isStatic()) return null;
-        return (Java.AbstractTypeDeclaration) s.getEnclosingScope();
-    }
-
-    private IClass getIClass(Java.ThisReference tr) throws CompileException {
-        if (tr.iClass == null) {
-
-            // Compile error if in static function context.
-            Java.Scope s;
-            for (s = tr.getEnclosingBlockStatement(); s instanceof Java.Statement || s instanceof Java.CatchClause; s = s.getEnclosingScope());
-            if (s instanceof Java.FunctionDeclarator) {
-                Java.FunctionDeclarator function = (Java.FunctionDeclarator) s;
-                if ((function.modifiers & Mod.STATIC) != 0) this.compileError("No current instance available in static method", tr.getLocation());
-            }
-
-            // Determine declaring type.
-            while (!(s instanceof Java.TypeDeclaration)) s = s.getEnclosingScope();
-            if (!(s instanceof Java.ClassDeclaration)) this.compileError("Only methods of classes can have a current instance", tr.getLocation());
-            tr.iClass = this.resolve((Java.ClassDeclaration) s);
-        }
-        return tr.iClass;
-    }
-
-    private IClass getReturnType(Java.FunctionDeclarator fd) throws CompileException {
-        if (fd.returnType == null) {
-            fd.returnType = this.getType(fd.type);
-        }
-        return fd.returnType;
-    }
-
-    /*package*/ IClass.IConstructor toIConstructor(final Java.ConstructorDeclarator cd) {
-        if (cd.iConstructor != null) return cd.iConstructor;
-
-        cd.iConstructor = this.resolve((Java.AbstractTypeDeclaration) cd.getDeclaringType()).new IConstructor() {
-
-            // Implement IMember.
-            public Access getAccess() {
-                switch (cd.modifiers & Mod.PPP) {
-                case Mod.PRIVATE:
-                    return Access.PRIVATE;
-                case Mod.PROTECTED:
-                    return Access.PROTECTED;
-                case Mod.PACKAGE:
-                    return Access.DEFAULT;
-                case Mod.PUBLIC:
-                    return Access.PUBLIC;
-                default:
-                    throw new RuntimeException("Invalid access");
-                }
-            }
-
-            // Implement IInvocable.
-            public String getDescriptor() throws CompileException {
-                if (!(cd.getDeclaringClass() instanceof Java.InnerClassDeclaration)) return super.getDescriptor();
-
-                List l = new ArrayList();
-
-                // Convert enclosing instance reference into prepended constructor parameters.
-                IClass outerClass = UnitCompiler.this.resolve(cd.getDeclaringClass()).getOuterIClass();
-                if (outerClass != null) l.add(outerClass.getDescriptor());
-
-                // Convert synthetic fields into prepended constructor parameters.
-                for (Iterator it = cd.getDeclaringClass().syntheticFields.values().iterator(); it.hasNext();) {
-                    IClass.IField sf = (IClass.IField) it.next();
-                    if (sf.getName().startsWith("val$")) l.add(sf.getType().getDescriptor());
-                }
-                Java.FunctionDeclarator.FormalParameter[] fps = cd.formalParameters;
-                for (int i = 0; i < fps.length; ++i) {
-                    l.add(UnitCompiler.this.getType(fps[i].type).getDescriptor());
-                }
-                String[] apd = (String[]) l.toArray(new String[l.size()]);
-                return new MethodDescriptor(apd, Descriptor.VOID_).toString();
-            }
-
-            public IClass[] getParameterTypes() throws CompileException {
-                Java.FunctionDeclarator.FormalParameter[] fps = cd.formalParameters;
-                IClass[] res = new IClass[fps.length];
-                for (int i = 0; i < fps.length; ++i) {
-                    res[i] = UnitCompiler.this.getType(fps[i].type);
-                }
-                return res;
-            }
-            public IClass[] getThrownExceptions() throws CompileException {
-                IClass[] res = new IClass[cd.thrownExceptions.length];
-                for (int i = 0; i < res.length; ++i) {
-                    res[i] = UnitCompiler.this.getType(cd.thrownExceptions[i]);
-                }
-                return res;
-            }
-
-            public String toString() {
-                StringBuffer sb = new StringBuffer();
-                sb.append(cd.getDeclaringType().getClassName());
-                sb.append('(');
-                Java.FunctionDeclarator.FormalParameter[] fps = cd.formalParameters;
-                for (int i = 0; i < fps.length; ++i) {
-                    if (i != 0) sb.append(", ");
-                    try {
-                        sb.append(UnitCompiler.this.getType(fps[i].type).toString());
-                    } catch (CompileException ex) {
-                        sb.append("???");
-                    }
-                }
-                return sb.append(')').toString();
-            }
-        };
-        return cd.iConstructor;
-    }
-
-    public IClass.IMethod toIMethod(final Java.MethodDeclarator md) {
-        if (md.iMethod != null) return md.iMethod;
-        md.iMethod = this.resolve((Java.AbstractTypeDeclaration) md.getDeclaringType()).new IMethod() {
-
-            // Implement IMember.
-            public Access getAccess() {
-                switch (md.modifiers & Mod.PPP) {
-                case Mod.PRIVATE:
-                    return Access.PRIVATE;
-                case Mod.PROTECTED:
-                    return Access.PROTECTED;
-                case Mod.PACKAGE:
-                    return Access.DEFAULT;
-                case Mod.PUBLIC:
-                    return Access.PUBLIC;
-                default:
-                    throw new RuntimeException("Invalid access");
-                }
-            }
-
-            // Implement IInvocable.
-            public IClass[] getParameterTypes() throws CompileException {
-                Java.FunctionDeclarator.FormalParameter[] fps = md.formalParameters;
-                IClass[] res = new IClass[fps.length];
-                for (int i = 0; i < fps.length; ++i) {
-                    res[i] = UnitCompiler.this.getType(fps[i].type);
-                }
-                return res;
-            }
-            public IClass[] getThrownExceptions() throws CompileException {
-                IClass[] res = new IClass[md.thrownExceptions.length];
-                for (int i = 0; i < res.length; ++i) {
-                    res[i] = UnitCompiler.this.getType(md.thrownExceptions[i]);
-                }
-                return res;
-            }
-
-            // Implement IMethod.
-            public boolean isStatic() { return (md.modifiers & Mod.STATIC) != 0; }
-            public boolean isAbstract() { return (md.getDeclaringType() instanceof Java.InterfaceDeclaration) || (md.modifiers & Mod.ABSTRACT) != 0; }
-            public IClass getReturnType() throws CompileException {
-                return UnitCompiler.this.getReturnType(md);
-            }
-            public String getName() { return md.name; }
-        };
-        return md.iMethod;
-    }
-
-    private IClass.IInvocable toIInvocable(Java.FunctionDeclarator fd) {
-        if (fd instanceof Java.ConstructorDeclarator) {
-            return this.toIConstructor((Java.ConstructorDeclarator) fd);
-        } else
-        if (fd instanceof Java.MethodDeclarator) {
-            return this.toIMethod((Java.MethodDeclarator) fd);
-        } else
-        {
-            throw new RuntimeException("FunctionDeclarator is neither ConstructorDeclarator nor MethodDeclarator");
-        }
-    }
-
-    /**
-     * If the given name was declared in a simple type import, load that class.
-     */
-    private IClass importSingleType(String simpleTypeName, Location location) throws CompileException {
-        String[] ss = this.getSingleTypeImport(simpleTypeName);
-        if (ss == null) return null;
-
-        IClass iClass = this.loadFullyQualifiedClass(ss);
-        if (iClass == null) {
-            this.compileError("Imported class \"" + Java.join(ss, ".") + "\" could not be loaded", location);
-            return this.iClassLoader.OBJECT;
-        }
-        return iClass;
-    }
-
-    /**
-     * Check if the given name was imported through a "single type import", e.g.<pre>
-     *     import java.util.Map</pre>
-     * 
-     * @return the fully qualified name or <code>null</code>
-     */
-    public String[] getSingleTypeImport(String name) {
-        return (String[]) this.singleTypeImports.get(name);
-    }
-
-    /**
-     * 6.5.2.BL1.B1.B5, 6.5.2.BL1.B1.B6 Type-import-on-demand.<br>
-     * 6.5.5.1.6 Type-import-on-demand declaration.
-     * @return <code>null</code> if the given <code>simpleTypeName</code> cannot be resolved through any of the import-on-demand directives
-     */
-    public IClass importTypeOnDemand(String simpleTypeName, Location location) throws CompileException {
-
-        // Check cache. (A cache for unimportable types is not required, because
-        // the class is importable 99.9%.)
-        IClass importedClass = (IClass) this.onDemandImportableTypes.get(simpleTypeName);
-        if (importedClass != null) return importedClass;
-
-        // Cache miss...
-        for (Iterator i = this.typeImportsOnDemand.iterator(); i.hasNext();) {
-            String[] ss = (String[]) i.next();
-            String[] ss2 = concat(ss, simpleTypeName);
-            IClass iClass = this.loadFullyQualifiedClass(ss2);
-            if (iClass != null) {
-                if (importedClass != null && importedClass != iClass) this.compileError("Ambiguous class name: \"" + importedClass + "\" vs. \"" + iClass + "\"", location);
-                importedClass = iClass;
-            }
-        }
-        if (importedClass == null) return null;
-
-        // Put in cache and return.
-        this.onDemandImportableTypes.put(simpleTypeName, importedClass);
-        return importedClass;
-    }
-    private final Map onDemandImportableTypes = new HashMap();   // String simpleTypeName => IClass
-    private void declareClassDollarMethod(Java.ClassLiteral cl) {
-
-        // Method "class$" is not yet declared; declare it like
-        //
-        //   static java.lang.Class class$(java.lang.String className) {
-        //       try {
-        //           return java.lang.Class.forName(className);
-        //       } catch (java.lang.ClassNotFoundException ex) {
-        //           throw new java.lang.NoClassDefFoundError(ex.getMessage());
-        //       }
-        //   }
-        //
-        Location loc = cl.getLocation();
-        Java.AbstractTypeDeclaration declaringType;
-        for (Java.Scope s = cl.getEnclosingBlockStatement();; s = s.getEnclosingScope()) {
-            if (s instanceof Java.AbstractTypeDeclaration) {
-                declaringType = (Java.AbstractTypeDeclaration) s;
-                break;
-            }
-        }
-        Java.Block body = new Java.Block(loc);
-
-        // try {
-        // return Class.forName(className);
-        Java.MethodInvocation mi = new Java.MethodInvocation(
-            loc,                                               // location
-            new Java.SimpleType(loc, this.iClassLoader.CLASS), // optionalTarget
-            "forName",                                         // methodName
-            new Java.Rvalue[] {                                // arguments
-                new Java.AmbiguousName(loc, new String[] { "className" } )
-            }
-        );
-
-        IClass classNotFoundExceptionIClass;
-        try {
-            classNotFoundExceptionIClass = this.iClassLoader.loadIClass("Ljava/lang/ClassNotFoundException;");
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException("Loading class \"ClassNotFoundException\": " + ex.getMessage());
-        }
-        if (classNotFoundExceptionIClass == null) throw new RuntimeException("SNO: Cannot load \"ClassNotFoundException\"");
-
-        IClass noClassDefFoundErrorIClass;
-        try {
-            noClassDefFoundErrorIClass = this.iClassLoader.loadIClass("Ljava/lang/NoClassDefFoundError;");
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException("Loading class \"NoClassDefFoundError\": " + ex.getMessage());
-        }
-        if (noClassDefFoundErrorIClass == null) throw new RuntimeException("SNO: Cannot load \"NoClassFoundError\"");
-
-        // catch (ClassNotFoundException ex) {
-        Java.Block b = new Java.Block(loc);
-        // throw new NoClassDefFoundError(ex.getMessage());
-        b.addStatement(new Java.ThrowStatement(loc, new Java.NewClassInstance(
-            loc,                                                  // location
-            (Java.Rvalue) null,                                   // optionalQualification
-            new Java.SimpleType(loc, noClassDefFoundErrorIClass), // type
-            new Java.Rvalue[] {                                   // arguments
-                new Java.MethodInvocation(
-                    loc,                                                // location
-                    new Java.AmbiguousName(loc, new String[] { "ex"} ), // optionalTarget
-                    "getMessage",                                       // methodName
-                    new Java.Rvalue[0]                                  // arguments
-                )
-            }
-        )));
-
-        List l = new ArrayList();
-        l.add(new Java.CatchClause(
-            loc,                                         // location
-            new Java.FunctionDeclarator.FormalParameter( // caughtException
-                loc,                                                    // location
-                true,                                                   // finaL
-                new Java.SimpleType(loc, classNotFoundExceptionIClass), // type
-                "ex"                                                    // name
-            ),
-            b                                            // body
-        ));
-        Java.TryStatement ts = new Java.TryStatement(
-            loc,                               // location
-            new Java.ReturnStatement(loc, mi), // body
-            l,                                 // catchClauses
-            null                               // optionalFinally
-        );
-
-        body.addStatement(ts);
-
-        // Class class$(String className)
-        Java.FunctionDeclarator.FormalParameter fp = new Java.FunctionDeclarator.FormalParameter(
-            loc,                                                // location
-            false,                                              // finaL
-            new Java.SimpleType(loc, this.iClassLoader.STRING), // type
-            "className"                                         // name
-        );
-        Java.MethodDeclarator cdmd = new Java.MethodDeclarator(
-            loc,                                                  // location
-            null,                                                 // optionalDocComment
-            Mod.STATIC,                                           // modifiers
-            new Java.SimpleType(loc, this.iClassLoader.CLASS),    // type
-            "class$",                                             // name
-            new Java.FunctionDeclarator.FormalParameter[] { fp }, // formalParameters
-            new Java.Type[0],                                     // thrownExceptions
-            body                                                  // optionalBody
-        );
-
-        declaringType.addDeclaredMethod(cdmd);
-        declaringType.invalidateMethodCaches();
-    }
-
-    private IClass pushConstant(Locatable l, Object value) {
-        if (
-            value instanceof Integer   ||
-            value instanceof Short     ||
-            value instanceof Character ||
-            value instanceof Byte
-        ) {
-            int i = (
-                value instanceof Character ?
-                ((Character) value).charValue() :
-                ((Number) value).intValue()
-            );
-            if (i >= -1 && i <= 5) {
-                this.writeOpcode(l, Opcode.ICONST_0 + i);
-            } else
-            if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
-                this.writeOpcode(l, Opcode.BIPUSH);
-                this.writeByte((byte) i);
-            } else {
-                this.writeLDC(l, this.addConstantIntegerInfo(i));
-            }
-            return IClass.INT;
-        }
-        if (value instanceof Long) {
-            long lv = ((Long) value).longValue();
-            if (lv >= 0L && lv <= 1L) {
-                this.writeOpcode(l, Opcode.LCONST_0 + (int) lv);
-            } else {
-                this.writeOpcode(l, Opcode.LDC2_W);
-                this.writeConstantLongInfo(lv);
-            }
-            return IClass.LONG;
-        }
-        if (value instanceof Float) {
-            float fv = ((Float) value).floatValue();
-            if (
-                Float.floatToIntBits(fv) == Float.floatToIntBits(0.0F) // POSITIVE zero!
-                || fv == 1.0F
-                || fv == 2.0F
-            ) {
-                this.writeOpcode(l, Opcode.FCONST_0 + (int) fv);
-            } else
-            {
-                this.writeLDC(l, this.addConstantFloatInfo(fv));
-            }
-            return IClass.FLOAT;
-        }
-        if (value instanceof Double) {
-            double dv = ((Double) value).doubleValue();
-            if (
-                Double.doubleToLongBits(dv) == Double.doubleToLongBits(0.0D) // POSITIVE zero!
-                || dv == 1.0D
-            ) {
-                this.writeOpcode(l, Opcode.DCONST_0 + (int) dv);
-            } else
-            {
-                this.writeOpcode(l, Opcode.LDC2_W);
-                this.writeConstantDoubleInfo(dv);
-            }
-            return IClass.DOUBLE;
-        }
-        if (value instanceof String) {
-            String s = (String) value;
-            String ss[] = UnitCompiler.makeUTF8Able(s);
-            this.writeLDC(l, this.addConstantStringInfo(ss[0]));
-            for (int i = 1; i < ss.length; ++i) {
-                this.writeLDC(l, this.addConstantStringInfo(ss[i]));
-                this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
-                this.writeConstantMethodrefInfo(
-                    Descriptor.STRING,
-                    "concat",                                // classFD
-                    "(" + Descriptor.STRING + ")" + Descriptor.STRING // methodMD
-                );
-            }
-            return this.iClassLoader.STRING;
-        }
-        if (value instanceof Boolean) {
-            this.writeOpcode(l, ((Boolean) value).booleanValue() ? Opcode.ICONST_1 : Opcode.ICONST_0);
-            return IClass.BOOLEAN;
-        }
-        if (value == Java.Rvalue.CONSTANT_VALUE_NULL) {
-            this.writeOpcode(l, Opcode.ACONST_NULL);
-            return IClass.VOID;
-        }
-        throw new RuntimeException("Unknown literal type \"" + value.getClass().getName() + "\"");
-    }
-
-    /**
-     * Only strings that can be UTF8-encoded into 65535 bytes can be stored as constant string
-     * infos.
-     *
-     * @param s The string to split into suitable chunks
-     * @return the chunks that can be UTF8-encoded into 65535 bytes
-     */
-    private static String[] makeUTF8Able(String s) {
-        if (s.length() < (65536 / 3)) return new String[] { s };
-
-        int sLength = s.length(), uTFLength = 0;
-        int from = 0;
-        List l = new ArrayList();
-        for (int i = 0;; i++) {
-            if (i == sLength) {
-                l.add(s.substring(from));
-                break;
-            }
-            if (uTFLength >= 65532) {
-                l.add(s.substring(from, i));
-                if (i + (65536 / 3) > sLength) {
-                    l.add(s.substring(i));
-                    break;
-                }
-                from = i;
-                uTFLength = 0;
-            }
-            int c = s.charAt(i);
-            if (c >= 0x0001 && c <= 0x007F) {
-                ++uTFLength;
-            } else
-            if (c > 0x07FF) {
-                uTFLength += 3;
-            } else
-            {
-                uTFLength += 2;
-            }
-        }
-        return (String[]) l.toArray(new String[l.size()]);
-
-    }
-    private void writeLDC(Locatable l, short index) {
-        if (0 <= index && index <= 255) {
-            this.writeOpcode(l, Opcode.LDC);
-            this.writeByte((byte) index);
-        } else {
-            this.writeOpcode(l, Opcode.LDC_W);
-            this.writeShort(index);
-        }
-    }
-
-    /**
-     * Implements "assignment conversion" (JLS2 5.2).
-     */
-    private void assignmentConversion(
-        Locatable l,
-        IClass    sourceType,
-        IClass    targetType,
-        Object    optionalConstantValue
-    ) throws CompileException {
-        if (UnitCompiler.DEBUG) System.out.println("assignmentConversion(" + sourceType + ", " + targetType + ", " + optionalConstantValue + ")");
-
-        // JLS2 5.1.1 Identity conversion.
-        if (this.tryIdentityConversion(sourceType, targetType)) return;
-
-        // JLS2 5.1.2 Widening primitive conversion.
-        if (this.tryWideningPrimitiveConversion(l, sourceType, targetType)) return;
-
-        // JLS2 5.1.4 Widening reference conversion.
-        if (this.isWideningReferenceConvertible(sourceType, targetType)) return;
-
-        // A boxing conversion (JLS3 5.1.7) optionally followed by a widening reference conversion.
-        {
-            IClass boxedType = this.isBoxingConvertible(sourceType);
-            if (boxedType != null) {
-                if (this.tryIdentityConversion(boxedType, targetType)) {
-                    this.boxingConversion(l, sourceType, boxedType);
-                    return;
-                } else
-                if (this.isWideningReferenceConvertible(boxedType, targetType)) {
-                    this.boxingConversion(l, sourceType, boxedType);
-                    return;
-                }
-            }
-        }
-
-        // An unboxing conversion (JLS3 5.1.8) optionally followed by a widening primitive conversion.
-        {
-            IClass unboxedType = this.isUnboxingConvertible(sourceType);
-            if (unboxedType != null) {
-                if (this.tryIdentityConversion(unboxedType, targetType)) {
-                    this.unboxingConversion(l, sourceType, unboxedType);
-                    return;
-                } else
-                if (this.isWideningPrimitiveConvertible(unboxedType, targetType)) {
-                    this.unboxingConversion(l, sourceType, unboxedType);
-                    this.tryWideningPrimitiveConversion(l, unboxedType, targetType);
-                    return;
-                }
-            }
-        }
-
-        // 5.2 Special narrowing primitive conversion.
-        if (optionalConstantValue != null) {
-            if (this.tryConstantAssignmentConversion(
-                l,
-                optionalConstantValue, // constantValue
-                targetType             // targetType
-            )) return;
-        }
-
-        this.compileError("Assignment conversion not possible from type \"" + sourceType + "\" to type \"" + targetType + "\"", l.getLocation());
-    }
-
-    /**
-     * Implements "assignment conversion" (JLS2 5.2) on a constant value.
-     */
-    private Object assignmentConversion(
-        Locatable l,
-        Object    value,
-        IClass    targetType
-    ) throws CompileException {
-        Object result = null;
-
-        if (targetType == IClass.BOOLEAN) {
-            if (value instanceof Boolean) result = value;
-        } else
-        if (targetType == this.iClassLoader.STRING) {
-            if (value instanceof String) result = value;
-        } else
-        if (targetType == IClass.BYTE) {
-            if (value instanceof Byte) {
-                result = value;
-            } else
-            if (value instanceof Short || value instanceof Integer) {
-                int x = ((Number) value).intValue();
-                if (x >= Byte.MIN_VALUE && x <= Byte.MAX_VALUE) result = new Byte((byte) x);
-            } else
-            if (value instanceof Character) {
-                int x = ((Character) value).charValue();
-                if (x >= Byte.MIN_VALUE && x <= Byte.MAX_VALUE) result = new Byte((byte) x);
-            }
-        } else
-        if (targetType == IClass.SHORT) {
-            if (value instanceof Byte) {
-                result = new Short(((Number) value).shortValue());
-            } else
-            if (value instanceof Short) {
-                result = value;
-            } else
-            if (value instanceof Character) {
-                int x = ((Character) value).charValue();
-                if (x >= Short.MIN_VALUE && x <= Short.MAX_VALUE) result = new Short((short) x);
-            } else
-            if (value instanceof Integer) {
-                int x = ((Integer) value).intValue();
-                if (x >= Short.MIN_VALUE && x <= Short.MAX_VALUE) result = new Short((short) x);
-            }
-        } else
-        if (targetType == IClass.CHAR) {
-            if (value instanceof Short) {
-                result = value;
-            } else
-            if (value instanceof Byte || value instanceof Short || value instanceof Integer) {
-                int x = ((Number) value).intValue();
-                if (x >= Character.MIN_VALUE && x <= Character.MAX_VALUE) result = new Character((char) x);
-            }
-        } else
-        if (targetType == IClass.INT) {
-            if (value instanceof Integer) {
-                result = value;
-            } else
-            if (value instanceof Byte || value instanceof Short) {
-                result = new Integer(((Number) value).intValue());
-            } else
-            if (value instanceof Character) {
-                result = new Integer(((Character) value).charValue());
-            }
-        } else
-        if (targetType == IClass.LONG) {
-            if (value instanceof Long) {
-                result = value;
-            } else
-            if (value instanceof Byte || value instanceof Short || value instanceof Integer) {
-                result = new Long(((Number) value).longValue());
-            } else
-            if (value instanceof Character) {
-                result = new Long(((Character) value).charValue());
-            }
-        } else
-        if (targetType == IClass.FLOAT) {
-            if (value instanceof Float) {
-                result = value;
-            } else
-            if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) {
-                result = new Float(((Number) value).floatValue());
-            } else
-            if (value instanceof Character) {
-                result = new Float(((Character) value).charValue());
-            }
-        } else
-        if (targetType == IClass.DOUBLE) {
-            if (value instanceof Double) {
-                result = value;
-            } else
-            if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long || value instanceof Float) {
-                result = new Double(((Number) value).doubleValue());
-            } else
-            if (value instanceof Character) {
-                result = new Double(((Character) value).charValue());
-            }
-        } else
-        if (value == Java.Rvalue.CONSTANT_VALUE_NULL && !targetType.isPrimitive()) {
-            result = value;
-        }
-        if (result == null) this.compileError("Cannot convert constant of type \"" + value.getClass().getName() + "\" to type \"" + targetType.toString() + "\"", l.getLocation());
-        return result;
-    }
-
-    /**
-     * Implements "unary numeric promotion" (JLS3 5.6.1)
-     *
-     * @return The promoted type.
-     */
-    private IClass unaryNumericPromotion(Locatable l, IClass type) throws CompileException {
-        type = this.convertToPrimitiveNumericType(l, type);
-
-        IClass promotedType = this.unaryNumericPromotionType(l, type);
-
-        this.numericPromotion(l, type, promotedType);
-        return promotedType;
-    }
-
-    private void reverseUnaryNumericPromotion(Locatable l, IClass sourceType, IClass targetType) throws CompileException {
-        IClass unboxedType = this.isUnboxingConvertible(targetType);
-        IClass pt = unboxedType != null ? unboxedType : targetType;
-        if (
-            !this.tryIdentityConversion(sourceType, pt) &&
-            !this.tryNarrowingPrimitiveConversion(
-                l,          // locatable
-                sourceType, // sourceType
-                pt          // targetType
-            )
-        ) throw new RuntimeException("SNO: reverse unary numeric promotion failed");
-        if (unboxedType != null) this.boxingConversion(l, unboxedType, targetType);
-    }
-
-    /**
-     * If the given type is a primitive type, return that type.
-     * If the given type is a primitive wrapper class, unbox the operand on top of the operand
-     * stack and return the primitive type.
-     * Otherwise, issue a compile error.
-     */
-    private IClass convertToPrimitiveNumericType(Locatable l, IClass type) throws CompileException {
-        if (type.isPrimitiveNumeric()) return type;
-        IClass unboxedType = this.isUnboxingConvertible(type);
-        if (unboxedType != null) {
-            this.unboxingConversion(l, type, unboxedType);
-            return unboxedType;
-        }
-        this.compileError("Object of type \"" + type.toString() + "\" cannot be converted to a numeric type", l.getLocation());
-        return type;
-    }
-
-    private void numericPromotion(Locatable l, IClass sourceType, IClass targetType) {
-        if (
-            !this.tryIdentityConversion(sourceType, targetType) &&
-            !this.tryWideningPrimitiveConversion(
-                l,          // locatable
-                sourceType, // sourceType
-                targetType  // targetType
-            )
-        ) throw new RuntimeException("SNO: Conversion failed");
-    }
-
-    private IClass unaryNumericPromotionType(Locatable l, IClass type) throws CompileException {
-        if (!type.isPrimitiveNumeric()) this.compileError("Unary numeric promotion not possible on non-numeric-primitive type \"" + type + "\"", l.getLocation());
-
-        return (
-            type == IClass.DOUBLE ? IClass.DOUBLE :
-            type == IClass.FLOAT  ? IClass.FLOAT  :
-            type == IClass.LONG   ? IClass.LONG   :
-            IClass.INT
-        );
-    }
-
-    /**
-     * Implements "binary numeric promotion" (5.6.2)
-     *
-     * @return The promoted type.
-     */
-    private IClass binaryNumericPromotion(
-        Locatable            locatable,
-        IClass               type1,
-        CodeContext.Inserter convertInserter1,
-        IClass               type2
-    ) throws CompileException {
-        return this.binaryNumericPromotion(locatable, type1, convertInserter1, type2, this.codeContext.currentInserter());
-    }
-    /**
-     * Implements "binary numeric promotion" (5.6.2)
-     *
-     * @return The promoted type.
-     */
-    private IClass binaryNumericPromotion(
-        Locatable            l,
-        IClass               type1,
-        CodeContext.Inserter convertInserter1,
-        IClass               type2,
-        CodeContext.Inserter convertInserter2
-    ) throws CompileException {
-        IClass promotedType;
-        {
-            IClass c1 = this.isUnboxingConvertible(type1);
-            IClass c2 = this.isUnboxingConvertible(type2);
-            promotedType = this.binaryNumericPromotionType(
-                l,
-                c1 != null ? c1 : type1,
-                c2 != null ? c2 : type2
-            );
-        }
-
-        if (convertInserter1 != null) {
-            this.codeContext.pushInserter(convertInserter1);
-            try {
-                this.numericPromotion(l, this.convertToPrimitiveNumericType(l, type1), promotedType);
-            } finally {
-                this.codeContext.popInserter();
-            }
-        }
-
-        if (convertInserter2 != null) {
-            this.codeContext.pushInserter(convertInserter2);
-            try {
-                this.numericPromotion(l, this.convertToPrimitiveNumericType(l, type2), promotedType);
-            } finally {
-                this.codeContext.popInserter();
-            }
-        }
-
-        return promotedType;
-    }
-
-    private IClass binaryNumericPromotionType(
-        Java.Locatable locatable,
-        IClass    type1,
-        IClass    type2
-    ) throws CompileException {
-        if (
-            !type1.isPrimitiveNumeric() ||
-            !type2.isPrimitiveNumeric()
-        ) this.compileError("Binary numeric promotion not possible on types \"" + type1 + "\" and \"" + type2 + "\"", locatable.getLocation());
-
-        return (
-            type1 == IClass.DOUBLE || type2 == IClass.DOUBLE ? IClass.DOUBLE :
-            type1 == IClass.FLOAT  || type2 == IClass.FLOAT  ? IClass.FLOAT  :
-            type1 == IClass.LONG   || type2 == IClass.LONG   ? IClass.LONG   :
-            IClass.INT
-        );
-    }
-
-    /**
-     * Checks whether "identity conversion" (5.1.1) is possible.
-     *
-     * @return Whether the conversion is possible
-     */
-    private boolean isIdentityConvertible(
-        IClass sourceType,
-        IClass targetType
-    ) {
-        return sourceType == targetType;
-    }
-
-    /**
-     * Implements "identity conversion" (5.1.1).
-     *
-     * @return Whether the conversion was possible
-     */
-    private boolean tryIdentityConversion(
-        IClass sourceType,
-        IClass targetType
-    ) {
-        return sourceType == targetType;
-    }
-    
-    private boolean isWideningPrimitiveConvertible(
-        IClass sourceType,
-        IClass targetType
-    ) {
-        return UnitCompiler.PRIMITIVE_WIDENING_CONVERSIONS.get(
-            sourceType.getDescriptor() + targetType.getDescriptor()
-        ) != null;
-    }
-
-    /**
-     * Implements "widening primitive conversion" (5.1.2).
-     *
-     * @return Whether the conversion succeeded
-     */
-    private boolean tryWideningPrimitiveConversion(
-        Locatable l,
-        IClass    sourceType,
-        IClass    targetType
-    ) {
-        byte[] opcodes = (byte[]) UnitCompiler.PRIMITIVE_WIDENING_CONVERSIONS.get(sourceType.getDescriptor() + targetType.getDescriptor());
-        if (opcodes != null) {
-            this.writeOpcodes(l, opcodes);
-            return true;
-        }
-        return false;
-    }
-    private static final HashMap PRIMITIVE_WIDENING_CONVERSIONS = new HashMap();
-    static { UnitCompiler.fillConversionMap(new Object[] {
-        new byte[0],
-        Descriptor.BYTE_  + Descriptor.SHORT_,
-
-        Descriptor.BYTE_  + Descriptor.INT_,
-        Descriptor.SHORT_ + Descriptor.INT_,
-        Descriptor.CHAR_  + Descriptor.INT_,
-
-        new byte[] { Opcode.I2L },
-        Descriptor.BYTE_  + Descriptor.LONG_,
-        Descriptor.SHORT_ + Descriptor.LONG_,
-        Descriptor.CHAR_  + Descriptor.LONG_,
-        Descriptor.INT_   + Descriptor.LONG_,
-
-        new byte[] { Opcode.I2F },
-        Descriptor.BYTE_  + Descriptor.FLOAT_,
-        Descriptor.SHORT_ + Descriptor.FLOAT_,
-        Descriptor.CHAR_  + Descriptor.FLOAT_,
-        Descriptor.INT_   + Descriptor.FLOAT_,
-
-        new byte[] { Opcode.L2F },
-        Descriptor.LONG_  + Descriptor.FLOAT_,
-
-        new byte[] { Opcode.I2D },
-        Descriptor.BYTE_  + Descriptor.DOUBLE_,
-        Descriptor.SHORT_ + Descriptor.DOUBLE_,
-        Descriptor.CHAR_  + Descriptor.DOUBLE_,
-        Descriptor.INT_   + Descriptor.DOUBLE_,
-
-        new byte[] { Opcode.L2D },
-        Descriptor.LONG_  + Descriptor.DOUBLE_,
-
-        new byte[] { Opcode.F2D },
-        Descriptor.FLOAT_ + Descriptor.DOUBLE_,
-    }, UnitCompiler.PRIMITIVE_WIDENING_CONVERSIONS); }
-    private static void fillConversionMap(Object[] array, HashMap map) {
-        byte[] opcodes = null;
-        for (int i = 0; i < array.length; ++i) {
-            Object o = array[i];
-            if (o instanceof byte[]) {
-                opcodes = (byte[]) o;
-            } else {
-                map.put(o, opcodes);
-            }
-        }
-    }
-
-    /**
-     * Checks if "widening reference conversion" (5.1.4) is possible.
-     *
-     * @return Whether the conversion is possible
-     */
-    private boolean isWideningReferenceConvertible(
-        IClass sourceType,
-        IClass targetType
-    ) throws CompileException {
-        if (
-            targetType.isPrimitive() ||
-            sourceType == targetType
-        ) return false;
-
-        return targetType.isAssignableFrom(sourceType);
-    }
-
-    /**
-     * Performs "widening reference conversion" (5.1.4) if possible.
-     *
-     * @return Whether the conversion was possible
-     */
-    private boolean tryWideningReferenceConversion(
-        IClass sourceType,
-        IClass targetType
-    ) throws CompileException {
-        if (
-            targetType.isPrimitive() ||
-            sourceType == targetType
-        ) return false;
-        
-        return targetType.isAssignableFrom(sourceType);
-    }
-    
-    /**
-     * Check whether "narrowing primitive conversion" (JLS 5.1.3) is possible.
-     */
-    private boolean isNarrowingPrimitiveConvertible(
-        IClass sourceType,
-        IClass targetType
-    ) {
-        return UnitCompiler.PRIMITIVE_NARROWING_CONVERSIONS.containsKey(sourceType.getDescriptor() + targetType.getDescriptor());
-    }
-
-    /**
-     * Implements "narrowing primitive conversion" (JLS 5.1.3).
-     *
-     * @return Whether the conversion succeeded
-     */
-    private boolean tryNarrowingPrimitiveConversion(
-        Locatable l,
-        IClass    sourceType,
-        IClass    targetType
-    ) {
-        byte[] opcodes = (byte[]) UnitCompiler.PRIMITIVE_NARROWING_CONVERSIONS.get(sourceType.getDescriptor() + targetType.getDescriptor());
-        if (opcodes != null) {
-            this.writeOpcodes(l, opcodes);
-            return true;
-        }
-        return false;
-    }
-
-    private static final HashMap PRIMITIVE_NARROWING_CONVERSIONS = new HashMap();
-    static { UnitCompiler.fillConversionMap(new Object[] {
-        new byte[0],
-        Descriptor.BYTE_ + Descriptor.CHAR_,
-        Descriptor.SHORT_ + Descriptor.CHAR_,
-        Descriptor.CHAR_ + Descriptor.SHORT_,
-
-        new byte[] { Opcode.I2B },
-        Descriptor.SHORT_ + Descriptor.BYTE_,
-        Descriptor.CHAR_ + Descriptor.BYTE_,
-        Descriptor.INT_ + Descriptor.BYTE_,
-
-        new byte[] { Opcode.I2S },
-        Descriptor.INT_ + Descriptor.SHORT_,
-        Descriptor.INT_ + Descriptor.CHAR_,
-
-        new byte[] { Opcode.L2I, Opcode.I2B },
-        Descriptor.LONG_ + Descriptor.BYTE_,
-
-        new byte[] { Opcode.L2I, Opcode.I2S },
-        Descriptor.LONG_ + Descriptor.SHORT_,
-        Descriptor.LONG_ + Descriptor.CHAR_,
-
-        new byte[] { Opcode.L2I },
-        Descriptor.LONG_ + Descriptor.INT_,
-
-        new byte[] { Opcode.F2I, Opcode.I2B },
-        Descriptor.FLOAT_ + Descriptor.BYTE_,
-
-        new byte[] { Opcode.F2I, Opcode.I2S },
-        Descriptor.FLOAT_ + Descriptor.SHORT_,
-        Descriptor.FLOAT_ + Descriptor.CHAR_,
-
-        new byte[] { Opcode.F2I },
-        Descriptor.FLOAT_ + Descriptor.INT_,
-
-        new byte[] { Opcode.F2L },
-        Descriptor.FLOAT_ + Descriptor.LONG_,
-
-        new byte[] { Opcode.D2I, Opcode.I2B },
-        Descriptor.DOUBLE_ + Descriptor.BYTE_,
-
-        new byte[] { Opcode.D2I, Opcode.I2S },
-        Descriptor.DOUBLE_ + Descriptor.SHORT_,
-        Descriptor.DOUBLE_ + Descriptor.CHAR_,
-
-        new byte[] { Opcode.D2I },
-        Descriptor.DOUBLE_ + Descriptor.INT_,
-
-        new byte[] { Opcode.D2L },
-        Descriptor.DOUBLE_ + Descriptor.LONG_,
-
-        new byte[] { Opcode.D2F },
-        Descriptor.DOUBLE_ + Descriptor.FLOAT_,
-    }, UnitCompiler.PRIMITIVE_NARROWING_CONVERSIONS); }
-
-    /**
-     * Check if "constant assignment conversion" (JLS 5.2, paragraph 1) is possible.
-     * @param constantValue The constant value that is to be converted
-     * @param targetType The type to convert to
-     */
-    private boolean tryConstantAssignmentConversion(
-        Locatable l,
-        Object    constantValue,
-        IClass    targetType
-    ) throws CompileException {
-        if (UnitCompiler.DEBUG) System.out.println("isConstantPrimitiveAssignmentConvertible(" + constantValue + ", " + targetType + ")");
-
-        int cv;
-        if (constantValue instanceof Byte) {
-            cv = ((Byte) constantValue).byteValue();
-        } else
-        if (constantValue instanceof Short) {
-            cv = ((Short) constantValue).shortValue();
-        } else
-        if (constantValue instanceof Integer) {
-            cv = ((Integer) constantValue).intValue();
-        } else
-        if (constantValue instanceof Character) {
-            cv = ((Character) constantValue).charValue();
-        } else
-        {
-            return false;
-        }
-
-        if (targetType == IClass.BYTE ) return cv >= Byte.MIN_VALUE && cv <= Byte.MAX_VALUE;
-        if (targetType == IClass.SHORT) return cv >= Short.MIN_VALUE && cv <= Short.MAX_VALUE;
-        if (targetType == IClass.CHAR ) return cv >= Character.MIN_VALUE && cv <= Character.MAX_VALUE;
-
-        IClassLoader icl = this.iClassLoader;
-        if (targetType == icl.BYTE && cv >= Byte.MIN_VALUE && cv <= Byte.MAX_VALUE) {
-            this.boxingConversion(l, IClass.BYTE, targetType);
-            return true;
-        }
-        if (targetType == icl.SHORT && cv >= Short.MIN_VALUE && cv <= Short.MAX_VALUE) {
-            this.boxingConversion(l, IClass.SHORT, targetType);
-            return true;
-        }
-        if (targetType == icl.CHARACTER && cv >= Character.MIN_VALUE && cv <= Character.MAX_VALUE) {
-            this.boxingConversion(l, IClass.CHAR, targetType);
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Check whether "narrowing reference conversion" (JLS 5.1.5) is possible.
-     */
-    private boolean isNarrowingReferenceConvertible(
-        IClass sourceType,
-        IClass targetType
-    ) throws CompileException {
-        if (sourceType.isPrimitive()) return false;
-        if (sourceType == targetType) return false;
-
-        // 5.1.5.1
-        if (sourceType.isAssignableFrom(targetType)) return true;
-
-        // 5.1.5.2
-        if (
-            targetType.isInterface() &&
-            !sourceType.isFinal() &&
-            !targetType.isAssignableFrom(sourceType)
-        ) return true;
-
-        // 5.1.5.3
-        if (
-            sourceType == this.iClassLoader.OBJECT &&
-            targetType.isArray()
-        ) return true;
-
-        // 5.1.5.4
-        if (
-            sourceType == this.iClassLoader.OBJECT &&
-            targetType.isInterface()
-        ) return true;
-
-        // 5.1.5.5
-        if (
-            sourceType.isInterface() &&
-            !targetType.isFinal()
-        ) return true;
-
-        // 5.1.5.6
-        if (
-            sourceType.isInterface() &&
-            targetType.isFinal() &&
-            sourceType.isAssignableFrom(targetType)
-        ) return true;
-
-        // 5.1.5.7
-        // TODO: Check for redefinition of methods with same signature but different return type.
-        if (
-            sourceType.isInterface() &&
-            targetType.isInterface() &&
-            !targetType.isAssignableFrom(sourceType)
-        ) return true;
-
-        // 5.1.5.8
-        if (sourceType.isArray() && targetType.isArray()) {
-            IClass st = sourceType.getComponentType();
-            IClass tt = targetType.getComponentType();
-            if (
-                this.isNarrowingPrimitiveConvertible(st, tt) ||
-                this.isNarrowingReferenceConvertible(st, tt)
-            ) return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Implements "narrowing reference conversion" (5.1.5).
-     *
-     * @return Whether the conversion succeeded
-     */
-    private boolean tryNarrowingReferenceConversion(
-        Locatable l,
-        IClass    sourceType,
-        IClass    targetType
-    ) throws CompileException {
-        if (!this.isNarrowingReferenceConvertible(sourceType, targetType)) return false;
-
-        this.writeOpcode(l, Opcode.CHECKCAST);
-        this.writeConstantClassInfo(targetType.getDescriptor());
-        return true;
-    }
-
-    /*
-     * @return the boxed type or <code>null</code>
-     */
-    private IClass isBoxingConvertible(IClass sourceType) {
-        IClassLoader icl = this.iClassLoader;
-        if (sourceType == IClass.BOOLEAN) return icl.BOOLEAN;
-        if (sourceType == IClass.BYTE   ) return icl.BYTE;
-        if (sourceType == IClass.CHAR   ) return icl.CHARACTER;
-        if (sourceType == IClass.SHORT  ) return icl.SHORT;
-        if (sourceType == IClass.INT    ) return icl.INTEGER;
-        if (sourceType == IClass.LONG   ) return icl.LONG;
-        if (sourceType == IClass.FLOAT  ) return icl.FLOAT;
-        if (sourceType == IClass.DOUBLE ) return icl.DOUBLE;
-        return null;
-    }
-
-    private boolean tryBoxingConversion(
-        Locatable l,
-        IClass    sourceType,
-        IClass    targetType
-    ) throws CompileException {
-        if (this.isBoxingConvertible(sourceType) == targetType) {
-            this.boxingConversion(l, sourceType, targetType);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @param sourceType a primitive type (except VOID)
-     * @param targetType the corresponding wrapper type
-     */
-    private void boxingConversion(Locatable l, IClass sourceType, IClass targetType) throws CompileException {
-
-        // In some pre-1.5 JDKs, only some wrapper classes have the static "Target.valueOf(source)" method.
-        if (targetType.hasIMethod("valueOf", new IClass[] { sourceType })) {
-            this.writeOpcode(l, Opcode.INVOKESTATIC);
-            this.writeConstantMethodrefInfo(
-                targetType.getDescriptor(),
-                "valueOf",                                         // classFD
-                '(' + sourceType.getDescriptor() + ')' + targetType.getDescriptor() // methodFD
-            );
-            return;
-        }
-        // new Target(source)
-        this.writeOpcode(l, Opcode.NEW);
-        this.writeConstantClassInfo(targetType.getDescriptor());
-        if (Descriptor.hasSize2(sourceType.getDescriptor())) {
-            this.writeOpcode(l, Opcode.DUP_X2);
-            this.writeOpcode(l, Opcode.DUP_X2);
-            this.writeOpcode(l, Opcode.POP);
-        } else
-        {
-            this.writeOpcode(l, Opcode.DUP_X1);
-            this.writeOpcode(l, Opcode.SWAP);
-        }
-        this.writeOpcode(l, Opcode.INVOKESPECIAL);
-        this.writeConstantMethodrefInfo(
-            targetType.getDescriptor(),
-            "<init>",                               // classFD
-            '(' + sourceType.getDescriptor() + ')' + Descriptor.VOID_ // methodMD
-        );
-    }
-
-    /*
-     * @return the unboxed type or <code>null</code>
-     */
-    private IClass isUnboxingConvertible(IClass sourceType) {
-        IClassLoader icl = this.iClassLoader;
-        if (sourceType == icl.BOOLEAN  ) return IClass.BOOLEAN;
-        if (sourceType == icl.BYTE     ) return IClass.BYTE;
-        if (sourceType == icl.CHARACTER) return IClass.CHAR;
-        if (sourceType == icl.SHORT    ) return IClass.SHORT;
-        if (sourceType == icl.INTEGER  ) return IClass.INT;
-        if (sourceType == icl.LONG     ) return IClass.LONG;
-        if (sourceType == icl.FLOAT    ) return IClass.FLOAT;
-        if (sourceType == icl.DOUBLE   ) return IClass.DOUBLE;
-        return null;
-    }
-    
-    private boolean tryUnboxingConversion(
-        Locatable l,
-        IClass    sourceType,
-        IClass    targetType
-    ) {
-        if (this.isUnboxingConvertible(sourceType) == targetType) {
-            this.unboxingConversion(l, sourceType, targetType);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @param targetType a primitive type (except VOID)
-     * @param sourceType the corresponding wrapper type
-     */
-    private void unboxingConversion(Locatable l, IClass sourceType, IClass targetType) {
-
-        // "source.targetValue()"
-        this.writeOpcode(l, Opcode.INVOKEVIRTUAL);
-        this.writeConstantMethodrefInfo(
-            sourceType.getDescriptor(),
-            targetType.toString() + "Value",       // classFD
-            "()" + targetType.getDescriptor() // methodFD
-        );
-    }
-    
-    /**
-     * Attempt to load an {@link IClass} by fully-qualified name
-     * @param identifiers
-     * @return <code>null</code> if a class with the given name could not be loaded
-     */
-    private IClass loadFullyQualifiedClass(String[] identifiers) throws CompileException {
-
-        // Compose the descriptor (like "La/b/c;") and remember the positions of the slashes
-        // (2 and 4).
-        int[] slashes = new int[identifiers.length - 1];
-        StringBuffer sb = new StringBuffer("L");
-        for (int i = 0;; ++i) {
-            sb.append(identifiers[i]);
-            if (i == identifiers.length - 1) break;
-            slashes[i] = sb.length();
-            sb.append('/');
-        }
-        sb.append(';');
-
-        // Attempt to load the IClass and replace dots with dollar signs, i.e.:
-        // La/b/c; La/b$c; La$b$c;
-        for (int j = slashes.length - 1;; --j) {
-            IClass result;
-            try {
-                result = this.iClassLoader.loadIClass(sb.toString());
-            } catch (ClassNotFoundException ex) {
-                if (ex.getException() instanceof CompileException) throw (CompileException) ex.getException();
-                throw new CompileException(sb.toString(), null, ex);
-            }
-            if (result != null) return result;
-            if (j < 0) break;
-            sb.setCharAt(slashes[j], '$');
-        }
-        return null;
-    }
-
-    // Load the value of a local variable onto the stack and return its type.
-    private IClass load(
-        Locatable          l,
-        Java.LocalVariable localVariable
-    ) {
-        this.load(
-            l,
-            localVariable.type,
-            localVariable.localVariableArrayIndex
-        );
-        return localVariable.type;
-    }
-    private void load(
-        Locatable l,
-        IClass    type,
-        int       index
-    ) {
-        if (index <= 3) {
-            this.writeOpcode(l, Opcode.ILOAD_0 + 4 * this.ilfda(type) + index);
-        } else
-        if (index <= 255) {
-            this.writeOpcode(l, Opcode.ILOAD + this.ilfda(type));
-            this.writeByte(index);
-        } else
-        {
-            this.writeOpcode(l, Opcode.WIDE);
-            this.writeOpcode(l, Opcode.ILOAD + this.ilfda(type));
-            this.writeShort(index);
-        }
-    }
-
-    /**
-     * Assign stack top value to the given local variable. (Assignment conversion takes effect.)
-     * If <copde>optionalConstantValue</code> is not <code>null</code>, then the top stack value
-     * is a constant value with that type and value, and a narrowing primitive conversion as
-     * described in JLS 5.2 is applied.
-     */
-    private void store(
-        Locatable          l,
-        IClass             valueType,
-        Java.LocalVariable localVariable
-    ) {
-        this.store(
-            l,                                    // l
-            localVariable.type,                   // lvType
-            localVariable.localVariableArrayIndex // lvIndex
-        );
-    }
-    private void store(
-        Locatable l,
-        IClass    lvType,
-        short     lvIndex
-    ) {
-        if (lvIndex <= 3) {
-            this.writeOpcode(l, Opcode.ISTORE_0 + 4 * this.ilfda(lvType) + lvIndex);
-        } else
-        if (lvIndex <= 255) {
-            this.writeOpcode(l, Opcode.ISTORE + this.ilfda(lvType));
-            this.writeByte(lvIndex);
-        } else
-        {
-            this.writeOpcode(l, Opcode.WIDE);
-            this.writeOpcode(l, Opcode.ISTORE + this.ilfda(lvType));
-            this.writeShort(lvIndex);
-        }
-    }
-
-    private void dup(Locatable l, int n) {
-        switch (n) {
-
-        case 0:
-            ;
-            break;
-
-        case 1:
-            this.writeOpcode(l, Opcode.DUP);
-            break;
-
-        case 2:
-            this.writeOpcode(l, Opcode.DUP2);
-            break;
-
-        default:
-            throw new RuntimeException("dup(" + n + ")");
-        }
-    }
-    private void dupx(
-        Locatable l,
-        IClass    type,
-        int       x
-    ) {
-        if (x < 0 || x > 2) throw new RuntimeException("SNO: x has value " + x);
-        int dup  = Opcode.DUP  + x;
-        int dup2 = Opcode.DUP2 + x;
-        this.writeOpcode(l, (
-            type == IClass.LONG || type == IClass.DOUBLE ?
-            dup2 :
-            dup
-        ));
-    }
-
-    private void pop(Locatable l, IClass type) {
-        if (type == IClass.VOID) return;
-        this.writeOpcode(l, (
-            type == IClass.LONG || type == IClass.DOUBLE ?
-            Opcode.POP2 :
-            Opcode.POP
-        ));
-    }
-
-    static int ilfd(IClass t) {
-        if (
-            t == IClass.BYTE ||
-            t == IClass.CHAR ||
-            t == IClass.INT ||
-            t == IClass.SHORT ||
-            t == IClass.BOOLEAN
-        ) return 0;
-        if (t == IClass.LONG  ) return 1;
-        if (t == IClass.FLOAT ) return 2;
-        if (t == IClass.DOUBLE) return 3;
-        throw new RuntimeException("Unexpected type \"" + t + "\"");
-    }
-    static int ilfd(
-        IClass t,
-        int    opcodeInt,
-        int    opcodeLong,
-        int    opcodeFloat,
-        int    opcodeDouble
-    ) {
-        if (
-            t == IClass.BYTE ||
-            t == IClass.CHAR ||
-            t == IClass.INT ||
-            t == IClass.SHORT ||
-            t == IClass.BOOLEAN
-        ) return opcodeInt;
-        if (t == IClass.LONG  ) return opcodeLong;
-        if (t == IClass.FLOAT ) return opcodeFloat;
-        if (t == IClass.DOUBLE) return opcodeDouble;
-        throw new RuntimeException("Unexpected type \"" + t + "\"");
-    }
-    private int ilfda(IClass t) {
-        return !t.isPrimitive() ? 4 : UnitCompiler.ilfd(t);
-    }
-    static int ilfdabcs(IClass t) {
-        if (t == IClass.INT   ) return 0;
-        if (t == IClass.LONG  ) return 1;
-        if (t == IClass.FLOAT ) return 2;
-        if (t == IClass.DOUBLE) return 3;
-        if (!t.isPrimitive()  ) return 4;
-        if (t == IClass.BOOLEAN || t == IClass.BYTE) return 5;
-        if (t == IClass.CHAR  ) return 6;
-        if (t == IClass.SHORT ) return 7;
-        throw new RuntimeException("Unexpected type \"" + t + "\"");
-    }
-
-    /**
-     * Find a named field in the given {@link IClass}.
-     * Honor superclasses and interfaces. See JLS 8.3.
-     * @return <code>null</code> if no field is found
-     */
-    private IClass.IField findIField(
-        IClass   iClass,
-        String   name,
-        Location location
-    ) throws CompileException {
-
-        // Search for a field with the given name in the current class.
-        IClass.IField f = iClass.getDeclaredIField(name);
-        if(f != null) return f;
-
-        // Examine superclass.
-        {
-            IClass superclass = iClass.getSuperclass();
-            if (superclass != null) f = this.findIField(superclass, name, location);
-        }
-
-        // Examine interfaces.
-        IClass[] ifs = iClass.getInterfaces();
-        for (int i = 0; i < ifs.length; ++i) {
-            IClass.IField f2 = this.findIField(ifs[i], name, location);
-            if (f2 != null) {
-                if (f != null) throw new CompileException("Access to field \"" + name + "\" is ambiguous - both \"" + f.getDeclaringIClass() + "\" and \"" + f2.getDeclaringIClass() + "\" declare it", location);
-                f = f2;
-            }
-        }
-        return f;
-    }
-
-    /**
-     * Find a named type in the given {@link IClass}.
-     * Honor superclasses, interfaces and enclosing type declarations.
-     * @return <code>null</code> if no type with the given name is found
-     */
-    private IClass findMemberType(
-        IClass   iClass,
-        String   name,
-        Location location
-    ) throws CompileException {
-        IClass[] types = iClass.findMemberType(name);
-        if (types.length == 0) return null;
-        if (types.length == 1) return types[0];
-
-        StringBuffer sb = new StringBuffer("Type \"" + name + "\" is ambiguous: " + types[0].toString());
-        for (int i = 1; i < types.length; ++i) sb.append(" vs. ").append(types[i].toString());
-        this.compileError(sb.toString(), location);
-        return types[0];
-    }
-
-    /**
-     * Find one class or interface declared in this compilation unit by name.
-     *
-     * @param className Fully qualified class name, e.g. "pkg1.pkg2.Outer$Inner".
-     * @return <code>null</code> if a class with that name is not declared in this compilation unit
-     */
-    public IClass findClass(String className) {
-
-        // Examine package name.
-        String packageName = (
-            this.compilationUnit.optionalPackageDeclaration == null ? null :
-            this.compilationUnit.optionalPackageDeclaration.packageName
-        );
-        if (packageName != null) {
-            if (!className.startsWith(packageName + '.')) return null;
-            className = className.substring(packageName.length() + 1);
-        }
-
-        StringTokenizer st = new StringTokenizer(className, "$");
-        Java.TypeDeclaration td = this.compilationUnit.getPackageMemberTypeDeclaration(st.nextToken());
-        if (td == null) return null;
-        while (st.hasMoreTokens()) {
-            td = td.getMemberTypeDeclaration(st.nextToken());
-            if (td == null) return null;
-        }
-        return this.resolve((Java.AbstractTypeDeclaration) td);
-    }
-
-    /**
-     * Equivalent to {@link #compileError(String, Location)} with a
-     * <code>null</code> location argument.
-     */
-    private void compileError(String message) throws CompileException {
-        this.compileError(message, null);
-    }
-
-    /**
-     * Issue a compile error with the given message. This is done through the
-     * {@link ErrorHandler} that was installed through
-     * {@link #setCompileErrorHandler(ErrorHandler)}. Such a handler typically throws
-     * a {@link CompileException}, but it may as well decide to return normally. Consequently,
-     * the calling code must be prepared that {@link #compileError(String, Location)}
-     * returns normally, and must attempt to continue compiling.
-     *
-     * @param message The message to report
-     * @param optionalLocation The location to report
-     */
-    private void compileError(String message, Location optionalLocation) throws CompileException {
-        ++this.compileErrorCount;
-        if (this.optionalCompileErrorHandler != null) {
-            this.optionalCompileErrorHandler.handleError(message, optionalLocation);
-        } else {
-            throw new CompileException(message, optionalLocation);
-        }
-    }
-
-    /**
-     * Issues a warning with the given message an location an returns. This is done through
-     * a {@link WarningHandler} that was installed through
-     * {@link #setWarningHandler(WarningHandler)}.
-     * <p>
-     * The <code>handle</code> argument qulifies the warning and is typically used by
-     * the {@link WarningHandler} to suppress individual warnings.
-     *
-     * @param handle
-     * @param message
-     * @param optionalLocation
-     */
-    private void warning(String handle, String message, Location optionalLocation) {
-        if (this.optionalWarningHandler != null) this.optionalWarningHandler.handleWarning(handle, message, optionalLocation);
-    }
-
-    /**
-     * Interface type for {@link UnitCompiler#setCompileErrorHandler}.
-     */
-    public interface ErrorHandler {
-        void handleError(String message, Location optionalLocation) throws CompileException;
-    }
-
-    /**
-     * By default, {@link CompileException}s are thrown on compile errors, but an application
-     * my install its own (thread-local) {@link ErrorHandler}.
-     * <p>
-     * Be aware that a single problem during compilation often causes a bunch of compile errors,
-     * so a good {@link ErrorHandler} counts errors and throws a {@link CompileException} when
-     * a limit is reached.
-     * <p>
-     * If the given {@link ErrorHandler} does not throw {@link CompileException}s, then
-     * {@link #compileUnit(EnumeratorSet)} will throw one when the compilation of the unit
-     * is finished, and errors had occurred. In other words: The {@link ErrorHandler} may
-     * throw a {@link CompileException} or not, but {@link #compileUnit(EnumeratorSet)} will
-     * definitely throw a {@link CompileException} if one or more compile errors have
-     * occurred.
-     *
-     * @param optionalCompileErrorHandler <code>null</code> to restore the default behavior (throwing a {@link CompileException}
-     */
-    public void setCompileErrorHandler(ErrorHandler optionalCompileErrorHandler) {
-        this.optionalCompileErrorHandler = optionalCompileErrorHandler;
-    }
-
-    /**
-     * By default, warnings are discarded, but an application my install a custom
-     * {@link WarningHandler}.
-     *
-     * @param optionalWarningHandler <code>null</code> to indicate that no warnings be issued
-     */
-    public void setWarningHandler(WarningHandler optionalWarningHandler) {
-        this.optionalWarningHandler = optionalWarningHandler;
-    }
-
-    private CodeContext getCodeContext() {
-        CodeContext res = this.codeContext;
-        if (res == null) throw new RuntimeException("S.N.O.: Null CodeContext");
-        return res;
-    }
-
-    private CodeContext replaceCodeContext(CodeContext newCodeContext) {
-        CodeContext oldCodeContext = this.codeContext;
-        this.codeContext = newCodeContext;
-        return oldCodeContext;
-    }
-
-    private CodeContext createDummyCodeContext() {
-        return new CodeContext(this.getCodeContext().getClassFile());
-    }
-
-    private void writeByte(int v) {
-        this.codeContext.write((short) -1, (byte) v);
-    }
-    private void writeShort(int v) {
-        this.codeContext.write((short) -1, (byte) (v >> 8), (byte) v);
-    }
-    private void writeInt(int v) {
-        this.codeContext.write((short) -1, (byte) (v >> 24), (byte) (v >> 16), (byte) (v >> 8), (byte) v);
-    }
-
-    private void writeOpcode(Java.Locatable l, int opcode) {
-        this.codeContext.write(l.getLocation().getLineNumber(), (byte) opcode);
-    }
-    private void writeOpcodes(Java.Locatable l, byte[] opcodes) {
-        this.codeContext.write(l.getLocation().getLineNumber(), opcodes);
-    }
-    private void writeBranch(Java.Locatable l, int opcode, final CodeContext.Offset dst) {
-        this.codeContext.writeBranch(l.getLocation().getLineNumber(), opcode, dst);
-    }
-    private void writeOffset(CodeContext.Offset src, final CodeContext.Offset dst) {
-        this.codeContext.writeOffset((short) -1, src, dst);
-    }
-
-    // Wrappers for "ClassFile.addConstant...Info()". Saves us some coding overhead.
-
-    private void writeConstantClassInfo(String descriptor) {
-        CodeContext ca = this.codeContext;
-        ca.writeShort((short) -1, ca.getClassFile().addConstantClassInfo(descriptor));
-    }
-    private void writeConstantFieldrefInfo(String classFD, String fieldName, String fieldFD) {
-        CodeContext ca = this.codeContext;
-        ca.writeShort((short) -1, ca.getClassFile().addConstantFieldrefInfo(classFD, fieldName, fieldFD));
-    }
-    private void writeConstantMethodrefInfo(String classFD, String methodName, String methodMD) {
-        CodeContext ca = this.codeContext;
-        ca.writeShort((short) -1, ca.getClassFile().addConstantMethodrefInfo(classFD, methodName, methodMD));
-    }
-    private void writeConstantInterfaceMethodrefInfo(String classFD, String methodName, String methodMD) {
-        CodeContext ca = this.codeContext;
-        ca.writeShort((short) -1, ca.getClassFile().addConstantInterfaceMethodrefInfo(classFD, methodName, methodMD));
-    }
-/* UNUSED
-    private void writeConstantStringInfo(String value) {
-        this.codeContext.writeShort((short) -1, this.addConstantStringInfo(value));
-    }
-*/
-    private short addConstantStringInfo(String value) {
-        return this.codeContext.getClassFile().addConstantStringInfo(value);
-    }
-/* UNUSED
-    private void writeConstantIntegerInfo(int value) {
-        this.codeContext.writeShort((short) -1, this.addConstantIntegerInfo(value));
-    }
-*/
-    private short addConstantIntegerInfo(int value) {
-        return this.codeContext.getClassFile().addConstantIntegerInfo(value);
-    }
-/* UNUSED
-    private void writeConstantFloatInfo(float value) {
-        this.codeContext.writeShort((short) -1, this.addConstantFloatInfo(value));
-    }
-*/
-    private short addConstantFloatInfo(float value) {
-        return this.codeContext.getClassFile().addConstantFloatInfo(value);
-    }
-    private void writeConstantLongInfo(long value) {
-        CodeContext ca = this.codeContext;
-        ca.writeShort((short) -1, ca.getClassFile().addConstantLongInfo(value));
-    }
-    private void writeConstantDoubleInfo(double value) {
-        CodeContext ca = this.codeContext;
-        ca.writeShort((short) -1, ca.getClassFile().addConstantDoubleInfo(value));
-    }
-
-    public CodeContext.Offset getWhereToBreak(Java.BreakableStatement bs) {
-        if (bs.whereToBreak == null) {
-            bs.whereToBreak = this.codeContext.new Offset();
-        }
-        return bs.whereToBreak;
-    }
-
-    private Java.TypeBodyDeclaration getDeclaringTypeBodyDeclaration(Java.QualifiedThisReference qtr) throws CompileException {
-        if (qtr.declaringTypeBodyDeclaration == null) {
-
-            // Compile error if in static function context.
-            Java.Scope s;
-            for (s = qtr.getEnclosingBlockStatement(); !(s instanceof Java.TypeBodyDeclaration); s = s.getEnclosingScope());
-            qtr.declaringTypeBodyDeclaration = (Java.TypeBodyDeclaration) s;
-            if (qtr.declaringTypeBodyDeclaration.isStatic()) this.compileError("No current instance available in static method", qtr.getLocation());
-
-            // Determine declaring type.
-            qtr.declaringClass = (Java.ClassDeclaration) qtr.declaringTypeBodyDeclaration.getDeclaringType();
-        }
-        return qtr.declaringTypeBodyDeclaration;
-    }
-
-    private Java.ClassDeclaration getDeclaringClass(Java.QualifiedThisReference qtr) throws CompileException {
-        if (qtr.declaringClass == null) {
-            this.getDeclaringTypeBodyDeclaration(qtr);
-        }
-        return qtr.declaringClass;
-    }
-
-    private void referenceThis(Locatable l) {
-        this.writeOpcode(l, Opcode.ALOAD_0);
-    }
-
-    /**
-     * Expects "dimExprCount" values of type "integer" on the operand stack.
-     * Creates an array of "dimExprCount" + "dims" dimensions of
-     * "componentType".
-     *
-     * @return The type of the created array
-     */
-    private IClass newArray(
-        Locatable l,
-        int       dimExprCount,
-        int       dims,
-        IClass    componentType
-    ) {
-        if (dimExprCount == 1 && dims == 0 && componentType.isPrimitive()) {
-
-            // "new <primitive>[<n>]"
-            this.writeOpcode(l, Opcode.NEWARRAY);
-            this.writeByte((
-                componentType == IClass.BOOLEAN ? 4 :
-                componentType == IClass.CHAR    ? 5 :
-                componentType == IClass.FLOAT   ? 6 :
-                componentType == IClass.DOUBLE  ? 7 :
-                componentType == IClass.BYTE    ? 8 :
-                componentType == IClass.SHORT   ? 9 :
-                componentType == IClass.INT     ? 10 :
-                componentType == IClass.LONG    ? 11 : -1
-            ));
-            return componentType.getArrayIClass(this.iClassLoader.OBJECT);
-        }
-
-        if (dimExprCount == 1) {
-            IClass at = componentType.getArrayIClass(dims, this.iClassLoader.OBJECT);
-
-            // "new <class-or-interface>[<n>]"
-            // "new <anything>[<n>][]..."
-            this.writeOpcode(l, Opcode.ANEWARRAY);
-            this.writeConstantClassInfo(at.getDescriptor());
-            return at.getArrayIClass(this.iClassLoader.OBJECT);
-        } else {
-            IClass at = componentType.getArrayIClass(dimExprCount + dims, this.iClassLoader.OBJECT);
-
-            // "new <anything>[]..."
-            // "new <anything>[<n>][<m>]..."
-            // "new <anything>[<n>][<m>]...[]..."
-            this.writeOpcode(l, Opcode.MULTIANEWARRAY);
-            this.writeConstantClassInfo(at.getDescriptor());
-            this.writeByte(dimExprCount);
-            return at;
-        }
-    }
-
-    /**
-     * Short-hand implementation of {@link IClass.IField} that implements a
-     * non-constant, non-static, package-accessible field.
-     */
-    public static class SimpleIField extends IClass.IField {
-        private final String name;
-        private final IClass type;
-
-        public SimpleIField(
-            IClass declaringIClass,
-            String name,
-            IClass type
-        ) {
-            declaringIClass.super();
-            this.name = name;
-            this.type = type;
-        }
-        public Object  getConstantValue() { return null; }
-        public String  getName()          { return this.name; }
-        public IClass  getType()          { return this.type; }
-        public boolean isStatic()         { return false; }
-        public Access  getAccess()        { return Access.DEFAULT; }
-    };
-
-    private static Access modifiers2Access(short modifiers) {
-        return (
-            (modifiers & Mod.PUBLIC   ) != 0 ? Access.PUBLIC    :
-            (modifiers & Mod.PROTECTED) != 0 ? Access.PROTECTED :
-            (modifiers & Mod.PRIVATE  ) != 0 ? Access.PRIVATE   :
-            Access.DEFAULT
-        );
-    }
-
-    private static String last(String[] sa) {
-        if (sa.length == 0) throw new IllegalArgumentException("SNO: Empty string array");
-        return sa[sa.length - 1];
-    }
-
-    private static String[] allButLast(String[] sa) {
-        if (sa.length == 0) throw new IllegalArgumentException("SNO: Empty string array");
-        String[] tmp = new String[sa.length - 1];
-        System.arraycopy(sa, 0, tmp, 0, tmp.length);
-        return tmp;
-    }
-
-    private static String[] concat(String[] sa, String s) {
-        String[] tmp = new String[sa.length + 1];
-        System.arraycopy(sa, 0, tmp, 0, sa.length);
-        tmp[sa.length] = s;
-        return tmp;
-    }
-    
-    // Used to write byte code while compiling one constructor/method.
-    private CodeContext codeContext = null;
-
-    // Used for elaborate compile error handling.
-    private ErrorHandler optionalCompileErrorHandler = null;
-    private int          compileErrorCount = 0;
-
-    // Used for elaborate warning handling.
-    private WarningHandler optionalWarningHandler = null;
-
-    public final Java.CompilationUnit compilationUnit;
-
-    private final IClassLoader iClassLoader;
-    private final boolean      isStringBuilderAvailable;
-    private List               generatedClassFiles;
-    private EnumeratorSet      debuggingInformation;
-
-    private final Map        singleTypeImports     = new HashMap();   // String simpleTypeName => String[] fullyQualifiedTypeName
-    private final Collection typeImportsOnDemand;                     // String[] package
-    private final Map        singleStaticImports   = new HashMap();   // String staticMemberName => IField, List of IMethod, or IClass
-    private final Collection staticImportsOnDemand = new ArrayList(); // IClass
-}
diff --git a/src/org/codehaus/janino/UnparseVisitor.java b/src/org/codehaus/janino/UnparseVisitor.java
deleted file mode 100644
index 443c463..0000000
--- a/src/org/codehaus/janino/UnparseVisitor.java
+++ /dev/null
@@ -1,775 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.util.AutoIndentWriter;
-
-/**
- * A visitor that unparses (un-compiles) an AST to a {@link Writer}. See
- * {@link #main(String[])} for a usage example.
- */
-public class UnparseVisitor implements Visitor.ComprehensiveVisitor {
-    protected final AutoIndentWriter aiw;
-    protected final PrintWriter      pw;
-
-    /**
-     * Testing of parsing/unparsing.
-     * <p>
-     * Reads compilation units from the files named on the command line
-     * and unparses them to {@link System#out}.
-     */
-    public static void main(String[] args) throws Exception {
-        Writer w = new BufferedWriter(new OutputStreamWriter(System.out));
-        for (int i = 0; i < args.length; ++i) {
-            String fileName = args[i];
-
-            // Parse each compilation unit.
-            FileReader r = new FileReader(fileName);
-            Java.CompilationUnit cu;
-            try {
-                cu = new Parser(new Scanner(fileName, r)).parseCompilationUnit();
-            } finally {
-                r.close();
-            }
-
-            // Unparse each compilation unit.
-            UnparseVisitor.unparse(cu, w);
-        }
-        w.flush();
-    }
-
-    /**
-     * Unparse the given {@link Java.CompilationUnit} to the given {@link Writer}.
-     */
-    public static void unparse(Java.CompilationUnit cu, Writer w) {
-        new UnparseVisitor(w).unparseCompilationUnit(cu);
-    }
-
-    public UnparseVisitor(Writer w) {
-        this.aiw = new AutoIndentWriter(w);
-        this.pw = new PrintWriter(this.aiw, true);
-    }
-
-    public void unparseCompilationUnit(Java.CompilationUnit cu) {
-        if (cu.optionalPackageDeclaration != null) {
-            this.pw.println("package " + cu.optionalPackageDeclaration.packageName + ';');
-        }
-        for (Iterator it = cu.importDeclarations.iterator(); it.hasNext();) {
-            ((Java.CompilationUnit.ImportDeclaration) it.next()).accept(this);
-        }
-        for (Iterator it = cu.packageMemberTypeDeclarations.iterator(); it.hasNext();) {
-            this.unparseTypeDeclaration((Java.PackageMemberTypeDeclaration) it.next());
-            this.pw.println();
-        }
-    }
-
-    public void visitSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid) {
-        this.pw.println("import " + Java.join(stid.identifiers, ".") + ';');
-    }
-    public void visitTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) {
-        this.pw.println("import " + Java.join(tiodd.identifiers, ".") + ".*;");
-    }
-    public void visitSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration ssid) {
-        this.pw.println("import static " + Java.join(ssid.identifiers, ".") + ';');
-    }
-    public void visitStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd) {
-        this.pw.println("import static " + Java.join(siodd.identifiers, ".") + ".*;");
-    }
-
-    public void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd) {
-        this.unparseNamedClassDeclaration(lcd);
-    }
-    public void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd) {
-        this.unparseNamedClassDeclaration(mcd);
-    }
-    public void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid) {
-        this.unparseInterfaceDeclaration(mid);
-    }
-    public void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd) {
-        this.unparseNamedClassDeclaration(pmcd);
-    }
-    public void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) {
-        this.unparseInterfaceDeclaration(pmid);
-    }
-    public void visitConstructorDeclarator(Java.ConstructorDeclarator cd) {
-        this.unparseDocComment(cd);
-        this.unparseModifiers(cd.modifiers);
-        Java.ClassDeclaration declaringClass = cd.getDeclaringClass();
-        this.pw.print(declaringClass instanceof Java.NamedClassDeclaration ? ((Java.NamedClassDeclaration) declaringClass).name : "UNNAMED");
-        this.unparseFunctionDeclaratorRest(cd);
-        this.pw.print(' ');
-        if (cd.optionalConstructorInvocation != null) {
-            this.pw.println('{');
-            this.unparseBlockStatement(cd.optionalConstructorInvocation);
-            this.pw.println(';');
-            for (Iterator it = cd.optionalBody.statements.iterator(); it.hasNext();) {
-                this.unparseBlockStatement((Java.BlockStatement) it.next());
-                this.pw.println();
-            }
-            this.pw.print('}');
-        } else {
-            this.unparseBlockStatement(cd.optionalBody);
-        }
-    }
-    public void visitMethodDeclarator(Java.MethodDeclarator md) {
-        this.unparseDocComment(md);
-        this.unparseModifiers(md.modifiers);
-        this.unparseType(md.type);
-        this.pw.print(' ' + md.name);
-        this.unparseFunctionDeclaratorRest(md);
-        if (md.optionalBody != null) {
-            this.pw.print(' ');
-            this.unparseBlockStatement(md.optionalBody);
-        } else {
-            this.pw.print(';');
-        }
-    }
-    public void visitFieldDeclaration(Java.FieldDeclaration fd) {
-        this.unparseDocComment(fd);
-        this.unparseModifiers(fd.modifiers);
-        this.unparseType(fd.type);
-        this.pw.print(' ');
-        for (int i = 0; i < fd.variableDeclarators.length; ++i) {
-            if (i > 0) this.pw.print(", ");
-            this.unparseVariableDeclarator(fd.variableDeclarators[i]);
-        }
-        this.pw.print(';');
-    }
-    public void visitInitializer(Java.Initializer i) {
-        if (i.statiC) this.pw.print("static ");
-        this.unparseBlockStatement(i.block);
-    }
-    public void visitBlock(Java.Block b) {
-        this.pw.println('{');
-        for (Iterator it = b.statements.iterator(); it.hasNext();) {
-            this.unparseBlockStatement((Java.BlockStatement) it.next());
-            this.pw.println();
-        }
-        this.pw.print('}');
-    }
-    public void visitBreakStatement(Java.BreakStatement bs) {
-        this.pw.print("break");
-        if (bs.optionalLabel != null) this.pw.print(' ' + bs.optionalLabel);
-        this.pw.print(';');
-    }
-    public void visitContinueStatement(Java.ContinueStatement cs) {
-        this.pw.print("continue");
-        if (cs.optionalLabel != null) this.pw.print(' ' + cs.optionalLabel);
-        this.pw.print(';');
-    }
-    public void visitDoStatement(Java.DoStatement ds) {
-        this.pw.print("do ");
-        this.unparseBlockStatement(ds.body);
-        this.pw.print("while (");
-        this.unparse(ds.condition);
-        this.pw.print(");");
-    }
-    public void visitEmptyStatement(Java.EmptyStatement es) {
-        this.pw.print(';');
-    }
-    public void visitExpressionStatement(Java.ExpressionStatement es) {
-        this.unparse(es.rvalue);
-        this.pw.print(';');
-    }
-    public void visitForStatement(Java.ForStatement fs) {
-        this.pw.print("for (");
-        if (fs.optionalInit != null) {
-            this.unparseBlockStatement(fs.optionalInit);
-        } else { 
-            this.pw.print(';');
-        }
-        if (fs.optionalCondition != null) {
-            this.pw.print(' ');
-            this.unparse(fs.optionalCondition);
-        } 
-        this.pw.print(';');
-        if (fs.optionalUpdate != null) {
-            this.pw.print(' ');
-            for (int i = 0; i < fs.optionalUpdate.length; ++i) {
-                if (i > 0) this.pw.print(", ");
-                this.unparse(fs.optionalUpdate[i]);
-            }
-        }
-        this.pw.print(") ");
-        this.unparseBlockStatement(fs.body);
-    }
-    public void visitIfStatement(Java.IfStatement is) {
-        this.pw.print("if (");
-        this.unparse(is.condition);
-        this.pw.print(") ");
-        this.unparseBlockStatement(is.thenStatement);
-        if (is.optionalElseStatement != null) {
-            this.pw.print(" else ");
-            this.unparseBlockStatement(is.optionalElseStatement);
-        }
-    }
-    public void visitLabeledStatement(Java.LabeledStatement ls) {
-        this.pw.println(ls.label + ':');
-        this.unparseBlockStatement(ls.body);
-    }
-    public void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds) {
-        this.unparseTypeDeclaration(lcds.lcd);
-    }
-    public void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
-        this.unparseModifiers(lvds.modifiers);
-        this.unparseType(lvds.type);
-        this.pw.print(' ');
-        this.unparseVariableDeclarator(lvds.variableDeclarators[0]);
-        for (int i = 1; i < lvds.variableDeclarators.length; ++i) {
-            this.pw.print(", ");
-            this.unparseVariableDeclarator(lvds.variableDeclarators[i]);
-        }
-        this.pw.print(';');
-    }
-    public void visitReturnStatement(Java.ReturnStatement rs) {
-        this.pw.print("return");
-        if (rs.optionalReturnValue != null) {
-            this.pw.print(' ');
-            this.unparse(rs.optionalReturnValue);
-        } 
-        this.pw.print(';');
-    }
-    public void visitSwitchStatement(Java.SwitchStatement ss) {
-        this.pw.print("switch (");
-        this.unparse(ss.condition);
-        this.pw.println(") {");
-        for (Iterator it = ss.sbsgs.iterator(); it.hasNext();) {
-            Java.SwitchStatement.SwitchBlockStatementGroup sbgs = (Java.SwitchStatement.SwitchBlockStatementGroup) it.next();
-            this.aiw.unindent();
-            try {
-                for (Iterator it2 = sbgs.caseLabels.iterator(); it2.hasNext();) {
-                    Java.Rvalue rv = (Java.Rvalue) it2.next();
-                    this.pw.print("case ");
-                    this.unparse(rv);
-                    this.pw.println(':');
-                }
-                if (sbgs.hasDefaultLabel) this.pw.println("default:");
-            } finally {
-                this.aiw.indent();
-            }
-            for (Iterator it2 = sbgs.blockStatements.iterator(); it2.hasNext();) {
-                this.unparseBlockStatement((Java.BlockStatement) it2.next());
-                this.pw.println();
-            }
-        }
-        this.pw.print('}');
-    }
-    public void visitSynchronizedStatement(Java.SynchronizedStatement ss) {
-        this.pw.print("synchronized (");
-        this.unparse(ss.expression);
-        this.pw.print(") ");
-        this.unparseBlockStatement(ss.body);
-    }
-    public void visitThrowStatement(Java.ThrowStatement ts) {
-        this.pw.print("throw ");
-        this.unparse(ts.expression);
-        this.pw.print(';');
-    }
-    public void visitTryStatement(Java.TryStatement ts) {
-        this.pw.print("try ");
-        this.unparseBlockStatement(ts.body);
-        for (Iterator it = ts.catchClauses.iterator(); it.hasNext();) {
-            Java.CatchClause cc = (Java.CatchClause) it.next();
-            this.pw.print(" catch (");
-            this.unparseFormalParameter(cc.caughtException);
-            this.pw.print(") ");
-            this.unparseBlockStatement(cc.body);
-        }
-        if (ts.optionalFinally != null) {
-            this.pw.print(" finally ");
-            this.unparseBlockStatement(ts.optionalFinally);
-        }
-    }
-    public void visitWhileStatement(Java.WhileStatement ws) {
-        this.pw.print("while (");
-        this.unparse(ws.condition);
-        this.pw.print(") ");
-        this.unparseBlockStatement(ws.body);
-    }
-    public void unparseVariableDeclarator(Java.VariableDeclarator vd) {
-        this.pw.print(vd.name);
-        for (int i = 0; i < vd.brackets; ++i) this.pw.print("[]");
-        if (vd.optionalInitializer != null) {
-            this.pw.print(" = ");
-            this.unparseArrayInitializerOrRvalue(vd.optionalInitializer);
-        }
-    }
-    public void unparseFormalParameter(Java.FunctionDeclarator.FormalParameter fp) {
-        if (fp.finaL) this.pw.print("final ");
-        this.unparseType(fp.type);
-        this.pw.print(' ' + fp.name);
-    }
-    public void visitMethodInvocation(Java.MethodInvocation mi) {
-        if (mi.optionalTarget != null) {
-            this.unparseLhs(mi.optionalTarget, ".");
-            this.pw.print('.');
-        }
-        this.pw.print(mi.methodName);
-        this.unparseFunctionInvocationArguments(mi.arguments);
-    }
-    public void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci) {
-        this.pw.print("this");
-        this.unparseFunctionInvocationArguments(aci.arguments);
-    }
-    public void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci) {
-        if (sci.optionalQualification != null) {
-            this.unparseLhs(sci.optionalQualification, ".");
-            this.pw.print('.');
-        }
-        this.pw.print("super");
-        this.unparseFunctionInvocationArguments(sci.arguments);
-    }
-    public void visitNewClassInstance(Java.NewClassInstance nci) {
-        if (nci.optionalQualification != null) {
-            this.unparseLhs(nci.optionalQualification, ".");
-            this.pw.print('.');
-        }
-        this.pw.print("new " + nci.type.toString());
-        this.unparseFunctionInvocationArguments(nci.arguments);
-    }
-    public void visitAssignment(Java.Assignment a) {
-        this.unparseLhs(a.lhs, a.operator);
-        this.pw.print(' ' + a.operator + ' ');
-        this.unparseRhs(a.rhs, a.operator);
-    }
-    public void visitAmbiguousName(Java.AmbiguousName an) { this.pw.print(an.toString()); }
-    public void visitArrayAccessExpression(Java.ArrayAccessExpression aae) {
-        this.unparseLhs(aae.lhs, "[ ]");
-        this.pw.print('[');
-        this.unparse(aae.index);
-        this.pw.print(']');
-    }
-    public void visitArrayLength(Java.ArrayLength al) {
-        this.unparseLhs(al.lhs, ".");
-        this.pw.print(".length");
-    }
-    public void visitArrayType(Java.ArrayType at) {
-        this.unparseType(at.componentType);
-        this.pw.print("[]");
-    }
-    public void visitBasicType(Java.BasicType bt) {
-        this.pw.print(bt.toString());
-    }
-    public void visitBinaryOperation(Java.BinaryOperation bo) {
-        this.unparseLhs(bo.lhs, bo.op);
-        this.pw.print(' ' + bo.op + ' ');
-        this.unparseRhs(bo.rhs, bo.op);
-    }
-    public void visitCast(Java.Cast c) {
-        this.pw.print('(');
-        this.unparseType(c.targetType);
-        this.pw.print(") ");
-        this.unparseRhs(c.value, "cast");
-    }
-    public void visitClassLiteral(Java.ClassLiteral cl) {
-        this.unparseType(cl.type);
-        this.pw.print(".class");
-    }
-    public void visitConditionalExpression(Java.ConditionalExpression ce) {
-        this.unparseLhs(ce.lhs, "?:");
-        this.pw.print(" ? ");
-        this.unparseLhs(ce.mhs, "?:");
-        this.pw.print(" : ");
-        this.unparseRhs(ce.rhs, "?:");
-    }
-    public void visitCrement(Java.Crement c) {
-        if (c.pre) {
-            this.pw.print(c.operator);
-            this.unparseUnaryOperation(c.operand, c.operator + "x");
-        } else
-        {
-            this.unparseUnaryOperation(c.operand, "x" + c.operator);
-            this.pw.print(c.operator);
-        }
-    }
-    public void visitFieldAccess(Java.FieldAccess fa) {
-        this.unparseLhs(fa.lhs, ".");
-        this.pw.print('.' + fa.field.getName());
-    }
-    public void visitFieldAccessExpression(Java.FieldAccessExpression fae) {
-        this.unparseLhs(fae.lhs, ".");
-        this.pw.print('.' + fae.fieldName);
-    }
-    public void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) {
-        if (scfae.optionalQualification != null) {
-            this.unparseType(scfae.optionalQualification);
-            this.pw.print(".super." + scfae.fieldName);
-        } else
-        {
-            this.pw.print("super." + scfae.fieldName);
-        }
-    }
-    public void visitInstanceof(Java.Instanceof io) {
-        this.unparseLhs(io.lhs, "instanceof");
-        this.pw.print(" instanceof ");
-        this.unparseType(io.rhs);
-    }
-    public void visitLiteral(Java.Literal l) { this.pw.print(l.toString()); }
-    public void visitLocalVariableAccess(Java.LocalVariableAccess lva) { this.pw.print(lva.toString()); }
-    public void visitNewArray(Java.NewArray na) {
-        this.pw.print("new ");
-        this.unparseType(na.type);
-        for (int i = 0; i < na.dimExprs.length; ++i) {
-            this.pw.print('[');
-            this.unparse(na.dimExprs[i]);
-            this.pw.print(']');
-        }
-        for (int i = 0; i < na.dims; ++i) {
-            this.pw.print("[]");
-        }
-    }
-    public void visitNewInitializedArray(Java.NewInitializedArray nai) {
-        this.pw.print("new ");
-        this.unparseType(nai.arrayType);
-        this.pw.print(" ");
-        this.unparseArrayInitializerOrRvalue(nai.arrayInitializer);
-    }
-    public void visitPackage(Java.Package p) { this.pw.print(p.toString()); }
-    public void visitParameterAccess(Java.ParameterAccess pa) { this.pw.print(pa.toString()); }
-    public void visitQualifiedThisReference(Java.QualifiedThisReference qtr) {
-        this.unparseType(qtr.qualification);
-        this.pw.print(".this");
-    }
-    public void visitReferenceType(Java.ReferenceType rt) { this.pw.print(rt.toString()); }
-    public void visitRvalueMemberType(Java.RvalueMemberType rmt) { this.pw.print(rmt.toString()); }
-    public void visitSimpleType(Java.SimpleType st) { this.pw.print(st.toString()); }
-    public void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi) {
-        this.pw.print("super." + smi.methodName);
-        this.unparseFunctionInvocationArguments(smi.arguments);
-    }
-    public void visitThisReference(Java.ThisReference tr) {
-        this.pw.print("this");
-    }
-    public void visitUnaryOperation(Java.UnaryOperation uo) {
-        this.pw.print(uo.operator);
-        this.unparseUnaryOperation(uo.operand, uo.operator + "x");
-    }
-    public void visitParenthesizedExpression(Java.ParenthesizedExpression pe) {
-        this.pw.print('(');
-        this.unparse(pe.value);
-        this.pw.print(')');
-    }
-
-    // Helpers
-
-    private void unparseBlockStatement(Java.BlockStatement blockStatement) {
-        blockStatement.accept(this);
-    }
-
-    private void unparseTypeDeclaration(Java.TypeDeclaration typeDeclaration) {
-        typeDeclaration.accept(this);
-    }
-
-    private void unparseType(Java.Type type) {
-        ((Java.Atom) type).accept(this);
-    }
-
-    private void unparse(Java.Atom operand) {
-        ((Java.Atom) operand).accept(this);
-    }
-
-    /**
-     * Iff the <code>operand</code> is unnatural for the <code>unaryOperator</code>, enclose the
-     * <code>operand</code> in parentheses. Example: "a+b" is an unnatural operand for unary "!x". 
-     *
-     * @param unaryOperator ++x --x +x -x ~x !x x++ x--
-     */
-    private void unparseUnaryOperation(Java.Rvalue operand, String unaryOperator) {
-        int cmp = UnparseVisitor.comparePrecedence(unaryOperator, operand);
-        this.unparse(operand, cmp < 0);
-    }
-
-    /**
-     * Iff the <code>lhs</code> is unnatural for the <code>binaryOperator</code>, enclose the
-     * <code>lhs</code> in parentheses. Example: "a+b" is an unnatural lhs for operator "*". 
-     *
-     * @param binaryOperator = +=... ?: || && | ^ & == != < > <= >= instanceof << >> >>> + - * / % cast
-     */
-
-    private void unparseLhs(Java.Atom lhs, String binaryOperator) {
-        int cmp = UnparseVisitor.comparePrecedence(binaryOperator, lhs);
-        this.unparse(lhs, cmp < 0 || (cmp == 0 && UnparseVisitor.isLeftAssociate(binaryOperator)));
-    }
-
-
-    /**
-     * Iff the <code>rhs</code> is unnatural for the <code>binaryOperator</code>, enclose the
-     * <code>rhs</code> in parentheses. Example: "a+b" is an unnatural rhs for operator "*". 
-     */
-    private void unparseRhs(Java.Rvalue rhs, String binaryOperator) {
-        int cmp = UnparseVisitor.comparePrecedence(binaryOperator, rhs);
-        this.unparse(rhs, cmp < 0 || (cmp == 0 && UnparseVisitor.isRightAssociate(binaryOperator)));
-    }
-
-    private void unparse(Java.Atom operand, boolean natural) {
-        if (!natural) this.pw.print("((( ");
-        this.unparse(operand);
-        if (!natural) this.pw.print(" )))");
-    }
-
-    /**
-     * Return true iff operator is right associative e.g. <code>a = b = c</code> evaluates as
-     * <code>a = (b = c)</code>.
-     *
-     * @return Return true iff operator is right associative
-     */
-    private static boolean isRightAssociate(String op) {
-        return UnparseVisitor.RIGHT_ASSOCIATIVE_OPERATORS.contains(op);
-    }
-
-    /**
-     * Return true iff operator is left associative e.g. <code>a - b - c</code> evaluates as
-     * <code>(a - b) - c</code>.
-     *
-     * @return Return true iff operator is left associative
-     */
-    private static boolean isLeftAssociate(String op) {
-        return UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS.contains(op);
-    }
-
-    /**
-     * Returns a value
-     * <ul>
-     *   <li>< 0 iff the <code>operator</code> has lower precedence than the <code>operand</code>
-     *   <li>==; 0 iff the <code>operator</code> has equal precedence than the <code>operand</code>
-     *   <li>> 0 iff the <code>operator</code> has higher precedence than the <code>operand</code>
-     * </ul>
-     */
-    private static int comparePrecedence(String operator, Java.Atom operand) {
-        if (operand instanceof Java.BinaryOperation) {
-            return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence(((Java.BinaryOperation) operand).op); 
-        } else
-        if (operand instanceof Java.UnaryOperation) {
-            return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence(((Java.UnaryOperation) operand).operator + "x"); 
-        } else
-        if (operand instanceof Java.ConditionalExpression) {
-            return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("?:"); 
-        } else
-        if (operand instanceof Java.Instanceof) {
-            return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("instanceof"); 
-        } else
-        if (operand instanceof Java.Cast) {
-            return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("cast"); 
-        } else
-        if (operand instanceof Java.MethodInvocation || operand instanceof Java.FieldAccess) {
-            return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("."); 
-        } else
-        if (operand instanceof Java.NewArray) {
-            return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence("new"); 
-        } else
-        if (operand instanceof Java.Crement) {
-            Java.Crement c = (Java.Crement) operand;
-            return UnparseVisitor.getOperatorPrecedence(operator) - UnparseVisitor.getOperatorPrecedence(c.pre ? c.operator + "x" : "x" + c.operator);
-        } else
-        {
-            // All other rvalues (e.g. literal) have higher precedence than any operator.
-            return -1;
-        }
-    }
-    private static final int getOperatorPrecedence(String operator) {
-        return ((Integer) UnparseVisitor.OPERATOR_PRECEDENCE.get(operator)).intValue();
-    }
-    private static final Set LEFT_ASSOCIATIVE_OPERATORS = new HashSet();
-    private static final Set RIGHT_ASSOCIATIVE_OPERATORS = new HashSet();
-    private static final Set UNARY_OPERATORS = new HashSet();
-    private static final Map OPERATOR_PRECEDENCE = new HashMap();
-    static {
-        Object[] ops = {
-            UnparseVisitor.RIGHT_ASSOCIATIVE_OPERATORS, "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=", "^=", "|=",
-            UnparseVisitor.RIGHT_ASSOCIATIVE_OPERATORS, "?:",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "||",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "&&",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "|",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "^",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "&",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "==", "!=",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "<", ">", "<=", ">=", "instanceof",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "<<", ">>", ">>>",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "+", "-",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "*", "/", "%",
-            UnparseVisitor.RIGHT_ASSOCIATIVE_OPERATORS, "cast",
-            UnparseVisitor.UNARY_OPERATORS,             "++x", "--x", "+x", "-x", "~x", "!x",
-            UnparseVisitor.UNARY_OPERATORS,             "x++", "x--",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  "new",
-            UnparseVisitor.LEFT_ASSOCIATIVE_OPERATORS,  ".", "[ ]",
-        };
-        int precedence = 0;
-        LOOP1: for (int i = 0;;) {
-            Set s = (Set) ops[i++];
-            Integer pi = new Integer(++precedence);
-            for (;;) {
-                if (i == ops.length) break LOOP1;
-                if (!(ops[i] instanceof String)) break;
-                String op = (String) ops[i++];
-                s.add(op);
-                UnparseVisitor.OPERATOR_PRECEDENCE.put(op, pi);
-            }
-        }
-    }
-
-    private void unparseNamedClassDeclaration(Java.NamedClassDeclaration ncd) {
-        this.unparseDocComment(ncd);
-        this.unparseModifiers(ncd.modifiers);
-        this.pw.print("class " + ncd.name);
-        if (ncd.optionalExtendedType != null) {
-            this.pw.print(" extends ");
-            this.unparseType(ncd.optionalExtendedType);
-        } 
-        if (ncd.implementedTypes.length > 0) this.pw.print(" implements " + Java.join(ncd.implementedTypes, ", "));
-        this.pw.println(" {");
-        this.unparseClassDeclarationBody(ncd);
-        this.pw.print('}');
-    }
-    private void unparseArrayInitializerOrRvalue(Java.ArrayInitializerOrRvalue aiorv) {
-        if (aiorv instanceof Java.Rvalue) {
-            this.unparse((Java.Rvalue) aiorv);
-        } else
-        if (aiorv instanceof Java.ArrayInitializer) {
-            Java.ArrayInitializer ai = (Java.ArrayInitializer) aiorv;
-            if (ai.values.length == 0) {
-                this.pw.print("{}");
-            } else
-            {
-                this.pw.print("{ ");
-                this.unparseArrayInitializerOrRvalue(ai.values[0]);
-                for (int i = 1; i < ai.values.length; ++i) {
-                    this.pw.print(", ");
-                    this.unparseArrayInitializerOrRvalue(ai.values[i]);
-                }
-                this.pw.print(" }");
-            }
-        } else
-        {
-            throw new RuntimeException("Unexpected array initializer or rvalue class " + aiorv.getClass().getName());
-        }
-    }
-
-    public void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) {
-        this.unparseType(acd.baseType);
-        this.pw.println(" {");
-        this.unparseClassDeclarationBody(acd);
-        this.pw.print('}');
-    }
-    public void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
-        if (naci.optionalQualification != null) {
-            this.unparseLhs(naci.optionalQualification, ".");
-            this.pw.print('.');
-        }
-        this.pw.print("new " + naci.anonymousClassDeclaration.baseType.toString() + '(');
-        for (int i = 0; i < naci.arguments.length; ++i) {
-            if (i > 0) this.pw.print(", ");
-            this.unparse(naci.arguments[i]);
-        }
-        this.pw.println(") {");
-        this.unparseClassDeclarationBody(naci.anonymousClassDeclaration);
-        this.pw.print('}');
-    }
-    // Multi-line!
-    private void unparseClassDeclarationBody(Java.ClassDeclaration cd) {
-        for (Iterator it = cd.constructors.iterator(); it.hasNext();) {
-            ((Java.ConstructorDeclarator) it.next()).accept(this);
-            this.pw.println();
-        }
-        this.unparseAbstractTypeDeclarationBody(cd);
-        for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
-            ((Java.TypeBodyDeclaration) it.next()).accept(this);
-            this.pw.println();
-        }
-    }
-    private void unparseInterfaceDeclaration(Java.InterfaceDeclaration id) {
-        this.unparseDocComment(id);
-        this.unparseModifiers(id.modifiers);
-        this.pw.print("interface " + id.name);
-        if (id.extendedTypes.length > 0) this.pw.print(" extends " + Java.join(id.extendedTypes, ", "));
-        this.pw.println(" {");
-        this.unparseAbstractTypeDeclarationBody(id);
-        for (Iterator it = id.constantDeclarations.iterator(); it.hasNext();) {
-            ((Java.TypeBodyDeclaration) it.next()).accept(this);
-            this.pw.println();
-        }
-        this.pw.print('}');
-    }
-    // Multi-line!
-    private void unparseAbstractTypeDeclarationBody(Java.AbstractTypeDeclaration atd) {
-        for (Iterator it = atd.declaredMethods.iterator(); it.hasNext();) {
-            ((Java.MethodDeclarator) it.next()).accept(this);
-            this.pw.println();
-        }
-        for (Iterator it = atd.declaredClassesAndInterfaces.iterator(); it.hasNext();) {
-            ((Java.TypeBodyDeclaration) it.next()).accept(this);
-            this.pw.println();
-        }
-    }
-    private void unparseFunctionDeclaratorRest(Java.FunctionDeclarator fd) {
-        this.pw.print('(');
-        for (int i = 0; i < fd.formalParameters.length; ++i) {
-            if (i > 0) this.pw.print(", ");
-            this.unparseFormalParameter(fd.formalParameters[i]);
-        }
-        this.pw.print(')');
-        if (fd.thrownExceptions.length > 0) this.pw.print(" throws " + Java.join(fd.thrownExceptions, ", "));
-    }
-    private void unparseDocComment(Java.DocCommentable dc) {
-        String optionalDocComment = dc.getDocComment();
-        if (optionalDocComment != null) {
-            this.pw.println();
-            this.pw.print("/**");
-            this.aiw.setPrefix(" *");
-            try {
-                this.pw.print(optionalDocComment);
-            } finally {
-                this.aiw.setPrefix(null);
-            }
-            this.pw.println("*/");
-        }
-    }
-    private void unparseModifiers(short modifiers) {
-        if (modifiers != 0) {
-            this.pw.print(Mod.shortToString(modifiers) + ' ');
-        }
-    }
-    private void unparseFunctionInvocationArguments(Java.Rvalue[] arguments) {
-        this.pw.print('(');
-        for (int i = 0; i < arguments.length; ++i) {
-            if (i > 0) this.pw.print(", ");
-            this.unparse(arguments[i]);
-        }
-        this.pw.print(')');
-    }
-
-}
diff --git a/src/org/codehaus/janino/Visitor.java b/src/org/codehaus/janino/Visitor.java
deleted file mode 100644
index 019e7bb..0000000
--- a/src/org/codehaus/janino/Visitor.java
+++ /dev/null
@@ -1,138 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-/**
- * Basis for the "visitor" pattern as described in "Gamma, Helm, Johnson,
- * Vlissides: Design Patterns".
- */
-public class Visitor {
-    public interface ComprehensiveVisitor
-    extends ImportVisitor, TypeDeclarationVisitor, TypeBodyDeclarationVisitor, BlockStatementVisitor, AtomVisitor {
-    }
-
-    public interface ImportVisitor {
-        void visitSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid);
-        void visitTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd);
-        void visitSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration ssid);
-        void visitStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd);
-    }
-    
-    public interface TypeDeclarationVisitor {
-        void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd);
-        void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd);
-        void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd);
-        void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid);
-        void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid);
-        void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd);
-    }
-    
-    public interface TypeBodyDeclarationVisitor {
-        void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid);
-        void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd);
-        void visitConstructorDeclarator(Java.ConstructorDeclarator cd);
-        void visitInitializer(Java.Initializer i);
-        void visitMethodDeclarator(Java.MethodDeclarator md);
-        void visitFieldDeclaration(Java.FieldDeclaration fd);
-    }
-    
-    public interface BlockStatementVisitor {
-        void visitInitializer(Java.Initializer i);
-        void visitFieldDeclaration(Java.FieldDeclaration fd);
-        void visitLabeledStatement(Java.LabeledStatement ls);
-        void visitBlock(Java.Block b);
-        void visitExpressionStatement(Java.ExpressionStatement es);
-        void visitIfStatement(Java.IfStatement is);
-        void visitForStatement(Java.ForStatement fs);
-        void visitWhileStatement(Java.WhileStatement ws);
-        void visitTryStatement(Java.TryStatement ts);
-        void visitSwitchStatement(Java.SwitchStatement ss);
-        void visitSynchronizedStatement(Java.SynchronizedStatement ss);
-        void visitDoStatement(Java.DoStatement ds);
-        void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds);
-        void visitReturnStatement(Java.ReturnStatement rs);
-        void visitThrowStatement(Java.ThrowStatement ts);
-        void visitBreakStatement(Java.BreakStatement bs);
-        void visitContinueStatement(Java.ContinueStatement cs);
-        void visitEmptyStatement(Java.EmptyStatement es);
-        void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds);
-        void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci);
-        void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci);
-    }
-    
-    public interface AtomVisitor extends RvalueVisitor, TypeVisitor {
-        void visitPackage(Java.Package p);
-    }
-    
-    public interface TypeVisitor {
-        void visitArrayType(Java.ArrayType at);
-        void visitBasicType(Java.BasicType bt);
-        void visitReferenceType(Java.ReferenceType rt);
-        void visitRvalueMemberType(Java.RvalueMemberType rmt);
-        void visitSimpleType(Java.SimpleType st);
-    }
-    
-    public interface RvalueVisitor extends LvalueVisitor {
-        void visitArrayLength(Java.ArrayLength al);
-        void visitAssignment(Java.Assignment a);
-        void visitUnaryOperation(Java.UnaryOperation uo);
-        void visitBinaryOperation(Java.BinaryOperation bo);
-        void visitCast(Java.Cast c);
-        void visitClassLiteral(Java.ClassLiteral cl);
-        void visitConditionalExpression(Java.ConditionalExpression ce);
-        void visitCrement(Java.Crement c);
-        void visitInstanceof(Java.Instanceof io);
-        void visitMethodInvocation(Java.MethodInvocation mi);
-        void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi);
-        void visitLiteral(Java.Literal l);
-        void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci);
-        void visitNewArray(Java.NewArray na);
-        void visitNewInitializedArray(Java.NewInitializedArray nia);
-        void visitNewClassInstance(Java.NewClassInstance nci);
-        void visitParameterAccess(Java.ParameterAccess pa);
-        void visitQualifiedThisReference(Java.QualifiedThisReference qtr);
-        void visitThisReference(Java.ThisReference tr);
-    }
-    
-    public interface LvalueVisitor {
-        void visitAmbiguousName(Java.AmbiguousName an);
-        void visitArrayAccessExpression(Java.ArrayAccessExpression aae);
-        void visitFieldAccess(Java.FieldAccess fa);
-        void visitFieldAccessExpression(Java.FieldAccessExpression fae);
-        void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae);
-        void visitLocalVariableAccess(Java.LocalVariableAccess lva);
-        void visitParenthesizedExpression(Java.ParenthesizedExpression pe);
-    }
-}
diff --git a/src/org/codehaus/janino/WarningHandler.java b/src/org/codehaus/janino/WarningHandler.java
deleted file mode 100644
index 8446374..0000000
--- a/src/org/codehaus/janino/WarningHandler.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino;
-
-/**
- * Interface type for {@link UnitCompiler#setWarningHandler(WarningHandler)}.
- */
-public interface WarningHandler {
-    void handleWarning(String handle, String message, Location optionalLocation);
-}
diff --git a/src/org/codehaus/janino/package.html b/src/org/codehaus/janino/package.html
deleted file mode 100644
index 868d100..0000000
--- a/src/org/codehaus/janino/package.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html><body>
-  The classes in this package pose the core of the Janino Java<sup>TM</sup>
-  compiler.
-  <p>
-  The package comprises a scanner ({@link org.codehaus.janino.Scanner}, a parser
-  ({@link org.codehaus.janino.Parser}) and a class file library. The parser builds a
-  syntax tree from the "Java.*" classes that represents the parsed code. The
-  {@link org.codehaus.janino.UnitCompiler#compileUnit} method compiles this syntax
-  tree into a {@link org.codehaus.janino.util.ClassFile} object, which can write
-  Java<sup>TM</sup> bytecode to an "OutputStream".
-</body></html>
diff --git a/src/org/codehaus/janino/samples/ClassBodyDemo.java b/src/org/codehaus/janino/samples/ClassBodyDemo.java
deleted file mode 100644
index b0438cf..0000000
--- a/src/org/codehaus/janino/samples/ClassBodyDemo.java
+++ /dev/null
@@ -1,96 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.samples;
-
-import java.io.*;
-import java.lang.reflect.*;
-
-import org.codehaus.janino.*;
-
-public class ClassBodyDemo {
-    public static void main(String[] args) throws Exception {
-        if (args.length > 0 && args[0].equals("-help")) {
-            System.out.println("Usage:  ClassBodyDemo <class-body> { <argument> }");
-            System.out.println("        ClassBodyDemo -help");
-            System.out.println("If <class-body> starts with a '@', then the class body is read");
-            System.out.println("from the named file.");
-            System.out.println("The <class-body> must declare a method \"public static main(String[])\"");
-            System.out.println("to which the <argument>s are passed. If the return type of that method is");
-            System.out.println("not VOID, then the returned value is printed to STDOUT.");
-            System.exit(0);
-        }
-
-        int i = 0;
-
-        // Get class body.
-        if (i >= args.length) {
-            System.err.println("Class body missing; try \"-help\".");
-        }
-        String classBody = args[i++];
-        if (classBody.startsWith("@")) classBody = ClassBodyDemo.readFileToString(classBody.substring(1));
-
-        // Get arguments.
-        String[] arguments = new String[args.length - i];
-        System.arraycopy(args, i, arguments, 0, arguments.length);
-
-        // Compile the class body.
-        Class c = new ClassBodyEvaluator(classBody).getClazz();
-
-        // Invoke the "public static main(String[])" method.
-        Method m = c.getMethod("main", new Class[] { String[].class });
-        Integer returnValue = (Integer) m.invoke(null, new Object[] { arguments });
-
-        // If non-VOID, print the return value.
-        if (m.getReturnType() != Void.TYPE) System.out.println(DemoBase.toString(returnValue));
-    }
-
-    private ClassBodyDemo() {}
-
-    private static String readFileToString(String fileName) throws IOException {
-        Reader r = new FileReader(fileName);
-        try {
-            StringBuffer sb = new StringBuffer();
-            char[] ca = new char[1024];
-            for (;;) {
-                int cnt = r.read(ca, 0, ca.length);
-                if (cnt == -1) break;
-                sb.append(ca, 0, cnt);
-            }
-            return sb.toString();
-        } finally {
-            r.close();
-        }
-    }
-}
diff --git a/src/org/codehaus/janino/samples/DeclarationCounter.java b/src/org/codehaus/janino/samples/DeclarationCounter.java
deleted file mode 100644
index fb647d0..0000000
--- a/src/org/codehaus/janino/samples/DeclarationCounter.java
+++ /dev/null
@@ -1,99 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.samples;
-
-import java.io.*;
-
-import org.codehaus.janino.*;
-import org.codehaus.janino.util.*;
-
-/**
- * An example application for the {@link org.codehaus.janino.util.Traverser}:
- * Reads, scans and parses the files named on the command line and counts
- * several kinds of declarations.
- */
-public class DeclarationCounter extends Traverser {
-    public static void main(String[] args) throws Scanner.ScanException, IOException, Parser.ParseException {
-        DeclarationCounter dc = new DeclarationCounter();
-        for (int i = 0; i < args.length; ++i) {
-            String fileName = args[i];
-
-            // Parse each compilation unit.
-            FileReader r = new FileReader(fileName);
-            Java.CompilationUnit cu;
-            try {
-                cu = new Parser(new Scanner(fileName, r)).parseCompilationUnit();
-            } finally {
-                r.close();
-            }
-
-            // Traverse it and count declarations.
-            dc.traverseCompilationUnit(cu);
-        }
-
-        System.out.println("Class declarations:     " + dc.classDeclarationCount);
-        System.out.println("Interface declarations: " + dc.interfaceDeclarationCount);
-        System.out.println("Fields:                 " + dc.fieldCount);
-        System.out.println("Local variables:        " + dc.localVariableCount);
-    }
-
-    // Count class declarations.
-    public void traverseClassDeclaration(Java.ClassDeclaration cd) {
-        ++this.classDeclarationCount;
-        super.traverseClassDeclaration(cd);
-    }
-    private int classDeclarationCount = 0;
-
-    // Count interface declarations.
-    public void traverseInterfaceDeclaration(Java.InterfaceDeclaration id) {
-        ++this.interfaceDeclarationCount;
-        super.traverseInterfaceDeclaration(id);
-    }
-    private int interfaceDeclarationCount = 0;
-
-    // Count fields.
-    public void traverseFieldDeclaration(Java.FieldDeclaration fd) {
-        this.fieldCount += fd.variableDeclarators.length;
-        super.traverseFieldDeclaration(fd);
-    }
-    private int fieldCount = 0;
-
-    // Count local variables.
-    public void traverseLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
-        this.localVariableCount += lvds.variableDeclarators.length;
-        super.traverseLocalVariableDeclarationStatement(lvds);
-    }
-    private int localVariableCount = 0;
-}
diff --git a/src/org/codehaus/janino/samples/DemoBase.java b/src/org/codehaus/janino/samples/DemoBase.java
deleted file mode 100644
index 68958b5..0000000
--- a/src/org/codehaus/janino/samples/DemoBase.java
+++ /dev/null
@@ -1,154 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.samples;
-
-import java.util.*;
-import java.lang.reflect.*;
-
-/**
- * Common base class for the "...Demo" classes that demostrate Janino.
- */
-
-public class DemoBase {
-    protected DemoBase() {}
-
-    public static Object createObject(
-        Class type,
-        String value
-    ) throws
-    NoSuchMethodException,
-    InstantiationException,
-    InvocationTargetException,
-    IllegalAccessException {
-
-        // Wrap primitive parameters.
-        if (type.isPrimitive()) {
-            type = (
-                type == boolean.class ? Boolean.class   :
-                type == char.class    ? Character.class :
-                type == byte.class    ? Byte.class      :
-                type == short.class   ? Short.class     :
-                type == int.class     ? Integer.class   :
-                type == long.class    ? Long.class      :
-                type == float.class   ? Float.class     :
-                type == double.class  ? Double.class    : void.class
-            );
-        }
-
-        // Construct object, assuming it has a default constructor or a
-        // constructor with one single "String" argument.
-        if (value.equals("")) {
-            return type.getConstructor(new Class[0]).newInstance(new Object[0]);
-        } else {
-            return type.getConstructor(new Class[] { String.class }).newInstance(new Object[] { value });
-        }
-    }
-
-    public static String[] explode(String s) {
-        StringTokenizer st = new StringTokenizer(s, ",");
-        List l = new ArrayList();
-        while (st.hasMoreTokens()) l.add(st.nextToken());
-        return (String[]) l.toArray(new String[l.size()]);
-    }
-
-    public static Class stringToType(String s) {
-        int brackets = 0;
-        while (s.endsWith("[]")) {
-            ++brackets;
-            s = s.substring(0, s.length() - 2);
-        }
-
-        if (brackets == 0) {
-            // "Class.forName("C")" does not work.
-            if (s.equals("void"   )) return void.class;
-            if (s.equals("boolean")) return boolean.class;
-            if (s.equals("char"   )) return char.class;
-            if (s.equals("byte"   )) return byte.class;
-            if (s.equals("short"  )) return short.class;
-            if (s.equals("int"    )) return int.class;
-            if (s.equals("long"   )) return long.class;
-            if (s.equals("float"  )) return float.class;
-            if (s.equals("double" )) return double.class;
-        }
-
-        // Automagically convert primitive type names.
-        if (s.equals("void"   )) { s = "V"; } else
-        if (s.equals("boolean")) { s = "Z"; } else
-        if (s.equals("char"   )) { s = "C"; } else
-        if (s.equals("byte"   )) { s = "B"; } else
-        if (s.equals("short"  )) { s = "S"; } else
-        if (s.equals("int"    )) { s = "I"; } else
-        if (s.equals("long"   )) { s = "J"; } else
-        if (s.equals("float"  )) { s = "F"; } else
-        if (s.equals("double" )) { s = "D"; }
-
-        while (--brackets >= 0) s = '[' + s;
-        try {
-            return Class.forName(s);
-        } catch (ClassNotFoundException ex) {
-            ex.printStackTrace();
-            System.exit(1);
-            throw new RuntimeException(); // Never reached.
-        }
-    }
-
-    public static Class[] stringToTypes(String s) {
-        StringTokenizer st = new StringTokenizer(s, ",");
-        List l = new ArrayList();
-        while (st.hasMoreTokens()) l.add(DemoBase.stringToType(st.nextToken()));
-        Class[] res = new Class[l.size()];
-        l.toArray(res);
-        return res;
-    }
-
-    public static String toString(Object o) {
-        if (o == null) return "(null)";
-
-        // Pretty-print array.
-        Class clazz = o.getClass();
-        if (clazz.isArray()) {
-            StringBuffer sb = new StringBuffer(clazz.getComponentType().toString()).append("[] { ");
-            for (int i = 0; i < Array.getLength(o); ++i) {
-                if (i > 0) sb.append(", ");
-                sb.append(DemoBase.toString(Array.get(o, i)));
-            }
-            sb.append(" }");
-            return sb.toString();
-        }
-
-        // Apply default "toString()" method.
-        return o.toString();
-    }
-}
diff --git a/src/org/codehaus/janino/samples/ExpressionDemo.java b/src/org/codehaus/janino/samples/ExpressionDemo.java
deleted file mode 100644
index decdb86..0000000
--- a/src/org/codehaus/janino/samples/ExpressionDemo.java
+++ /dev/null
@@ -1,129 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.samples;
-
-import org.codehaus.janino.*;
-
-/**
- * A test program that allows you to play around with the
- * {@link org.codehaus.janino.ExpressionEvaluator ExpressionEvaluator} class.
- */
-
-public class ExpressionDemo extends DemoBase {
-    public static void main(String[] args) throws Exception {
-        Class    optionalExpressionType = null;
-        String[] parameterNames         = { };
-        Class[]  parameterTypes         = { };
-        Class[]  thrownExceptions       = new Class[0];
-        String[] optionalDefaultImports = null;
-
-        int i;
-        for (i = 0; i < args.length; ++i) {
-            String arg = args[i];
-            if (!arg.startsWith("-")) break;
-            if (arg.equals("-et")) {
-                optionalExpressionType = DemoBase.stringToType(args[++i]);
-            } else
-            if (arg.equals("-pn")) {
-                parameterNames = DemoBase.explode(args[++i]);
-            } else
-            if (arg.equals("-pt")) {
-                parameterTypes = DemoBase.stringToTypes(args[++i]);
-            } else
-            if (arg.equals("-te")) {
-                thrownExceptions = DemoBase.stringToTypes(args[++i]);
-            } else
-            if (arg.equals("-di")) {
-                optionalDefaultImports = DemoBase.explode(args[++i]);
-            } else
-            if (arg.equals("-help")) {
-                System.err.println("Usage:  ExpressionDemo { <option> } <expression> { <parameter-value> }");
-                System.err.println("Compiles and evaluates the given expression and prints its value.");
-                System.err.println("Valid options are");
-                System.err.println(" -et <expression-type> (default: any)");
-                System.err.println(" -pn <comma-separated-parameter-names> (default: none)");
-                System.err.println(" -pt <comma-separated-parameter-types> (default: none)");
-                System.err.println(" -te <comma-separated-thrown-exception-types> (default: none)");
-                System.err.println(" -di <comma-separated-default-imports> (default: none)");
-                System.err.println(" -help");
-                System.err.println("The number of parameter names, types and values must be identical.");
-                System.exit(0);
-            } else
-            {
-                System.err.println("Invalid command line option \"" + arg + "\"; try \"-help\".");
-                System.exit(0);
-            }
-        }
-
-        if (i >= args.length) {
-            System.err.println("Expression missing; try \"-help\".");
-            System.exit(1);
-        }
-        String expression = args[i++];
-
-        if (parameterTypes.length != parameterNames.length) {
-            System.err.println("Parameter type count (" + parameterTypes.length + ") and parameter name count (" + parameterNames.length + ") do not match; try \"-help\".");
-            System.exit(1);
-        }
-
-        // One command line argument for each parameter.
-        if (args.length - i != parameterNames.length) {
-            System.err.println("Parameter value count (" + (args.length - i)  + ") and parameter name count (" + parameterNames.length + ") do not match; try \"-help\".");
-            System.exit(1);
-        }
-
-        // Convert command line arguments to parameter values.
-        Object[] parameterValues = new Object[parameterNames.length];
-        for (int j = 0; j < parameterNames.length; ++j) {
-            parameterValues[j] = DemoBase.createObject(parameterTypes[j], args[i + j]);
-        }
-
-        // Create "ExpressionEvaluator" object.
-        ExpressionEvaluator ee = new ExpressionEvaluator();
-        ee.setExpressionType(optionalExpressionType);
-        ee.setDefaultImports(optionalDefaultImports);
-        ee.setParameters(parameterNames, parameterTypes);
-        ee.setThrownExceptions(thrownExceptions);
-        ee.cook(expression);
-
-        // Evaluate expression with actual parameter values.
-        Object res = ee.evaluate(parameterValues);
-
-        // Print expression result.
-        System.out.println("Result = " + DemoBase.toString(res));
-    }
-
-    private ExpressionDemo() {}
-}
diff --git a/src/org/codehaus/janino/samples/ScriptDemo.java b/src/org/codehaus/janino/samples/ScriptDemo.java
deleted file mode 100644
index 8f7d298..0000000
--- a/src/org/codehaus/janino/samples/ScriptDemo.java
+++ /dev/null
@@ -1,126 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.samples;
-
-import org.codehaus.janino.*;
-
-/**
- * A test program that allows you to play around with the
- * {@link org.codehaus.janino.ScriptEvaluator ScriptEvaluator} class.
- */
-
-public class ScriptDemo extends DemoBase {
-    public static void main(String[] args) throws Exception {
-        Class    returnType     = void.class;
-        String[] parameterNames = {};
-        Class[]  parameterTypes = {};
-
-        int i;
-        for (i = 0; i < args.length; ++i) {
-            String arg = args[i];
-            if (!arg.startsWith("-")) break;
-            if (arg.equals("-rt")) {
-                returnType = DemoBase.stringToType(args[++i]);
-            } else
-            if (arg.equals("-pn")) {
-                parameterNames = DemoBase.explode(args[++i]);
-            } else
-            if (arg.equals("-pt")) {
-                parameterTypes = DemoBase.stringToTypes(args[++i]);
-            } else
-            if (arg.equals("-help")) {
-                ScriptDemo.usage();
-                System.exit(0);
-            } else
-            {
-                System.err.println("Invalid command line option \"" + arg + "\".");
-                ScriptDemo.usage();
-                System.exit(0);
-            }
-        }
-
-        if (i == args.length) {
-            System.err.println("Script missing on command line; try \"-help\".");
-            System.exit(1);
-        }
-        String script = args[i++];
-
-        if (parameterTypes.length != parameterNames.length) {
-            System.err.println("Parameter type count and parameter name count do not match.");
-            ScriptDemo.usage();
-            System.exit(1);
-        }
-
-        // One command line argument for each parameter.
-        if (args.length - i != parameterNames.length) {
-            System.err.println("Argument and parameter count do not match.");
-            ScriptDemo.usage();
-            System.exit(1);
-        }
-
-        // Convert command line arguments to parameter values.
-        Object[] parameterValues = new Object[parameterNames.length];
-        for (int j = 0; j < parameterNames.length; ++j) {
-            parameterValues[j] = DemoBase.createObject(parameterTypes[j], args[i + j]);
-        }
-
-        // Create "ScriptEvaluator" object.
-        ScriptEvaluator se = new ScriptEvaluator(
-            script,
-            returnType,
-            parameterNames,
-            parameterTypes
-        );
-
-        // Evaluate script with actual parameter values.
-        Object res = se.evaluate(parameterValues);
-
-        // Print script return value.
-        System.out.println("Result = " + DemoBase.toString(res));
-    }
-
-    private ScriptDemo() {}
-
-    private static void usage() {
-        System.err.println("Usage:  ScriptDemo { <option> } <script> { <parameter-value> }");
-        System.err.println("Valid options are");
-        System.err.println(" -rt <return-type>");
-        System.err.println(" -pn <comma-separated-parameter-names>");
-        System.err.println(" -pt <comma-separated-parameter-types>");
-        System.err.println(" -help");
-        System.err.println("The number of parameter names, types and values must be identical.");
-        System.err.println("The default is no parameters.");
-    }
-}
diff --git a/src/org/codehaus/janino/samples/ShippingCost.java b/src/org/codehaus/janino/samples/ShippingCost.java
deleted file mode 100644
index f9fe8d5..0000000
--- a/src/org/codehaus/janino/samples/ShippingCost.java
+++ /dev/null
@@ -1,72 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.samples;
-
-import org.codehaus.janino.*;
-
-/**
- * Sample application which demonstrates how to use the
- * {@link org.codehaus.janino.ExpressionEvaluator ExpressionEvaluator} class.
- */
-
-public class ShippingCost {
-    public static void main(String[] args) throws Exception {
-        if (args.length != 1) {
-            System.err.println("Usage: <total>");
-            System.err.println("Computes the shipping costs from the double value \"total\".");
-            System.err.println("If \"total\" is less than 100.0, then the result is 7.95, else the result is 0.");
-            System.exit(1);
-        }
-
-        // Convert command line argument to parameter "total".
-        Object[] parameterValues = new Object[] { new Double(args[0]) };
-
-        // Create "ExpressionEvaluator" object.
-        ExpressionEvaluator ee = new ExpressionEvaluator(
-            "total >= 100.0 ? 0.0 : 7.95", // expression
-            double.class,                  // optionalExpressionType
-            new String[] { "total" },      // parameterNames,
-            new Class[] { double.class },  // parameterTypes
-            new Class[0],                  // thrownExceptions
-            null                           // optionalClassLoader
-        );
-
-        // Evaluate expression with actual parameter values.
-        Object res = ee.evaluate(parameterValues);
-
-        // Print expression result.
-        System.out.println("Result = " + (res == null ? "(null)" : res.toString()));
-    }
-}
diff --git a/src/org/codehaus/janino/samples/package.html b/src/org/codehaus/janino/samples/package.html
deleted file mode 100644
index 90ce689..0000000
--- a/src/org/codehaus/janino/samples/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
-  Sample applications for the Janino Java<sup>TM</sup> compiler.
-</body></html>
diff --git a/src/org/codehaus/janino/tools/Disassembler.java b/src/org/codehaus/janino/tools/Disassembler.java
deleted file mode 100644
index 80d50dc..0000000
--- a/src/org/codehaus/janino/tools/Disassembler.java
+++ /dev/null
@@ -1,1425 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.tools;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * A Java bytecode disassembler, comparable to JAVAP, which is part of
- * Sun's JDK.
- * <p>
- * Notice that this tool does not depend on any other classes or libraries (other than the
- * standard JDK library).
- */
-
-public class Disassembler {
-    private IndentPrintWriter ipw = new IndentPrintWriter(System.out);
-    private boolean           verbose = false;
-    private File              sourceDirectory = new File(".");
-
-    /**
-     * Usage:
-     * <pre>
-     *   java new.janino.tools.Disassembler [ -o <i>output-file</i> ] [ -help ]
-     * </pre>
-     * @param args
-     * @throws IOException
-     */
-    public static void main(String[] args) throws IOException {
-        Disassembler d = new Disassembler();
-        int i;
-        for (i = 0; i < args.length; ++i) {
-            String arg = args[i];
-            if (arg.charAt(0) != '-') break;
-            if (arg.equals("-o")) {
-                d.setOut(new FileOutputStream(args[++i]));
-            } else
-            if (arg.equals("-verbose")) {
-                d.setVerbose(true);
-            } else
-            if (arg.equals("-src")) {
-                d.setSourceDirectory(new File(args[++i]));
-            } else
-            if (arg.equals("-help")) {
-                System.out.println("Usage:  java jexpr.Jdisasm [ -o <output-file> ] [ -verbose ] [ -src <source-dir> ] <class-file> ...");
-                System.exit(0);
-            } else
-            {
-                System.err.println("Unrecognized command line option \"" + arg + "\"; try \"-help\".");
-            }
-        }
-        if (i == args.length) {
-            System.err.println("Class file name missing, try \"-help\".");
-            System.exit(1);
-        }
-        for (; i < args.length; ++i) {
-            d.disasm(new File(args[i]));
-        }
-    }
-
-    public Disassembler() {}
-
-    public void setOut(OutputStream os) {
-        this.ipw = new IndentPrintWriter(os);
-    }
-    public void setVerbose(boolean verbose) {
-        this.verbose = verbose;
-    }
-    public void setSourceDirectory(File sourceDirectory) {
-        this.sourceDirectory = sourceDirectory;
-    }
-
-//    void print(byte b)   { this.ipw.print(b); }
-//    void print(short s)  { this.ipw.print(s); }
-    void print(int i)    { this.ipw.print(i); }
-//    void print(long l)   { this.ipw.print(l); }
-//    void print(float f)  { this.ipw.print(f); }
-//    void print(double d) { this.ipw.print(d); }
-    void print(String s) { this.ipw.print(s); }
-    void println()         { this.ipw.println(); }
-    void println(String s) { this.ipw.println(s); }
-    void indent(String s) {
-        this.ipw.print(s);
-        this.ipw.indent();
-    }
-    void indentln(String s) {
-        this.ipw.println(s);
-        this.ipw.indent();
-    }
-    void unindent(String s) {
-        this.ipw.unindent();
-        this.ipw.print(s);
-    }
-    void unindentln(String s) {
-        this.ipw.unindent();
-        this.ipw.println(s);
-    }
-
-    /**
-     * Disassemble one Java<sup>TM</sup> class file to {@link System#out}.
-     * 
-     * @param file
-     * @throws IOException
-     */
-    public void disasm(File file) throws IOException {
-        InputStream is = new FileInputStream(file);
-        try {
-            disasm(is);
-        } finally {
-            try { is.close(); } catch (IOException ex) {}
-        }
-    }
-
-    public void disasm(InputStream is) throws IOException {
-        this.disasmClassFile(new DataInputStream(is));
-        this.println();
-        this.ipw.flush();
-    }
-
-    private void disasmClassFile(DataInputStream dis) throws IOException {
-        this.indentln("ClassFile {"); {
-            this.println("magic = 0x" + Integer.toHexString(dis.readInt()));
-            this.println("minor_version = " + dis.readShort());
-            this.println("major_version = " + dis.readShort());
-
-            this.constantPool = new ConstantPoolInfo[dis.readShort()];
-            for (short i = 1; i < this.constantPool.length;) {
-                ConstantPoolInfo cpi = readConstantPoolInfo(dis);
-                this.constantPool[i++] = cpi;
-                for (int j = cpi.getSizeInConstantPool(); j > 1; --j) {
-                    this.constantPool[i++] = null;
-                }
-            }
-            this.indentln("constant_pool[] = {"); {
-                for (short i = 1; i < this.constantPool.length;) {
-                    this.print(i + ": ");
-                    ConstantPoolInfo cpi = this.constantPool[i];
-                    cpi.print(); // Must be invoked only after "this.constantPool" is initialized.
-                    this.println();
-                    i += cpi.getSizeInConstantPool();
-                }
-            } this.unindentln("}");
-
-            this.println("access_flags = " + decodeAccess(dis.readShort()));
-
-            short thisClass = dis.readShort();
-            this.indent("this_class = " + thisClass + " ("); {
-                this.printConstantPoolEntry(thisClass);
-            } this.unindentln(")");
-
-            short superClass = dis.readShort();
-            this.indent("super_class = " + superClass + " ("); {
-                this.printConstantPoolEntry(superClass);
-            } this.unindentln(")");
-
-            this.indentln("interfaces[] = {"); {
-                short interfacesCount = dis.readShort();
-                for (short i = 0; i < interfacesCount; ++i) {
-                    this.printConstantPoolEntry(null, dis.readShort());
-                    this.println();
-                }
-            } this.unindentln("}");
-
-            this.indentln("fields[] = {"); {
-                short fieldsCount = dis.readShort();
-                for (short i = 0; i < fieldsCount; ++i) {
-                    disasmFieldInfo(dis);
-                    this.println();
-                }
-            } this.unindentln("}");
-
-            MethodInfo[] methodInfos;
-            {
-                short methodsCount = dis.readShort();
-                methodInfos = new MethodInfo[methodsCount];
-                for (int i = 0; i < methodsCount; ++i) methodInfos[i] = this.readMethodInfo(dis);
-            }
-
-            AttributeInfo[] attributes;
-            {
-                short attributesCount = dis.readShort();
-                attributes = new AttributeInfo[attributesCount];
-                for (short i = 0; i < attributesCount; ++i) attributes[i] = this.readAttributeInfo(dis);
-            }
-
-            Map sourceLines = new HashMap();
-            READ_SOURCE_LINES: {
-                for (int i = 0; i < attributes.length; ++i) {
-                    if (attributes[i] instanceof SourceFileAttribute) {
-                        ConstantPoolInfo cpi = Disassembler.this.getConstantPoolEntry(((SourceFileAttribute) attributes[i]).sourceFileIndex);
-                        if (cpi instanceof ConstantUtf8Info) {
-                            String sourceFile = ((ConstantUtf8Info) cpi).getValue();
-                            LineNumberReader lnr;
-                            try {
-                                lnr = new LineNumberReader(new FileReader(new File(this.sourceDirectory, sourceFile)));
-                            } catch (FileNotFoundException ex) {
-                                ;
-                                break READ_SOURCE_LINES;
-                            }
-                            try {
-                                for (;;) {
-                                    String sl = lnr.readLine();
-                                    if (sl == null) break;
-                                    sourceLines.put(new Integer(lnr.getLineNumber()), sl);
-                                }
-                            } finally {
-                                lnr.close();
-                            }
-                        }
-                    }
-                }
-            }
-
-            this.indentln("methods[] = {"); {
-                for (short i = 0; i < methodInfos.length; ++i) {
-                    methodInfos[i].print(sourceLines);
-                    this.println();
-                }
-            } this.unindentln("}");
-
-            this.indentln("attributes[] = {"); {
-                for (short i = 0; i < attributes.length; ++i) {
-                    attributes[i].print();
-                    this.println();
-                }
-            } this.unindentln("}");
-        } this.unindent("}");
-    }
-
-    private ConstantPoolInfo readConstantPoolInfo(final DataInputStream dis) throws IOException {
-        byte tag = dis.readByte();
-        switch (tag) {
-        case 7:
-            {
-                final short nameIndex = dis.readShort();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.print("CONSTANT_Class_info { ");
-                        Disassembler.this.printConstantPoolEntry("name_index", nameIndex);
-                        Disassembler.this.print(" }");
-                    }
-                };
-            }
-        case 9:
-            {
-                final short classIndex = dis.readShort();
-                final short nameAndTypeIndex = dis.readShort();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.indentln("CONSTANT_Fieldref_info {"); {
-                            Disassembler.this.printConstantPoolEntry("class_index", classIndex);
-                            Disassembler.this.println();
-                            Disassembler.this.printConstantPoolEntry("name_and_type_index", nameAndTypeIndex);
-                            Disassembler.this.println();
-                        } Disassembler.this.unindent("}");
-                    }
-                };
-            }
-        case 10:
-            {
-                final short classIndex = dis.readShort();
-                final short nameAndTypeIndex = dis.readShort();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.indentln("CONSTANT_Methodref_info {"); {
-                            Disassembler.this.printConstantPoolEntry("class_index", classIndex);
-                            Disassembler.this.println();
-                            Disassembler.this.printConstantPoolEntry("name_and_type_index", nameAndTypeIndex);
-                            Disassembler.this.println();
-                        } Disassembler.this.unindent("}");
-                    }
-                };
-            }
-        case 11:
-            {
-                final short classIndex = dis.readShort();
-                final short nameAndTypeIndex = dis.readShort();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.indentln("CONSTANT_InterfaceMethodref_info {"); {
-                            Disassembler.this.printConstantPoolEntry("class_index", classIndex);
-                            Disassembler.this.println();
-                            Disassembler.this.printConstantPoolEntry("name_and_type_index", nameAndTypeIndex);
-                            Disassembler.this.println();
-                        } Disassembler.this.unindent("}");
-                    }
-                };
-            }
-        case 8:
-            {
-                final short stringIndex = dis.readShort();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        ConstantPoolInfo cpi = Disassembler.this.getConstantPoolEntry(stringIndex);
-                        String s;
-                        if (cpi == null) {
-                            s = "INVALID CONSTANT POOL INDEX";
-                        } else
-                        if (!(cpi instanceof ConstantUtf8Info)) {
-                            s = "STRING CONSTANT VALUE IS NOT UTF8";
-                        } else {
-                            s = ((ConstantUtf8Info) cpi).getValue();
-                            if (s.length() > 80) {
-                                s = Disassembler.stringToJavaLiteral(s.substring(0, 80)) + "... (" + s.length() + " chars)"; 
-                            } else {
-                                s = Disassembler.stringToJavaLiteral(s);
-                            }
-                        }
-                        if (Disassembler.this.verbose) {
-                            Disassembler.this.print("CONSTANT_String_info { string_index = " + stringIndex + " (" + s + ") }");
-                        } else {
-                            Disassembler.this.print(s);
-                        }
-                    }
-                };
-            }
-        case 3:
-            {
-                final int bytes = dis.readInt();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.print("CONSTANT_Integer_info { bytes = " + bytes + " }");
-                    }
-                };
-            }
-        case 4:
-            {
-                final float bytes = dis.readFloat();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.print("CONSTANT_Float_info { bytes = " + bytes + " }");
-                    }
-                };
-            }
-        case 5:
-            {
-                final long bytes = dis.readLong();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.print("CONSTANT_Long_info { high_bytes/low_bytes = " + bytes + " }");
-                    }
-                    public int getSizeInConstantPool() { return 2; }
-                };
-            }
-        case 6:
-            {
-                final double bytes = dis.readDouble();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.print("CONSTANT_Double_info { high_bytes/low_bytes = " + bytes + " }");
-                    }
-                    public int getSizeInConstantPool() { return 2; }
-                };
-            }
-        case 12:
-            {
-                final short nameIndex = dis.readShort();
-                final short descriptorIndex = dis.readShort();
-                return new ConstantPoolInfo() {
-                    public void print() {
-                        Disassembler.this.indentln("CONSTANT_NameAndType_info {"); {
-                            Disassembler.this.printConstantPoolEntry("name_index", nameIndex);
-                            Disassembler.this.println();
-                            Disassembler.this.printConstantPoolEntry("descriptor_index", descriptorIndex);
-                            Disassembler.this.println();
-                        } Disassembler.this.unindent("}");
-                    }
-                };
-            }
-        case 1:
-            return new ConstantUtf8Info(dis.readUTF());
-        default:
-            throw new RuntimeException("Invalid cp_info tag \"" + (int) tag + "\"");
-        }
-    }
-
-    private static String stringToJavaLiteral(String s) {
-        for (int i = 0; i < s.length();) {
-            char c = s.charAt(i);
-            int idx = "\r\n\"\t\b".indexOf(c);
-            if (idx == -1) {
-                ++i;
-            } else {
-                s = s.substring(0, i) + '\\' + "rn\"tb".charAt(idx) + s.substring(i + 1);
-                i += 2;
-            }
-            if (i >= 80) break;
-        }
-        return '"' + s + '"';
-    }
-
-    private void disasmFieldInfo(DataInputStream dis) throws IOException {
-        this.indentln("field_info {"); {
-            this.println("access_flags = " + decodeAccess(dis.readShort()));
-
-            this.printConstantPoolEntry("name_index", dis.readShort());
-            this.println();
-
-            this.printConstantPoolEntry("descriptor_index", dis.readShort());
-            this.println();
-
-            this.indentln("attributes[] = {"); {
-                short attributesCount = dis.readShort();
-                for (short i = 0; i < attributesCount; ++i) {
-                    disasmAttributeInfo(dis);
-                    this.println();
-                }
-            } this.unindentln("}");
-        } this.unindent("}");
-    }
-
-    private MethodInfo readMethodInfo(DataInputStream dis) throws IOException {
-        final short accessFlags = dis.readShort();
-        final short nameIndex = dis.readShort();
-        final short descriptorIndex = dis.readShort();
-        final AttributeInfo[] attributeInfos;
-        {
-            short attributesCount = dis.readShort();
-            attributeInfos = new AttributeInfo[attributesCount];
-            for (short i = 0; i < attributesCount; ++i) attributeInfos[i] = this.readAttributeInfo(dis);
-        }
-        return new MethodInfo() {
-            public void print(Map sourceLines) {
-                Disassembler.this.indentln("method_info {"); {
-                    Disassembler.this.println("access_flags = " + decodeAccess(accessFlags));
-        
-                    Disassembler.this.printConstantPoolEntry("name_index", nameIndex);
-                    Disassembler.this.println();
-        
-                    Disassembler.this.printConstantPoolEntry("descriptor_index", descriptorIndex);
-                    Disassembler.this.println();
-        
-                    Disassembler.this.indentln("attributes[] = {"); {
-                        for (short i = 0; i < attributeInfos.length; ++i) {
-                            AttributeInfo ai = attributeInfos[i];
-                            if (ai instanceof SourceRelatedAttributeInfo) {
-                                ((SourceRelatedAttributeInfo) ai).print(sourceLines);
-                            } else {
-                                ai.print();
-                            }
-                            Disassembler.this.println();
-                        }
-                    } Disassembler.this.unindentln("}");
-                } Disassembler.this.unindent("}");
-            }
-        };
-    }
-    private interface MethodInfo {
-        public void print(
-            Map sourceLines // Integer lineNumber => String line
-        );
-    }
-
-    private void disasmAttributeInfo(DataInputStream dis) throws IOException {
-        this.readAttributeInfo(dis).print();
-    }
-
-    private AttributeInfo readAttributeInfo(DataInputStream dis) throws IOException {
-
-        // Determine attribute name.
-        short attributeNameIndex = dis.readShort();
-        String attributeName;
-        {
-            ConstantPoolInfo cpi = Disassembler.this.getConstantPoolEntry(attributeNameIndex);
-            if (cpi == null) {
-                attributeName = "INVALID CONSTANT POOL INDEX";
-            } else
-            if (!(cpi instanceof ConstantUtf8Info)) {
-                attributeName = "ATTRIBUTE NAME IS NOT UTF8";
-            } else {
-                attributeName = ((ConstantUtf8Info) cpi).getValue();
-            }
-        }
-
-        // Read attribute body into byte array and create a DataInputStream.
-        int attributeLength = dis.readInt();
-        final byte[] ba = new byte[attributeLength];
-        if (dis.read(ba) != ba.length) throw new EOFException();
-        ByteArrayInputStream bais = new ByteArrayInputStream(ba);
-        DataInputStream dis2 = new DataInputStream(bais);
-
-        // Parse the attribute body.
-        AttributeInfo res = this.readAttributeBody(attributeName, dis2);
-
-        // Check for extraneous bytes.
-        int av = bais.available();
-        if (av > 0) throw new RuntimeException(av + " extraneous bytes in attribute \"" + attributeName + "\"");
-
-        return res;
-    }
-    private AttributeInfo readAttributeBody(
-        final String          attributeName,
-        final DataInputStream dis
-    ) throws IOException {
-        if (attributeName.equals("ConstantValue")) {
-            final short constantValueIndex = dis.readShort();
-            return new AttributeInfo() {
-                public void print() {
-                    Disassembler.this.indent("ConstantValue " + constantValueIndex + " ("); {
-                        Disassembler.this.printConstantPoolEntry(constantValueIndex);
-                    } Disassembler.this.unindent(")");
-                }
-            };
-        } else
-        if (attributeName.equals("Code")) {
-            final short                 maxStack       = dis.readShort();
-            final short                 maxLocals      = dis.readShort();
-            final byte[]                code           = readByteArray(dis, dis.readInt());
-            final ExceptionTableEntry[] exceptionTable = readExceptionTable(dis);
-            final AttributeInfo[]       attributes     = readAttributes(dis);
-            return new SourceRelatedAttributeInfo() {
-                public void print(Map sourceLines) {
-                    Disassembler.this.indentln("Code {"); {
-                        Disassembler.this.println("max_stack = " + maxStack);
-                        Disassembler.this.println("max_locals = " + maxLocals);
-
-                        Disassembler.this.indentln("code = { "); {
-                            LocalVariableTableAttribute localVariableTableAttribute = null;
-                            LineNumberTableAttribute    lineNumberTableAttribute = null;
-                            for (int i = 0; i < attributes.length; ++i) {
-                                AttributeInfo a = attributes[i];
-                                if (a instanceof LocalVariableTableAttribute) {
-                                    if (localVariableTableAttribute != null) throw new RuntimeException("Duplicate LocalVariableTable attribute");
-                                    localVariableTableAttribute = (LocalVariableTableAttribute) a;
-                                }
-                                if (a instanceof LineNumberTableAttribute) {
-                                    if (lineNumberTableAttribute != null) throw new RuntimeException("Duplicate LineNumberTable attribute");
-                                    lineNumberTableAttribute = (LineNumberTableAttribute) a;
-                                }
-                            }
-                            try {
-                                disasmBytecode(
-                                    new ByteArrayInputStream(code),
-                                    localVariableTableAttribute,
-                                    lineNumberTableAttribute,
-                                    sourceLines
-                                );
-                            } catch (IOException ignored) {
-                                ;
-                            }
-                        } Disassembler.this.unindentln("}");
-
-                        Disassembler.this.indentln("exception_table = {"); {
-                            for (int i = 0; i < exceptionTable.length; ++i) {
-                                exceptionTable[i].print();
-                                Disassembler.this.println();
-                            }
-                        } Disassembler.this.unindentln("}");
-
-                        Disassembler.this.indentln("attributes[] = {"); {
-                            for (int i = 0; i < attributes.length; ++i) {
-                                attributes[i].print();
-                                Disassembler.this.println();
-                            }
-                        } Disassembler.this.unindentln("}");
-                    } Disassembler.this.unindent("}");
-                }
-            };
-        } else
-        if (attributeName.equals("Exceptions")) {
-            final short[] exceptionIndexTable = readShortArray(dis, dis.readShort());
-            return new AttributeInfo() {
-                public void print() {
-                    Disassembler.this.indentln("Exceptions {"); {
-                        Disassembler.this.indentln("exception_index_table = {"); {
-                            for (short i = 0; i < exceptionIndexTable.length; ++i) {
-                                short exceptionIndex = exceptionIndexTable[i];
-                                Disassembler.this.print(exceptionIndex + " (");
-                                Disassembler.this.printConstantPoolEntry(exceptionIndex);
-                                Disassembler.this.println("),");
-                            }
-                        } Disassembler.this.unindentln("}");
-                    } Disassembler.this.unindent("}");
-                }
-            };
-        } else
-        if (attributeName.equals("InnerClasses")) {
-            final short[] data = readShortArray(dis, 4 * dis.readShort());
-            return new AttributeInfo() {
-                public void print() {
-                    Disassembler.this.indentln("InnerClasses {"); {
-                        Disassembler.this.indentln("classes = {"); {
-                            for (int i = 0; i < data.length; i += 4) {
-                                Disassembler.this.indentln("{"); {
-                                    Disassembler.this.printConstantPoolEntry("inner_class_info_index", data[i]);
-                                    Disassembler.this.println();
-    
-                                    short outerClassInfoIndex = data[i + 1];
-                                    if (outerClassInfoIndex == 0) {
-                                        Disassembler.this.print("(not a member)");
-                                    } else {
-                                        Disassembler.this.printConstantPoolEntry("outer_class_info_index", outerClassInfoIndex);
-                                    }
-                                    Disassembler.this.println();
-    
-                                    short innerNameIndex = data[i + 2];
-                                    if (innerNameIndex == 0) {
-                                        Disassembler.this.print("(anonymous)");
-                                    } else {
-                                        Disassembler.this.printConstantPoolEntry("inner_name_index", innerNameIndex);
-                                    }
-                                    Disassembler.this.println();
-    
-                                    Disassembler.this.println("inner_class_access_flags = " + decodeAccess(data[i + 3]));
-                                } Disassembler.this.unindentln(i == data.length - 1 ? "}" : "},");
-                            }
-                        } Disassembler.this.unindentln("}");
-                    } Disassembler.this.unindent("}");
-                }
-            };
-        } else
-        if (attributeName.equals("Synthetic")) {
-            return new AttributeInfo() {
-                public void print() {
-                    Disassembler.this.print("Synthetic");
-                }
-            };
-        } else
-        if (attributeName.equals("SourceFile")) {
-            return new SourceFileAttribute(dis.readShort());
-        } else
-        if (attributeName.equals("LineNumberTable")) {
-            return new LineNumberTableAttribute(readShortArray(dis, 2 * dis.readShort()));
-        } else
-        if (attributeName.equals("LocalVariableTable")) {
-            return new LocalVariableTableAttribute(readShortArray(dis, 5 * dis.readShort()));
-        } else
-        if (attributeName.equals("Deprecated")) {
-            return new AttributeInfo() {
-                public void print() {
-                    Disassembler.this.print("Deprecated");
-                }
-            };
-        } else
-        {
-            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            for (;;) {
-                int c = dis.read();
-                if (c == -1) break;
-                baos.write(c);
-            }
-            return new AttributeInfo() {
-                public void print() {
-                    Disassembler.this.indentln(attributeName + " {"); {
-                        Disassembler.this.print("info = { ");
-                        for (int i = 0; i < this.info.length; ++i) {
-                            Disassembler.this.print("0x" + Integer.toHexString(0xff & this.info[i]) + ", ");
-                        }
-                        Disassembler.this.println("}");
-                    } Disassembler.this.unindent("}");
-                }
-                private byte[] info = baos.toByteArray();
-            };
-        }
-    }
-    private interface AttributeInfo {
-        public void print();
-    }
-    private abstract static class SourceRelatedAttributeInfo implements AttributeInfo {
-        public void print() {
-            throw new UnsupportedOperationException("print");
-        }
-        public abstract void print(Map sourceLines);
-    }
-    private class SourceFileAttribute implements AttributeInfo {
-        final short sourceFileIndex;
-        SourceFileAttribute(short sourceFileIndex) {
-            this.sourceFileIndex = sourceFileIndex;
-        }
-        public void print() {
-            Disassembler.this.indentln("SourceFile {"); {
-                Disassembler.this.printConstantPoolEntry("sourcefile_index", this.sourceFileIndex);
-                Disassembler.this.println();
-            } Disassembler.this.unindent("}");
-        }
-    }
-    public class LineNumberTableAttribute implements AttributeInfo {
-        private final short[] data;
-        public LineNumberTableAttribute(short[] data) {
-            this.data = data;
-        }
-        public void print() {
-            Disassembler.this.indentln("LineNumberTable {"); {
-                Disassembler.this.indentln("line_number_table = {"); {
-                    for (short i = 0; i < this.data.length; i += 2) {
-                        Disassembler.this.print("start_pc = " + this.data[i]);
-                        Disassembler.this.print(", ");
-                        Disassembler.this.println("line_number = " + this.data[i + 1]);
-                    }
-                } Disassembler.this.unindentln("}");
-            } Disassembler.this.unindent("}");
-        }
-        public short findLineNumber(short offset) {
-            for (short i = 0; i < this.data.length; i += 2) {
-                if (this.data[i] == offset) return this.data[i + 1];
-            }
-            return -1;
-        }
-    }
-    private class LocalVariableTableAttribute implements AttributeInfo {
-        public LocalVariableTableAttribute(short[] data) { this.data = data; }
-        public void print() {
-            Disassembler.this.indentln("LocalVariableTable {"); {
-                Disassembler.this.indentln("local_variable_table = {"); {
-                    for (int i = 0; i < this.data.length; i += 5) {
-                        Disassembler.this.print("start_pc = " + this.data[i]);
-                        Disassembler.this.print(", ");
-                        Disassembler.this.print("length = " + this.data[i + 1]);
-                        Disassembler.this.print(", ");
-                        Disassembler.this.printConstantPoolEntry("name_index", this.data[i + 2]);
-                        Disassembler.this.print(", ");
-                        Disassembler.this.printConstantPoolEntry("descriptor_index", this.data[i + 3]);
-                        Disassembler.this.print(", ");
-                        Disassembler.this.println("index = " + this.data[i + 4]);
-                    }
-                } Disassembler.this.unindentln("}");
-            } Disassembler.this.unindent("}");
-        }
-        public String find(short index, int instructionOffset) {
-            for (int i = 0; i < this.data.length; i += 5) {
-                short startPC = this.data[i];
-                short length  = this.data[i + 1];
-                if (
-                    instructionOffset >= startPC &&
-                    instructionOffset <= startPC + length &&
-                    index == this.data[i + 4]
-                ) {
-                    String name       = ((ConstantUtf8Info) Disassembler.this.getConstantPoolEntry(this.data[i + 2])).getValue();
-                    String descriptor = ((ConstantUtf8Info) Disassembler.this.getConstantPoolEntry(this.data[i + 3])).getValue();
-                    return Disassembler.decodeDescriptor(descriptor) + " " + name;
-                }
-            }
-            return "anonymous";
-        }
-        private short[] data;
-    }
-    private static byte[] readByteArray(InputStream is, int size) throws IOException {
-        byte[] res = new byte[size];
-        if (is.read(res) != size) throw new EOFException("EOF in byte array");
-        return res;
-    }
-    private ExceptionTableEntry[] readExceptionTable(DataInputStream dis) throws IOException {
-        ExceptionTableEntry[] res = new ExceptionTableEntry[dis.readShort()];
-        for (short i = 0; i < res.length; ++i) {
-            res[i] = new ExceptionTableEntry(
-                dis.readShort(),
-                dis.readShort(),
-                dis.readShort(),
-                dis.readShort()
-            );
-        }
-        return res;
-    }
-    private class ExceptionTableEntry {
-        ExceptionTableEntry(short startPC, short endPC, short handlerPC, short catchType) {
-            this.startPC   = startPC;
-            this.endPC     = endPC;
-            this.handlerPC = handlerPC;
-            this.catchType = catchType;
-        }
-        public void print() {
-            Disassembler.this.print("start_pc = " + this.startPC + ", end_pc = " + this.endPC + ", handler_pc = " + this.handlerPC + ", catch_type = " + this.catchType + " (");
-            if (this.catchType == 0) {
-                Disassembler.this.print("finally");
-            } else {
-                Disassembler.this.printConstantPoolEntry(this.catchType);
-            }
-            Disassembler.this.print(")");
-        }
-        private short startPC, endPC, handlerPC, catchType;
-    }
-
-    private AttributeInfo[] readAttributes(DataInputStream dis) throws IOException {
-        AttributeInfo[] res = new AttributeInfo[dis.readShort()];
-        for (int i = 0; i < res.length; ++i) {
-            res[i] = Disassembler.this.readAttributeInfo(dis);
-        }
-        return res;
-    }
-
-    private static short[] readShortArray(DataInputStream dis, int size) throws IOException {
-        short[] res = new short[size];
-        for (int i = 0; i < res.length; ++i) res[i] = dis.readShort();
-        return res;
-    }
-
-    private void disasmBytecode(
-        InputStream                 is,
-        LocalVariableTableAttribute localVariableTableAttribute,
-        LineNumberTableAttribute    lineNumberTableAttribute,
-        Map                         sourceLines // Integer lineNumber => String sourceLine
-    ) throws IOException {
-        CountingInputStream cis = new CountingInputStream(is);
-        DataInputStream     dis = new DataInputStream(cis);
-
-        for (;;) {
-            short instructionOffset = (short) cis.getCount();
-
-            int opcode = dis.read();
-            if (opcode == -1) return; // EOF
-
-            if (lineNumberTableAttribute != null) {
-                short lineNumber = lineNumberTableAttribute.findLineNumber(instructionOffset);
-                if (lineNumber != -1) {
-                    String sourceLine = (String) sourceLines.get(new Integer(lineNumber));
-                    if (sourceLine == null) sourceLine = "(Source line not available)";
-                    this.println("            Line " + lineNumber + ": " + sourceLine);
-                }
-            }
-            this.print(instructionOffset + ": ");
-
-            Instruction instruction = opcodeToInstruction[opcode];
-            if (instruction == null) {
-                this.println("??? (invalid opcode \"" + opcode + "\")");
-                continue;
-            }
-            disasmInstruction(instruction, dis, instructionOffset, localVariableTableAttribute);
-            this.println();
-        }
-    }
-    private void disasmInstruction(
-        Instruction                 instruction,
-        DataInputStream             dis,
-        int                         instructionOffset,
-        LocalVariableTableAttribute localVariableTableAttribute
-    ) throws IOException {
-        this.print(instruction.getMnemonic());
-        Operand[] operands = instruction.getOperands();
-        if (operands != null) {
-            for (int i = 0; i < operands.length; ++i) {
-                Operand operand = operands[i];
-                this.print(" ");
-                operand.disasm(dis, instructionOffset, localVariableTableAttribute, this);
-            }
-        }
-    }
-
-    private static final String[] instructions = new String[] {
-        "50  aaload",
-        "83  aastore",
-        "1   aconst_null",
-        "25  aload         localvariablearrayindex1",
-        "42  aload_0       localvariablearrayindex_0",
-        "43  aload_1       localvariablearrayindex_1",
-        "44  aload_2       localvariablearrayindex_2",
-        "45  aload_3       localvariablearrayindex_3",
-        "189 anewarray     constantpoolindex2",
-        "176 areturn",
-        "190 arraylength",
-        "58  astore        localvariablearrayindex1",
-        "75  astore_0      localvariablearrayindex_0",
-        "76  astore_1      localvariablearrayindex_1",
-        "77  astore_2      localvariablearrayindex_2",
-        "78  astore_3      localvariablearrayindex_3",
-        "191 athrow",
-        "51  baload",
-        "84  bastore",
-        "16  bipush        signedbyte",
-        "52  caload",
-        "85  castore",
-        "192 checkcast     constantpoolindex2",
-        "144 d2f",
-        "142 d2i",
-        "143 d2l",
-        "99  dadd",
-        "49  daload",
-        "82  dastore",
-        "152 dcmpg",
-        "151 dcmpl",
-        "14  dconst_0",
-        "15  dconst_1",
-        "111 ddiv",
-        "24  dload         localvariablearrayindex1",
-        "38  dload_0       localvariablearrayindex_0",
-        "39  dload_1       localvariablearrayindex_1",
-        "40  dload_2       localvariablearrayindex_2",
-        "41  dload_3       localvariablearrayindex_3",
-        "107 dmul",
-        "119 dneg",
-        "115 drem",
-        "175 dreturn",
-        "57  dstore        localvariablearrayindex1",
-        "71  dstore_0      localvariablearrayindex_0",
-        "72  dstore_1      localvariablearrayindex_1",
-        "73  dstore_2      localvariablearrayindex_2",
-        "74  dstore_3      localvariablearrayindex_3",
-        "103 dsub",
-        "89  dup",
-        "90  dup_x1",
-        "91  dup_x2",
-        "92  dup2",
-        "93  dup2_x1",
-        "94  dup2_x2",
-        "141 f2d",
-        "139 f2i",
-        "140 f2l",
-        "98  fadd",
-        "48  faload",
-        "81  fastore",
-        "150 fcmpg",
-        "149 fcmpl",
-        "11  fconst_0",
-        "12  fconst_1",
-        "13  fconst_2",
-        "110 fdiv",
-        "23  fload         localvariablearrayindex1",
-        "34  fload_0       localvariablearrayindex_0",
-        "35  fload_1       localvariablearrayindex_1",
-        "36  fload_2       localvariablearrayindex_2",
-        "37  fload_3       localvariablearrayindex_3",
-        "106 fmul",
-        "118 fneg",
-        "114 frem",
-        "174 freturn",
-        "56  fstore        localvariablearrayindex1",
-        "67  fstore_0      localvariablearrayindex_0",
-        "68  fstore_1      localvariablearrayindex_1",
-        "69  fstore_2      localvariablearrayindex_2",
-        "70  fstore_3      localvariablearrayindex_3",
-        "102 fsub",
-        "180 getfield      constantpoolindex2",
-        "178 getstatic     constantpoolindex2",
-        "167 goto          branchoffset2",
-        "200 goto_w        branchoffset4",
-        "145 i2b",
-        "146 i2c",
-        "135 i2d",
-        "134 i2f",
-        "133 i2l",
-        "147 i2s",
-        "96  iadd",
-        "46  iaload",
-        "126 iand",
-        "79  iastore",
-        "2   iconst_m1",
-        "3   iconst_0",
-        "4   iconst_1",
-        "5   iconst_2",
-        "6   iconst_3",
-        "7   iconst_4",
-        "8   iconst_5",
-        "108 idiv",
-        "165 if_acmpeq",
-        "166 if_acmpne",
-        "159 if_icmpeq     branchoffset2",
-        "160 if_icmpne     branchoffset2",
-        "161 if_icmplt     branchoffset2",
-        "162 if_icmpge     branchoffset2",
-        "163 if_icmpgt     branchoffset2",
-        "164 if_icmple     branchoffset2",
-        "153 ifeq          branchoffset2",
-        "154 ifne          branchoffset2",
-        "155 iflt          branchoffset2",
-        "156 ifge          branchoffset2",
-        "157 ifgt          branchoffset2",
-        "158 ifle          branchoffset2",
-        "199 ifnonnull     branchoffset2",
-        "198 ifnull        branchoffset2",
-        "132 iinc          localvariablearrayindex1 signedbyte",
-        "21  iload         localvariablearrayindex1",
-        "26  iload_0       localvariablearrayindex_0",
-        "27  iload_1       localvariablearrayindex_1",
-        "28  iload_2       localvariablearrayindex_2",
-        "29  iload_3       localvariablearrayindex_3",
-        "104 imul",
-        "116 ineg",
-        "193 instanceof      constantpoolindex2",
-        "185 invokeinterface constantpoolindex2 signedbyte signedbyte",
-        "183 invokespecial   constantpoolindex2",
-        "184 invokestatic    constantpoolindex2",
-        "182 invokevirtual   constantpoolindex2",
-        "128 ior",
-        "112 irem",
-        "172 ireturn",
-        "120 ishl",
-        "122 ishr",
-        "54  istore          localvariablearrayindex1",
-        "59  istore_0        localvariablearrayindex_0",
-        "60  istore_1        localvariablearrayindex_1",
-        "61  istore_2        localvariablearrayindex_2",
-        "62  istore_3        localvariablearrayindex_3",
-        "100 isub",
-        "124 iushr",
-        "130 ixor",
-        "168 jsr             branchoffset2",
-        "201 jsr_w           branchoffset4",
-        "138 l2d",
-        "137 l2f",
-        "136 l2i",
-        "97  ladd",
-        "47  laload",
-        "127 land",
-        "80  lastore",
-        "148 lcmp",
-        "9   lconst_0",
-        "10  lconst_1",
-        "18  ldc           constantpoolindex1",
-        "19  ldc_w         constantpoolindex2",
-        "20  ldc2_w        constantpoolindex2",
-        "109 ldiv",
-        "22  lload         localvariablearrayindex1",
-        "30  lload_0       localvariablearrayindex_0",
-        "31  lload_1       localvariablearrayindex_1",
-        "32  lload_2       localvariablearrayindex_2",
-        "33  lload_3       localvariablearrayindex_3",
-        "105 lmul",
-        "117 lneg",
-        "171 lookupswitch  lookupswitch",
-        "129 lor",
-        "113 lrem",
-        "173 lreturn",
-        "121 lshl",
-        "123 lshr",
-        "55  lstore        localvariablearrayindex1",
-        "63  lstore_0      localvariablearrayindex_0",
-        "64  lstore_1      localvariablearrayindex_1",
-        "65  lstore_2      localvariablearrayindex_2",
-        "66  lstore_3      localvariablearrayindex_3",
-        "101 lsub",
-        "125 lushr",
-        "131 lxor",
-        "194 monitorenter",
-        "195 monitorexit",
-        "197 multianewarray constantpoolindex2 unsignedbyte",
-        "187 new           constantpoolindex2",
-        "188 newarray      atype",
-        "0   nop",
-        "87  pop",
-        "88  pop2",
-        "181 putfield      constantpoolindex2",
-        "179 putstatic     constantpoolindex2",
-        "169 ret           localvariablearrayindex1",
-        "177 return",
-        "53  saload",
-        "86  sastore",
-        "17  sipush        signedshort",
-        "95  swap",
-        "170 tableswitch   tableswitch",
-        "196 wide          wide",
-    };
-    private static final String[] wideInstructions = new String[] {
-        "21  iload         localvariablearrayindex2",
-        "23  fload         localvariablearrayindex2",
-        "25  aload         localvariablearrayindex2",
-        "22  lload         localvariablearrayindex2",
-        "24  dload         localvariablearrayindex2",
-        "54  istore        localvariablearrayindex2",
-        "56  fstore        localvariablearrayindex2",
-        "58  astore        localvariablearrayindex2",
-        "55  lstore        localvariablearrayindex2",
-        "57  dstore        localvariablearrayindex2",
-        "169 ret           localvariablearrayindex2",
-        "132 iinc          localvariablearrayindex2 signedshort",
-    };
-    private static final Instruction[] opcodeToInstruction     = new Instruction[256];
-    private static final Instruction[] opcodeToWideInstruction = new Instruction[256];
-    static {
-        compileInstructions(instructions, opcodeToInstruction);
-        compileInstructions(wideInstructions, opcodeToWideInstruction);
-    }
-    private static void compileInstructions(String[] instructions, Instruction[] opcodeToInstruction) {
-        for (int j = 0; j < instructions.length; ++j) {
-            StringTokenizer st = new StringTokenizer(instructions[j]);
-            String os = st.nextToken();
-            int opcode = Integer.parseInt(os);
-            String mnemonic = st.nextToken();
-            Operand[] operands = null;
-            if (st.hasMoreTokens()) {
-                List l = new ArrayList();
-                while (st.hasMoreTokens()) {
-                    String s = st.nextToken();
-                    Operand operand;
-                    if (s.equals("constantpoolindex1")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                short index = (short) (0xff & dis.readByte());
-                                d.printConstantPoolEntry(index);
-                            }
-                        };
-                    } else
-                    if (s.equals("constantpoolindex2")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                d.printConstantPoolEntry(dis.readShort());
-                            }
-                        };
-                    } else
-                    if (s.equals("localvariablearrayindex1")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                short index = dis.readByte();
-                                d.print(index);
-                                if (localVariableTableAttribute != null) {
-                                    d.print(" (" + localVariableTableAttribute.find(index, instructionOffset + 2) + ")");
-                                }
-                            }
-                        };
-                    } else
-                    if (s.equals("localvariablearrayindex2")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                short index = dis.readShort();
-                                d.print(index);
-                                if (localVariableTableAttribute != null) {
-                                    d.print(" (" + localVariableTableAttribute.find(index, instructionOffset + 3) + ")");
-                                }
-                            }
-                        };
-                    } else
-                    if (s.startsWith("localvariablearrayindex_")) {
-                        final short index = Short.parseShort(s.substring(s.length() - 1));
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                if (localVariableTableAttribute != null) {
-                                    d.print("(" + localVariableTableAttribute.find(index, instructionOffset + 1) + ")");
-                                }
-                            }
-                        };
-                    } else
-                    if (s.equals("branchoffset2")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                d.print(instructionOffset + dis.readShort());
-                            }
-                        };
-                    } else
-                    if (s.equals("branchoffset4")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                d.print(instructionOffset + dis.readInt());
-                            }
-                        };
-                    } else
-                    if (s.equals("signedbyte")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                d.print(dis.readByte());
-                            }
-                        };
-                    } else
-                    if (s.equals("unsignedbyte")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                d.print(0xff & dis.readByte());
-                            }
-                        };
-                    } else
-                    if (s.equals("atype")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                byte b = dis.readByte();
-                                d.print(
-                                    b ==  4 ? "BOOLEAN" :
-                                    b ==  5 ? "CHAR" :
-                                    b ==  6 ? "FLOAT" :
-                                    b ==  7 ? "DOUBLE" :
-                                    b ==  8 ? "BYTE" :
-                                    b ==  9 ? "SHORT" :
-                                    b == 10 ? "INT" :
-                                    b == 11 ? "LONG" :
-                                    new Integer(0xff & b).toString()
-                                );
-                            }
-                        };
-                    } else
-                    if (s.equals("signedshort")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                d.print(dis.readShort());
-                            }
-                        };
-                    } else
-                    if (s.equals("tableswitch")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                int npads = 3 - (instructionOffset % 4);
-                                for (int i = 0; i < npads; ++i) if (dis.readByte() != (byte) 0) throw new RuntimeException("Non-zero pad byte in \"tableswitch\"");
-                                d.print("default => " + (instructionOffset + dis.readInt()));
-                                int low = dis.readInt();
-                                int high = dis.readInt();
-                                for (int i = low; i <= high; ++i) {
-                                    int offset = dis.readInt();
-                                    d.print(", " + i + " => " + (instructionOffset + offset));
-                                }
-                            }
-                        };
-                    } else
-                    if (s.equals("lookupswitch")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                int npads = 3 - (instructionOffset % 4);
-                                for (int i = 0; i < npads; ++i) {
-                                    byte b = dis.readByte();
-                                    if (b != (byte) 0) d.print("Padding byte #" + i + " is " + (b & 0xff));
-                                } 
-                                d.print("default => " + (instructionOffset + dis.readInt()));
-                                int npairs = dis.readInt();
-                                for (int i = 0; i < npairs; ++i) {
-                                    int match  = dis.readInt();
-                                    int offset = dis.readInt();
-                                    d.print(", " + match + " => " + (instructionOffset + offset));
-                                }
-                            }
-                        };
-                    } else
-                    if (s.equals("wide")) {
-                        operand = new Operand() {
-                            public void disasm(DataInputStream dis, int instructionOffset, LocalVariableTableAttribute localVariableTableAttribute, Disassembler d) throws IOException {
-                                int subopcode = 0xff & dis.readByte();
-                                Instruction wideInstruction = opcodeToWideInstruction[subopcode];
-                                if (wideInstruction == null) throw new RuntimeException("Invalid opcode " + subopcode + " after opcode WIDE");
-                                d.disasmInstruction(wideInstruction, dis, instructionOffset, localVariableTableAttribute);
-                            }
-                        };
-                    } else
-                    {
-                        throw new RuntimeException("Unknown operand \"" + s + "\"");
-                    }
-                    l.add(operand);
-                }
-                operands = (Operand[]) l.toArray(new Operand[l.size()]);
-            }
-            opcodeToInstruction[opcode] = new Instruction(mnemonic, operands);
-        }
-    }
-
-    private ConstantPoolInfo getConstantPoolEntry(short index) {
-        if ((index & 0xffff) < this.constantPool.length) {
-            return this.constantPool[index & 0xffff];
-        } else {
-            return null;
-        }
-    }
-
-    private void printConstantPoolEntry(short index) {
-        if (this.verbose) this.print(index + " (");
-        if ((index & 0xffff) < this.constantPool.length) {
-            ConstantPoolInfo cpi = this.constantPool[index];
-            if (cpi == null) {
-                this.print("NULL CONSTANT POOL ENTRY");
-            } else {
-                cpi.print();
-            }
-        } else {
-            this.print("CONSTANT POOL INDEX OUT OF RANGE");
-        }
-        if (this.verbose) this.print(")");
-    }
-
-    private void printConstantPoolEntry(String label, short index) {
-        if (this.verbose) {
-            if (label != null) this.print(label + " = ");
-            this.print(index + " (");
-            this.printConstantPoolEntry(index);
-            this.print(")");
-        } else {
-            if (label != null) {
-                if (label.endsWith("_index")) label = label.substring(0, label.length() - 6);
-                this.print(label + " = ");
-            }
-            this.printConstantPoolEntry(index);
-        }
-    }
-
-    private static class Instruction {
-
-        /**
-         * 
-         * @param mnemonic
-         * @param operands <code>null</code> is equivalent to "zero operands"
-         */
-        public Instruction(String mnemonic, Operand[] operands) {
-            this.mnemonic = mnemonic;
-            this.operands = operands;
-        }
-        public String    getMnemonic() { return this.mnemonic; }
-        public Operand[] getOperands() { return this.operands; }
-
-        private final String    mnemonic;
-        private final Operand[] operands;
-    }
-    private interface Operand {
-        void disasm(
-            DataInputStream             dis,
-            int                         instructionOffset,
-            LocalVariableTableAttribute localVariableTableAttribute, Disassembler d
-        ) throws IOException;
-    }
-
-    /**
-     * A variant of {@link PrintWriter} that allows for convenient indentation
-     * of output lines.
-     */
-    private static class IndentPrintWriter extends PrintWriter {
-        public IndentPrintWriter(OutputStream os) { super(os); }
-        public void write(char[] cbuf, int off, int len) {
-            this.handleIndentation();
-            super.write(cbuf, off, len);
-        }
-        public void write(String str, int off, int len) {
-            this.handleIndentation();
-            super.write(str, off, len);
-        }
-        public void println() { super.println(); this.atBOL = true; }
-        public void indent() { ++this.indentation; }
-        public void unindent() { --this.indentation; }
-
-        private void handleIndentation() {
-            if (this.atBOL) {
-                for (int i = 0; i < this.indentation; ++i) {
-                    super.write(INDENTATION_CHARS, 0, INDENTATION_CHARS.length);
-                } 
-                this.atBOL = false;
-            }
-        }
-        private final static char[] INDENTATION_CHARS = new char[] { ' ', ' ' };
-
-        private boolean atBOL = true;
-        private int      indentation = 0;
-    }
-
-    private abstract static class ConstantPoolInfo {
-        public abstract void print();
-        public int           getSizeInConstantPool() { return 1; }
-    }
-    private class ConstantUtf8Info extends ConstantPoolInfo {
-        public ConstantUtf8Info(String value) {
-            this.value = value;
-        }
-        public void print() {
-            Disassembler.this.print(this.value);
-        }
-        public String getValue() { return this.value; }
-        private String value;
-    }
-
-    private ConstantPoolInfo[] constantPool = null;
-
-    private static class CountingInputStream extends InputStream {
-        public CountingInputStream(InputStream is) { this.is = is; }
-        public int read() throws IOException {
-            int res = this.is.read();
-            if (res != -1) ++this.count;
-            return res;
-        }
-        public int read(byte[] b, int off, int len) throws IOException {
-            int res = super.read(b, off, len);
-            if (res != -1) this.count += res;
-            return res;
-        }
-        public long getCount() { return this.count; }
-
-        private InputStream is;
-        private long count = 0L;
-    }
-
-    private static String decodeAccess(short n) {
-        StringBuffer sb = new StringBuffer();
-        if ((n & 0x0007) == 0) { sb.append("package "           );               }
-        if ((n & 0x0007) == 1) { sb.append("public "            ); n &= ~0x0007; }
-        if ((n & 0x0007) == 2) { sb.append("private "           ); n &= ~0x0007; }
-        if ((n & 0x0007) == 4) { sb.append("protected "         ); n &= ~0x0007; }
-        if ((n & 0x0008) != 0) { sb.append("static "            ); n &= ~0x0008; }
-        if ((n & 0x0010) != 0) { sb.append("final "             ); n &= ~0x0010; }
-        if ((n & 0x0020) != 0) { sb.append("super/synchronized "); n &= ~0x0020; }
-        if ((n & 0x0040) != 0) { sb.append("volatile "          ); n &= ~0x0040; }
-        if ((n & 0x0080) != 0) { sb.append("transient "         ); n &= ~0x0080; }
-        if ((n & 0x0100) != 0) { sb.append("native "            ); n &= ~0x0100; }
-        if ((n & 0x0200) != 0) { sb.append("interface "         ); n &= ~0x0200; }
-        if ((n & 0x0400) != 0) { sb.append("abstract "          ); n &= ~0x0400; }
-        if ((n & 0x0800) != 0) { sb.append("strict "            ); n &= ~0x0800; }
-        if (n != 0) sb.append("+ " + n + " ");
-        return sb.substring(0, sb.length() - 1);
-    }
-
-    private static String decodeDescriptor(String d) {
-        int brackets = 0;
-        while (d.charAt(0) == '[') {
-            ++brackets;
-            d = d.substring(1);
-        }
-        if (d.length() == 1) {
-            int idx = "BCDFIJSZ".indexOf(d.charAt(0));
-            if (idx != -1) d = PRIMITIVES[idx];
-        } else
-        if (d.charAt(0) == 'L' && d.charAt(d.length() - 1) == ';') {
-            d = d.substring(1, d.length() - 1);
-        }
-        for (; brackets > 0; --brackets) d += "[]";
-        return d;
-    }
-    private static final String[] PRIMITIVES = { "byte", "char", "double", "float", "int", "long", "short", "boolean" };
-}
diff --git a/src/org/codehaus/janino/tools/HprofScrubber.java b/src/org/codehaus/janino/tools/HprofScrubber.java
deleted file mode 100644
index 6ea4e32..0000000
--- a/src/org/codehaus/janino/tools/HprofScrubber.java
+++ /dev/null
@@ -1,220 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.tools;
-
-import java.io.*;
-import java.text.*;
-import java.util.*;
-
-/**
- * Example for object allocation statistics:
- * 
- *     java -Xrunhprof:heap=sites,monitor=n,cutoff=0,depth=4 MyClass
- */
-public class HprofScrubber {
-    private static class Site {
-        public final int allocatedBytes;
-        public final int allocatedObjects;
-        public final int traceNumber;
-        public final String className;
-        public Site(int allocatedBytes, int allocatedObjects, int traceNumber, String className) {
-            this.allocatedBytes   = allocatedBytes;
-            this.allocatedObjects = allocatedObjects;
-            this.traceNumber      = traceNumber;
-            this.className        = className;
-        }
-    }
-
-    private static class Sample {
-        public final int count;
-        public final int traceNumber;
-        public Sample(int count, int traceNumber) {
-            this.count       = count;
-            this.traceNumber = traceNumber;
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        String fileName = args.length == 0 ? "java.hprof.txt" : args[0];
-
-        BufferedReader br = new BufferedReader(new FileReader(fileName));
-        try {
-            Map traces = new HashMap(); // Integer number => String[] stackFrames
-            List sites = new ArrayList(); // Site
-            List samples = new ArrayList(); // Sample
-
-            String s = br.readLine();
-            while (s != null) {
-                if (s.startsWith("SITES BEGIN")) {
-                    br.readLine();
-                    br.readLine();
-                    for (;;) {
-                        s = br.readLine();
-                        if (s.startsWith("SITES END")) break;
-                        StringTokenizer st = new StringTokenizer(s);
-                        st.nextToken(); // rank
-                        st.nextToken(); // percent self
-                        st.nextToken(); // percent accum
-                        st.nextToken(); // live bytes
-                        st.nextToken(); // live objects
-                        sites.add(new Site(
-                            Integer.parseInt(st.nextToken()), // allocatedBytes
-                            Integer.parseInt(st.nextToken()), // allocatedObjects
-                            Integer.parseInt(st.nextToken()), // traceNumber
-                            st.nextToken()                    // className
-                        ));
-                    }
-                } else
-                if (s.startsWith("TRACE ") && s.endsWith(":")) {
-                    int traceNumber = Integer.parseInt(s.substring(6, s.length() - 1));
-                    List l = new ArrayList();
-                    for (;;) {
-                        s = br.readLine();
-                        if (!s.startsWith("\t")) break;
-                        l.add(s.substring(1));
-                    }
-                    traces.put(
-                        new Integer(traceNumber),
-                        l.toArray(new String[l.size()])
-                    );
-                } else
-                if (s.startsWith("CPU SAMPLES BEGIN")) {
-                    br.readLine();
-                    for (;;) {
-                        s = br.readLine();
-                        if (s.startsWith("CPU SAMPLES END")) break;
-                        StringTokenizer st = new StringTokenizer(s);
-                        st.nextToken(); // rank
-                        st.nextToken(); // percent self
-                        st.nextToken(); // percent accum
-                        int count = Integer.parseInt(st.nextToken());
-                        if (count == 0) continue;
-                        int trace = Integer.parseInt(st.nextToken());
-                        samples.add(new Sample(count, trace));
-                    }
-                } else {
-                    s = br.readLine();
-                }
-            }
-
-            HprofScrubber.dumpSites((Site[]) sites.toArray(new Site[sites.size()]), traces);
-
-            HprofScrubber.dumpSamples((Sample[]) samples.toArray(new Sample[samples.size()]), traces);
-
-        } finally {
-            try { br.close(); } catch (IOException e) {}
-        }
-    }
-
-    private static void dumpSites(Site[] ss, Map traces) {
-        Arrays.sort(ss, new Comparator() {
-            public int compare(Object o1, Object o2) {
-                return ((Site) o2).allocatedBytes - ((Site) o1).allocatedBytes;
-            }
-        });
-    
-        int totalAllocatedBytes = 0, totalAllocatedObjects = 0;
-        for (int i = 0; i < ss.length; ++i) {
-            Site site = ss[i];
-            totalAllocatedBytes += site.allocatedBytes;
-            totalAllocatedObjects += site.allocatedObjects;
-        }
-    
-        System.out.println("          percent          alloc'ed");
-        System.out.println("rank   self  accum      bytes  objects  class name");
-        System.out.println("Total:              " + totalAllocatedBytes + "  " + totalAllocatedObjects);
-    
-        double accumulatedPercentage = 0.0;
-        MessageFormat mf = new MessageFormat("{0,number,00000} {1,number,00.00}% {2,number,00.00}% {3,number,000000000} {4,number,000000000} {5}");
-        for (int i = 0; i < ss.length; ++i) {
-            Site site = ss[i];
-            double selfPercentage = 100.0 * ((double) site.allocatedBytes / (double) totalAllocatedBytes);
-            accumulatedPercentage += selfPercentage;
-    //      System.out.println((i + 1) + "      " + selfPercentage + "% " + accumulatedPercentage + "%    " + site.allocatedBytes + " " + site.allocatedObjects + " "  + site.className);
-            System.out.println(mf.format(
-                new Object[] {
-                    new Integer(i + 1),
-                    new Double(selfPercentage),
-                    new Double(accumulatedPercentage),
-                    new Integer(site.allocatedBytes),
-                    new Integer(site.allocatedObjects),
-                    site.className
-                },
-                new StringBuffer(),
-                new FieldPosition(0)
-            ));
-            String[] stackFrames = (String[]) traces.get(new Integer(site.traceNumber));
-            if (stackFrames != null) {
-                for (int j = 0; j < stackFrames.length; ++j) {
-                    System.out.println("                           " + stackFrames[j]);
-                }
-            }
-        }
-    }
-
-    private static void dumpSamples(Sample[] ss, Map traces) {
-        int totalCount = 0;
-        for (int i = 0; i < ss.length; ++i) totalCount += ss[i].count;
-
-        System.out.println("          percent");
-        System.out.println("rank   self  accum      count");
-        System.out.println("Total:              " + totalCount);
-
-        double accumulatedPercentage = 0.0;
-        MessageFormat mf = new MessageFormat("{0,number,00000} {1,number,00.00}% {2,number,00.00}% {3,number,000000000}");
-        for (int i = 0; i < ss.length; ++i) {
-            Sample sample = ss[i];
-            double selfPercentage = 100.0 * ((double) sample.count / (double) totalCount);
-            accumulatedPercentage += selfPercentage;
-//          System.out.println((i + 1) + "      " + selfPercentage + "% " + accumulatedPercentage + "%    " + site.allocatedBytes + " " + site.allocatedObjects + " "  + site.className);
-            System.out.println(mf.format(
-                new Object[] {
-                    new Integer(i + 1),
-                    new Double(selfPercentage),
-                    new Double(accumulatedPercentage),
-                    new Integer(sample.count)
-                },
-                new StringBuffer(),
-                new FieldPosition(0)
-            ));
-            String[] stackFrames = (String[]) traces.get(new Integer(sample.traceNumber));
-            if (stackFrames != null) {
-                for (int j = 0; j < stackFrames.length; ++j) {
-                    System.out.println("                           " + stackFrames[j]);
-                }
-            }
-        }
-    }
-}
diff --git a/src/org/codehaus/janino/tools/JGrep.java b/src/org/codehaus/janino/tools/JGrep.java
deleted file mode 100644
index d770aa8..0000000
--- a/src/org/codehaus/janino/tools/JGrep.java
+++ /dev/null
@@ -1,692 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.tools;
-
-import java.util.*;
-import java.io.*;
-
-import org.codehaus.janino.*;
-import org.codehaus.janino.Scanner; // Resolve ambiguity with JDK 1.5's "java.util.Scanner".
-import org.codehaus.janino.util.*;
-import org.codehaus.janino.util.enumerator.*;
-import org.codehaus.janino.util.iterator.*;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * Reads a set of compilation units from the file system and searches it for specific
- * Java<sup>TM</sup> constructs, e.g. invocations of a particular method.
- *
- * Usage:
- * <pre>
- * java org.codehaus.janino.JGrep \
- *           [ -dirs <i>directory-name-patterns</i> ] \
- *           [ -files <i>file-name-patterns</i> ] \
- *           { <i>directory-path</i> } \
- *           -method-invocation <i>class.method(arg-types)</i>
- * java org.codehaus.janino.JGrep -help
- * </pre>
- * 
- * If "-dirs" is not given, then all <i>directory-path</i>es are scanned for files.
- * The <i>directory-name-patterns</i> work as described in
- * {@link org.codehaus.janino.util.StringPattern#parseCombinedPattern(String)}.
- * <p>
- * If "-files" is not given, then all files ending in ".java" are read. The
- * <i>file-name-patterns</i> work as described in
- * {@link org.codehaus.janino.util.StringPattern#parseCombinedPattern(String)}.
- */
-public class JGrep {
-    private static final boolean DEBUG = false;
-    private List         parsedCompilationUnits = new ArrayList(); // UnitCompiler
-
-    /**
-     * Command line interface.
-     */
-    public static void main(String[] args) {
-        int idx = 0;
-
-        StringPattern[] directoryNamePatterns = StringPattern.PATTERNS_ALL;
-        StringPattern[] fileNamePatterns = new StringPattern[] { new StringPattern("*.java") };
-        File[]          classPath = new File[] { new File(".") };
-        File[]          optionalExtDirs = null;
-        File[]          optionalBootClassPath = null;
-        String          optionalCharacterEncoding = null;
-        boolean         verbose = false;
-
-        for (; idx < args.length; ++idx) {
-            String arg = args[idx];
-            if (arg.charAt(0) != '-') break;
-            if (arg.equals("-dirs")) {
-                directoryNamePatterns = StringPattern.parseCombinedPattern(args[++idx]);
-            } else
-            if (arg.equals("-files")) {
-                fileNamePatterns = StringPattern.parseCombinedPattern(args[++idx]);
-            } else
-            if (arg.equals("-classpath")) {
-                classPath = PathResourceFinder.parsePath(args[++idx]);
-            } else
-            if (arg.equals("-extdirs")) {
-                optionalExtDirs = PathResourceFinder.parsePath(args[++idx]);
-            } else
-            if (arg.equals("-bootclasspath")) {
-                optionalBootClassPath = PathResourceFinder.parsePath(args[++idx]);
-            } else
-            if (arg.equals("-encoding")) {
-                optionalCharacterEncoding = args[++idx];
-            } else
-            if (arg.equals("-verbose")) {
-                verbose = true;
-            } else
-            if (arg.equals("-help")) {
-                for (int j = 0; j < JGrep.USAGE.length; ++j) System.out.println(JGrep.USAGE[j]);
-                System.exit(1);
-            } else
-            {
-                System.err.println("Unexpected command-line argument \"" + arg + "\", try \"-help\".");
-                System.exit(1);
-                /* NEVER REACHED */ return;
-            }
-        }
-
-        // { directory-path }
-        File[] rootDirectories;
-        {
-            int first = idx;
-            for (; idx < args.length && args[idx].charAt(0) != '-'; ++idx);
-            if (idx == first) {
-                System.err.println("No <directory-path>es given, try \"-help\".");
-                System.exit(1);
-                /* NEVER REACHED */ return;
-            }
-            rootDirectories = new File[idx - first];
-            for (int i = first; i < idx; ++i) rootDirectories[i - first] = new File(args[i]);
-        }
-
-        // Create the JGrep object.
-        final JGrep jGrep = new JGrep(
-            classPath,
-            optionalExtDirs,
-            optionalBootClassPath,
-            optionalCharacterEncoding,
-            verbose
-        );
-
-        List mits = new ArrayList();
-        for (; idx < args.length; ++idx) {
-            String arg = args[idx];
-            if (arg.equals("-method-invocation")) {
-                MethodInvocationTarget mit;
-                try {
-                    mit = JGrep.parseMethodInvocationPattern(args[++idx]);
-                } catch (Exception ex) {
-                    System.err.println("Parsing method invocation pattern \"" + args[idx] + "\": " + ex.getMessage());
-                    System.exit(1);
-                    /* NEVER REACHED */ return;
-                }
-                while (idx < args.length - 1) {
-                    arg = args[idx + 1];
-                    if (arg.startsWith("predicate:")) {
-                        String predicateExpression = arg.substring(10);
-                        try {
-                            mit.predicates.add(ExpressionEvaluator.createFastExpressionEvaluator(
-                                new Scanner(null, new StringReader(predicateExpression)), // expression
-                                JGrep.class.getName() + "PE",                             // className
-                                null,                                                     // optionalExtendedType
-                                MethodInvocationPredicate.class,                          // interfaceToImplement
-                                new String[] { "uc", "invocation", "method" },            // parameterNames
-                                null                                                      // optionalClassLoader
-                            ));
-                        } catch (Exception ex) {
-                            System.err.println("Compiling predicate expression \"" + predicateExpression + "\": " + ex.getMessage());
-                            System.exit(1);
-                            /* NEVER REACHED */ return;
-                        }
-                    } else
-                    if (arg.startsWith("action:")) {
-                        String action = arg.substring(7);
-                        try {
-                            mit.actions.add(Action.getMethodInvocationAction(action));
-                        } catch (Exception ex) {
-                            System.err.println("Compiling method invocation action \"" + action + "\": " + ex.getMessage());
-                            System.exit(1);
-                            /* NEVER REACHED */ return;
-                        }
-                    } else
-                    {
-                        break;
-                    }
-                    ++idx;
-                }
-                mits.add(mit);
-            } else
-            {
-                System.err.println("Unexpected command-line argument \"" + arg + "\", try \"-help\".");
-                System.exit(1);
-                /* NEVER REACHED */ return;
-            }
-        }
-
-        // JGrep the root directories.
-        try {
-            jGrep.jGrep(
-                rootDirectories,
-                directoryNamePatterns,
-                fileNamePatterns,
-                mits                   // methodInvocationTargets
-            );
-        } catch (Exception e) {
-            System.err.println(e.toString());
-            System.exit(1);
-        }
-    }
-
-    private static final class Action extends Enumerator {
-        public static final Action PRINT_LOCATION_AND_MATCH = new Action("print-location-and-match");
-        public static final Action PRINT_LOCATION           = new Action("print-location");
-   
-        private Action(String name) { super(name); }
-        public static Action fromString(String name) throws EnumeratorFormatException {
-            return (Action) Enumerator.fromString(name, Action.class);
-        }
-
-        static MethodInvocationAction getMethodInvocationAction(String action) throws CompileException, Parser.ParseException, Scanner.ScanException {
-            if ("print-location-and-match".equals(action)) {
-                return new MethodInvocationAction() { public void execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) { System.out.println(invocation.getLocation() + ": " + method); } };
-            } else
-            if ("print-location".equals(action)) {
-                return new MethodInvocationAction() { public void execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) { System.out.println(invocation.getLocation()); } };
-            } else
-            {
-                return (MethodInvocationAction) ScriptEvaluator.createFastScriptEvaluator(
-                    action,                                       // script
-                    MethodInvocationAction.class,                 // interfaceToImplement
-                    new String[] { "uc", "invocation", "method" } // parameterNames
-                );
-            }
-        }
-    }
-
-    private static MethodInvocationTarget parseMethodInvocationPattern(String mip) throws Scanner.ScanException, IOException, Parser.ParseException {
-        MethodInvocationTarget mit = new MethodInvocationTarget();
-        Scanner scanner = new Scanner(null, new StringReader(mip));
-        Parser parser = new Parser(scanner);
-
-        for (;;) {
-            String s = JGrep.readIdentifierPattern(parser);
-            if (parser.peekOperator("(")) {
-                mit.methodNamePattern = s;
-                parser.eatToken();
-                List l = new ArrayList();
-                if (!parser.peekOperator(")")) {
-                    for (;;) {
-                        l.add(JGrep.readIdentifierPattern(parser));
-                        if (parser.peekOperator(")")) break;
-                        parser.readOperator(",");
-                    }
-                }
-                mit.optionalArgumentTypeNamePatterns = (String[]) l.toArray(new String[l.size()]);
-                return mit;
-            } else
-            if (parser.peekOperator(".")) {
-                if (mit.optionalClassNamePattern == null) {
-                    mit.optionalClassNamePattern = s;
-                } else
-                {
-                    mit.optionalClassNamePattern += '.' + s;
-                }
-                parser.eatToken();
-            } else
-            if (scanner.peek().isEOF()) {
-                mit.methodNamePattern = s;
-                return mit;
-            }
-        }
-    }
-
-    private static String readIdentifierPattern(Parser p) throws Parser.ParseException, Scanner.ScanException, IOException {
-        StringBuffer sb = new StringBuffer();
-        if (p.peekOperator("*")) {
-            sb.append('*');
-            p.eatToken();
-        } else
-        {
-            sb.append(p.readIdentifier());
-        }
-        for (;;) {
-            if (p.peekOperator("*")) {
-                sb.append('*');
-                p.eatToken();
-            } else
-            if (p.peekIdentifier()) {
-                sb.append(p.readIdentifier());
-            } else
-            {
-                return sb.toString();
-            }
-        }
-    }
-    private static class MethodInvocationTarget {
-        String   optionalClassNamePattern = null;
-        String   methodNamePattern = null;
-        String[] optionalArgumentTypeNamePatterns = null;
-        List     predicates = new ArrayList(); // MethodInvocationPredicate
-        List     actions = new ArrayList(); // MethodInvocationAction
-
-        void apply(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws CompileException {
-            if (this.optionalClassNamePattern != null) {
-                if (!typeMatches(this.optionalClassNamePattern, Descriptor.toClassName(method.getDeclaringIClass().getDescriptor()))) return;
-            }
-            if (!new StringPattern(this.methodNamePattern).matches(method.getName())) return;
-            IClass[] fpts = method.getParameterTypes();
-            if (this.optionalArgumentTypeNamePatterns != null) {
-                String[] atnps = this.optionalArgumentTypeNamePatterns;
-                if (atnps.length != fpts.length) return;
-                for (int i = 0; i < atnps.length; ++i) {
-                    if (!new StringPattern(atnps[i]).matches(Descriptor.toClassName(fpts[i].getDescriptor())));
-                }
-            }
-            for (Iterator it = this.predicates.iterator(); it.hasNext();) {
-                MethodInvocationPredicate mip = (MethodInvocationPredicate) it.next();
-                try {
-                    if (!mip.evaluate(uc, invocation, method)) return;
-                } catch (Exception ex) {
-                    return; // Treat exception as a "false" predicate.
-                }
-            }
-            for (Iterator it = this.actions.iterator(); it.hasNext();) {
-                MethodInvocationAction mia = (MethodInvocationAction) it.next();
-                try {
-                    mia.execute(uc, invocation, method);
-                } catch (Exception ex) {
-                    ; // Ignore action throwing an exception.
-                }
-            }
-        }
-    }
-    public interface MethodInvocationPredicate { boolean evaluate(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws Exception; }
-    public interface MethodInvocationAction { void execute(UnitCompiler uc, Java.Invocation invocation, IClass.IMethod method) throws Exception; }
-
-    static boolean typeMatches(String pattern, String typeName) {
-        return new StringPattern(pattern).matches(
-            pattern.indexOf('.') == -1
-            ? typeName.substring(typeName.lastIndexOf('.') + 1)
-            : typeName
-        );
-    }
-    private static final String[] USAGE = {
-        "To be written.", // TODO
-/*
-        "Usage:",
-        "",
-        "  java org.codehaus.janino.Compiler [ <option> ] ... <source-file> ...",
-        "",
-        "Supported <option>s are:",
-        "  -d <output-dir>           Where to save class files",
-        "  -sourcepath <dirlist>     Where to look for other source files",
-        "  -classpath <dirlist>      Where to look for other class files",
-        "  -extdirs <dirlist>        Where to look for other class files",
-        "  -bootclasspath <dirlist>  Where to look for other class files",
-        "  -encoding <encoding>      Encoding of source files, e.g. \"UTF-8\" or \"ISO-8859-1\"",
-        "  -verbose",
-        "  -g                        Generate all debugging info",
-        "  -g:none                   Generate no debugging info",
-        "  -g:{lines,vars,source}    Generate only some debugging info",
-        "  -warn:<pattern-list>      Issue certain warnings; examples:",
-        "    -warn:*                 Enables all warnings",
-        "    -warn:IASF              Only warn against implicit access to static fields",
-        "    -warn:*-IASF            Enables all warnings, except those against implicit",
-        "                            access to static fields",
-        "    -warn:*-IA*+IASF        Enables all warnings, except those against implicit",
-        "                            accesses, but do warn against implicit access to",
-        "                            static fields",
-        "  -rebuild                  Compile all source files, even if the class files",
-        "                            seems up-to-date",
-        "  -help",
-        "",
-        "The default encoding in this environment is \"" + new InputStreamReader(new ByteArrayInputStream(new byte[0])).getEncoding() + "\".",
-*/
-    };
-
-    private /*final*/ IClassLoader iClassLoader;
-    private /*final*/ String       optionalCharacterEncoding;
-    private /*final*/ Benchmark    benchmark;
-
-    public JGrep(
-        File[]  classPath,
-        File[]  optionalExtDirs,
-        File[]  optionalBootClassPath,
-        String  optionalCharacterEncoding,
-        boolean verbose
-    ) {
-        this(
-            JGrep.createJavacLikePathIClassLoader( // iClassLoader
-                optionalBootClassPath,
-                optionalExtDirs,
-                classPath
-            ),
-            optionalCharacterEncoding,             // optionalCharacterEncoding
-            verbose                                // verbose
-        );
-
-        this.benchmark.report("*** JGrep - search Java(TM) source files for specific language constructs");
-        this.benchmark.report("*** For more information visit http://janino.codehaus.org");
-        this.benchmark.report("Class path",         classPath                );
-        this.benchmark.report("Ext dirs",           optionalExtDirs          );
-        this.benchmark.report("Boot class path",    optionalBootClassPath    );
-        this.benchmark.report("Character encoding", optionalCharacterEncoding);
-    }
-
-    public JGrep(
-        IClassLoader iClassLoader,
-        final String optionalCharacterEncoding,
-        boolean      verbose
-    ) {
-        this.iClassLoader              = new JGrepIClassLoader(iClassLoader);
-        this.optionalCharacterEncoding = optionalCharacterEncoding;
-        this.benchmark                 = new Benchmark(verbose);
-    }
-
-    /**
-     * Create an {@link IClassLoader} that looks for classes in the given "boot class
-     * path", then in the given "extension directories", and then in the given
-     * "class path".
-     * <p>
-     * The default for the <code>optionalBootClassPath</code> is the path defined in
-     * the system property "sun.boot.class.path", and the default for the
-     * <code>optionalExtensionDirs</code> is the path defined in the "java.ext.dirs"
-     * system property.
-     */
-    private static IClassLoader createJavacLikePathIClassLoader(
-        final File[] optionalBootClassPath,
-        final File[] optionalExtDirs,
-        final File[] classPath
-    ) {
-        ResourceFinder bootClassPathResourceFinder = new PathResourceFinder(
-            optionalBootClassPath == null ?
-            PathResourceFinder.parsePath(System.getProperty("sun.boot.class.path")):
-            optionalBootClassPath
-        );
-        ResourceFinder extensionDirectoriesResourceFinder = new JarDirectoriesResourceFinder(
-            optionalExtDirs == null ?
-            PathResourceFinder.parsePath(System.getProperty("java.ext.dirs")):
-            optionalExtDirs
-        );
-        ResourceFinder classPathResourceFinder = new PathResourceFinder(classPath);
-
-        // We can load classes through "ResourceFinderIClassLoader"s, which means
-        // they are read into "ClassFile" objects, or we can load classes through
-        // "ClassLoaderIClassLoader"s, which means they are loaded into the JVM.
-        //
-        // In my environment, the latter is slightly faster. No figures about
-        // resource usage yet.
-        //
-        // In applications where the generated classes are not loaded into the
-        // same JVM instance, we should avoid to use the
-        // ClassLoaderIClassLoader, because that assumes that final fields have
-        // a constant value, even if not compile-time-constant but only
-        // initialization-time constant. The classical example is
-        // "File.separator", which is non-blank final, but not compile-time-
-        // constant.
-        if (true) {
-            IClassLoader icl;
-            icl = new ResourceFinderIClassLoader(bootClassPathResourceFinder, null);
-            icl = new ResourceFinderIClassLoader(extensionDirectoriesResourceFinder, icl);
-            icl = new ResourceFinderIClassLoader(classPathResourceFinder, icl);
-            return icl;
-        } else {
-            ClassLoader cl;
-
-            cl = SimpleCompiler.BOOT_CLASS_LOADER;
-            cl = new ResourceFinderClassLoader(bootClassPathResourceFinder, cl);
-            cl = new ResourceFinderClassLoader(extensionDirectoriesResourceFinder, cl);
-            cl = new ResourceFinderClassLoader(classPathResourceFinder, cl);
-
-            return new ClassLoaderIClassLoader(cl);
-        }
-    }
-
-    public void jGrep(
-        File[]                rootDirectories,
-        final StringPattern[] directoryNamePatterns,
-        final StringPattern[] fileNamePatterns,
-        List                  methodInvocationTargets // MethodInvocationTarget
-    ) throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
-        this.benchmark.report("Root dirs",               rootDirectories                );
-        this.benchmark.report("Directory name patterns", directoryNamePatterns          );
-        this.benchmark.report("File name patterns",      fileNamePatterns);
-
-        this.jGrep(DirectoryIterator.traverseDirectories(
-            rootDirectories,              // rootDirectories
-            new FilenameFilter() {        // directoryNameFilter
-                public boolean accept(File dir, String name) {
-                    return StringPattern.matches(directoryNamePatterns, name);
-                }
-            },
-            new FilenameFilter() {        // fileNameFilter
-                public boolean accept(File dir, String name) {
-                    return StringPattern.matches(fileNamePatterns, name);
-                }
-            }
-        ), methodInvocationTargets);
-    }
-
-    public void jGrep(Iterator sourceFilesIterator, final List methodInvocationTargets)
-    throws Scanner.ScanException, Parser.ParseException, CompileException, IOException {
-
-        // Parse the given source files.
-        this.benchmark.beginReporting();
-        int sourceFileCount = 0;
-        try {
-
-            // Parse all source files.
-            while (sourceFilesIterator.hasNext()) {
-                File sourceFile = (File) sourceFilesIterator.next();
-                UnitCompiler uc = new UnitCompiler(this.parseCompilationUnit(
-                    sourceFile,                    // sourceFile
-                    this.optionalCharacterEncoding // optionalCharacterEncoding
-                ), this.iClassLoader);
-                this.parsedCompilationUnits.add(uc);
-                ++sourceFileCount;
-            }
-        } finally {
-            this.benchmark.endReporting("Parsed " + sourceFileCount + " source file(s)");
-        }
-
-        // Traverse the parsed compilation units.
-        this.benchmark.beginReporting();
-        try {
-            for (Iterator it = this.parsedCompilationUnits.iterator(); it.hasNext();) {
-                final UnitCompiler uc = (UnitCompiler) it.next();
-                this.benchmark.beginReporting("Grepping \"" + uc.compilationUnit.optionalFileName + "\"");
-                class UCE extends RuntimeException { final CompileException ce; UCE(CompileException ce) { this.ce = ce; } }
-                try {
-                    new Traverser() {
-    
-                        // "method(...)", "x.method(...)"
-                        public void traverseMethodInvocation(Java.MethodInvocation mi) {
-                            try {
-                                this.match(mi, uc.findIMethod(mi));
-                            } catch (CompileException ex) {
-                                throw new UCE(ex);
-                            }
-                            super.traverseMethodInvocation(mi);
-                        }
-    
-                        // "super.method(...)"
-                        public void traverseSuperclassMethodInvocation(Java.SuperclassMethodInvocation scmi) {
-                            try {
-                                this.match(scmi, uc.findIMethod(scmi));
-                            } catch (CompileException ex) {
-                                throw new UCE(ex);
-                            }
-                            super.traverseSuperclassMethodInvocation(scmi);
-                        }
-                            
-                        // new Xyz(...)
-                        public void traverseNewClassInstance(Java.NewClassInstance nci) {
-    //                        System.out.println(nci.getLocation() + ": " + nci);
-                            super.traverseNewClassInstance(nci);
-                        }
-    
-                        // new Xyz(...) {}
-                        public void traverseNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
-    //                        System.out.println(naci.getLocation() + ": " + naci);
-                            super.traverseNewAnonymousClassInstance(naci);
-                        }
-    
-                        // Explicit constructor invocation ("this(...)", "super(...)").
-                        public void traverseConstructorInvocation(Java.ConstructorInvocation ci) {
-    //                        System.out.println(ci.getLocation() + ": " + ci);
-                            super.traverseConstructorInvocation(ci);
-                        }
-
-                        private void match(Java.Invocation invocation, IClass.IMethod method) throws CompileException {
-                            for (Iterator it2 = methodInvocationTargets.iterator(); it2.hasNext();) {
-                                MethodInvocationTarget mit = (MethodInvocationTarget) it2.next();
-                                mit.apply(uc, invocation, method);
-                            }
-                        }
-                    }.traverseCompilationUnit(uc.compilationUnit);
-                } catch (UCE uce) {
-                    throw uce.ce;
-                } finally {
-                    this.benchmark.endReporting();
-                }
-            }
-        } finally {
-            this.benchmark.endReporting("Traversed " + sourceFileCount + " compilation units");
-        }
-    }
-
-    /**
-     * Read one compilation unit from a file and parse it.
-     * <p>
-     * The <code>inputStream</code> is closed before the method returns.
-     * @return the parsed compilation unit
-     */
-    private Java.CompilationUnit parseCompilationUnit(
-        File   sourceFile,
-        String optionalCharacterEncoding
-    ) throws Scanner.ScanException, Parser.ParseException, IOException {
-        InputStream is = new BufferedInputStream(new FileInputStream(sourceFile));
-        try {
-            Parser parser = new Parser(new Scanner(sourceFile.getPath(), is, optionalCharacterEncoding));
-
-            this.benchmark.beginReporting("Parsing \"" + sourceFile + "\"");
-            try {
-                return parser.parseCompilationUnit();
-            } finally {
-                this.benchmark.endReporting();
-            }
-        } finally {
-            try { is.close(); } catch (IOException ex) {}
-        }
-    }
-
-    /**
-     * Construct the name of a file that could store the byte code of the class with the given
-     * name.
-     * <p>
-     * If <code>optionalDestinationDirectory</code> is non-null, the returned path is the
-     * <code>optionalDestinationDirectory</code> plus the package of the class (with dots replaced
-     * with file separators) plus the class name plus ".class". Example:
-     * "destdir/pkg1/pkg2/Outer$Inner.class"
-     * <p>
-     * If <code>optionalDestinationDirectory</code> is null, the returned path is the
-     * directory of the <code>sourceFile</code> plus the class name plus ".class". Example:
-     * "srcdir/Outer$Inner.class"
-     * @param className E.g. "pkg1.pkg2.Outer$Inner"
-     * @param sourceFile E.g. "srcdir/Outer.java"
-     * @param optionalDestinationDirectory E.g. "destdir"
-     */
-    public static File getClassFile(String className, File sourceFile, File optionalDestinationDirectory) {
-        if (optionalDestinationDirectory != null) {
-            return new File(optionalDestinationDirectory, ClassFile.getClassFileResourceName(className));
-        } else {
-            int idx = className.lastIndexOf('.');
-            return new File(sourceFile.getParentFile(), ClassFile.getClassFileResourceName(className.substring(idx + 1)));
-        }
-    }
-
-    /**
-     * A specialized {@link IClassLoader} that loads {@link IClass}es from the following
-     * sources:
-     * <ol>
-     *   <li>An already-parsed compilation unit
-     *   <li>A class file in the output directory (if existant and younger than source file)
-     *   <li>A source file in any of the source path directories
-     *   <li>The parent class loader
-     * </ol>
-     * Notice that the {@link JGrepIClassLoader} is an inner class of {@link JGrep} and
-     * heavily uses {@link JGrep}'s members.
-     */
-    private class JGrepIClassLoader extends IClassLoader {
-
-        /**
-         * @param optionalParentIClassLoader {@link IClassLoader} through which {@link IClass}es are to be loaded
-         */
-        public JGrepIClassLoader(IClassLoader optionalParentIClassLoader) {
-            super(optionalParentIClassLoader);
-            super.postConstruct();
-        }
-
-        /**
-         * @param type field descriptor of the {@IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
-         */
-        protected IClass findIClass(final String type) {
-            if (JGrep.DEBUG) System.out.println("type = " + type);
-
-            // Class type.
-            String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
-            if (JGrep.DEBUG) System.out.println("2 className = \"" + className + "\"");
-
-            // Do not attempt to load classes from package "java".
-            if (className.startsWith("java.")) return null;
-
-            // Check the already-parsed compilation units.
-            for (int i = 0; i < JGrep.this.parsedCompilationUnits.size(); ++i) {
-                UnitCompiler uc = (UnitCompiler) JGrep.this.parsedCompilationUnits.get(i);
-                IClass res = uc.findClass(className);
-                if (res != null) {
-                    this.defineIClass(res);
-                    return res;
-                } 
-            }
-            return null;
-        }
-    }
-}
-
-
diff --git a/src/org/codehaus/janino/tools/package.html b/src/org/codehaus/janino/tools/package.html
deleted file mode 100644
index 22b7a62..0000000
--- a/src/org/codehaus/janino/tools/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
-  Auxiliary command line tools related to JANINO.
-</body></html>
diff --git a/src/org/codehaus/janino/util/AutoIndentWriter.java b/src/org/codehaus/janino/util/AutoIndentWriter.java
deleted file mode 100644
index 393b6d2..0000000
--- a/src/org/codehaus/janino/util/AutoIndentWriter.java
+++ /dev/null
@@ -1,92 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import java.io.*;
-
-/**
- * A {@link java.io.FilterWriter} that automatically indents lines by looking at
- * trailing opening braces ('{') and leading closing braces ('}').
- */
-public class AutoIndentWriter extends FilterWriter {
-    private static final String LINE_SEPARATOR = System.getProperty("line.separator");
-    private int                 previousChar = -1;
-    private int                 indentation = 0;
-    private String              prefix = null;
-
-    public AutoIndentWriter(Writer out) {
-        super(out);
-    }
-
-    public void write(int c) throws IOException {
-        if (AutoIndentWriter.isLineSeparatorChar(c)) {
-            if (this.previousChar == '{') this.indent();
-        } else
-        if (AutoIndentWriter.isLineSeparatorChar(this.previousChar)) {
-            if (c == '}') this.unindent();
-            for (int i = 0; i < this.indentation; ++i) this.out.write("    ");
-            if (this.prefix != null) this.out.write(this.prefix);
-        }
-        super.write(c);
-        this.previousChar = c;
-    }
-
-    public void unindent() {
-        --this.indentation;
-    }
-
-    public void indent() {
-        ++this.indentation;
-    }
-
-    /**
-     * The prefix, if non-null, is printed between the indentation space and
-     * the line data.
-     */
-    public void setPrefix(String prefix) {
-        this.prefix = prefix;
-    }
-
-    public void write(char[] cbuf, int off, int len) throws IOException {
-        for (; len > 0; --len) this.write(cbuf[off++]);
-    }
-    public void write(String str, int off, int len) throws IOException {
-        for (; len > 0; --len) this.write(str.charAt(off++));
-    }
-
-    private static boolean isLineSeparatorChar(int c) {
-        return AutoIndentWriter.LINE_SEPARATOR.indexOf(c) != -1;
-    }
-}
diff --git a/src/org/codehaus/janino/util/Benchmark.java b/src/org/codehaus/janino/util/Benchmark.java
deleted file mode 100644
index a7fb7d8..0000000
--- a/src/org/codehaus/janino/util/Benchmark.java
+++ /dev/null
@@ -1,220 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import java.util.*;
-
-/**
- * Implements a scheme for benchmarking, i.e. for determining and/or reporting the time elapsed
- * between the beginning and the end of an activity.
- * <p>
- * The measurement is done by invoking {@link #begin()} and later calling {@link #end()} whichs
- * returns the time elapsed since the call to {@link #begin()}.
- * <p>
- * Notice that calls to {@link #begin()} and {@link #end()} can be nested, and each call to
- * {@link #end()} refers to the matching {@link #begin()} call. To ensure that all calls match,
- * the preferred way to write a benchmark is
- * <pre>
- * ...
- * Benchmark b = new Benchmark();
- * ...
- * b.begin();
- * try {
- *     ....
- * } finally {
- *     long ms = b.end();
- * }
- * </pre>
- * This code layout also makes it visually easy to write correct pairs of {@link #begin()} /
- * {@link #end()} pairs.
- * <p>
- * The pair {@link #beginReporting()} and {@link #endReporting()} do basically the same, but
- * report the benchmarking information through an internal {@link Reporter} object. The default
- * {@link Reporter} prints its messages by <code>System.out.println()</code>.
- * <p>
- * Reporting is only enabled if the Benchmark object was created through {@link #Benchmark(boolean)}
- * with a <code>true</code> argument.
- */
-public class Benchmark {
-    private final Stack beginTimes = new Stack(); // Long
-
-    public Benchmark() {
-        this.reportingEnabled = false;
-        this.reporter         = null;
-    }
-
-    /**
-     * @see Benchmark
-     */
-    public void begin() {
-        this.beginTimes.push(new Long(System.currentTimeMillis()));
-    }
-
-    /**
-     * @see Benchmark
-     */
-    public long end() {
-        return System.currentTimeMillis() - ((Long) this.beginTimes.pop()).longValue();
-    }
-
-    // Reporting-related methods and fields.
-
-    /**
-     * Set up a {@link Benchmark} with a default {@link Reporter} that reports to
-     * <code>System.out</code>.
-     */
-    public Benchmark(boolean reportingEnabled) {
-        this.reportingEnabled = reportingEnabled;
-        this.reporter         = new Reporter() {
-            public void report(String message) { System.out.println(message); }
-        };
-    }
-
-    /**
-     * Set up a {@link Benchmark} with a custom {@link Reporter}.
-     */
-    public Benchmark(
-        boolean reportingEnabled,
-        Reporter reporter
-    ) {
-        this.reportingEnabled = reportingEnabled;
-        this.reporter         = reporter;
-    }
-
-    private final boolean  reportingEnabled;
-    private final Reporter reporter;
-
-    /**
-     * Interface used to report messages.
-     */
-    public interface Reporter {
-        void report(String message);
-    }
-
-    /**
-     * Begin a benchmark (see {@link #begin()}) and report the fact.
-     */
-    public void beginReporting() {
-        if (!this.reportingEnabled) return;
-
-        this.reportIndented("Beginning...");
-        this.begin();
-    }
-
-    /**
-     * Begin a benchmark (see {@link #begin()}) and report the fact.
-     */
-    public void beginReporting(String message) {
-        if (!this.reportingEnabled) return;
-        this.reportIndented(message + "...");
-        this.begin();
-    }
-
-    /**
-     * End a benchmark (see {@link #end()}) and report the fact.
-     */
-    public void endReporting() {
-        if (!this.reportingEnabled) return;
-        this.reportIndented("... took " + this.end() + " ms");
-    }
-
-    /**
-     * End a benchmark (see {@link #begin()}) and report the fact.
-     */
-    public void endReporting(String message) {
-        if (!this.reportingEnabled) return;
-        this.reportIndented("... took " + this.end() + " ms: " + message);
-    }
-
-    /**
-     * Report the given message.
-     */
-    public void report(String message) {
-        if (!this.reportingEnabled) return;
-        this.reportIndented(message);
-    }
-
-    /**
-     * Report the <code>title</code>, a colon, a space, and the pretty-printed
-     * {@link Object}.
-     * @param optionalTitle
-     * @param o
-     */
-    public void report(String optionalTitle, Object o) {
-        if (!this.reportingEnabled) return;
-
-        String prefix = optionalTitle == null ? "" : (
-            optionalTitle
-            + ": "
-            + (optionalTitle.length() < Benchmark.PAD.length() ? Benchmark.PAD.substring(optionalTitle.length()) : "") 
-        );
-
-        if (o == null) {
-            this.reportIndented(prefix + "(undefined)");
-        } else
-        if (o.getClass().isArray()) {
-            Object[] oa = (Object[]) o;
-            if (oa.length == 0) {
-                this.reportIndented(prefix + "(empty)");
-            } else
-            if (oa.length == 1) {
-                this.reportIndented(prefix + oa[0].toString());
-            } else {
-                this.reportIndented(optionalTitle == null ? "Array:" : optionalTitle + ':');
-                this.begin();
-                try {
-                    for (int i = 0; i < oa.length; ++i) this.report(null, oa[i]);
-                } finally {
-                    this.end();
-                }
-            }
-        } else
-        {
-            this.reportIndented(prefix + o.toString());
-        }
-    }
-    private static final String PAD = "                       ";
-
-    /**
-     * Report a message through {@link #reporter}, indent by N spaces where N is the current
-     * benchmark stack depth.
-     */
-    private void reportIndented(String message) {
-        StringBuffer sb = new StringBuffer();
-        for (int i = this.beginTimes.size(); i > 0; --i) sb.append("  ");
-        sb.append(message);
-        this.reporter.report(sb.toString());
-    }
-}
diff --git a/src/org/codehaus/janino/util/CausedException.java b/src/org/codehaus/janino/util/CausedException.java
deleted file mode 100644
index efe4249..0000000
--- a/src/org/codehaus/janino/util/CausedException.java
+++ /dev/null
@@ -1,107 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import java.io.*;
-import java.lang.reflect.*;
-
-/**
- * For compatibility with pre-1.4 JDKs, this class mimics 
- */
-public class CausedException extends Exception {
-    private Throwable     optionalCause = null;
-    private static Method INIT_CAUSE; // Null for pre-1.4 JDKs.
-    static {
-        try {
-            CausedException.INIT_CAUSE = Exception.class.getDeclaredMethod("initCause", new Class[] { Throwable.class });
-        } catch (NoSuchMethodException e) {
-            CausedException.INIT_CAUSE = null;
-        }
-    }
-
-    public CausedException() {
-    }
-
-    public CausedException(String message) {
-        super(message);
-    }
-
-    public CausedException(String message, Throwable optionalCause) {
-        super(message);
-        this.initCause(optionalCause);
-    }
-
-    public CausedException(Throwable optionalCause) {
-        super(optionalCause == null ? null : optionalCause.getMessage());
-        this.initCause(optionalCause);
-    }
-
-    public Throwable initCause(Throwable optionalCause) {
-        if (CausedException.INIT_CAUSE == null) {
-            this.optionalCause = optionalCause;
-        } else
-        {
-            try {
-                CausedException.INIT_CAUSE.invoke(this, new Object[] { optionalCause});
-            } catch (IllegalArgumentException e) {
-                throw new RuntimeException("Calling \"initCause()\"");
-            } catch (IllegalAccessException e) {
-                throw new RuntimeException("Calling \"initCause()\"");
-            } catch (InvocationTargetException e) {
-                throw new RuntimeException("Calling \"initCause()\"");
-            }
-        }
-        return this;
-    }
-
-    public Throwable getCause() {
-        return this.optionalCause;
-    }
-
-    public void printStackTrace(PrintStream ps) {
-        super.printStackTrace(ps);
-        if (this.optionalCause == null) return;
-
-        ps.print("Caused by: ");
-        this.optionalCause.printStackTrace(ps);
-    }
-    public void printStackTrace(PrintWriter pw) {
-        super.printStackTrace(pw);
-        if (this.optionalCause == null) return;
-
-        pw.print("Caused by: ");
-        this.optionalCause.printStackTrace(pw);
-    }
-}
diff --git a/src/org/codehaus/janino/util/ClassFile.java b/src/org/codehaus/janino/util/ClassFile.java
deleted file mode 100644
index f3910fe..0000000
--- a/src/org/codehaus/janino/util/ClassFile.java
+++ /dev/null
@@ -1,1514 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import java.io.*;
-import java.util.*;
-
-import org.codehaus.janino.Descriptor;
-
-
-/**
- * An object that represents the Java<sup>TM</sup> "class file" format.
- * <p>
- * {@link #ClassFile(InputStream)} creates a {@link ClassFile} object from the bytecode
- * read from the given {@link InputStream}.
- * <p>
- * {@link #store(OutputStream)} generates Java<sup>TM</sup> bytecode
- * which is suitable for being processed by a Java<sup>TM</sup> virtual
- * machine.
- */
-public class ClassFile {
-
-    /**
-     * Construct from parsed components.
-     * @param accessFlags as defined by {@link org.codehaus.janino.Mod}
-     * @param thisClassFD the field descriptor for this class
-     * @param superclassFD the field descriptor for the extended class (e.g. "Ljava/lang/Object;")
-     * @param interfaceFDs the field descriptors for the implemented interfaces
-     */
-    public ClassFile(
-        short    accessFlags,
-        String   thisClassFD,
-        String   superclassFD,
-        String[] interfaceFDs
-    ) {
-        this.majorVersion  = ClassFile.MAJOR_VERSION_JDK_1_1;
-        this.minorVersion  = ClassFile.MINOR_VERSION_JDK_1_1;
-
-        this.constantPool  = new ArrayList();
-        this.constantPool.add(null); // Add fake "0" index entry.
-        this.constantPoolMap = new HashMap();
-
-        this.accessFlags   = accessFlags;
-        this.thisClass     = this.addConstantClassInfo(thisClassFD);
-        this.superclass    = this.addConstantClassInfo(superclassFD);
-        this.interfaces    = new short[interfaceFDs.length];
-        for (int i = 0; i < interfaceFDs.length; ++i) {
-            this.interfaces[i] = this.addConstantClassInfo(interfaceFDs[i]);
-        }
-
-        this.fieldInfos    = new ArrayList();
-        this.methodInfos   = new ArrayList();
-        this.attributes    = new ArrayList();
-    }
-
-    /**
-     * Adds a "SourceFile" attribute to this class file. (Does not check whether one exists already.)
-     * @param sourceFileName
-     */
-    public void addSourceFileAttribute(String sourceFileName) {
-        this.attributes.add(new SourceFileAttribute(
-            this.addConstantUtf8Info("SourceFile"),  // attributeNameIndex
-            this.addConstantUtf8Info(sourceFileName) // sourceFileIndex
-        ));
-    }
-
-    public void addDeprecatedAttribute() {
-        this.attributes.add(new DeprecatedAttribute(this.addConstantUtf8Info("Deprecated")));
-    }
-
-    /**
-     * Find the "InnerClasses" attribute of this class file
-     * @return <code>null</code> if this class has no "InnerClasses" attribute
-     */
-    public InnerClassesAttribute getInnerClassesAttribute() {
-        Short ni = (Short) this.constantPoolMap.get(new ConstantUtf8Info("InnerClasses"));
-        if (ni == null) return null;
-
-        for (Iterator it = this.attributes.iterator(); it.hasNext();) {
-            AttributeInfo ai = (AttributeInfo) it.next();
-            if (ai.nameIndex == ni.shortValue() && ai instanceof InnerClassesAttribute) return (InnerClassesAttribute) ai;
-        }
-        return null;
-    }
-
-    /**
-     * Create an "InnerClasses" attribute if it does not exist, then add the given entry
-     * to the "InnerClasses" attribute.
-     * @param e
-     */
-    public void addInnerClassesAttributeEntry(InnerClassesAttribute.Entry e) {
-        InnerClassesAttribute ica = this.getInnerClassesAttribute();
-        if (ica == null) {
-            ica = new InnerClassesAttribute(this.addConstantUtf8Info("InnerClasses"));
-            this.attributes.add(ica);
-        }
-        ica.getEntries().add(e);
-        return;
-    }
-
-    /**
-     * Read "class file" data from a {@link InputStream} and construct a
-     * {@link ClassFile} object from it.
-     * <p>
-     * If the {@link ClassFile} is created with this constructor, then most modifying operations
-     * lead to a {@link UnsupportedOperationException}; only fields, methods and
-     * attributes can be added. 
-     * @param inputStream
-     * @throws IOException
-     * @throws ClassFormatError
-     */
-    public ClassFile(InputStream inputStream) throws IOException, ClassFormatError {
-        DataInputStream dis = inputStream instanceof DataInputStream ? (DataInputStream) inputStream : new DataInputStream(inputStream);
-
-        int magic = dis.readInt();                           // magic
-        if (magic != ClassFile.CLASS_FILE_MAGIC) throw new ClassFormatError("Invalid magic number");
-
-        this.minorVersion = dis.readShort();                 // minor_version
-        this.majorVersion = dis.readShort();                 // major_version
-        if (!ClassFile.isRecognizedVersion(this.majorVersion, this.minorVersion)) throw new ClassFormatError("Unrecognized class file format version " + this.majorVersion + "/" + this.minorVersion);
-
-        this.constantPool = new ArrayList();
-        this.constantPoolMap = new HashMap();
-        this.loadConstantPool(dis);                          // constant_pool_count, constant_pool
-
-        this.accessFlags  = dis.readShort();                 // access_flags
-        this.thisClass    = dis.readShort();                 // this_class
-        this.superclass   = dis.readShort();                 // super_class
-        this.interfaces   = ClassFile.readShortArray(dis);   // interfaces_count, interfaces
-
-        this.fieldInfos  = Collections.unmodifiableList(this.loadFields(dis));     // fields_count, fields
-        this.methodInfos = Collections.unmodifiableList(this.loadMethods(dis));    // methods_count, methods
-        this.attributes  = Collections.unmodifiableList(this.loadAttributes(dis)); // attributes_count, attributes
-    }
-
-    /**
-     * @return The fully qualified name of this class, e.g. "pkg1.pkg2.Outer$Inner"
-     */
-    public String getThisClassName() {
-        return this.getConstantClassName(this.thisClass).replace('/', '.');
-    }
-
-    /**
-     * Sets the major and minor class file version numbers (JVMS 4.1). The class file version
-     * defaults to the JDK 1.1 values (45.3) which execute on virtually every JVM.
-     * @param majorVersion
-     * @param minorVersion
-     */
-    public void setVersion(short majorVersion, short minorVersion) {
-        this.majorVersion = majorVersion;
-        this.minorVersion = minorVersion;
-    }
-
-    /**
-     * Returns the current major class file version number.
-     */
-    public short getMajorVersion() {
-        return this.majorVersion;
-    }
-
-    /**
-     * Returns the current minor class file version number.
-     */
-    public short getMinorVersion() {
-        return this.minorVersion;
-    }
-
-    public static boolean isRecognizedVersion(short majorVersion, short minorVersion) {
-        return (
-            (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_1 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_1) ||
-            (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_2 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_2) ||
-            (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_3 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_3) ||
-            (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_4 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_4) ||
-            (majorVersion == ClassFile.MAJOR_VERSION_JDK_1_5 && minorVersion == ClassFile.MINOR_VERSION_JDK_1_5)
-        );
-    }
-
-    /**
-     * Add a "CONSTANT_Class_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1221">JVM specification, section 4.4.1</a>
-     */
-    public short addConstantClassInfo(String typeFD) {
-        String s;
-        if (Descriptor.isClassOrInterfaceReference(typeFD)) {
-            s = Descriptor.toInternalForm(typeFD);
-        } else
-        if (Descriptor.isArrayReference(typeFD)) {
-            s = typeFD;
-        } else
-        {
-            throw new RuntimeException("\"" + Descriptor.toString(typeFD) + "\" is neither a class nor an array");
-        }
-
-        return this.addToConstantPool(new ConstantClassInfo(this.addConstantUtf8Info(s)));
-    }
-
-    /**
-     * Add a "CONSTANT_Fieldref_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#42041">JVM specification, section 4.4.2</a>
-     */
-    public short addConstantFieldrefInfo(
-        String classFD,
-        String fieldName,
-        String fieldFD
-    ) {
-        return this.addToConstantPool(new ConstantFieldrefInfo(
-            this.addConstantClassInfo(classFD),
-            this.addConstantNameAndTypeInfo(fieldName, fieldFD)
-        ));
-    }
-
-    /**
-     * Add a "CONSTANT_Methodref_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#42041">JVM specification, section 4.4.2</a>
-     */
-    public short addConstantMethodrefInfo(
-        String classFD,
-        String methodName,
-        String methodMD
-    ) {
-        return this.addToConstantPool(new ConstantMethodrefInfo(
-            this.addConstantClassInfo(classFD),
-            this.addConstantNameAndTypeInfo(methodName, methodMD)
-        ));
-    }
-
-    /**
-     * Add a "CONSTANT_InterfaceMethodref_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#42041">JVM specification, section 4.4.2</a>
-     */
-    public short addConstantInterfaceMethodrefInfo(
-        String classFD,
-        String methodName,
-        String methodMD
-    ) {
-        return this.addToConstantPool(new ConstantInterfaceMethodrefInfo(
-            this.addConstantClassInfo(classFD),
-            this.addConstantNameAndTypeInfo(methodName, methodMD)
-        ));
-    }
-
-    /**
-     * Add a "CONSTANT_String_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#29297">JVM specification, section 4.4.3</a>
-     */
-    public short addConstantStringInfo(String string) {
-        return this.addToConstantPool(new ConstantStringInfo(this.addConstantUtf8Info(string)));
-    }
-
-    /**
-     * Add a "CONSTANT_Integer_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#21942">JVM specification, section 4.4.4</a>
-     */
-    public short addConstantIntegerInfo(final int value) {
-        return this.addToConstantPool(new ConstantIntegerInfo(value));
-    }
-
-    /**
-     * Add a "CONSTANT_Float_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#21942">JVM specification, section 4.4.4</a>
-     */
-    public short addConstantFloatInfo(final float value) {
-        return this.addToConstantPool(new ConstantFloatInfo(value));
-    }
-
-    /**
-     * Add a "CONSTANT_Long_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1348">JVM specification, section 4.4.5</a>
-     */
-    public short addConstantLongInfo(final long value) {
-        return this.addToConstantPool(new ConstantLongInfo(value));
-    }
-
-    /**
-     * Add a "CONSTANT_Double_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1348">JVM specification, section 4.4.5</a>
-     */
-    public short addConstantDoubleInfo(final double value) {
-        return this.addToConstantPool(new ConstantDoubleInfo(value));
-    }
-
-    /**
-     * Add a "CONSTANT_NameAndType_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1327">JVM specification, section 4.4.6</a>
-     */
-    private short addConstantNameAndTypeInfo(String name, String descriptor) {
-        return this.addToConstantPool(new ConstantNameAndTypeInfo(
-            this.addConstantUtf8Info(name),
-            this.addConstantUtf8Info(descriptor)
-        ));
-    }
-
-    /**
-     * Add a "CONSTANT_Utf8_info" structure to the class file.
-     * 
-     * @see <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#7963">JVM specification, section 4.4.7</a>
-     */
-    public short addConstantUtf8Info(final String s) {
-        return this.addToConstantPool(new ConstantUtf8Info(s));
-    }
-
-    /**
-     * Convenience method that adds a String, Integer, Float, Long or Double ConstantInfo.
-     */
-    private short addConstantSIFLDInfo(Object cv) {
-        if (cv instanceof String) {
-            return this.addConstantStringInfo((String) cv);
-        } else
-        if (
-            cv instanceof Byte    ||
-            cv instanceof Short   ||
-            cv instanceof Integer
-        ) {
-            return this.addConstantIntegerInfo(((Number) cv).intValue());
-        } else
-        if (cv instanceof Boolean) {
-            return this.addConstantIntegerInfo(((Boolean) cv).booleanValue() ? 1 : 0);
-        } else
-        if (cv instanceof Character) {
-            return this.addConstantIntegerInfo(((Character) cv).charValue());
-        } else
-        if (cv instanceof Float) {
-            return this.addConstantFloatInfo(((Float) cv).floatValue());
-        } else
-        if (cv instanceof Long) {
-            return this.addConstantLongInfo(((Long) cv).longValue());
-        } else
-        if (cv instanceof Double) {
-            return this.addConstantDoubleInfo(((Double) cv).doubleValue());
-        } else
-        {
-            throw new RuntimeException("Unexpected constant value type \"" + cv.getClass().getName() + "\"");
-        }
-    }
-
-    private short addToConstantPool(ConstantPoolInfo cpi) {
-        Short index = (Short) this.constantPoolMap.get(cpi);
-        if (index != null) return index.shortValue();
-
-        short res = (short) this.constantPool.size();
-        this.constantPool.add(cpi);
-        if (cpi.isWide()) this.constantPool.add(null);
-
-        this.constantPoolMap.put(cpi, new Short(res));
-        return res;
-    }
-
-    public FieldInfo addFieldInfo(
-        short  accessFlags,
-        String fieldName,
-        String fieldTypeFD,
-        Object optionalConstantValue
-    ) {
-        List attributes = new ArrayList();
-        if (optionalConstantValue != null) {
-            attributes.add(new ConstantValueAttribute(
-                this.addConstantUtf8Info("ConstantValue"),
-                this.addConstantSIFLDInfo(optionalConstantValue)
-            ));
-        }
-        FieldInfo fi = new FieldInfo(
-            accessFlags,                           // accessFlags
-            this.addConstantUtf8Info(fieldName),   // nameIndex
-            this.addConstantUtf8Info(fieldTypeFD), // descriptorIndex
-            attributes                             // attributes
-        );
-        this.fieldInfos.add(fi);
-        return fi;
-    }
-
-    public MethodInfo addMethodInfo(
-        short  accessFlags,
-        String methodName,
-        String methodMD
-    ) {
-        MethodInfo mi = new MethodInfo(
-            accessFlags,                          // accessFlags
-            this.addConstantUtf8Info(methodName), // nameIndex
-            this.addConstantUtf8Info(methodMD),   // desriptorIndex
-            new ArrayList()                       // attributes
-        );
-        this.methodInfos.add(mi);
-        return mi;
-    }
-
-    public ConstantPoolInfo getConstantPoolInfo(short index) {
-        return (ConstantPoolInfo) this.constantPool.get(0xffff & index);
-    }
-
-    /**
-     * @param index Index to a <code>CONSTANT_Class_info</code> in the constant pool
-     * @return The name of the denoted class in "internal form" (see JVMS 4.2)
-     */
-    public String getConstantClassName(short index) {
-        ConstantClassInfo cci = (ConstantClassInfo) this.getConstantPoolInfo(index);
-        ConstantUtf8Info  cui = (ConstantUtf8Info) this.getConstantPoolInfo(cci.nameIndex);
-        return cui.s;
-    }
-
-    /**
-     * @param index Index to a <code>CONSTANT_Utf8_info</code> in the constant pool
-     * @return The string represented by the structure
-     */
-    public String getConstantUtf8(short index) {
-        ConstantUtf8Info cui = (ConstantUtf8Info) this.getConstantPoolInfo(index);
-        return cui.s;
-    }
-
-    /**
-     * u4 length, u1[length]
-     */
-    private static byte[] readLengthAndBytes(DataInputStream dis) throws IOException {
-        byte[] ba = new byte[dis.readInt()];
-        dis.readFully(ba);
-        return ba;
-    }
-
-    /**
-     * u2 length, u2[length]
-     */
-    private static short[] readShortArray(DataInputStream dis) throws IOException {
-        short count = dis.readShort();
-        short[] result = new short[count];
-        for (int i = 0; i < count; ++i) result[i] = dis.readShort();
-        return result;
-    }
-
-    /**
-     * u2 constant_pool_count, constant_pool[constant_pool_count]
-     */
-    private void loadConstantPool(DataInputStream dis) throws IOException {
-        this.constantPool.clear();
-        this.constantPoolMap.clear();
-
-        short constantPoolCount = dis.readShort(); // constant_pool_count
-        this.constantPool.add(null);
-        for (short i = 1; i < constantPoolCount; ++i) {
-            ConstantPoolInfo cpi = ConstantPoolInfo.loadConstantPoolInfo(dis);
-            this.constantPool.add(cpi);
-            this.constantPoolMap.put(cpi, new Short(i));
-            if (cpi.isWide()) {
-                this.constantPool.add(null);
-                ++i;
-            }
-        }
-    }
-
-    /**
-     * u2 fields_count, fields[fields_count]
-     */
-    private List loadFields(DataInputStream dis) throws IOException {
-        short fieldsCount = dis.readShort();
-        List fields = new ArrayList(fieldsCount);
-        for (int i = 0; i < fieldsCount; ++i) {
-            fields.add(new FieldInfo(
-                dis.readShort(),         // accessFlags
-                dis.readShort(),         // nameIndex
-                dis.readShort(),         // descriptorIndex
-                this.loadAttributes(dis) // attributes
-            ));
-        }
-        return fields;
-    }
-
-    /**
-     * u2 methods_count, methods[methods_count]
-     */
-    private List loadMethods(DataInputStream dis) throws IOException {
-        short methodsCount = dis.readShort();
-        List methods = new ArrayList(methodsCount);
-        for (int i = 0; i < methodsCount; ++i) methods.add(this.loadMethodInfo(dis));
-        return methods;
-    }
-
-    /**
-     * u2 attributes_count, attributes[attributes_count]
-     */
-    private List loadAttributes(DataInputStream dis) throws IOException {
-        short attributesCount = dis.readShort();
-        List attributes = new ArrayList(attributesCount);
-        for (int i = 0; i < attributesCount; ++i) attributes.add(this.loadAttribute(dis));
-        return attributes;
-    }
-
-    /**
-     * Write {@link ClassFile} to an {@link OutputStream}, in "class file" format.
-     * <p>
-     * Notice that if an {@link IOException} is thrown, the class file is
-     * probably written incompletely and thus invalid. The calling method must take
-     * care of this situation, e.g. by closing the output stream and then deleting the
-     * file.
-     * @param os
-     * @throws IOException
-     */
-    public void store(OutputStream os) throws IOException {
-        DataOutputStream dos = os instanceof DataOutputStream ? (DataOutputStream) os : new DataOutputStream(os);
-
-        dos.writeInt(ClassFile.CLASS_FILE_MAGIC);            // magic
-        dos.writeShort(this.minorVersion);                   // minor_version
-        dos.writeShort(this.majorVersion);                   // major_version
-        ClassFile.storeConstantPool(dos, this.constantPool); // constant_pool_count, constant_pool
-        dos.writeShort(this.accessFlags);                    // access_flags
-        dos.writeShort(this.thisClass);                      // this_class
-        dos.writeShort(this.superclass);                     // super_class
-        ClassFile.storeShortArray(dos, this.interfaces);     // interfaces_count, interfaces
-        ClassFile.storeFields(dos, this.fieldInfos);         // fields_count, fields
-        ClassFile.storeMethods(dos, this.methodInfos);       // methods_count, methods
-        ClassFile.storeAttributes(dos, this.attributes);     // attributes_count, attributes
-    }
-
-    /**
-     * u2 constant_pool_count, constant_pool[constant_pool_count - 1]
-     */
-    private static void storeConstantPool(DataOutputStream dos, List constantPool) throws IOException {
-        dos.writeShort(constantPool.size());
-        for (int i = 1; i < constantPool.size(); ++i) {
-            ConstantPoolInfo cpi = (ConstantPoolInfo) constantPool.get(i);
-            if (cpi == null) continue; // (Double or Long CPI.)
-            cpi.store(dos);
-        }
-    }
-
-    /**
-     * u2 count, u2[count]
-     */
-    private static void storeShortArray(DataOutputStream dos, short[] sa) throws IOException {
-        dos.writeShort(sa.length);
-        for (int i = 0; i < sa.length; ++i) dos.writeShort(sa[i]);
-    }
-
-    /**
-     * u2 fields_count, fields[fields_count]
-     */
-    private static void storeFields(DataOutputStream dos, List fieldInfos) throws IOException {
-        dos.writeShort(fieldInfos.size());
-        for (int i = 0; i < fieldInfos.size(); ++i) ((FieldInfo) fieldInfos.get(i)).store(dos);
-    }
-
-    /**
-     * u2 methods_count, methods[methods_count]
-     */
-    private static void storeMethods(DataOutputStream dos, List methodInfos) throws IOException {
-        dos.writeShort(methodInfos.size());
-        for (int i = 0; i < methodInfos.size(); ++i) ((MethodInfo) methodInfos.get(i)).store(dos);
-    }
-
-    /**
-     * u2 attributes_count, attributes[attributes_count]
-     */
-    private static void storeAttributes(DataOutputStream dos, List attributeInfos) throws IOException {
-        dos.writeShort(attributeInfos.size());
-        for (int i = 0; i < attributeInfos.size(); ++i) ((AttributeInfo) attributeInfos.get(i)).store(dos);
-    }
-
-    /**
-     * Construct the name of a resource that could contain the source code of
-     * the class with the given name.
-     * <p>
-     * Notice that member types are declared inside a different type, so the relevant source file
-     * is that of the outermost declaring class.
-     * 
-     * @param className Fully qualified class name, e.g. "pkg1.pkg2.Outer$Inner"
-     * @return the name of the resource, e.g. "pkg1/pkg2/Outer.java"
-     */
-    public static String getSourceResourceName(String className) {
-
-        // Strip nested type suffixes.
-        {
-            int idx = className.lastIndexOf('.') + 1;
-            idx = className.indexOf('$', idx);
-            if (idx != -1) className = className.substring(0, idx);
-        }
-
-        return className.replace('.', '/') + ".java";
-    }
-
-    /**
-     * Construct the name of a resource that could contain the class file of the
-     * class with the given name.
-     * 
-     * @param className Fully qualified class name, e.g. "pkg1.pkg2.Outer$Inner"
-     * @return the name of the resource, e.g. "pkg1/pkg2/Outer$Inner.class"
-     */
-    public static String getClassFileResourceName(String className) {
-        return className.replace('.', '/') + ".class";
-    }
-
-    /**
-     * Return the byte code of this {@link ClassFile} as a byte array.
-     */
-    public byte[] toByteArray() {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try {
-            this.store(baos);
-        } catch (IOException ex) {
-            // ByteArrayOutputStream should never throw IOExceptions.
-            throw new RuntimeException(ex.toString());
-        }
-        return baos.toByteArray();
-    }
-
-    private static final int CLASS_FILE_MAGIC = 0xcafebabe;
-
-    public final static short MAJOR_VERSION_JDK_1_1 = 45; 
-    public final static short MINOR_VERSION_JDK_1_1 = 3; 
-    public final static short MAJOR_VERSION_JDK_1_2 = 46;
-    public final static short MINOR_VERSION_JDK_1_2 = 0;
-    public final static short MAJOR_VERSION_JDK_1_3 = 47;
-    public final static short MINOR_VERSION_JDK_1_3 = 0;
-    public final static short MAJOR_VERSION_JDK_1_4 = 48;
-    public final static short MINOR_VERSION_JDK_1_4 = 0;
-    public final static short MAJOR_VERSION_JDK_1_5 = 49;
-    public final static short MINOR_VERSION_JDK_1_5 = 0;
-
-    private short        majorVersion;
-    private short        minorVersion;
-    public /*final*/ List    constantPool; // ConstantPoolInfo
-    public /*final*/ short   accessFlags;
-    public /*final*/ short   thisClass;
-    public /*final*/ short   superclass;
-    public /*final*/ short[] interfaces;
-    public /*final*/ List    fieldInfos;   // FieldInfo
-    public /*final*/ List    methodInfos;  // MethodInfo
-    private /*final*/ List   attributes;   // AttributeInfo
-
-    // Convenience.
-    private /*final*/ Map constantPoolMap; // ConstantPoolInfo => Short
-
-    public static abstract class ConstantPoolInfo {
-        abstract public void store(DataOutputStream dos) throws IOException;
-        abstract public boolean isWide();
-
-        private static ConstantPoolInfo loadConstantPoolInfo(DataInputStream dis) throws IOException {
-            byte tag = dis.readByte();
-//System.out.println("tag=" + tag);
-            switch (tag) {
-
-            case 7:
-                return new ConstantClassInfo(dis.readShort());
-
-            case 9:
-                return new ConstantFieldrefInfo(dis.readShort(), dis.readShort());
-
-            case 10:
-                return new ConstantMethodrefInfo(dis.readShort(), dis.readShort());
-
-            case 11:
-                return new ConstantInterfaceMethodrefInfo(dis.readShort(), dis.readShort());
-
-            case 8:
-                return new ConstantStringInfo(dis.readShort());
-
-            case 3:
-                return new ConstantIntegerInfo(dis.readInt());
-
-            case 4:
-                return new ConstantFloatInfo(dis.readFloat());
-
-            case 5:
-                return new ConstantLongInfo(dis.readLong());
-
-            case 6:
-                return new ConstantDoubleInfo(dis.readDouble());
-
-            case 12:
-                return new ConstantNameAndTypeInfo(dis.readShort(), dis.readShort());
-
-            case 1:
-                return new ConstantUtf8Info(dis.readUTF());
-
-            default:
-                throw new ClassFormatError("Invalid constant pool tag " + tag);
-            }
-        }
-    }
-
-    public static abstract class ConstantValuePoolInfo extends ConstantPoolInfo {
-        public abstract Object getValue(ClassFile classFile);
-    }
-
-    public static class ConstantClassInfo extends ConstantPoolInfo {
-        private final short nameIndex;
-
-        public ConstantClassInfo(short nameIndex) { this.nameIndex = nameIndex; }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(7);
-            dos.writeShort(this.nameIndex);
-        }
-        public boolean equals(Object o) {
-            return o instanceof ConstantClassInfo && ((ConstantClassInfo) o).nameIndex == this.nameIndex;
-        }
-        public int hashCode() { return this.nameIndex; }
-    }
-    public static class ConstantFieldrefInfo extends ConstantPoolInfo {
-        private final short classIndex;
-        private final short nameAndTypeIndex;
-
-        public ConstantFieldrefInfo(short classIndex, short nameAndTypeIndex) {
-            this.classIndex = classIndex;
-            this.nameAndTypeIndex = nameAndTypeIndex;
-        }
-
-        public short getNameAndTypeIndex() { return this.nameAndTypeIndex; }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(9);
-            dos.writeShort(this.classIndex);
-            dos.writeShort(this.nameAndTypeIndex);
-        }
-        public boolean equals(Object o) {
-            return (
-                o instanceof ConstantFieldrefInfo &&
-                ((ConstantFieldrefInfo) o).classIndex       == this.classIndex &&
-                ((ConstantFieldrefInfo) o).nameAndTypeIndex == this.nameAndTypeIndex
-            );
-        }
-        public int hashCode() { return this.classIndex + (this.nameAndTypeIndex << 16); }
-    }
-    public static class ConstantMethodrefInfo extends ConstantPoolInfo {
-        private final short classIndex;
-        private final short nameAndTypeIndex;
-
-        public ConstantMethodrefInfo(short classIndex, short nameAndTypeIndex) {
-            this.classIndex = classIndex;
-            this.nameAndTypeIndex = nameAndTypeIndex;
-        }
-
-        public short getNameAndTypeIndex() { return this.nameAndTypeIndex; }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(10);
-            dos.writeShort(this.classIndex);
-            dos.writeShort(this.nameAndTypeIndex);
-        }
-        public boolean equals(Object o) {
-            return (
-                o instanceof ConstantMethodrefInfo &&
-                ((ConstantMethodrefInfo) o).classIndex       == this.classIndex &&
-                ((ConstantMethodrefInfo) o).nameAndTypeIndex == this.nameAndTypeIndex
-            );
-        }
-        public int hashCode() { return this.classIndex + (this.nameAndTypeIndex << 16); }
-    }
-    public static class ConstantInterfaceMethodrefInfo extends ConstantPoolInfo {
-        private final short classIndex;
-        private final short nameAndTypeIndex;
-
-        public ConstantInterfaceMethodrefInfo(short classIndex, short nameAndTypeIndex) {
-            this.classIndex = classIndex;
-            this.nameAndTypeIndex = nameAndTypeIndex;
-        }
-
-        public short getNameAndTypeIndex() { return this.nameAndTypeIndex; }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(11);
-            dos.writeShort(this.classIndex);
-            dos.writeShort(this.nameAndTypeIndex);
-        }
-        public boolean equals(Object o) {
-            return (
-                o instanceof ConstantInterfaceMethodrefInfo &&
-                ((ConstantInterfaceMethodrefInfo) o).classIndex ==       this.classIndex &&
-                ((ConstantInterfaceMethodrefInfo) o).nameAndTypeIndex == this.nameAndTypeIndex
-            );
-        }
-        public int hashCode() { return this.classIndex + (this.nameAndTypeIndex << 16); }
-    }
-    static class ConstantStringInfo extends ConstantValuePoolInfo {
-        private final short stringIndex;
-
-        public ConstantStringInfo(short stringIndex) {
-            this.stringIndex = stringIndex;
-        }
-
-        // Implement ConstantValuePoolInfo.
-        public Object getValue(ClassFile classFile) {
-            return classFile.getConstantUtf8(this.stringIndex);
-        }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(8);
-            dos.writeShort(this.stringIndex);
-        }
-        public boolean equals(Object o) {
-            return o instanceof ConstantStringInfo && ((ConstantStringInfo) o).stringIndex == this.stringIndex;
-        }
-        public int hashCode() { return this.stringIndex; }
-    }
-    private static class ConstantIntegerInfo extends ConstantValuePoolInfo {
-        private final int value;
-
-        public ConstantIntegerInfo(int value) {
-            this.value = value;
-        }
-
-        // Implement ConstantValuePoolInfo.
-        public Object getValue(ClassFile classFile) { return new Integer(this.value); }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(3);
-            dos.writeInt(this.value);
-        }
-        public boolean equals(Object o) {
-            return o instanceof ConstantIntegerInfo && ((ConstantIntegerInfo) o).value == this.value;
-        }
-        public int hashCode() { return this.value; }
-    }
-    private static class ConstantFloatInfo extends ConstantValuePoolInfo {
-        private final float value;
-
-        public ConstantFloatInfo(float value) {
-            this.value = value;
-        }
-
-        // Implement ConstantValuePoolInfo.
-        public Object getValue(ClassFile classFile) { return new Float(this.value); }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(4);
-            dos.writeFloat(this.value);
-        }
-        public boolean equals(Object o) {
-            return o instanceof ConstantFloatInfo && ((ConstantFloatInfo) o).value == this.value;
-        }
-        public int hashCode() { return Float.floatToIntBits(this.value); }
-    }
-    private static class ConstantLongInfo extends ConstantValuePoolInfo {
-        private final long value;
-
-        public ConstantLongInfo(long value) {
-            this.value = value;
-        }
-
-        // Implement ConstantValuePoolInfo.
-        public Object getValue(ClassFile classFile) { return new Long(this.value); }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return true; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(5);
-            dos.writeLong(this.value);
-        }
-        public boolean equals(Object o) {
-            return o instanceof ConstantLongInfo && ((ConstantLongInfo) o).value == this.value;
-        }
-        public int hashCode() { return (int) this.value ^ (int) (this.value >> 32); }
-    }
-    private static class ConstantDoubleInfo extends ConstantValuePoolInfo {
-        private final double value;
-
-        public ConstantDoubleInfo(double value) {
-            this.value = value;
-        }
-
-        // Implement ConstantValuePoolInfo.
-        public Object getValue(ClassFile classFile) { return new Double(this.value); }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return true; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(6);
-            dos.writeDouble(this.value);
-        }
-        public boolean equals(Object o) {
-            return o instanceof ConstantDoubleInfo && ((ConstantDoubleInfo) o).value == this.value;
-        }
-        public int hashCode() {
-            long bits = Double.doubleToLongBits(this.value);
-            return (int) bits ^ (int) (bits >> 32);
-        }
-    }
-    public static class ConstantNameAndTypeInfo extends ConstantPoolInfo {
-        private final short nameIndex;
-        private final short descriptorIndex;
-
-        public ConstantNameAndTypeInfo(short nameIndex, short descriptorIndex) {
-            this.nameIndex       = nameIndex;
-            this.descriptorIndex = descriptorIndex;
-        }
-
-        public short getDescriptorIndex() { return this.descriptorIndex; }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(12);
-            dos.writeShort(this.nameIndex);
-            dos.writeShort(this.descriptorIndex);
-        }
-        public boolean equals(Object o) {
-            return (
-                o instanceof ConstantNameAndTypeInfo &&
-                ((ConstantNameAndTypeInfo) o).nameIndex       == this.nameIndex &&
-                ((ConstantNameAndTypeInfo) o).descriptorIndex == this.descriptorIndex
-            );
-        }
-        public int hashCode() { return this.nameIndex + (this.descriptorIndex << 16); }
-    }
-    public static class ConstantUtf8Info extends ConstantPoolInfo {
-        private final String s;
-
-        public ConstantUtf8Info(String s) {
-            if (s == null) throw new RuntimeException();
-            this.s = s;
-        }
-
-        public String getString() { return this.s; }
-
-        // Implement ConstantPoolInfo.
-        public boolean isWide() { return false; }
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeByte(1);
-            try {
-                dos.writeUTF(this.s);
-            } catch (UTFDataFormatException e) {
-                throw new ClassFormatError("String constant too long to store in class file");
-            }
-        }
-        public boolean equals(Object o) {
-            return o instanceof ConstantUtf8Info && ((ConstantUtf8Info) o).s.equals(this.s);
-        }
-        public int hashCode() { return this.s.hashCode(); }
-    }
-
-    /**
-     * This class represents a "method_info" structure, as defined by the
-     * JVM specification.
-     */
-    public class MethodInfo {
-        private final short accessFlags;
-        private final short nameIndex;
-        private final short descriptorIndex;
-        private final List  attributes; // AttributeInfo
-
-        /**
-         * Initialize the "method_info" structure.
-         */
-        public MethodInfo(
-            short accessFlags,
-            short nameIndex,
-            short descriptorIndex,
-            List  attributes
-        ) {
-            this.accessFlags     = accessFlags;
-            this.nameIndex       = nameIndex;
-            this.descriptorIndex = descriptorIndex;
-            this.attributes      = attributes;
-        }
-
-        public ClassFile getClassFile() { return ClassFile.this; }
-
-        public short           getAccessFlags()     { return this.accessFlags; }
-        public short           getNameIndex()       { return this.nameIndex; }
-        public short           getDescriptorIndex() { return this.descriptorIndex; }
-        public AttributeInfo[] getAttributes()      { return (AttributeInfo[]) this.attributes.toArray(new AttributeInfo[this.attributes.size()]); }
-
-        public void addAttribute(AttributeInfo attribute) {
-            this.attributes.add(attribute);
-        }
-
-        /**
-         * Write this object to a {@link DataOutputStream}, in the format
-         * defined by the JVM specification.
-         */
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeShort(this.accessFlags);                // access_flags
-            dos.writeShort(this.nameIndex);                  // name_index
-            dos.writeShort(this.descriptorIndex);            // descriptor_index
-            ClassFile.storeAttributes(dos, this.attributes); // attributes_count, attributes
-        }
-    }
-
-    private MethodInfo loadMethodInfo(DataInputStream dis) throws IOException {
-        return new MethodInfo(
-            dis.readShort(),         // accessFlags
-            dis.readShort(),         // nameIndex
-            dis.readShort(),         // descriptorIndex
-            this.loadAttributes(dis) // attributes
-        );
-    }
-
-    public static class FieldInfo {
-        public FieldInfo(
-            short accessFlags,
-            short nameIndex,
-            short descriptorIndex,
-            List  attributes
-        ) {
-            this.accessFlags     = accessFlags;
-            this.nameIndex       = nameIndex;
-            this.descriptorIndex = descriptorIndex;
-            this.attributes      = attributes;
-        }
-
-        public short           getAccessFlags()     { return this.accessFlags; }
-        public short           getNameIndex()       { return this.nameIndex; }
-        public short           getDescriptorIndex() { return this.descriptorIndex; }
-        public AttributeInfo[] getAttributes()      { return (AttributeInfo[]) this.attributes.toArray(new AttributeInfo[this.attributes.size()]); }
-
-        public void addAttribute(AttributeInfo attribute) {
-            this.attributes.add(attribute);
-        }
-
-        public void store(DataOutputStream dos) throws IOException {
-            dos.writeShort(this.accessFlags);                // access_flags
-            dos.writeShort(this.nameIndex);                  // name_index
-            dos.writeShort(this.descriptorIndex);            // descriptor_index
-            ClassFile.storeAttributes(dos, this.attributes); // attibutes_count, attributes
-        }
-
-        private final short accessFlags;
-        private final short nameIndex;
-        private final short descriptorIndex;
-        private final List  attributes; // AttributeInfo
-    }
-
-    /**
-     * Representation of a class file attribute (see JVMS 4.7).
-     */
-    public abstract static class AttributeInfo {
-        public AttributeInfo(short nameIndex) {
-            this.nameIndex = nameIndex;
-        }
-        public void store(DataOutputStream dos) throws IOException {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            this.storeBody(new DataOutputStream(baos));
-
-            dos.writeShort(this.nameIndex); // attribute_name_index;
-            dos.writeInt(baos.size());      // attribute_length
-            baos.writeTo(dos);              // info
-        }
-        protected abstract void storeBody(DataOutputStream dos) throws IOException;
-
-        private final short nameIndex;
-    }
-
-    /**
-     * Load one class file attribute. The returned object will be of
-     * {@link AttributeInfo}-derived type, depending on the attribute's name; e.g. if the
-     * name of the attribute is "SourceFile", then the returned object will be of type
-     * {@link SourceFileAttribute}.
-     */
-    private AttributeInfo loadAttribute(DataInputStream dis) throws IOException {
-        short attributeNameIndex = dis.readShort(); // attribute_name_index
-        int   attributeLength    = dis.readInt();   // attribute_length
-
-        final byte[] ba = new byte[attributeLength];
-        dis.readFully(ba);
-        ByteArrayInputStream bais = new ByteArrayInputStream(ba);
-        DataInputStream      bdis = new DataInputStream(bais);
-
-        String attributeName = this.getConstantUtf8(attributeNameIndex);
-        AttributeInfo result;
-        if ("ConstantValue".equals(attributeName)) {
-            result = ConstantValueAttribute.loadBody(attributeNameIndex, bdis);
-        } else
-        if ("Code".equals(attributeName)) {
-            result = CodeAttribute.loadBody(attributeNameIndex, this, bdis);
-        } else
-        if ("Exceptions".equals(attributeName)) {
-            result = ExceptionsAttribute.loadBody(attributeNameIndex, bdis);
-        } else
-        if ("InnerClasses".equals(attributeName)) {
-            result = InnerClassesAttribute.loadBody(attributeNameIndex, bdis);
-        } else
-        if ("Synthetic".equals(attributeName)) {
-            result = SyntheticAttribute.loadBody(attributeNameIndex, bdis);
-        } else
-        if ("SourceFile".equals(attributeName)) {
-            result = SourceFileAttribute.loadBody(attributeNameIndex, bdis);
-        } else
-        if ("LineNumberTable".equals(attributeName)) {
-            result = LineNumberTableAttribute.loadBody(attributeNameIndex, bdis);
-        } else
-        if ("LocalVariableTable".equals(attributeName)) {
-            result = LocalVariableTableAttribute.loadBody(attributeNameIndex, bdis);
-        } else
-        if ("Deprecated".equals(attributeName)) {
-            result = DeprecatedAttribute.loadBody(attributeNameIndex, bdis);
-        } else
-        {
-            return new AttributeInfo(attributeNameIndex) {
-                protected void storeBody(DataOutputStream dos) throws IOException { dos.write(ba); }
-            };
-        }
-
-        if (bais.available() > 0) throw new ClassFormatError((ba.length - bais.available()) + " bytes of trailing garbage in body of attribute \"" + attributeName + "\"");
-
-        return result;
-    }
-
-    /**
-     * Representation of a "ConstantValue" attribute (see JVMS 4.7.2).
-     */
-    public static class ConstantValueAttribute extends AttributeInfo {
-        private final short constantValueIndex;
-
-        ConstantValueAttribute(short attributeNameIndex, short constantValueIndex) {
-            super(attributeNameIndex);
-            this.constantValueIndex = constantValueIndex;
-        }
-
-        public short getConstantValueIndex() { return this.constantValueIndex; }
-
-        private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
-            return new ConstantValueAttribute(
-                attributeNameIndex, // attributeNameIndex
-                dis.readShort()     // constantValueIndex
-            );
-        }
-
-        // Implement "AttributeInfo".
-        protected void storeBody(DataOutputStream dos) throws IOException {
-            dos.writeShort(this.constantValueIndex);
-        }
-    }
-
-    /**
-     * Representation of an "Exceptions" attribute (see JVMS 4.7.4).
-     */
-    public static class ExceptionsAttribute extends AttributeInfo {
-        private final short[] exceptionIndexes;
-
-        public ExceptionsAttribute(short attributeNameIndex, short[] exceptionIndexes) {
-            super(attributeNameIndex);
-            this.exceptionIndexes = exceptionIndexes;
-        }
-
-        public short[] getExceptionIndexes() {
-            short[] eis = new short[this.exceptionIndexes.length];
-            System.arraycopy(this.exceptionIndexes, 0, eis, 0, eis.length);
-            return eis;
-        }
-
-        private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
-            return new ExceptionsAttribute(
-                attributeNameIndex,           // attributeNameIndex
-                ClassFile.readShortArray(dis) // exceptionIndexes
-            );
-        }
-
-        // Implement "AttributeInfo".
-        protected void storeBody(DataOutputStream dos) throws IOException {
-            ClassFile.storeShortArray(dos, this.exceptionIndexes);
-        }
-    }
-
-    /**
-     * Representation of an "InnerClasses" attribute (see JVMS 4.7.5).
-     */
-    public static class InnerClassesAttribute extends AttributeInfo {
-        private final List entries; // InnerClassesAttribute.Entry
-
-        InnerClassesAttribute(short attributeNameIndex) {
-            super(attributeNameIndex);
-            this.entries = new ArrayList();
-        }
-        InnerClassesAttribute(short attributeNameIndex, Entry[] entries) {
-            super(attributeNameIndex);
-            this.entries = new ArrayList(Arrays.asList(entries));
-        }
-
-        public List getEntries() {
-            return this.entries;
-        }
-
-        private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
-            Entry[] ics = new Entry[dis.readShort()]; // number_of_classes
-            for (short i = 0; i < ics.length; ++i) {  // classes
-                ics[i] = new InnerClassesAttribute.Entry(
-                    dis.readShort(), // innerClassInfoIndex
-                    dis.readShort(), // outerClassInfoIndex
-                    dis.readShort(), // innerNameIndex
-                    dis.readShort()  // innerClassAccessFlags
-                );
-            }
-            return new InnerClassesAttribute(attributeNameIndex, ics);
-        }
-
-        // Implement "AttributeInfo".
-        protected void storeBody(DataOutputStream dos) throws IOException {
-            dos.writeShort(this.entries.size());
-            for (Iterator it = this.entries.iterator(); it.hasNext();) {
-                Entry e = (Entry) it.next();
-                dos.writeShort(e.innerClassInfoIndex);
-                dos.writeShort(e.outerClassInfoIndex);
-                dos.writeShort(e.innerNameIndex);
-                dos.writeShort(e.innerClassAccessFlags);
-            }
-        }
-
-        public static class Entry {
-            public final short innerClassInfoIndex, outerClassInfoIndex, innerNameIndex, innerClassAccessFlags;
-
-            public Entry(short innerClassInfoIndex, short outerClassInfoIndex, short innerNameIndex, short innerClassAccessFlags) {
-                this.innerClassInfoIndex   = innerClassInfoIndex;
-                this.outerClassInfoIndex   = outerClassInfoIndex;
-                this.innerNameIndex        = innerNameIndex;
-                this.innerClassAccessFlags = innerClassAccessFlags;
-            }
-        }
-    }
-
-    /**
-     * Representation of a "Synthetic" attribute (see JVMS 4.7.6).
-     */
-    public static class SyntheticAttribute extends AttributeInfo {
-        SyntheticAttribute(short attributeNameIndex) {
-            super(attributeNameIndex);
-        }
-
-        private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) {
-            return new SyntheticAttribute(
-                attributeNameIndex // attributeNameIndex
-            );
-        }
-
-        // Implement "AttributeInfo".
-        protected void storeBody(DataOutputStream dos) throws IOException {
-        }
-    }
-
-    /**
-     * Representation of a "SourceFile" attribute (see JVMS 4.7.7).
-     */
-    public static class SourceFileAttribute extends AttributeInfo {
-        private final short sourceFileIndex;
-
-        public SourceFileAttribute(short attributeNameIndex, short sourceFileIndex) {
-            super(attributeNameIndex);
-            this.sourceFileIndex = sourceFileIndex;
-        }
-
-        private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
-            return new SourceFileAttribute(
-                attributeNameIndex, // attributeNameIndex
-                dis.readShort()     // sourceFileNameIndex
-            );
-        }
-
-        // Implement "AttributeInfo".
-        protected void storeBody(DataOutputStream dos) throws IOException {
-            dos.writeShort(this.sourceFileIndex);
-        }
-    }
-
-    /**
-     * Representation of a "LineNumberTable" attribute (see JVMS 4.7.8).
-     */
-    public static class LineNumberTableAttribute extends AttributeInfo {
-        private final Entry[] entries;
-
-        public LineNumberTableAttribute(short attributeNameIndex, Entry[] entries) {
-            super(attributeNameIndex);
-            this.entries = entries;
-        }
-
-        private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
-            Entry[] lntes = new Entry[dis.readShort()]; // line_number_table_length
-            for (short i = 0; i < lntes.length; ++i) {  // line_number_table
-                lntes[i] = new LineNumberTableAttribute.Entry(
-                    dis.readShort(), // startPC
-                    dis.readShort()  // lineNumber
-                );
-            }
-            return new LineNumberTableAttribute(attributeNameIndex, lntes);
-        }
-
-        // Implement "AttributeInfo".
-        protected void storeBody(DataOutputStream dos) throws IOException {
-            dos.writeShort(this.entries.length);            // line_number_table_length
-            for (int i = 0; i < this.entries.length; ++i) {
-                dos.writeShort(this.entries[i].startPC);
-                dos.writeShort(this.entries[i].lineNumber);
-            }
-        }
-
-        public static class Entry {
-            public final int startPC, lineNumber;
-            public Entry(int startPC, int lineNumber) {
-                this.startPC    = startPC;
-                this.lineNumber = lineNumber;
-            }
-        }
-    }
-
-    /**
-     * Representation of a "LocalVariableTable" attribute (see JVMS 4.7.9).
-     */
-    public static class LocalVariableTableAttribute extends AttributeInfo {
-        private final Entry[] entries;
-
-        LocalVariableTableAttribute(short attributeNameIndex, Entry[] entries) {
-            super(attributeNameIndex);
-            this.entries = entries;
-        }
-
-        private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) throws IOException {
-            short localVariableTableLength = dis.readShort();
-            Entry[] lvtes = new Entry[localVariableTableLength];   // local_variable_table_length
-            for (short i = 0; i < localVariableTableLength; ++i) { // local_variable_table
-                lvtes[i] = new LocalVariableTableAttribute.Entry(
-                    dis.readShort(), // startPC
-                    dis.readShort(), // length
-                    dis.readShort(), // nameIndex
-                    dis.readShort(), // descriptorIndex
-                    dis.readShort()  // index
-                );
-            }
-            return new LocalVariableTableAttribute(attributeNameIndex, lvtes);
-        }
-        // Implement "AttributeInfo".
-        protected void storeBody(DataOutputStream dos) throws IOException {
-            dos.writeShort(this.entries.length);            // local_variable_table_length
-            for (int i = 0; i < this.entries.length; ++i) { // local_variable_table
-                Entry lnte = this.entries[i];
-                dos.writeShort(lnte.startPC);         // start_pc;
-                dos.writeShort(lnte.length);          // length
-                dos.writeShort(lnte.nameIndex);       // name_index
-                dos.writeShort(lnte.descriptorIndex); // descriptor_index
-                dos.writeShort(lnte.index);           // index
-            }
-        }
-
-        public static class Entry {
-            public final short startPC, length, nameIndex, descriptorIndex, index;
-
-            public Entry(
-                short startPC,
-                short length,
-                short nameIndex,
-                short descriptorIndex,
-                short index
-            ) {
-                this.startPC         = startPC;
-                this.length          = length;
-                this.nameIndex       = nameIndex;
-                this.descriptorIndex = descriptorIndex;
-                this.index           = index;
-            }
-        }
-    }
-
-    /**
-     * Representation of a "Deprecated" attribute (see JVMS 4.7.10).
-     */
-    public static class DeprecatedAttribute extends AttributeInfo {
-        public DeprecatedAttribute(short attributeNameIndex) {
-            super(attributeNameIndex);
-        }
-
-        private static AttributeInfo loadBody(short attributeNameIndex, DataInputStream dis) {
-            return new DeprecatedAttribute(attributeNameIndex);
-        }
-
-        // Implement "AttributeInfo".
-        protected void storeBody(DataOutputStream dos) throws IOException {
-        }
-    }
-
-    /**
-     * Representation of an unmodifiable "Code" attribute, as read from a class file.
-     */
-    private static class CodeAttribute extends AttributeInfo {
-        private final short                 maxStack;
-        private final short                 maxLocals;
-        private final byte[]                code;
-        private final ExceptionTableEntry[] exceptionTableEntries;
-        private final AttributeInfo[]       attributes;
-
-        private CodeAttribute(
-            short                 attributeNameIndex,
-            short                 maxStack,
-            short                 maxLocals,
-            byte[]                code,
-            ExceptionTableEntry[] exceptionTableEntries,
-            AttributeInfo[]       attributes
-        ) {
-            super(attributeNameIndex);
-            this.maxStack              = maxStack;
-            this.maxLocals             = maxLocals;
-            this.code                  = code;
-            this.exceptionTableEntries = exceptionTableEntries;
-            this.attributes            = attributes;
-        }
-
-        public static AttributeInfo loadBody(short attributeNameIndex, ClassFile classFile, DataInputStream dis) throws IOException {
-            short  maxStack = dis.readShort();                                     // max_stack
-            short  maxLocals = dis.readShort();                                    // max_locals
-            byte[] code = ClassFile.readLengthAndBytes(dis);                       // code_length, code
-
-            ExceptionTableEntry[] etes = new ExceptionTableEntry[dis.readShort()]; // exception_table_length
-            for (int i = 0; i < etes.length; ++i) {                                // exception_table
-                etes[i] = new ExceptionTableEntry(
-                    dis.readShort(), // startPC
-                    dis.readShort(), // endPC
-                    dis.readShort(), // handlerPC
-                    dis.readShort()  // catchType
-                );
-            }
-
-            AttributeInfo[] attributes = new AttributeInfo[dis.readShort()];       // attributes_count
-            for (int i = 0; i < attributes.length; ++i) {                          // attributes
-                attributes[i] = classFile.loadAttribute(dis);
-            } 
-
-            return new CodeAttribute(
-                attributeNameIndex, // attributeNameIndex
-                maxStack,           // maxStack
-                maxLocals,          // maxLocals
-                code,               // code
-                etes,               // exceptionTableEntries
-                attributes          // attributes
-            );
-        }
-
-        protected void storeBody(DataOutputStream dos) throws IOException {
-            dos.writeShort(this.maxStack);                                // max_stack
-            dos.writeShort(this.maxLocals);                               // max_locals
-            dos.writeInt(this.code.length);                               // code_length
-            dos.write(this.code);                                         // code
-            dos.writeShort(this.exceptionTableEntries.length);            // exception_table_length
-            for (int i = 0; i < this.exceptionTableEntries.length; ++i) { // exception_table
-                ExceptionTableEntry ete = this.exceptionTableEntries[i];
-                dos.writeShort(ete.startPC  ); // start_pc
-                dos.writeShort(ete.endPC    ); // end_pc
-                dos.writeShort(ete.handlerPC); // handler_pc
-                dos.writeShort(ete.catchType); // catch_type
-            }
-            dos.writeShort(this.attributes.length);                       // attributes_count
-            for (int i = 0; i < this.attributes.length; ++i) {            // attributes
-                this.attributes[i].store(dos);
-            }
-        }
-
-        /**
-         * Representation of an entry in the "exception_table" of a "Code" attribute (see JVMS
-         * 4.7.3).
-         */
-        private static class ExceptionTableEntry {
-            private final short startPC, endPC, handlerPC, catchType;
-
-            public ExceptionTableEntry(
-                short startPC,
-                short endPC,
-                short handlerPC,
-                short catchType
-            ) {
-                this.startPC   = startPC;
-                this.endPC     = endPC;
-                this.handlerPC = handlerPC;
-                this.catchType = catchType;
-            }
-        }
-    }
-}
diff --git a/src/org/codehaus/janino/util/LocatedException.java b/src/org/codehaus/janino/util/LocatedException.java
deleted file mode 100644
index a192444..0000000
--- a/src/org/codehaus/janino/util/LocatedException.java
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import org.codehaus.janino.Location;
-
-/**
- * An {@link Exception} that is associated with an optional {@link Location} in a source file.
- */
-public class LocatedException extends CausedException {
-    private final Location optionalLocation;
-
-    public LocatedException(String message, Location optionalLocation) {
-        super(message);
-        this.optionalLocation = optionalLocation;
-    }
-
-    public LocatedException(String message, Location optionalLocation, Throwable optionalCause) {
-        super(message, optionalCause);
-        this.optionalLocation = optionalLocation;
-    }
-    
-    /**
-     * Returns the message specified at creation time, preceeded with nicely formatted location
-     * information (if any).
-     */
-    public String getMessage() {
-        return this.optionalLocation == null ? super.getMessage() : this.optionalLocation.toString() + ": " + super.getMessage();
-    }
-
-    /**
-     * Returns the {@link Location} object specified at
-     * construction time (may be <code>null</code>).
-     */
-    public Location getLocation() {
-        return this.optionalLocation;
-    }
-}
\ No newline at end of file
diff --git a/src/org/codehaus/janino/util/MultiIterator.java b/src/org/codehaus/janino/util/MultiIterator.java
deleted file mode 100644
index 921239d..0000000
--- a/src/org/codehaus/janino/util/MultiIterator.java
+++ /dev/null
@@ -1,163 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that traverses a {@link java.util.Collection} of
- * {@link java.util.Iterator}s.
- */
-public class MultiIterator implements Iterator {
-    private static final Iterator AT_END = new Iterator() {
-        public boolean hasNext() { return false; }
-        public Object  next()    { throw new NoSuchElementException(); }
-        public void    remove()  { throw new UnsupportedOperationException(); }
-    };
-
-    private final Iterator outer; // Over Iterators, Collections or arrays
-    private Iterator       inner = MultiIterator.AT_END;
-
-    /**
-     * @param iterators An array of {@link Iterator}s
-     */
-    public MultiIterator(Iterator[] iterators) {
-        this.outer = Arrays.asList(iterators).iterator();
-    }
-
-    /**
-     * @param collections An array of {@link Collection}s
-     */
-    public MultiIterator(Collection[] collections) {
-        this.outer = Arrays.asList(collections).iterator();
-    }
-
-    /**
-     * @param arrays An array of arrays
-     */
-    public MultiIterator(Object[][] arrays) {
-        this.outer = Arrays.asList(arrays).iterator();
-    }
-
-    /**
-     * @param collection A {@link Collection} of {@link Collection}s, {@link Iterator}s and/or arrays
-     */
-    public MultiIterator(Collection collection) {
-        this.outer = collection.iterator();
-    }
-
-    /**
-     * @param iterator An iterator over {@link Collection}s, {@link Iterator}s and/or arrays
-     */
-    public MultiIterator(Iterator iterator) {
-        this.outer = iterator;
-    }
-
-    /**
-     * @param array An array of {@link Collection}s, {@link Iterator}s and/or arrays
-     */
-    public MultiIterator(Object[] array) {
-        this.outer = Arrays.asList(array).iterator();
-    }
-
-    /**
-     * Iterates over the given {@link Collection}, prepended with the given {@link Object}.
-     */
-    public MultiIterator(Object object, Collection collection) {
-        this.outer = Arrays.asList(new Object[] {
-            new Object[] { object },
-            collection
-        }).iterator();
-    }
-
-    /**
-     * Iterates over the given {@link Collection}, appended with the given {@link Object}.
-     */
-    public MultiIterator(Collection collection, Object object) {
-        this.outer = Arrays.asList(new Object[] {
-            collection,
-            new Object[] { object }
-        }).iterator();
-    }
-
-    /**
-     * Iterates over the given {@link Iterator}, prepended with the given <code>prefix</code>.
-     */
-    public MultiIterator(Object prefix, Iterator iterator) {
-        this.outer = Arrays.asList(new Object[] {
-            new Object[] { prefix },
-            iterator
-        }).iterator();
-    }
-
-    /**
-     * Iterates over the given {@link Iterator}, appended with the given <code>suffix</code>.
-     */
-    public MultiIterator(Iterator iterator, Object suffix) {
-        this.outer = Arrays.asList(new Object[] {
-            iterator,
-            new Object[] { suffix }
-        }).iterator();
-    }
-
-    public boolean hasNext() {
-        for (;;) {
-            if (this.inner.hasNext()) return true;
-            if (!this.outer.hasNext()) return false;
-            Object o = this.outer.next();
-            if (o instanceof Iterator) {
-                this.inner = (Iterator) o;
-            } else
-            if (o instanceof Collection) {
-                this.inner = ((Collection) o).iterator();
-            } else
-            if (o instanceof Object[]) {
-                this.inner = Arrays.asList((Object[]) o).iterator();
-            } else
-            {
-                throw new RuntimeException("Unexpected element type \"" + o.getClass().getName() + "\"");
-            }
-        } 
-    }
-
-    public Object next() {
-        if (this.hasNext()) return this.inner.next();
-        throw new NoSuchElementException();
-    }
-
-    public void remove() {
-        this.inner.remove();
-    }
-}
diff --git a/src/org/codehaus/janino/util/PrimitiveWrapper.java b/src/org/codehaus/janino/util/PrimitiveWrapper.java
deleted file mode 100644
index a52e04c..0000000
--- a/src/org/codehaus/janino/util/PrimitiveWrapper.java
+++ /dev/null
@@ -1,50 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-/**
- * A helper class that wraps primitive values in their wrapper classes.
- */
-public class PrimitiveWrapper {
-    public static Boolean   wrap(boolean v) { return v ? Boolean.TRUE : Boolean.FALSE; }
-    public static Byte      wrap(byte    v) { return new Byte(v);      }
-    public static Short     wrap(short   v) { return new Short(v);     }
-    public static Integer   wrap(int     v) { return new Integer(v);   }
-    public static Long      wrap(long    v) { return new Long(v);      }
-    public static Character wrap(char    v) { return new Character(v); }
-    public static Float     wrap(float   v) { return new Float(v);     }
-    public static Double    wrap(double  v) { return new Double(v);    }
-    public static Object    wrap(Object  v) { return v;                }
-}
diff --git a/src/org/codehaus/janino/util/Producer.java b/src/org/codehaus/janino/util/Producer.java
deleted file mode 100644
index 3e24444..0000000
--- a/src/org/codehaus/janino/util/Producer.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-/**
- * An object that produces some {@link java.lang.Object} each time the
- * {@link #produce()} method is invoked. This behavior is similar to the
- * {@link java.util.Iterator}, but is represented by one single
- * {@link #produce()} method as opposed to {@link java.util.Iterator}'s
- * two methods {@link java.util.Iterator#hasNext()} and
- * {@link java.util.Iterator#next()}. This simplifies the implementation of
- * certain complex iterations.
- *
- * @see org.codehaus.janino.util.iterator.DirectoryIterator
- * @see org.codehaus.janino.util.iterator.ProducerIterator
- */
-public interface Producer {
-
-    /**
-     * Produce the next object.
-     *
-     * @return the next object or <code>null</code> to indicate that no more objects can be produced
-     */
-    Object produce();
-}
diff --git a/src/org/codehaus/janino/util/ResourceFinderClassLoader.java b/src/org/codehaus/janino/util/ResourceFinderClassLoader.java
deleted file mode 100644
index 23da2a6..0000000
--- a/src/org/codehaus/janino/util/ResourceFinderClassLoader.java
+++ /dev/null
@@ -1,120 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import java.io.*;
-
-import org.codehaus.janino.tools.Disassembler;
-import org.codehaus.janino.util.resource.*;
-
-
-/**
- * A {@link ClassLoader} that uses a {@link org.codehaus.janino.util.resource.ResourceFinder}
- * to find ".class" files.
- */
-public class ResourceFinderClassLoader extends ClassLoader {
-    private final static boolean DEBUG = false;
-
-    private final ResourceFinder resourceFinder;
-
-    public ResourceFinderClassLoader(ResourceFinder resourceFinder, ClassLoader parent) {
-        super(parent);
-        this.resourceFinder = resourceFinder;
-    }
-
-    public ResourceFinder getResourceFinder() {
-        return this.resourceFinder;
-    }
-
-    /**
-     * @throws ClassNotFoundException
-     */
-    protected Class findClass(String className) throws ClassNotFoundException {
-
-        // Find the resource containing the class bytecode.
-        Resource classFileResource = this.resourceFinder.findResource(ClassFile.getClassFileResourceName(className));
-        if (classFileResource == null) throw new ClassNotFoundException(className);
-
-        // Open the class file resource.
-        InputStream is;
-        try {
-            is = classFileResource.open();
-        } catch (IOException ex) {
-            throw new RuntimeException("Opening class file resource \"" + classFileResource.getFileName() + "\": " + ex.getMessage());
-        }
-
-        // Read bytecode from the resource into a byte array.
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try {
-            byte[] buffer = new byte[4096];
-            for (;;) {
-                int bytesRead = is.read(buffer);
-                if (bytesRead == -1) break;
-                baos.write(buffer, 0, bytesRead);
-            }
-        } catch (IOException ex) {
-            throw new ClassNotFoundException("Reading class file from \"" + classFileResource + "\"", ex);
-        } finally {
-            try { is.close(); } catch (IOException ex) {}
-        }
-        byte[] ba = baos.toByteArray();
-
-        // Disassemble the the class bytecode(for debugging).
-        if (ResourceFinderClassLoader.DEBUG) {
-            System.out.println("*** Disassembly of class \"" + className + "\":");
-            try {
-                new Disassembler().disasm(new ByteArrayInputStream(ba));
-                System.out.flush();
-            } catch (IOException ex) {
-                throw new RuntimeException("SNO: IOException despite ByteArrayInputStream");
-            }
-        }
-
-        // Define the class in this ClassLoader.
-        Class clazz = super.defineClass(null, ba, 0, ba.length);
-
-        if (!clazz.getName().equals(className)) {
-
-            // This is a really complicated case: We may find a class file on
-            // the class path that seemingly defines the class we are looking
-            // for, but doesn't. This is possible if the underlying file system
-            // has case-insensitive file names and/or file names that are
-            // limited in length (e.g. DOS 8.3).
-            throw new ClassNotFoundException(className);
-        }
-
-        return clazz;
-    }
-}
diff --git a/src/org/codehaus/janino/util/StringPattern.java b/src/org/codehaus/janino/util/StringPattern.java
deleted file mode 100644
index 366b39a..0000000
--- a/src/org/codehaus/janino/util/StringPattern.java
+++ /dev/null
@@ -1,191 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import java.util.*;
-
-/**
- * Implementation of a UNIX shell-like string pattern algorithm.
- * <p>
- * Additionally, the concept of the "combined pattern" is supported (see
- * {@link #matches(StringPattern[], String)}.
- */
-public class StringPattern {
-
-    /**
-     * @see #matches(StringPattern[], String)
-     */
-    public final static int INCLUDE = 0;
-
-    /**
-     * @see #matches(StringPattern[], String)
-     */
-    public final static int EXCLUDE = 1;
-
-    private final int    mode;
-    private final String pattern;
-
-    public StringPattern(int mode, String pattern) {
-        this.mode    = mode;
-        this.pattern = pattern;
-    }
-
-    public StringPattern(String pattern) {
-        this.mode    = StringPattern.INCLUDE;
-        this.pattern = pattern;
-    }
-
-    public int getMode() { return this.mode; }
-
-    /**
-     * Match the given <code>text</code> against the pattern represented by the current instance,
-     * as follows:
-     * <ul>
-     *   <li>
-     *     A <code>*</code> in the pattern matches any sequence of zero or more characters in the
-     *     <code>text</code>
-     *   </li>
-     *   <li>
-     *     A <code>?</code> in the pattern matches exactly one character in the <code>text</code>
-     *   </li>
-     *   <li>
-     *     Any other character in the pattern must appear exactly as it is in the <code>text</code>
-     * </ul>
-     * Notice: The <code>mode</code> flag of the current instance does not take any effect here.
-     */
-    public boolean matches(String text) {
-        return StringPattern.wildmatch(this.pattern, text);
-    }
-
-    /**
-     * Parse a "combined pattern" into an array of {@link StringPattern}s. A combined pattern
-     * string is structured as follows:
-     * <pre>
-     *   combined-pattern :=
-     *     [ '+' | '-' ] pattern
-     *     { ( '+' | '-' ) pattern }
-     * </pre>
-     * If a pattern is preceeded with a '-', then the {@link StringPattern} is created with mode
-     * {@link #EXCLUDE}, otherwise with mode {@link #INCLUDE}.
-     */
-    public static StringPattern[] parseCombinedPattern(String combinedPattern) {
-        ArrayList al = new ArrayList();
-        for (int k = 0, l; k < combinedPattern.length(); k = l) {
-            int patternMode;
-            char c = combinedPattern.charAt(k);
-            if (c == '+') {
-                patternMode = StringPattern.INCLUDE;
-                ++k;
-            } else
-            if (c == '-') {
-                patternMode = StringPattern.EXCLUDE;
-                ++k;
-            } else {
-                patternMode = StringPattern.INCLUDE;
-            }
-            for (l = k; l < combinedPattern.length(); ++l) {
-                c = combinedPattern.charAt(l);
-                if (c == '+' || c == '-') break;
-            }
-            al.add(new StringPattern(patternMode, combinedPattern.substring(k, l)));
-        }
-        return (StringPattern[]) al.toArray(new StringPattern[al.size()]);
-    }
-
-    /**
-     * Match a given <code>text</code> against an array of {@link StringPattern}s (which was
-     * typically created by {@link #parseCombinedPattern(String)}.
-     * <p>
-     * The last matching pattern takes effect; if its mode is {@link #INCLUDE}, then
-     * <code>true</code> is returned, if its mode is {@link #EXCLUDE}, then <code>false</code> is
-     * returned.
-     * <p>
-     * If <code>patterns</code> is {@link #PATTERNS_NONE}, or empty, or none of its patterns
-     * matches, then <code>false</code> is returned.
-     * <p>
-     * If <code>patterns</code> is {@link #PATTERNS_ALL}, then <code>true</code> is
-     * returned.
-     * <p>
-     * For backwards compatibility, <code>null</code> patterns are treated like
-     * {@link #PATTERNS_NONE}.
-     */
-    public static boolean matches(StringPattern[] patterns, String text) {
-        if (patterns == null) return false; // Backwards compatibility -- previously, "null" was officially documented.
-
-        for (int i = patterns.length - 1; i >= 0; --i) {
-            if (patterns[i].matches(text)) {
-                return patterns[i].getMode() == StringPattern.INCLUDE;
-            } 
-        }
-        return false; // No patterns defined or no pattern matches.
-    }
-    public static StringPattern[] PATTERNS_ALL = new StringPattern[] { new StringPattern("*") };
-    public static StringPattern[] PATTERNS_NONE = new StringPattern[0];
-
-    public String toString() {
-        return (
-            this.mode == StringPattern.INCLUDE ? '+' :
-            this.mode == StringPattern.EXCLUDE ? '-' :
-            '?'
-        ) + this.pattern;
-    }
-
-    private static boolean wildmatch(String pattern, String text) {
-        int i;
-        for (i = 0; i < pattern.length(); ++i) {
-            char c = pattern.charAt(i);
-            switch (c) {
-
-            case '?':
-                if (i == text.length()) return false;
-                break;
-
-            case '*':
-                if (pattern.length() == i + 1) return true; // Optimization for trailing '*'.
-                pattern = pattern.substring(i + 1);
-                for (; i <= text.length(); ++i) {
-                    if (StringPattern.wildmatch(pattern, text.substring(i))) return true;
-                }
-                return false;
-
-            default:
-                if (i == text.length()) return false;
-                if (text.charAt(i) != c) return false;
-                break;
-            }
-        }
-        return text.length() == i;
-    }
-}
\ No newline at end of file
diff --git a/src/org/codehaus/janino/util/TeeReader.java b/src/org/codehaus/janino/util/TeeReader.java
deleted file mode 100644
index a519281..0000000
--- a/src/org/codehaus/janino/util/TeeReader.java
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import java.io.*;
-
-/**
- * A {@link java.io.FilterReader} that copies the bytes being passed through
- * to a given {@link java.io.Writer}. This is in analogy with the UNIX "tee" command.
- */
-public class TeeReader extends FilterReader {
-    private final Writer  out;
-    private final boolean closeWriterOnEOF;
-
-    public TeeReader(Reader in, Writer out, boolean closeWriterOnEOF) {
-        super(in);
-        this.out              = out;
-        this.closeWriterOnEOF = closeWriterOnEOF;
-    }
-    public void close() throws IOException {
-        this.in.close();
-        this.out.close();
-    }
-    public int read() throws IOException {
-        int c = this.in.read();
-        if (c == -1) {
-            if (this.closeWriterOnEOF) {
-                this.out.close();
-            } else {
-                this.out.flush();
-            }
-        } else {
-            this.out.write(c);
-        }
-        return c;
-    }
-    public int read(char[] cbuf, int off, int len) throws IOException {
-        int bytesRead = this.in.read(cbuf, off, len);
-        if (bytesRead == -1) {
-            if (this.closeWriterOnEOF) {
-                this.out.close();
-            } else {
-                this.out.flush();
-            }
-        } else {
-            this.out.write(cbuf, off, bytesRead);
-        }
-        return bytesRead;
-    }
-}
diff --git a/src/org/codehaus/janino/util/Traverser.java b/src/org/codehaus/janino/util/Traverser.java
deleted file mode 100644
index 4b4d92b..0000000
--- a/src/org/codehaus/janino/util/Traverser.java
+++ /dev/null
@@ -1,599 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util;
-
-import org.codehaus.janino.*;
-import org.codehaus.janino.Java.CompilationUnit.*;
-import org.codehaus.janino.Visitor.ComprehensiveVisitor;
-
-import java.util.*;
-
-/**
- * This class traverses the subnodes of an AST. Derived classes may override
- * individual methods to process specific nodes, e.g.:<pre>
- *     LocalClassDeclaration lcd = ...;
- *     lcd.accept(new Traverser() {
- *         int n = 0;
- *         public void traverseMethodDeclarator(Java.MethodDeclarator md) {
- *             ++this.n;
- *             super.traverseMethodDeclarator(md);
- *         }
- *     }.comprehensiveVisitor());</pre>
- */
-public class Traverser {
-    private final Visitor.ComprehensiveVisitor cv = new Visitor.ComprehensiveVisitor() {
-        public final void visitSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid)      { Traverser.this.traverseSingleTypeImportDeclaration(stid); }
-        public final void visitTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) { Traverser.this.traverseTypeImportOnDemandDeclaration(tiodd); }
-        public final void visitSingleStaticImportDeclaration(SingleStaticImportDeclaration ssid)                       { Traverser.this.traverseSingleStaticImportDeclaration(ssid); }
-        public final void visitStaticImportOnDemandDeclaration(StaticImportOnDemandDeclaration siodd)                  { Traverser.this.traverseStaticImportOnDemandDeclaration(siodd); }
-        public final void visitAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd)                  { Traverser.this.traverseAnonymousClassDeclaration(acd); }
-        public final void visitLocalClassDeclaration(Java.LocalClassDeclaration lcd)                          { Traverser.this.traverseLocalClassDeclaration(lcd); }
-        public final void visitPackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd)         { Traverser.this.traversePackageMemberClassDeclaration(pmcd); }
-        public final void visitMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid)                { Traverser.this.traverseMemberInterfaceDeclaration(mid); }
-        public final void visitPackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) { Traverser.this.traversePackageMemberInterfaceDeclaration(pmid); }
-        public final void visitMemberClassDeclaration(Java.MemberClassDeclaration mcd)                        { Traverser.this.traverseMemberClassDeclaration(mcd); }
-        public final void visitConstructorDeclarator(Java.ConstructorDeclarator cd)                           { Traverser.this.traverseConstructorDeclarator(cd); }
-        public final void visitInitializer(Java.Initializer i)                                                { Traverser.this.traverseInitializer(i); }
-        public final void visitMethodDeclarator(Java.MethodDeclarator md)                                     { Traverser.this.traverseMethodDeclarator(md); }
-        public final void visitFieldDeclaration(Java.FieldDeclaration fd)                                     { Traverser.this.traverseFieldDeclaration(fd); }
-        public final void visitLabeledStatement(Java.LabeledStatement ls)                                     { Traverser.this.traverseLabeledStatement(ls); }
-        public final void visitBlock(Java.Block b)                                                            { Traverser.this.traverseBlock(b); }
-        public final void visitExpressionStatement(Java.ExpressionStatement es)                               { Traverser.this.traverseExpressionStatement(es); }
-        public final void visitIfStatement(Java.IfStatement is)                                               { Traverser.this.traverseIfStatement(is); }
-        public final void visitForStatement(Java.ForStatement fs)                                             { Traverser.this.traverseForStatement(fs); }
-        public final void visitWhileStatement(Java.WhileStatement ws)                                         { Traverser.this.traverseWhileStatement(ws); }
-        public final void visitTryStatement(Java.TryStatement ts)                                             { Traverser.this.traverseTryStatement(ts); }
-        public final void visitSwitchStatement(Java.SwitchStatement ss)                                       { Traverser.this.traverseSwitchStatement(ss); }
-        public final void visitSynchronizedStatement(Java.SynchronizedStatement ss)                           { Traverser.this.traverseSynchronizedStatement(ss); }
-        public final void visitDoStatement(Java.DoStatement ds)                                               { Traverser.this.traverseDoStatement(ds); }
-        public final void visitLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) { Traverser.this.traverseLocalVariableDeclarationStatement(lvds); }
-        public final void visitReturnStatement(Java.ReturnStatement rs)                                       { Traverser.this.traverseReturnStatement(rs); }
-        public final void visitThrowStatement(Java.ThrowStatement ts)                                         { Traverser.this.traverseThrowStatement(ts); }
-        public final void visitBreakStatement(Java.BreakStatement bs)                                         { Traverser.this.traverseBreakStatement(bs); }
-        public final void visitContinueStatement(Java.ContinueStatement cs)                                   { Traverser.this.traverseContinueStatement(cs); }
-        public final void visitEmptyStatement(Java.EmptyStatement es)                                         { Traverser.this.traverseEmptyStatement(es); }
-        public final void visitLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds)       { Traverser.this.traverseLocalClassDeclarationStatement(lcds); }
-        public final void visitPackage(Java.Package p)                                                        { Traverser.this.traversePackage(p); }
-        public final void visitArrayLength(Java.ArrayLength al)                                               { Traverser.this.traverseArrayLength(al); }
-        public final void visitAssignment(Java.Assignment a)                                                  { Traverser.this.traverseAssignment(a); }
-        public final void visitUnaryOperation(Java.UnaryOperation uo)                                         { Traverser.this.traverseUnaryOperation(uo); }
-        public final void visitBinaryOperation(Java.BinaryOperation bo)                                       { Traverser.this.traverseBinaryOperation(bo); }
-        public final void visitCast(Java.Cast c)                                                              { Traverser.this.traverseCast(c); }
-        public final void visitClassLiteral(Java.ClassLiteral cl)                                             { Traverser.this.traverseClassLiteral(cl); }
-        public final void visitConditionalExpression(Java.ConditionalExpression ce)                           { Traverser.this.traverseConditionalExpression(ce); }
-        public final void visitCrement(Java.Crement c)                                                        { Traverser.this.traverseCrement(c); }
-        public final void visitInstanceof(Java.Instanceof io)                                                 { Traverser.this.traverseInstanceof(io); }
-        public final void visitMethodInvocation(Java.MethodInvocation mi)                                     { Traverser.this.traverseMethodInvocation(mi); }
-        public final void visitSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi)                { Traverser.this.traverseSuperclassMethodInvocation(smi); }
-        public final void visitLiteral(Java.Literal l)                                                        { Traverser.this.traverseLiteral(l); }
-        public final void visitNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci)                 { Traverser.this.traverseNewAnonymousClassInstance(naci); }
-        public final void visitNewArray(Java.NewArray na)                                                     { Traverser.this.traverseNewArray(na); }
-        public final void visitNewInitializedArray(Java.NewInitializedArray nia)                              { Traverser.this.traverseNewInitializedArray(nia); }
-        public final void visitNewClassInstance(Java.NewClassInstance nci)                                    { Traverser.this.traverseNewClassInstance(nci); }
-        public final void visitParameterAccess(Java.ParameterAccess pa)                                       { Traverser.this.traverseParameterAccess(pa); }
-        public final void visitQualifiedThisReference(Java.QualifiedThisReference qtr)                        { Traverser.this.traverseQualifiedThisReference(qtr); }
-        public final void visitThisReference(Java.ThisReference tr)                                           { Traverser.this.traverseThisReference(tr); }
-        public final void visitArrayType(Java.ArrayType at)                                                   { Traverser.this.traverseArrayType(at); }
-        public final void visitBasicType(Java.BasicType bt)                                                   { Traverser.this.traverseBasicType(bt); }
-        public final void visitReferenceType(Java.ReferenceType rt)                                           { Traverser.this.traverseReferenceType(rt); }
-        public final void visitRvalueMemberType(Java.RvalueMemberType rmt)                                    { Traverser.this.traverseRvalueMemberType(rmt); }
-        public final void visitSimpleType(Java.SimpleType st)                                                 { Traverser.this.traverseSimpleType(st); }
-        public final void visitAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci)        { Traverser.this.traverseAlternateConstructorInvocation(aci); }
-        public final void visitSuperConstructorInvocation(Java.SuperConstructorInvocation sci)                { Traverser.this.traverseSuperConstructorInvocation(sci); }
-        public final void visitAmbiguousName(Java.AmbiguousName an)                                           { Traverser.this.traverseAmbiguousName(an); }
-        public final void visitArrayAccessExpression(Java.ArrayAccessExpression aae)                          { Traverser.this.traverseArrayAccessExpression(aae); }
-        public final void visitFieldAccess(Java.FieldAccess fa)                                               { Traverser.this.traverseFieldAccess(fa); }
-        public final void visitFieldAccessExpression(Java.FieldAccessExpression fae)                          { Traverser.this.traverseFieldAccessExpression(fae); }
-        public final void visitSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae)    { Traverser.this.traverseSuperclassFieldAccessExpression(scfae); }
-        public final void visitLocalVariableAccess(Java.LocalVariableAccess lva)                              { Traverser.this.traverseLocalVariableAccess(lva); }
-        public final void visitParenthesizedExpression(Java.ParenthesizedExpression pe)                       { Traverser.this.traverseParenthesizedExpression(pe); }
-    };
- 
-    public ComprehensiveVisitor comprehensiveVisitor() {
-        return this.cv;
-    }
-
-    // These may be overridden by derived classes.
-
-    public void traverseCompilationUnit(Java.CompilationUnit cu) {
-
-        // The optionalPackageDeclaration is considered an integral part of
-        // the compilation unit and is thus not traversed.
-
-        for (Iterator it = cu.importDeclarations.iterator(); it.hasNext();) {
-            ((Java.CompilationUnit.ImportDeclaration) it.next()).accept(this.cv);
-        }
-        for (Iterator it = cu.packageMemberTypeDeclarations.iterator(); it.hasNext();) {
-            ((Java.PackageMemberTypeDeclaration) it.next()).accept(this.cv);
-        }
-    }
-
-    public void traverseSingleTypeImportDeclaration(Java.CompilationUnit.SingleTypeImportDeclaration stid) {
-        this.traverseImportDeclaration(stid);
-    }
-
-    public void traverseTypeImportOnDemandDeclaration(Java.CompilationUnit.TypeImportOnDemandDeclaration tiodd) {
-        this.traverseImportDeclaration(tiodd);
-    }
-
-    public void traverseSingleStaticImportDeclaration(Java.CompilationUnit.SingleStaticImportDeclaration stid) {
-        this.traverseImportDeclaration(stid);
-    }
-
-    public void traverseStaticImportOnDemandDeclaration(Java.CompilationUnit.StaticImportOnDemandDeclaration siodd) {
-        this.traverseImportDeclaration(siodd);
-    }
-
-    public void traverseImportDeclaration(Java.CompilationUnit.ImportDeclaration id) {
-        this.traverseLocated(id);
-    }
-
-    public void traverseAnonymousClassDeclaration(Java.AnonymousClassDeclaration acd) {
-        acd.baseType.accept((Visitor.TypeVisitor) this.cv);
-        this.traverseClassDeclaration(acd);
-    }
-
-    public void traverseLocalClassDeclaration(Java.LocalClassDeclaration lcd) {
-        this.traverseNamedClassDeclaration(lcd);
-    }
-
-    public void traversePackageMemberClassDeclaration(Java.PackageMemberClassDeclaration pmcd) {
-        this.traverseNamedClassDeclaration(pmcd);
-    }
-
-    public void traverseMemberInterfaceDeclaration(Java.MemberInterfaceDeclaration mid) {
-        this.traverseInterfaceDeclaration(mid);
-    }
-
-    public void traversePackageMemberInterfaceDeclaration(Java.PackageMemberInterfaceDeclaration pmid) {
-        this.traverseInterfaceDeclaration(pmid);
-    }
-
-    public void traverseMemberClassDeclaration(Java.MemberClassDeclaration mcd) {
-        this.traverseNamedClassDeclaration(mcd);
-    }
-
-    public void traverseConstructorDeclarator(Java.ConstructorDeclarator cd) {
-        if (cd.optionalConstructorInvocation != null) cd.optionalConstructorInvocation.accept((Visitor.BlockStatementVisitor) this.cv);
-        this.traverseFunctionDeclarator(cd);
-    }
-
-    public void traverseInitializer(Java.Initializer i) {
-        i.block.accept(this.cv);
-        this.traverseAbstractTypeBodyDeclaration(i);
-    }
-
-    public void traverseMethodDeclarator(Java.MethodDeclarator md) {
-        this.traverseFunctionDeclarator(md);
-    }
-
-    public void traverseFieldDeclaration(Java.FieldDeclaration fd) {
-        fd.type.accept((Visitor.TypeVisitor) this.cv);
-        for (int i = 0; i < fd.variableDeclarators.length; ++i) {
-            Java.ArrayInitializerOrRvalue optionalInitializer = fd.variableDeclarators[i].optionalInitializer;
-            if (optionalInitializer != null) this.traverseArrayInitializerOrRvalue(optionalInitializer);
-        }
-        this.traverseStatement(fd);
-    }
-
-    public void traverseLabeledStatement(Java.LabeledStatement ls) {
-        ls.body.accept(this.cv);
-        this.traverseBreakableStatement(ls);
-    }
-
-    public void traverseBlock(Java.Block b) {
-        for (Iterator it = b.statements.iterator(); it.hasNext();) {
-            ((Java.Statement) it.next()).accept(this.cv);
-        }
-        this.traverseStatement(b);
-    }
-
-    public void traverseExpressionStatement(Java.ExpressionStatement es) {
-        es.rvalue.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseStatement(es);
-    }
-
-    public void traverseIfStatement(Java.IfStatement is) {
-        is.condition.accept((Visitor.RvalueVisitor) this.cv);
-        is.thenStatement.accept(this.cv);
-        if (is.optionalElseStatement != null) is.optionalElseStatement.accept(this.cv);
-        this.traverseStatement(is);
-    }
-
-    public void traverseForStatement(Java.ForStatement fs) {
-        if (fs.optionalInit != null) fs.optionalInit.accept(this.cv);
-        if (fs.optionalCondition != null) fs.optionalCondition.accept((Visitor.RvalueVisitor) this.cv);
-        if (fs.optionalUpdate != null) {
-            for (int i = 0; i < fs.optionalUpdate.length; ++i) fs.optionalUpdate[i].accept((Visitor.RvalueVisitor) this.cv);
-        }
-        fs.body.accept(this.cv);
-        this.traverseContinuableStatement(fs);
-    }
-
-    public void traverseWhileStatement(Java.WhileStatement ws) {
-        ws.condition.accept((Visitor.RvalueVisitor) this.cv);
-        ws.body.accept(this.cv);
-        this.traverseContinuableStatement(ws);
-    }
-
-    public void traverseTryStatement(Java.TryStatement ts) {
-        ts.body.accept(this.cv);
-        for (Iterator it = ts.catchClauses.iterator(); it.hasNext();) {
-            ((Java.CatchClause) it.next()).body.accept(this.cv);
-        }
-        if (ts.optionalFinally != null) ts.optionalFinally.accept(this.cv);
-        this.traverseStatement(ts);
-    }
-
-    public void traverseSwitchStatement(Java.SwitchStatement ss) {
-        ss.condition.accept((Visitor.RvalueVisitor) this.cv);
-        for (Iterator it = ss.sbsgs.iterator(); it.hasNext();) {
-            Java.SwitchStatement.SwitchBlockStatementGroup sbsg = (Java.SwitchStatement.SwitchBlockStatementGroup) it.next();
-            for (Iterator it2 = sbsg.caseLabels.iterator(); it2.hasNext();) {
-                ((Java.Rvalue) it2.next()).accept((Visitor.RvalueVisitor) this.cv);
-            }
-            for (Iterator it2 = sbsg.blockStatements.iterator(); it2.hasNext();) {
-                ((Java.BlockStatement) it2.next()).accept(this.cv);
-            }
-            this.traverseLocated(sbsg);
-        }
-        this.traverseBreakableStatement(ss);
-    }
-
-    public void traverseSynchronizedStatement(Java.SynchronizedStatement ss) {
-        ss.expression.accept((Visitor.RvalueVisitor) this.cv);
-        ss.body.accept(this.cv);
-        this.traverseStatement(ss);
-    }
-
-    public void traverseDoStatement(Java.DoStatement ds) {
-        ds.body.accept(this.cv);
-        ds.condition.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseContinuableStatement(ds);
-    }
-
-    public void traverseLocalVariableDeclarationStatement(Java.LocalVariableDeclarationStatement lvds) {
-        lvds.type.accept((Visitor.TypeVisitor) this.cv);
-        for (int i = 0; i < lvds.variableDeclarators.length; ++i) {
-            Java.ArrayInitializerOrRvalue optionalInitializer = lvds.variableDeclarators[i].optionalInitializer;
-            if (optionalInitializer != null) this.traverseArrayInitializerOrRvalue(optionalInitializer);
-        }
-        this.traverseStatement(lvds);
-    }
-
-    public void traverseReturnStatement(Java.ReturnStatement rs) {
-        if (rs.optionalReturnValue != null) rs.optionalReturnValue.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseStatement(rs);
-    }
-
-    public void traverseThrowStatement(Java.ThrowStatement ts) {
-        ts.expression.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseStatement(ts);
-    }
-
-    public void traverseBreakStatement(Java.BreakStatement bs) {
-        this.traverseStatement(bs);
-    }
-
-    public void traverseContinueStatement(Java.ContinueStatement cs) {
-        this.traverseStatement(cs);
-    }
-
-    public void traverseEmptyStatement(Java.EmptyStatement es) {
-        this.traverseStatement(es);
-    }
-
-    public void traverseLocalClassDeclarationStatement(Java.LocalClassDeclarationStatement lcds) {
-        lcds.lcd.accept(this.cv);
-        this.traverseStatement(lcds);
-    }
-
-    public void traversePackage(Java.Package p) {
-        this.traverseAtom(p);
-    }
-
-    public void traverseArrayLength(Java.ArrayLength al) {
-        al.lhs.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseRvalue(al);
-    }
-
-    public void traverseAssignment(Java.Assignment a) {
-        a.lhs.accept((Visitor.LvalueVisitor) this.cv);
-        a.rhs.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseRvalue(a);
-    }
-
-    public void traverseUnaryOperation(Java.UnaryOperation uo) {
-        uo.operand.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseBooleanRvalue(uo);
-    }
-
-    public void traverseBinaryOperation(Java.BinaryOperation bo) {
-        bo.lhs.accept((Visitor.RvalueVisitor) this.cv);
-        bo.rhs.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseBooleanRvalue(bo);
-    }
-
-    public void traverseCast(Java.Cast c) {
-        c.targetType.accept((Visitor.TypeVisitor) this.cv);
-        c.value.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseRvalue(c);
-    }
-
-    public void traverseClassLiteral(Java.ClassLiteral cl) {
-        cl.type.accept((Visitor.TypeVisitor) this.cv);
-        this.traverseRvalue(cl);
-    }
-
-    public void traverseConditionalExpression(Java.ConditionalExpression ce) {
-        ce.lhs.accept((Visitor.RvalueVisitor) this.cv);
-        ce.mhs.accept((Visitor.RvalueVisitor) this.cv);
-        ce.rhs.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseRvalue(ce);
-    }
-
-    public void traverseCrement(Java.Crement c) {
-        c.operand.accept((Visitor.LvalueVisitor) this.cv);
-        this.traverseRvalue(c);
-    }
-
-    public void traverseInstanceof(Java.Instanceof io) {
-        io.lhs.accept((Visitor.RvalueVisitor) this.cv);
-        io.rhs.accept((Visitor.TypeVisitor) this.cv);
-        this.traverseRvalue(io);
-    }
-
-    public void traverseMethodInvocation(Java.MethodInvocation mi) {
-        if (mi.optionalTarget != null) mi.optionalTarget.accept(this.cv);
-        this.traverseInvocation(mi);
-    }
-
-    public void traverseSuperclassMethodInvocation(Java.SuperclassMethodInvocation smi) {
-        this.traverseInvocation(smi);
-    }
-
-    public void traverseLiteral(Java.Literal l) {
-        this.traverseRvalue(l);
-    }
-
-    public void traverseNewAnonymousClassInstance(Java.NewAnonymousClassInstance naci) {
-        if (naci.optionalQualification != null) naci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
-        naci.anonymousClassDeclaration.accept(this.cv);
-        for (int i = 0; i < naci.arguments.length; ++i) naci.arguments[i].accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseRvalue(naci);
-    }
-
-    public void traverseNewArray(Java.NewArray na) {
-        na.type.accept((Visitor.TypeVisitor) this.cv);
-        for (int i =  0; i < na.dimExprs.length; ++i) na.dimExprs[i].accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseRvalue(na);
-    }
-
-    public void traverseNewInitializedArray(Java.NewInitializedArray nia) {
-        nia.arrayType.accept((Visitor.TypeVisitor) this.cv);
-        this.traverseArrayInitializerOrRvalue(nia.arrayInitializer);
-    }
-
-    public void traverseArrayInitializerOrRvalue(Java.ArrayInitializerOrRvalue aiorv) {
-        if (aiorv instanceof Java.Rvalue) {
-            ((Java.Atom) aiorv).accept(this.cv);
-        } else
-        if (aiorv instanceof Java.ArrayInitializer) {
-            Java.ArrayInitializerOrRvalue[] values = ((Java.ArrayInitializer) aiorv).values;
-            for (int i = 0; i < values.length; ++i) this.traverseArrayInitializerOrRvalue(values[i]);
-        } else
-        {
-            throw new RuntimeException("Unexpected array initializer or rvalue class " + aiorv.getClass().getName());
-        }
-    }
-    public void traverseNewClassInstance(Java.NewClassInstance nci) {
-        if (nci.optionalQualification != null) nci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
-        nci.type.accept((Visitor.TypeVisitor) this.cv);
-        for (int i = 0; i < nci.arguments.length; ++i) nci.arguments[i].accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseRvalue(nci);
-    }
-
-    public void traverseParameterAccess(Java.ParameterAccess pa) {
-        this.traverseRvalue(pa);
-    }
-
-    public void traverseQualifiedThisReference(Java.QualifiedThisReference qtr) {
-        qtr.qualification.accept((Visitor.TypeVisitor) this.cv);
-        this.traverseRvalue(qtr);
-    }
-
-    public void traverseThisReference(Java.ThisReference tr) {
-        this.traverseRvalue(tr);
-    }
-
-    public void traverseArrayType(Java.ArrayType at) {
-        at.componentType.accept((Visitor.TypeVisitor) this.cv);
-        this.traverseType(at);
-    }
-
-    public void traverseBasicType(Java.BasicType bt) {
-        this.traverseType(bt);
-    }
-
-    public void traverseReferenceType(Java.ReferenceType rt) {
-        this.traverseType(rt);
-    }
-
-    public void traverseRvalueMemberType(Java.RvalueMemberType rmt) {
-        rmt.rvalue.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseType(rmt);
-    }
-
-    public void traverseSimpleType(Java.SimpleType st) {
-        this.traverseType(st);
-    }
-
-    public void traverseAlternateConstructorInvocation(Java.AlternateConstructorInvocation aci) {
-        this.traverseConstructorInvocation(aci);
-    }
-
-    public void traverseSuperConstructorInvocation(Java.SuperConstructorInvocation sci) {
-        if (sci.optionalQualification != null) sci.optionalQualification.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseConstructorInvocation(sci);
-    }
-
-    public void traverseAmbiguousName(Java.AmbiguousName an) {
-        this.traverseLvalue(an);
-    }
-
-    public void traverseArrayAccessExpression(Java.ArrayAccessExpression aae) {
-        aae.lhs.accept((Visitor.RvalueVisitor) this.cv);
-        ((Java.Atom) aae.index).accept(this.cv);
-        this.traverseLvalue(aae);
-    }
-
-    public void traverseFieldAccess(Java.FieldAccess fa) {
-        fa.lhs.accept(this.cv);
-        this.traverseLvalue(fa);
-    }
-
-    public void traverseFieldAccessExpression(Java.FieldAccessExpression fae) {
-        fae.lhs.accept(this.cv);
-        this.traverseLvalue(fae);
-    }
-
-    public void traverseSuperclassFieldAccessExpression(Java.SuperclassFieldAccessExpression scfae) {
-        if (scfae.optionalQualification != null) scfae.optionalQualification.accept((Visitor.TypeVisitor) this.cv);
-        this.traverseLvalue(scfae);
-    }
-    
-    public void traverseLocalVariableAccess(Java.LocalVariableAccess lva) {
-        this.traverseLvalue(lva);
-    }
-
-    public void traverseParenthesizedExpression(Java.ParenthesizedExpression pe) {
-        pe.value.accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseLvalue(pe);
-    }
-
-    public void traverseClassDeclaration(Java.ClassDeclaration cd) {
-        for (Iterator it = cd.constructors.iterator(); it.hasNext();) {
-            ((Java.ConstructorDeclarator) it.next()).accept(this.cv);
-        }
-        for (Iterator it = cd.variableDeclaratorsAndInitializers.iterator(); it.hasNext();) {
-            ((Java.TypeBodyDeclaration) it.next()).accept(this.cv);
-        }
-        this.traverseAbstractTypeDeclaration(cd);
-    }
-
-    public void traverseAbstractTypeDeclaration(Java.AbstractTypeDeclaration atd) {
-        for (Iterator it = atd.declaredClassesAndInterfaces.iterator(); it.hasNext();) {
-            ((Java.NamedTypeDeclaration) it.next()).accept(this.cv);
-        }
-        for (Iterator it = atd.declaredMethods.iterator(); it.hasNext();) {
-            this.traverseMethodDeclarator((Java.MethodDeclarator) it.next());
-        }
-    }
-
-    public void traverseNamedClassDeclaration(Java.NamedClassDeclaration ncd) {
-        for (int i = 0; i < ncd.implementedTypes.length; ++i) {
-            ncd.implementedTypes[i].accept((Visitor.TypeVisitor) this.cv);
-        }
-        if (ncd.optionalExtendedType != null) ncd.optionalExtendedType.accept((Visitor.TypeVisitor) this.cv);
-        this.traverseClassDeclaration(ncd);
-    }
-
-    public void traverseInterfaceDeclaration(Java.InterfaceDeclaration id) {
-        for (Iterator it = id.constantDeclarations.iterator(); it.hasNext();) {
-            ((Java.TypeBodyDeclaration) it.next()).accept(this.cv);
-        }
-        for (int i = 0; i < id.extendedTypes.length; ++i) {
-            id.extendedTypes[i].accept((Visitor.TypeVisitor) this.cv);
-        }
-        this.traverseAbstractTypeDeclaration(id);
-    }
-
-    public void traverseFunctionDeclarator(Java.FunctionDeclarator fd) {
-        for (int i = 0; i < fd.formalParameters.length; ++i) {
-            fd.formalParameters[i].type.accept((Visitor.TypeVisitor) this.cv);
-        }
-        if (fd.optionalBody != null) fd.optionalBody.accept(this.cv);
-    }
-
-    public void traverseAbstractTypeBodyDeclaration(Java.AbstractTypeBodyDeclaration atbd) {
-        this.traverseLocated(atbd);
-    }
-
-    public void traverseStatement(Java.Statement s) {
-        this.traverseLocated(s);
-    }
-
-    public void traverseBreakableStatement(Java.BreakableStatement bs) {
-        this.traverseStatement(bs);
-    }
-
-    public void traverseContinuableStatement(Java.ContinuableStatement cs) {
-        this.traverseBreakableStatement(cs);
-    }
-
-    public void traverseRvalue(Java.Rvalue rv) {
-        this.traverseAtom(rv);
-    }
-
-    public void traverseBooleanRvalue(Java.BooleanRvalue brv) {
-        this.traverseRvalue(brv);
-    }
-
-    public void traverseInvocation(Java.Invocation i) {
-        for (int j = 0; j < i.arguments.length; ++j) i.arguments[j].accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseRvalue(i);
-    }
-
-    public void traverseConstructorInvocation(Java.ConstructorInvocation ci) {
-        for (int i = 0; i < ci.arguments.length; ++i) ci.arguments[i].accept((Visitor.RvalueVisitor) this.cv);
-        this.traverseAtom(ci);
-    }
-
-    public void traverseLvalue(Java.Lvalue lv) {
-        this.traverseRvalue(lv);
-    }
-
-    public void traverseType(Java.Type t) {
-        this.traverseAtom(t);
-    }
-
-    public void traverseAtom(Java.Atom a) {
-        this.traverseLocated(a);
-    }
-
-    public void traverseLocated(Java.Located l) {
-        ;
-    }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/Enumerator.java b/src/org/codehaus/janino/util/enumerator/Enumerator.java
deleted file mode 100644
index feca99a..0000000
--- a/src/org/codehaus/janino/util/enumerator/Enumerator.java
+++ /dev/null
@@ -1,143 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.enumerator;
-
-import java.util.*;
-
-/**
- * A class that represents an enumerated value. Its main features are its {@link #toString()} and
- * {@link #fromString(String, Class)} method, which map names to values and vice versa.
- * <p>
- * To use this class, derive from it and define one or more
- * <code>public static final</code> fields, as follows:
- * <pre>
- * public final class Suit extends Enumerator {
- * 
- *     // Exactly N instances of "Suit" exist to represent the N possible values.
- *     public static final Suit CLUBS    = new Suit("clubs");
- *     public static final Suit DIAMONDS = new Suit("diamonds");
- *     public static final Suit HEARTS   = new Suit("hearts");
- *     public static final Suit SPADES   = new Suit("spades");
- *
- *     // Optional, if you want to use EumeratorSet arithmetics.
- *     public static final EnumeratorSet NONE = new EnumeratorSet(Suit.class      ).setName("none");
- *     public static final EnumeratorSet ALL  = new EnumeratorSet(Suit.class, true).setName("all");
- * 
- *     // These MUST be declared exactly like this:
- *     private Suit(String name) { super(name); }
- *     public static Suit fromString(String name) throws EnumeratorFormatException {
- *         return (Suit) Enumerator.fromString(name, Suit.class);
- *     }
- * }
- * </pre>
- * 
- * @see <a href="http://java.sun.com/developer/Books/effectivejava/Chapter5.pdf">Effective Java, Item 21</a>
- * @see org.codehaus.janino.util.enumerator.EnumeratorSet
- */
-public abstract class Enumerator {
-    /*package*/ final String name;
-
-    /**
-     * Class enumeratorClass => Map: String name => Enumerator
-     */
-    private static final Map instances = Collections.synchronizedMap(new HashMap());
-
-    /**
-     * Initialize the enumerator to the given value.
-     */
-    protected Enumerator(String name) {
-        if (name == null) throw new NullPointerException();
-        this.name = name;
-
-        Enumerator.getInstances(this.getClass()).put(name, this);
-    }
-
-    /**
-     * Equality is reference identity.
-     */
-    public final boolean equals(Object that) {
-        return this == that;
-    }
-
-    /**
-     * Enforce {@link Object}'s notion of {@link Object#hashCode()}.
-     */
-    public final int hashCode() {
-        return super.hashCode();
-    }
-
-    /**
-     * Returns a mapping of name to Enumerator for the given enumeratorClass.
-     */
-    /*package*/ static Map getInstances(Class enumeratorClass) {
-        Map m = (Map) Enumerator.instances.get(enumeratorClass);
-        if (m != null) return m;
-
-        // The map need not be synchronized because it is modified only during initialization
-        // of the Enumerator.
-        m = new HashMap();
-        Enumerator.instances.put(enumeratorClass, m);
-        return m;
-    }
-
-    /**
-     * Initialize an {@link Enumerator} from a string.
-     * <p>
-     * The given string is converted into a value by looking at all instances of the given type
-     * created so far.
-     * <p>
-     * Derived classes should invoke this method as follows:<pre>
-     * public class Suit extends Enumerator {
-     *     ...
-     *     public static Suit fromString(String name) throws EnumeratorFormatException {
-     *         return (Suit) Enumerator.fromString(name, Suit.class);
-     *     }
-     * }</pre>
-     * 
-     * @throws EnumeratorFormatException if the string cannot be identified
-     */
-    protected static final Enumerator fromString(String name, Class enumeratorClass) throws EnumeratorFormatException {
-        Enumerator value = (Enumerator) Enumerator.getInstances(enumeratorClass).get(name);
-        if (value == null) throw new EnumeratorFormatException(name);
-        return value;
-    }
-
-    /**
-     * Returns the <code>name</code> passed to {@link #Enumerator(String)}.
-     */
-    public String toString() {
-        return this.name;
-    }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/EnumeratorFormatException.java b/src/org/codehaus/janino/util/enumerator/EnumeratorFormatException.java
deleted file mode 100644
index d5c0016..0000000
--- a/src/org/codehaus/janino/util/enumerator/EnumeratorFormatException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.enumerator;
-
-/**
- * Represents a problem related to parsing {@link org.codehaus.janino.util.enumerator.Enumerator}s
- * and {@link org.codehaus.janino.util.enumerator.EnumeratorSet}s, in analogy with
- * {@link EnumeratorFormatException}.
- */
-public class EnumeratorFormatException extends Exception {
-    public EnumeratorFormatException()               {}
-    public EnumeratorFormatException(String message) { super(message); }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/EnumeratorSet.java b/src/org/codehaus/janino/util/enumerator/EnumeratorSet.java
deleted file mode 100644
index ed7581c..0000000
--- a/src/org/codehaus/janino/util/enumerator/EnumeratorSet.java
+++ /dev/null
@@ -1,324 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.enumerator;
-
-import java.util.*;
-
-/**
- * A class that represents an immutable set of {@link Enumerator}s.
- * <p>
- * Its main features are its constructor, which initializes the object from a clear-text string,
- * and its {@link #toString()} method, which reconstructs the clear text values.
- * <p>
- * Sample code can be found in the documentation of {@link Enumerator}.
- */
-public class EnumeratorSet {
-    private final Class enumeratorClass;
-    private final Set   values;  // Enumerator-derived class
-    /*package*/ String  optionalName = null;
-
-    private EnumeratorSet(Class enumeratorClass, Set values) {
-        this.enumeratorClass = enumeratorClass;
-        this.values          = values;
-    }
-
-    /**
-     * Construct an empty set for values of the given {@link Enumerator}-derived type.
-     */
-    public EnumeratorSet(Class enumeratorClass) {
-        this(enumeratorClass, new HashSet());
-    }
-
-    /**
-     * Construct a set for values of the given {@link Enumerator}-derived type. If the
-     * <code>full</code> flag is <code>true</code>, all possible values are added to the set.
-     */
-    public EnumeratorSet(Class enumeratorClass, boolean full) {
-        this(enumeratorClass, new HashSet());
-        if (full) this.values.addAll(Enumerator.getInstances(enumeratorClass).values());
-    }
-
-    /**
-     * Construct a set for values of the given {@link Enumerator}-derived type and initialize it
-     * from a string.
-     * <p>
-     * Equivalent to <code>EnumeratorSet(enumeratorClass, s, ",")</code>.
-     */
-    public EnumeratorSet(Class enumeratorClass, String s) throws EnumeratorFormatException {
-        this(enumeratorClass, s, ",");
-    }
-
-    /**
-     * Construct a set for values of the given {@link Enumerator}-derived type and initialize it
-     * from a string.
-     * <p>
-     * The given string is parsed into tokens; each token is converted into a value as
-     * {@link Enumerator#fromString(String, Class)} does and added to this set. Named {@link EnumeratorSet}s
-     * declared in the <code>enumeratorClass</code> are also recognized and added. If the string names exactly one
-     * of those {@link EnumeratorSet}s declared in the <code>enumeratorClass</code>, then the resulting set
-     * inherits the name of theat {@link EnumeratorSet}.
-     * 
-     * @throws EnumeratorFormatException if a token cannot be identified
-     */
-    public EnumeratorSet(
-        Class   enumeratorClass,
-        String  s,
-        String  delimiter
-    ) throws EnumeratorFormatException {
-        Set vs = new HashSet();
-
-        Map des  = Enumerator.getInstances(enumeratorClass);
-        Map dess = EnumeratorSet.getNamedEnumeratorSets(enumeratorClass);
-
-        StringTokenizer st = new StringTokenizer(s, delimiter);
-        while (st.hasMoreTokens()) {
-            String name = st.nextToken();
-            Enumerator value = (Enumerator) des.get(name);
-            if (value != null) {
-                vs.add(value);
-                continue;
-            }
-
-            EnumeratorSet es = (EnumeratorSet) dess.get(name);
-            if (es != null) {
-                if (vs.isEmpty()) {
-                    vs = es.values;
-                    this.optionalName = es.optionalName;
-                } else
-                {
-                    vs.addAll(es.values);
-                }
-                continue;
-            }
-
-            throw new EnumeratorFormatException(name);
-        }
-
-        this.enumeratorClass = enumeratorClass;
-        this.values = vs;
-    }
-
-    /**
-     * Construct a copy of the given set.
-     */
-    public EnumeratorSet(EnumeratorSet that) {
-        this(that.enumeratorClass, that.values);
-    }
-
-    /**
-     * Add the given value to the set.
-     * 
-     * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
-     */
-    public EnumeratorSet add(Enumerator value) {
-        if (value.getClass() != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot add value of type \"" + value.getClass() + "\" to set of different type \"" + this.enumeratorClass + "\"");
-        Set vs = new HashSet(this.values);
-        vs.add(value);
-        return new EnumeratorSet(this.enumeratorClass, vs);
-    }
-
-    /**
-     * Add the values of the given set to this set.
-     * 
-     * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
-     */
-    public EnumeratorSet add(EnumeratorSet that) {
-        if (that.enumeratorClass != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot add set of type \"" + that.enumeratorClass + "\" to set of different type \"" + this.enumeratorClass + "\"");
-        Set vs;
-        if (this.values.isEmpty()) {
-            vs = that.values;
-        } else
-        if (that.values.isEmpty()) {
-            vs = this.values;
-        } else
-        {
-            vs = new HashSet(this.values);
-            vs.addAll(that.values);
-        }
-        return new EnumeratorSet(this.enumeratorClass, vs);
-    }
-
-    /**
-     * If this {@link EnumeratorSet} contains the given <code>value</code>, return an
-     * {@link EnumeratorSet} that lacks the <code>value</code>. Otherwise, return this
-     * {@link EnumeratorSet}.
-     * 
-     * @return the reduced set
-     * 
-     * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
-     */
-    public EnumeratorSet remove(Enumerator value) {
-        if (value.getClass() != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot remove value of type \"" + value.getClass() + "\" from set of different type \"" + this.enumeratorClass + "\"");
-        if (!this.values.contains(value)) return this;
-        Set vs = new HashSet(this.values);
-        vs.remove(value);
-        return new EnumeratorSet(this.enumeratorClass, vs);
-    }
-
-    /**
-     * Return this {@link EnumeratorSet} less <code>that</code> {@link EnumeratorSet}.
-     * 
-     * @return the reduced set
-     * 
-     * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
-     */
-    public EnumeratorSet remove(EnumeratorSet that) {
-        if (that.enumeratorClass != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot remove set of type \"" + that.enumeratorClass + "\" from set of different type \"" + this.enumeratorClass + "\"");
-        Set vs = new HashSet(this.values);
-        vs.removeAll(that.values);
-        return new EnumeratorSet(this.enumeratorClass, vs);
-    }
-
-    /**
-     * Check whether this set contains the given value
-     * 
-     * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
-     */
-    public boolean contains(Enumerator value) {
-        if (value.getClass() != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot check value of type \"" + value.getClass() + "\" within set of different type \"" + this.enumeratorClass + "\"");
-        return this.values.contains(value);
-    }
-
-    /**
-     * Check if this set contains any of the values of the given set.
-     * <p>
-     * Returns <code>false</code> if either of the two sets is empty.
-     * 
-     * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
-     */
-    public boolean containsAnyOf(EnumeratorSet that) {
-        if (that.enumeratorClass != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot compare set of type \"" + that.enumeratorClass + "\" with set of different type \"" + this.enumeratorClass + "\"");
-        for (Iterator it = that.values.iterator(); it.hasNext();) {
-            if (this.values.contains(it.next())) return true;
-        }
-        return false;
-    }
-
-    /**
-     * Check if this set contains all values of the given set.
-     * 
-     * @throws EnumeratorSetTypeException if this set was constructed for a different {@link Enumerator}-derived type
-     */
-    public boolean containsAllOf(EnumeratorSet that) {
-        if (that.enumeratorClass != this.enumeratorClass) throw new EnumeratorSetTypeException("Cannot compare set of type \"" + that.enumeratorClass + "\" with set of different type \"" + this.enumeratorClass + "\"");
-        return this.values.containsAll(that.values);
-    }
-
-    /**
-     * An {@link EnumeratorSet} can optionally be assigned a name, which is used by
-     * {@link #toString()}.
-     * 
-     * @return this object
-     */
-    public EnumeratorSet setName(String optionalName) {
-
-        // Check for non-change.
-        if (
-            (this.optionalName == optionalName)
-            || (this.optionalName != null && this.optionalName.equals(optionalName))
-        ) return this;
-
-        // Track all named EnumeratorSet instances.
-        Map namedEnumeratorSets = EnumeratorSet.getNamedEnumeratorSets(this.enumeratorClass);
-        if (this.optionalName != null) namedEnumeratorSets.remove(this.optionalName);
-        this.optionalName = optionalName;
-        if (this.optionalName != null) namedEnumeratorSets.put(this.optionalName, this);
-
-        return this;
-    }
-
-    /**
-     * Returns a map of all {@link EnumeratorSet}s instantiated for the given <code>enumeratorClass</code>.
-     * 
-     * @return String name => EnumeratorSet
-     */
-    private static Map getNamedEnumeratorSets(Class enumeratorClass) {
-        Map m = (Map) EnumeratorSet.namedEnumeratorSets.get(enumeratorClass);
-        if (m == null) {
-            m = new HashMap();
-            EnumeratorSet.namedEnumeratorSets.put(enumeratorClass, m);
-        }
-        return m;
-    }
-    private static final Map namedEnumeratorSets = new HashMap(); // Class enumeratorClass => String name => EnumeratorSet
-
-    /**
-     * Check the values' identity. Notice that the objects' names (see {@link #setName(String)} is
-     * not considered.
-     */
-    public boolean equals(Object that) {
-        return that instanceof EnumeratorSet && this.values.equals(((EnumeratorSet) that).values);
-    }
-
-    public int hashCode() {
-        return this.values.hashCode();
-    }
-
-    /**
-     * Convert an {@link EnumeratorSet} to a clear-text string.
-     * <p>
-     * Identical with <code>toString(",")</code>.
-     */
-    public String toString() {
-        return this.toString(",");
-    }
-
-    /**
-     * Convert an {@link EnumeratorSet} into a clear-text string.
-     * <p>
-     * If this {@link EnumeratorSet} has a name (see {@link #setName(String)}, then this name is
-     * returned.
-     * <p>
-     * Otherwise, if this {@link EnumeratorSet} is empty, an empty {@link String} is returned.
-     * <p>
-     * Otherwise, the values' names are concatenated, separated by the given delimiter, and returned.
-     */
-    public String toString(String delimiter) {
-
-        // If this EnumeratorSet has a name, then everything is very simple.
-        if (this.optionalName != null) return this.optionalName;
-
-        // Return "" for an empty set.
-        Iterator it = this.values.iterator();
-        if (!it.hasNext()) return "";
-
-        // Concatenate the enumerators' names.
-        StringBuffer sb = new StringBuffer(((Enumerator) it.next()).name);
-        while (it.hasNext()) {
-            sb.append(delimiter).append(((Enumerator) it.next()).name);
-        }
-        return sb.toString();
-    }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/EnumeratorSetTypeException.java b/src/org/codehaus/janino/util/enumerator/EnumeratorSetTypeException.java
deleted file mode 100644
index 25f17dd..0000000
--- a/src/org/codehaus/janino/util/enumerator/EnumeratorSetTypeException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.enumerator;
-
-/**
- * Indicates that an attempt was made to add or remove values of different type to an
- * {@link org.codehaus.janino.util.enumerator.EnumeratorSet}.
- */
-public class EnumeratorSetTypeException extends RuntimeException {
-    public EnumeratorSetTypeException()               {}
-    public EnumeratorSetTypeException(String message) { super(message); }
-}
diff --git a/src/org/codehaus/janino/util/enumerator/package.html b/src/org/codehaus/janino/util/enumerator/package.html
deleted file mode 100644
index e1dd7ec..0000000
--- a/src/org/codehaus/janino/util/enumerator/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
-  Representation of enumerators and enumerator sets.
-</body></html>
diff --git a/src/org/codehaus/janino/util/iterator/DirectoryIterator.java b/src/org/codehaus/janino/util/iterator/DirectoryIterator.java
deleted file mode 100644
index 917e247..0000000
--- a/src/org/codehaus/janino/util/iterator/DirectoryIterator.java
+++ /dev/null
@@ -1,132 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.codehaus.janino.util.Producer;
-
-/**
- * An {@link Iterator} that finds the normal {@link File}s who's names are
- * {@link FilenameFilter#accept(java.io.File, java.lang.String)}ed by the
- * <code>fileNameFilter</code> and
- * <ul>
- *   <li>
- *     that exist in the given <code>rootDirectory</code>,
- *   </li>
- *   <li>
- *     and those that exist in all subdirectories of the
- *     <code>rootDirectory</code> who's names are
- *     {@link FilenameFilter#accept(java.io.File, java.lang.String)}ed by the
- *     <code>directoryNameFilter</code>
- *   </li>
- * </ul>
- */
-public class DirectoryIterator extends ProducerIterator {
-    public DirectoryIterator(
-        final File           rootDirectory,
-        final FilenameFilter directoryNameFilter,
-        final FilenameFilter fileNameFilter
-    ) {
-        super(new Producer() {
-            private final List stateStack = DirectoryIterator.newArrayList(new State(rootDirectory));
-            public Object produce() {
-                while (!this.stateStack.isEmpty()) {
-                    State state = (State) this.stateStack.get(this.stateStack.size() - 1);
-                    if (state.directories.hasNext()) {
-                        this.stateStack.add(new State((File) state.directories.next()));
-                    } else
-                    if (state.files.hasNext()) {
-                        return (File) state.files.next();
-                    } else
-                    {
-                        this.stateStack.remove(this.stateStack.size() - 1);
-                    }
-                }
-                return null;
-            }
-    
-            class State {
-                State(File dir) {
-                    File[] entries = dir.listFiles();
-                    if (entries == null) throw new RuntimeException("Directory \"" + dir + "\" could not be read");
-                    List directoryList = new ArrayList();
-                    List fileList      = new ArrayList();
-                    for (int i = 0; i < entries.length; ++i) {
-                        File entry = entries[i];
-                        if (entry.isDirectory()) {
-                            if (directoryNameFilter.accept(dir, entry.getName())) directoryList.add(entry);
-                        } else
-                        if (entry.isFile()) {
-                            if (fileNameFilter.accept(dir, entry.getName())) fileList.add(entry);
-                        }
-                    }
-                    this.directories = directoryList.iterator();
-                    this.files       = fileList.iterator();
-                }
-                final Iterator directories; // File
-                final Iterator files;       // File
-            }
-        });
-    }
-
-    /**
-     * Create an {@link Iterator} that return all matching
-     * {@link File}s locatable in a <i>set</i> of root directories.
-     *
-     * @see #DirectoryIterator(File, FilenameFilter, FilenameFilter)
-     */
-    public static Iterator traverseDirectories(
-        File[]         rootDirectories,
-        FilenameFilter directoryNameFilter,
-        FilenameFilter fileNameFilter
-    ) {
-        List result = new ArrayList();
-        for (int i = 0; i < rootDirectories.length; ++i) {
-            result.add(new DirectoryIterator(rootDirectories[i], directoryNameFilter, fileNameFilter));
-        }
-        return new MultiDimensionalIterator(result.iterator(), 2);
-    }
-
-    private static ArrayList newArrayList(Object initialElement) {
-        ArrayList result = new ArrayList();
-        result.add(initialElement);
-        return result;
-    }
-}
diff --git a/src/org/codehaus/janino/util/iterator/EnumerationIterator.java b/src/org/codehaus/janino/util/iterator/EnumerationIterator.java
deleted file mode 100644
index a540108..0000000
--- a/src/org/codehaus/janino/util/iterator/EnumerationIterator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that iterates over the elements of an
- * {@link java.util.Enumeration}.
- */
-public class EnumerationIterator implements Iterator {
-    private final Enumeration e;
-
-    public EnumerationIterator(Enumeration e) { this.e = e; }
-
-    public boolean hasNext() { return this.e.hasMoreElements(); }
-    public Object  next()    { return this.e.nextElement(); }
-    public void    remove()  { throw new UnsupportedOperationException("remove"); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/FilterIterator.java b/src/org/codehaus/janino/util/iterator/FilterIterator.java
deleted file mode 100644
index 915f6e2..0000000
--- a/src/org/codehaus/janino/util/iterator/FilterIterator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that retrieves its elements from a delegate
- * {@link java.util.Iterator}. The default implementation simply passes
- * all method invocations to the delegate.
- */
-public abstract class FilterIterator implements Iterator {
-    protected final Iterator delegate;
-
-    public FilterIterator(Iterator delegate) { this.delegate = delegate; }
-
-    public boolean hasNext() { return this.delegate.hasNext(); }
-    public Object  next()    { return this.delegate.next(); }
-    public void    remove()  { this.delegate.remove(); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/FilterListIterator.java b/src/org/codehaus/janino/util/iterator/FilterListIterator.java
deleted file mode 100644
index 7ff914b..0000000
--- a/src/org/codehaus/janino/util/iterator/FilterListIterator.java
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.ListIterator} that retrieves its elements from a delegate
- * {@link java.util.ListIterator}. The default implementation simply passes
- * all method invocations to the delegate.
- */
-public abstract class FilterListIterator implements ListIterator {
-    /** */
-    protected final ListIterator delegate;
-
-    /** */
-    public FilterListIterator(ListIterator delegate) {
-        this.delegate = delegate;
-    }
-
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#hasNext()} */
-    public boolean hasNext()       { return this.delegate.hasNext(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#next()} */
-    public Object  next()          { return this.delegate.next(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#hasPrevious()} */
-    public boolean hasPrevious()   { return this.delegate.hasPrevious(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#previous()} */
-    public Object  previous()      { return this.delegate.previous(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#nextIndex()} */
-    public int     nextIndex()     { return this.delegate.nextIndex(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#previousIndex()} */
-    public int     previousIndex() { return this.delegate.previousIndex(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#remove()} */
-    public void    remove()        { this.delegate.remove(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#set(java.lang.Object)} */
-    public void    set(Object o)   { this.delegate.set(o); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#add(java.lang.Object)} */
-    public void    add(Object o)   { this.delegate.add(o); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/IteratorCollection.java b/src/org/codehaus/janino/util/iterator/IteratorCollection.java
deleted file mode 100644
index a99edd3..0000000
--- a/src/org/codehaus/janino/util/iterator/IteratorCollection.java
+++ /dev/null
@@ -1,82 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * A {@link java.util.Collection} that lazily reads its elements from an
- * {@link java.util.Iterator}.
- * <p>
- * In other words, you can call {@link #iterator()} as often as you want, but the
- * {@link IteratorCollection} will iterate over its delegate only once.
- */
-public class IteratorCollection extends AbstractCollection {
-    private final Iterator iterator; // The delegate.
-    private final List     elements = new ArrayList(); // Lazily-filled collection of the elements delivered by the delegate.
-
-    public IteratorCollection(Iterator iterator) {
-        this.iterator = iterator;
-    }
-
-    public Iterator iterator() {
-        return new Iterator() {
-            private Iterator elementsIterator = IteratorCollection.this.elements.iterator();
-            public Object next() {
-                if (this.elementsIterator != null) {
-                    if (this.elementsIterator.hasNext()) return this.elementsIterator.next();
-                    this.elementsIterator = null;
-                }
-                Object o = IteratorCollection.this.iterator.next();
-                IteratorCollection.this.elements.add(o);
-                return o;
-            }
-            public boolean hasNext() {
-                return (
-                    (this.elementsIterator != null && this.elementsIterator.hasNext())
-                    || IteratorCollection.this.iterator.hasNext()
-                );
-            }
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
-    }
-    public int size() {
-        int size = 0;
-        for (Iterator it = this.iterator(); it.hasNext(); it.next()) ++size;
-        return size;
-    }
-}
diff --git a/src/org/codehaus/janino/util/iterator/MultiDimensionalIterator.java b/src/org/codehaus/janino/util/iterator/MultiDimensionalIterator.java
deleted file mode 100644
index dcb7f42..0000000
--- a/src/org/codehaus/janino/util/iterator/MultiDimensionalIterator.java
+++ /dev/null
@@ -1,107 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that iterates over a delegate, which produces
- * arrays, {@link java.util.Collection}s, {@link java.util.Enumeration}s or
- * {@link java.util.Iterator}s. This {@link java.util.Iterator} returns the
- * elements of these objects.
- * <p>
- * The count of dimensions is declared at construction. Count "1" produces an
- * {@link java.util.Iterator} that adds no functionality to its delegate, count
- * "2" produces an {@link Iterator} that behaves as explained above, and so
- * forth.
- */
-public class MultiDimensionalIterator implements Iterator {
-    private final Iterator[] nest;
-    private static final Iterator EMPTY_ITERATOR = new Iterator() {
-        public boolean hasNext() { return false; }
-        public Object  next()    { throw new NoSuchElementException(); }
-        public void    remove()  { throw new UnsupportedOperationException("remove"); }
-    };
-
-    public MultiDimensionalIterator(Iterator delegate, int dimensionCount) {
-        this.nest = new Iterator[dimensionCount];
-        this.nest[0] = delegate;
-        for (int i = 1; i < dimensionCount; ++i) this.nest[i] = MultiDimensionalIterator.EMPTY_ITERATOR;
-    }
-
-    /**
-     * @throws UniterableElementException
-     */
-    public boolean hasNext() {
-
-        // Unroll this check because it is so performance critical:
-        if (this.nest[this.nest.length - 1].hasNext()) return true;
-
-        int i = this.nest.length - 2;
-        if (i < 0) return false;
-
-        for (;;) {
-            if (!this.nest[i].hasNext()) {
-                if (i == 0) return false;
-                --i;
-            } else {
-                if (i == this.nest.length - 1) return true;
-                Object o = this.nest[i].next();
-                if (o instanceof Iterator) {
-                    this.nest[++i] = (Iterator) o;
-                } else
-                if (o instanceof Object[]) {
-                    this.nest[++i] = Arrays.asList((Object[]) o).iterator();
-                } else
-                if (o instanceof Collection) {
-                    this.nest[++i] = ((Collection) o).iterator();
-                } else
-                if (o instanceof Enumeration) {
-                    this.nest[++i] = new EnumerationIterator((Enumeration) o);
-                } else
-                {
-                    throw new UniterableElementException();
-                }
-            }
-        }
-    }
-
-    public Object next() {
-        if (!this.hasNext()) throw new NoSuchElementException();
-        return this.nest[this.nest.length - 1].next();
-    }
-
-    public void remove() { throw new UnsupportedOperationException("remove"); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/ProducerIterator.java b/src/org/codehaus/janino/util/iterator/ProducerIterator.java
deleted file mode 100644
index e9e8bc9..0000000
--- a/src/org/codehaus/janino/util/iterator/ProducerIterator.java
+++ /dev/null
@@ -1,75 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-import org.codehaus.janino.util.Producer;
-
-/**
- * An {@link java.util.Iterator} that iterates over all the objects produced by a delegate
- * {@link org.codehaus.janino.util.Producer}.
- *
- * @see org.codehaus.janino.util.Producer
- */
-public class ProducerIterator implements Iterator {
-    private final Producer producer;
-
-    private static final Object UNKNOWN = new Object();
-    private static final Object AT_END = null;
-    private Object              nextElement = UNKNOWN;
-
-    public ProducerIterator(Producer producer) {
-        this.producer = producer;
-    }
-
-    public boolean hasNext() {
-        if (this.nextElement == UNKNOWN) this.nextElement = this.producer.produce();
-        return this.nextElement != AT_END;
-    }
-
-    public Object next() {
-        if (this.nextElement == UNKNOWN) this.nextElement = this.producer.produce();
-        if (this.nextElement == AT_END) throw new NoSuchElementException();
-        Object result = this.nextElement;
-        this.nextElement = UNKNOWN;
-        return result;
-    }
-
-    public void remove() {
-        throw new UnsupportedOperationException("remove");
-    }
-}
diff --git a/src/org/codehaus/janino/util/iterator/ReverseListIterator.java b/src/org/codehaus/janino/util/iterator/ReverseListIterator.java
deleted file mode 100644
index 9e76452..0000000
--- a/src/org/codehaus/janino/util/iterator/ReverseListIterator.java
+++ /dev/null
@@ -1,61 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * A {@link java.util.ListIterator} that reverses the direction of all operations
- * of a delegate {@link java.util.ListIterator}.
- */
-public class ReverseListIterator extends FilterListIterator {
-    /** */
-    public ReverseListIterator(ListIterator delegate) {
-        super(delegate);
-    }
-
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#hasPrevious()} */
-    public boolean hasNext()       { return super.hasPrevious(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#hasNext()} */
-    public boolean hasPrevious()   { return super.hasNext(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#previous()} */
-    public Object  next()          { return super.previous(); }
-    /** Calls {@link #delegate}.{@link java.util.ListIterator#next()} */
-    public Object  previous()      { return super.next(); }
-    /** Throws an {@link UnsupportedOperationException}. */
-    public int     nextIndex()     { throw new UnsupportedOperationException(); }
-    /** Throws an {@link UnsupportedOperationException}. */
-    public int     previousIndex() { throw new UnsupportedOperationException(); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/TransformingIterator.java b/src/org/codehaus/janino/util/iterator/TransformingIterator.java
deleted file mode 100644
index 4feba37..0000000
--- a/src/org/codehaus/janino/util/iterator/TransformingIterator.java
+++ /dev/null
@@ -1,56 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that transforms its elements on-the-fly.
- */
-public abstract class TransformingIterator extends FilterIterator {
-    public TransformingIterator(Iterator delegate) {
-        super(delegate);
-    }
-
-    public final Object next() {
-        return this.transform(this.delegate.next());
-    }
-
-    /**
-     * Derived classes must implement this method such that it does the
-     * desired transformation.
-     */
-    protected abstract Object transform(Object o);
-}
diff --git a/src/org/codehaus/janino/util/iterator/TraversingIterator.java b/src/org/codehaus/janino/util/iterator/TraversingIterator.java
deleted file mode 100644
index 1937b56..0000000
--- a/src/org/codehaus/janino/util/iterator/TraversingIterator.java
+++ /dev/null
@@ -1,100 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-import java.util.*;
-
-/**
- * An {@link java.util.Iterator} that iterates over a delegate, and while
- * it encounters an array, a {@link java.util.Collection}, an
- * {@link java.util.Enumeration} or a {@link java.util.Iterator} element, it iterates
- * into it recursively.
- * <p>
- * Be aware that {@link #hasNext()} must read ahead one element.
- */
-public class TraversingIterator implements Iterator {
-    private final Stack nest = new Stack(); // Iterator
-    private Object      nextElement = null;
-    private boolean     nextElementRead = false; // Have we read ahead?
-
-    public TraversingIterator(Iterator delegate) {
-        this.nest.push(delegate);
-    }
-
-    public boolean hasNext() {
-        return this.nextElementRead || this.readNext();
-    }
-
-    public Object next() {
-        if (!this.nextElementRead && !this.readNext()) throw new NoSuchElementException();
-        this.nextElementRead = false;
-        return this.nextElement;
-    }
-
-    /**
-     * Reads the next element and stores it in {@link #nextElement}.
-     * @return <code>false</code> if no more element can be read.
-     */
-    private boolean readNext() {
-        while (!this.nest.empty()) {
-            Iterator it = (Iterator) this.nest.peek();
-            if (!it.hasNext()) {
-                this.nest.pop();
-                continue;
-            }
-            Object o = it.next();
-            if (o instanceof Iterator) {
-                this.nest.push(o);
-            } else
-            if (o instanceof Object[]) {
-                this.nest.push(Arrays.asList((Object[]) o).iterator());
-            } else
-            if (o instanceof Collection) {
-                this.nest.push(((Collection) o).iterator());
-            } else
-            if (o instanceof Enumeration) {
-                this.nest.push(new EnumerationIterator((Enumeration) o));
-            } else
-            {
-                this.nextElement = o;
-                this.nextElementRead = true;
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public void remove() { throw new UnsupportedOperationException("remove"); }
-}
diff --git a/src/org/codehaus/janino/util/iterator/UniterableElementException.java b/src/org/codehaus/janino/util/iterator/UniterableElementException.java
deleted file mode 100644
index 291fef6..0000000
--- a/src/org/codehaus/janino/util/iterator/UniterableElementException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.iterator;
-
-/**
- * Thrown by {@link org.codehaus.janino.util.iterator.MultiDimensionalIterator} to
- * indicate that it has encountered an element that cannot be iterated.
- */
-public class UniterableElementException extends RuntimeException {
-    /** */
-    public UniterableElementException() {}
-}
diff --git a/src/org/codehaus/janino/util/iterator/package.html b/src/org/codehaus/janino/util/iterator/package.html
deleted file mode 100644
index 6968038..0000000
--- a/src/org/codehaus/janino/util/iterator/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
-  Some generic {@link java.util.Iterator}-related helper classes.
-</body></html>
diff --git a/src/org/codehaus/janino/util/package.html b/src/org/codehaus/janino/util/package.html
deleted file mode 100644
index 95aeb4d..0000000
--- a/src/org/codehaus/janino/util/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<html><body>
-  Application-independent helper classes.
-</body></html>
diff --git a/src/org/codehaus/janino/util/resource/DirectoryResourceCreator.java b/src/org/codehaus/janino/util/resource/DirectoryResourceCreator.java
deleted file mode 100644
index a2385cc..0000000
--- a/src/org/codehaus/janino/util/resource/DirectoryResourceCreator.java
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Creates a resource in a given directory:<pre>
- *     <i>destinationDirectory</i>/<i>resourceName</i></pre>
- */
-public class DirectoryResourceCreator extends FileResourceCreator {
-    private final File destinationDirectory;
-
-    public DirectoryResourceCreator(File destinationDirectory) {
-        this.destinationDirectory = destinationDirectory;
-    }
-
-    protected File getFile(String resourceName) {
-        return new File(this.destinationDirectory, resourceName.replace('/', File.separatorChar));
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/DirectoryResourceFinder.java b/src/org/codehaus/janino/util/resource/DirectoryResourceFinder.java
deleted file mode 100644
index 72147f0..0000000
--- a/src/org/codehaus/janino/util/resource/DirectoryResourceFinder.java
+++ /dev/null
@@ -1,85 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * A {@link org.codehaus.janino.util.resource.FileResourceFinder} that finds file resources in
- * a directory. The name of the file is constructed by concatenating a dirctory name
- * with the resource name such that slashes in the resource name map to file
- * separators.
- */
-public class DirectoryResourceFinder extends FileResourceFinder {
-    private final File directory;
-    private final Map  subdirectoryNameToFiles = new HashMap(); // String directoryName => Set => File
-
-    /**
-     * @param directory the directory to use as the search base
-     */
-    public DirectoryResourceFinder(File directory) {
-        this.directory = directory;
-    }
-
-    public String toString() { return "dir:" + this.directory; }
-
-    // Implement FileResourceFinder.
-    protected File findResourceAsFile(String resourceName) {
-    
-        // Determine the subdirectory name (null for no subdirectory).
-        int idx = resourceName.lastIndexOf('/');
-        String subdirectoryName = (
-            idx == -1 ? null :
-            resourceName.substring(0, idx).replace('/', File.separatorChar)
-        );
-    
-        // Determine files existing in this subdirectory.
-        Set files = (Set) this.subdirectoryNameToFiles.get(subdirectoryName); // String directoryName => Set => File
-        if (files == null) {
-            File subDirectory = (subdirectoryName == null) ? this.directory : new File(this.directory, subdirectoryName);
-            File[] fa = subDirectory.listFiles();
-            files = (fa == null) ? Collections.EMPTY_SET : new HashSet(Arrays.asList(fa));
-            this.subdirectoryNameToFiles.put(subdirectoryName, files);
-        }
-    
-        // Notice that "File.equals()" performs all the file-system dependent
-        // magic like case conversion.
-        File file = new File(this.directory, resourceName.replace('/', File.separatorChar));
-        if (!files.contains(file)) return null;
-    
-        return file;
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/FileResource.java b/src/org/codehaus/janino/util/resource/FileResource.java
deleted file mode 100644
index d72d17b..0000000
--- a/src/org/codehaus/janino/util/resource/FileResource.java
+++ /dev/null
@@ -1,55 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Representation of a resource that is a {@link java.io.File}.
- */
-public class FileResource implements Resource {
-    public FileResource(File file) { this.file = file; }
-
-    // Implement "Resource".
-    public final String      getFileName()             { return this.file.toString(); }
-    public final InputStream open() throws IOException { return new FileInputStream(this.file); }
-    public final long        lastModified()            { return this.file.lastModified(); }
-
-    public File getFile() { return this.file; }
-
-    public String toString() { return this.getFileName(); }
-
-    private final File file;
-}
diff --git a/src/org/codehaus/janino/util/resource/FileResourceCreator.java b/src/org/codehaus/janino/util/resource/FileResourceCreator.java
deleted file mode 100644
index e65a309..0000000
--- a/src/org/codehaus/janino/util/resource/FileResourceCreator.java
+++ /dev/null
@@ -1,62 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Stores a stream of bytes in a named resource.
- */
-public abstract class FileResourceCreator implements ResourceCreator {
-
-    public final OutputStream createResource(String resourceName) throws IOException {
-        File file = this.getFile(resourceName);
-
-        // Create directory for class file if it does not exist.
-        File dir = file.getParentFile();
-        if (dir != null && !dir.isDirectory()) {
-            if (!dir.mkdirs()) throw new IOException("Cannot create directory for class file \"" + file + "\"");
-        }
-
-        // Create the file.
-        return new FileOutputStream(file);
-    }
-
-    public final boolean deleteResource(String resourceName) {
-        return this.getFile(resourceName).delete();
-    }
-
-    protected abstract File getFile(String resourceName);
-}
diff --git a/src/org/codehaus/janino/util/resource/FileResourceFinder.java b/src/org/codehaus/janino/util/resource/FileResourceFinder.java
deleted file mode 100644
index c8816af..0000000
--- a/src/org/codehaus/janino/util/resource/FileResourceFinder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * This class specializes the {@link org.codehaus.janino.util.resource.ResourceFinder}
- * for finding resources in {@link java.io.File}s.
- * <p>
- * It finds {@link FileResource}s instead of simple
- * {@link Resource}s.
- */
-public abstract class FileResourceFinder extends ResourceFinder {
-    public final Resource findResource(String resourceName) {
-        File file = this.findResourceAsFile(resourceName);
-        if (file == null) return null;
-        return new FileResource(file);
-    }
-
-    /**
-     * Converts a given resource resource name into a {@link File}.
-     */
-    protected abstract File findResourceAsFile(String resourceName);
-}
diff --git a/src/org/codehaus/janino/util/resource/JarDirectoriesResourceFinder.java b/src/org/codehaus/janino/util/resource/JarDirectoriesResourceFinder.java
deleted file mode 100644
index d41c597..0000000
--- a/src/org/codehaus/janino/util/resource/JarDirectoriesResourceFinder.java
+++ /dev/null
@@ -1,80 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-import java.util.zip.*;
-
-import org.codehaus.janino.util.iterator.*;
-
-/**
- * Finds resources in any of the "*.jar" files that exist in a given set of directories.
- */
-public class JarDirectoriesResourceFinder extends LazyMultiResourceFinder {
-
-    /**
-     * @param directories The set of directories to search for JAR files.
-     */
-    public JarDirectoriesResourceFinder(final File[] directories) {
-        super(new MultiDimensionalIterator(
-        
-            // Iterate over directories.
-            new TransformingIterator(Arrays.asList(directories).iterator()) {
-                protected Object transform(Object o) { // File directory => Iterator ResourceFinder
-                    File directory = (File) o;
-
-                    if (!directory.exists()) return Collections.EMPTY_LIST.iterator();
-
-                    // Iterate over the JAR files in the given directory.
-                    File[] jarFiles = directory.listFiles(new FilenameFilter() {
-                        public boolean accept(File dir, String name) { return name.endsWith(".jar"); }
-                    });
-                    return new TransformingIterator(Arrays.asList(jarFiles).iterator()) {
-                        protected Object transform(Object o) { // File jarFile => ResourceFinder
-                            File zipFile = (File) o;
-                            try {
-                                return new ZipFileResourceFinder(new ZipFile(zipFile));
-                            } catch (IOException e) {
-                                return ResourceFinder.EMPTY_RESOURCE_FINDER;
-                            }
-                        }
-                    };
-                }
-            },
-            2
-        ));
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/LazyMultiResourceFinder.java b/src/org/codehaus/janino/util/resource/LazyMultiResourceFinder.java
deleted file mode 100644
index eb24f7d..0000000
--- a/src/org/codehaus/janino/util/resource/LazyMultiResourceFinder.java
+++ /dev/null
@@ -1,57 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.util.*;
-
-import org.codehaus.janino.util.iterator.IteratorCollection;
-
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that examines a set
- * of {@link org.codehaus.janino.util.resource.ResourceFinder}s lazily as it
- * searches for resources.
- *
- * @see org.codehaus.janino.util.iterator.IteratorCollection
- */
-public class LazyMultiResourceFinder extends MultiResourceFinder {
-
-    /**
-     * @param resourceFinders delegate {@link ResourceFinder}s
-     */
-    public LazyMultiResourceFinder(Iterator resourceFinders) {
-        super(new IteratorCollection(resourceFinders));
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/MapResourceCreator.java b/src/org/codehaus/janino/util/resource/MapResourceCreator.java
deleted file mode 100644
index 5bdb605..0000000
--- a/src/org/codehaus/janino/util/resource/MapResourceCreator.java
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * Creates resources as byte arrays in a delegate {@link java.util.Map}.
- */
-public class MapResourceCreator implements ResourceCreator {
-    private final Map map;
-
-    /**
-     * Auto-create the delegate {@link Map}.
-     */
-    public MapResourceCreator() {
-        this.map = new HashMap();
-    }
-    public MapResourceCreator(Map map) {
-        this.map = map;
-    }
-    public Map getMap() {
-        return this.map;
-    }
-
-    public OutputStream createResource(final String resourceName) throws IOException {
-        return new ByteArrayOutputStream() {
-            public void close() throws IOException {
-                super.close();
-                MapResourceCreator.this.map.put(resourceName, this.toByteArray());
-            }
-        };
-    }
-
-    public boolean deleteResource(String resourceName) {
-        return this.map.remove(resourceName) != null;
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/MapResourceFinder.java b/src/org/codehaus/janino/util/resource/MapResourceFinder.java
deleted file mode 100644
index ec24469..0000000
--- a/src/org/codehaus/janino/util/resource/MapResourceFinder.java
+++ /dev/null
@@ -1,65 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that provides access
- * to resource stored as byte arrays in a {@link java.util.Map}.
- */
-public class MapResourceFinder extends ResourceFinder {
-    private final Map map;
-    private long      lastModified = 0L;
-
-    public MapResourceFinder(Map map) {
-        this.map = map;
-    }
-    public void setLastModified(long lastModified) {
-        this.lastModified = lastModified;
-    }
-
-    public final Resource findResource(final String resourceName) {
-        final byte[] ba = (byte[]) this.map.get(resourceName);
-        if (ba == null) return null;
-
-        return new Resource() {
-            public InputStream open() throws IOException { return new ByteArrayInputStream(ba); }
-            public String getFileName()                  { return resourceName; }
-            public long lastModified()                   { return MapResourceFinder.this.lastModified; }
-        };
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/MultiResourceFinder.java b/src/org/codehaus/janino/util/resource/MultiResourceFinder.java
deleted file mode 100644
index 64e1041..0000000
--- a/src/org/codehaus/janino/util/resource/MultiResourceFinder.java
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.util.*;
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds its resources through a collection of
- * other {@link org.codehaus.janino.util.resource.ResourceFinder}s.
- */
-public class MultiResourceFinder extends ResourceFinder {
-    private final Collection resourceFinders; // One for each entry
-
-    /**
-     * @param resourceFinders The entries of the "path"
-     */
-    public MultiResourceFinder(Collection resourceFinders) {
-        this.resourceFinders = resourceFinders;
-    }
-
-    // Implement ResourceFinder.
-
-    public Resource findResource(String resourceName) {
-        for (Iterator it = this.resourceFinders.iterator(); it.hasNext();) {
-            ResourceFinder rf = (ResourceFinder) it.next();
-            Resource resource = rf.findResource(resourceName);
-//System.err.println("*** " + resourceName + " in " + rf + "? => " + url);
-            if (resource != null) return resource;
-        }
-        return null;
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/PathResourceFinder.java b/src/org/codehaus/janino/util/resource/PathResourceFinder.java
deleted file mode 100644
index 418a3a5..0000000
--- a/src/org/codehaus/janino/util/resource/PathResourceFinder.java
+++ /dev/null
@@ -1,145 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.*;
-import java.util.zip.*;
-
-import org.codehaus.janino.util.iterator.*;
-
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds its resources along a "path"
- * consisting of JAR file names, ZIP file names, and directory names.
- * @see org.codehaus.janino.util.resource.ZipFileResourceFinder
- * @see org.codehaus.janino.util.resource.DirectoryResourceFinder
- */
-public class PathResourceFinder extends LazyMultiResourceFinder {
-
-    /**
-     * @param entries The entries of the "path"
-     */
-    public PathResourceFinder(final File[] entries) {
-        super(PathResourceFinder.createIterator(Arrays.asList(entries).iterator()));
-    }
-
-    /**
-     * @param entries The entries of the "path" (type must be {@link File})
-     */
-    public PathResourceFinder(Iterator entries) {
-        super(entries);
-    }
-
-    /**
-     * @param path A java-like path, i.e. a "path separator"-separated list of entries.
-     */
-    public PathResourceFinder(String path) {
-        this(PathResourceFinder.parsePath(path));
-    }
-
-    private static Iterator createIterator(final Iterator entries) {
-        return new TransformingIterator(entries) {
-            protected Object transform(Object o) {
-                return PathResourceFinder.createResourceFinder((File) o);
-            }
-        };
-    }
-
-    /**
-     * Break a given string up by the system-dependent path-separator character (on UNIX systems,
-     * this character is ':'; on Microsoft Windows systems it is ';'). Empty components are
-     * ignored.
-     * <p>
-     * UNIX Examples:
-     * <dl>
-     *   <dt>A:B:C          <dd>A, B, C
-     *   <dt>::B:           <dd>B
-     *   <dt>:A             <dd>A
-     *   <dt>(Empty string) <dd>(Zero components)
-     * </dl>
-     *
-     * @see File#pathSeparatorChar
-     */
-    public static File[] parsePath(String s) {
-        int from = 0;
-        List l = new ArrayList(); // File
-        for (;;) {
-            int to = s.indexOf(File.pathSeparatorChar, from);
-            if (to == -1) {
-                if (from != s.length()) l.add(new File(s.substring(from)));
-                break;
-            }
-            if (to != from) l.add(new File(s.substring(from, to)));
-            from = to + 1;
-        }
-        return (File[]) l.toArray(new File[l.size()]);
-    }
-
-    /**
-     * A factory method that creates a Java classpath-style ResourceFinder as
-     * follows:
-     * <table>
-     *   <tr><th><code>entry</code></th><th>Returned {@link ResourceFinder}</th></tr>
-     *   <tr><td>"*.jar" file</td><td>{@link ZipFileResourceFinder}</td></tr>
-     *   <tr><td>"*.zip" file</td><td>{@link ZipFileResourceFinder}</td></tr>
-     *   <tr><td>directory</td><td>{@link DirectoryResourceFinder}</td></tr>
-     *   <tr><td>any other</td><td>A {@link ResourceFinder} that never finds a resource</td></tr>
-     * </table>
-     * @return a valid {@link ResourceFinder}
-     */
-    private static ResourceFinder createResourceFinder(final File entry) {
-
-        // ZIP file or JAR file.
-        if (
-            (entry.getName().endsWith(".jar") || entry.getName().endsWith(".zip")) &&
-            entry.isFile()
-        ) {
-            try {
-                return new ZipFileResourceFinder(new ZipFile(entry));
-            } catch (IOException e) {
-                return ResourceFinder.EMPTY_RESOURCE_FINDER;
-            }
-        }
-
-        // Directory.
-        if (entry.isDirectory()) {
-            return new DirectoryResourceFinder(entry);
-        }
-
-        // Invalid entry.
-        return ResourceFinder.EMPTY_RESOURCE_FINDER;
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/Resource.java b/src/org/codehaus/janino/util/resource/Resource.java
deleted file mode 100644
index b237b9a..0000000
--- a/src/org/codehaus/janino/util/resource/Resource.java
+++ /dev/null
@@ -1,73 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-
-
-/**
- * A {@link Resource} is "something" that is typically found by a
- * {@link org.codehaus.janino.util.resource.ResourceFinder}, can be {@link #open()}ed for
- * reading, and optionally has a {@link #lastModified()} property.
- * <p>
- * There also exists a {@link org.codehaus.janino.util.resource.ResourceCreator} concept which
- * opens a resource for writing, but that happens directly and not through an intermediate
- * {@link Resource} object.
- *
- * @see org.codehaus.janino.util.resource.ResourceFinder
- * @see org.codehaus.janino.util.resource.ResourceCreator
- */
-public interface Resource {
-
-    /**
-     * Opens the resource. The caller is responsible for closing the
-     * {@link java.io.InputStream}.
-     */
-    InputStream open() throws IOException;
-
-    /**
-     * Returns a decorative "file name" that can be used for reporting
-     * errors and the like. It does not necessarily map to a file in the
-     * local file system!
-     */
-    String getFileName();
-
-    /**
-     * Returns the time of the last modification, in milliseconds since
-     * 1970, or <code>0L</code> if the time of the last modification cannot
-     * be determined.
-     */
-    long lastModified();
-}
diff --git a/src/org/codehaus/janino/util/resource/ResourceCreator.java b/src/org/codehaus/janino/util/resource/ResourceCreator.java
deleted file mode 100644
index c2a097c..0000000
--- a/src/org/codehaus/janino/util/resource/ResourceCreator.java
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Opens a resource, characterized by a name, for writing.
- * <p>
- * There also exists a concept {@link org.codehaus.janino.util.resource.ResourceFinder} that
- * finds {@link org.codehaus.janino.util.resource.Resource}s for reading.
- *
- * @see org.codehaus.janino.util.resource.ResourceFinder
- */
-public interface ResourceCreator {
-
-    /**
-     * Create the designated resource.
-     *
-     * @param resourceName Designates the resource; typically structured by slashes ("/") like "<code>com/foo/pkg/Bar.class</code>"
-     * @return bytes written to this {@link OutputStream} are stored in the resource
-     * @throws IOException Problems creating the resource
-     */
-    public abstract OutputStream createResource(String resourceName) throws IOException;
-
-    /**
-     * Deletes the resource with the given name.
-     * 
-     * @return <code>false</code> if the resource could not be deleted
-     */
-    public abstract boolean deleteResource(String resourceName);
-}
diff --git a/src/org/codehaus/janino/util/resource/ResourceFinder.java b/src/org/codehaus/janino/util/resource/ResourceFinder.java
deleted file mode 100644
index c9c04dd..0000000
--- a/src/org/codehaus/janino/util/resource/ResourceFinder.java
+++ /dev/null
@@ -1,79 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-
-/**
- * Finds a resource by name.
- * <p>
- * Notice that there is a symmetrical concept
- * {@link org.codehaus.janino.util.resource.ResourceCreator} that creates resources for
- * writing.
- *
- * @see org.codehaus.janino.util.resource.ResourceCreator
- */
-public abstract class ResourceFinder {
-
-    /**
-     * Find a resource by name and open it for reading.
-     * 
-     * @param resourceName Designates the resource; typically structured by slashes ("/") like "<code>com/foo/pkg/Bar.class</code>"
-     * @return <code>null</code> if the resource could not be found
-     * @throws IOException The resource was found, but there are problems opening it
-     */
-    public final InputStream findResourceAsStream(String resourceName) throws IOException {
-        Resource resource = this.findResource(resourceName);
-        if (resource == null) return null;
-        return resource.open();
-    }
-
-    /**
-     * Find a resource by name and return it as a {@link Resource} object.
-     * 
-     * @param resourceName Designates the resource; typically structured by slashes ("/") like "<code>com/foo/pkg/Bar.class</code>"
-     * @return <code>null</code> if the resource could not be found
-     */
-    public abstract Resource findResource(String resourceName);
-
-    /**
-     * This one's useful when a resource finder is required, but cannot be created
-     * for some reason.
-     */
-    public static final ResourceFinder EMPTY_RESOURCE_FINDER = new ResourceFinder() {
-        public Resource findResource(String resourceName) { return null; }
-        public String toString() { return "invalid entry"; }
-    };
-}
diff --git a/src/org/codehaus/janino/util/resource/ZipFileResourceFinder.java b/src/org/codehaus/janino/util/resource/ZipFileResourceFinder.java
deleted file mode 100644
index 490ece2..0000000
--- a/src/org/codehaus/janino/util/resource/ZipFileResourceFinder.java
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- * Janino - An embedded Java[TM] compiler
- *
- * Copyright (c) 2001-2007, Arno Unkrig
- * 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. The name of the author may not be used to endorse or promote
- *       products derived from this software without specific prior
- *       written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.codehaus.janino.util.resource;
-
-import java.io.*;
-import java.util.zip.*;
-
-/**
- * A {@link org.codehaus.janino.util.resource.ResourceFinder} that finds resources in a ZIP file.
- */
-public class ZipFileResourceFinder extends ResourceFinder {
-    private final ZipFile zipFile;
-
-    public ZipFileResourceFinder(ZipFile zipFile) {
-        this.zipFile = zipFile;
-    }
-    public String toString() { return "zip:" + this.zipFile.getName(); }
-
-    // Implement ResourceFinder.
-
-    public Resource findResource(final String resourceName) {
-        final ZipEntry ze = this.zipFile.getEntry(resourceName);
-        if (ze == null) return null;
-        return new Resource() {
-            public InputStream open() throws IOException {
-                return ZipFileResourceFinder.this.zipFile.getInputStream(ze);
-            }
-            public String getFileName() {
-                return ZipFileResourceFinder.this.zipFile.getName() + ':' + resourceName;
-            }
-            public long lastModified() {
-                long l = ze.getTime();
-                return l == -1L ? 0L : l;
-            }
-
-            public String toString() { return this.getFileName(); }
-        };
-    }
-}
diff --git a/src/org/codehaus/janino/util/resource/package.html b/src/org/codehaus/janino/util/resource/package.html
deleted file mode 100644
index 7300054..0000000
--- a/src/org/codehaus/janino/util/resource/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<html><body>
-  Classes related to loading "resources"
-  ({@link org.codehaus.janino.util.resource.ResourceFinder}) and
-  creating resources
-  ({@link org.codehaus.janino.util.resource.ResourceCreator}).
-</body></html>
diff --git a/src/overview.html b/src/overview.html
deleted file mode 100644
index 9842631..0000000
--- a/src/overview.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<body>
-  <p>
-    <i>Janino</i>, an embedded compiler for the Java<sup>TM</sup>
-    programming language.
-  </p>
-  <p>
-    For download, documentation and contact see <a href="http://janino.codehaus.org">http://janino.codehaus.org</a>.
-  </p>
-</body>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/janino.git



More information about the pkg-java-commits mailing list