You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2022/08/16 16:39:31 UTC

[commons-bcel] 01/06: Sort members

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git

commit 52fae49e309655caf1ab733b678e1139873ad99f
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Tue Aug 16 10:10:08 2022 -0400

    Sort members
---
 src/examples/ClassDumper.java                 |  264 ++---
 src/examples/JasminVisitor.java               |  194 ++--
 src/examples/Mini/ASCII_CharStream.java       |  332 +++---
 src/examples/Mini/ASTExpr.java                |  308 +++---
 src/examples/Mini/ASTFactor.java              |    8 +-
 src/examples/Mini/ASTFunAppl.java             |  230 ++---
 src/examples/Mini/ASTFunDecl.java             |  466 ++++-----
 src/examples/Mini/ASTIdent.java               |   84 +-
 src/examples/Mini/ASTIfExpr.java              |  102 +-
 src/examples/Mini/ASTInteger.java             |   42 +-
 src/examples/Mini/ASTLetExpr.java             |  146 +--
 src/examples/Mini/ASTProgram.java             |  238 ++---
 src/examples/Mini/ASTTerm.java                |    8 +-
 src/examples/Mini/EnvEntry.java               |    2 +-
 src/examples/Mini/Environment.java            |  182 ++--
 src/examples/Mini/Function.java               |   30 +-
 src/examples/Mini/JJTMiniParserState.java     |  148 +--
 src/examples/Mini/MiniC.java                  |   62 +-
 src/examples/Mini/MiniParser.java             | 1336 ++++++++++++-------------
 src/examples/Mini/MiniParserTokenManager.java |  838 ++++++++--------
 src/examples/Mini/Node.java                   |   26 +-
 src/examples/Mini/ParseException.java         |  186 ++--
 src/examples/Mini/SimpleNode.java             |   40 +-
 src/examples/Mini/Token.java                  |   40 +-
 src/examples/Mini/TokenMgrError.java          |   38 +-
 src/examples/Mini/Variable.java               |   20 +-
 src/examples/Package.java                     |  144 +--
 src/examples/TransitiveHull.java              |  144 +--
 src/examples/helloify.java                    |   52 +-
 src/examples/listclass.java                   |  116 +--
 30 files changed, 2913 insertions(+), 2913 deletions(-)

diff --git a/src/examples/ClassDumper.java b/src/examples/ClassDumper.java
index c755d97e..98fececd 100644
--- a/src/examples/ClassDumper.java
+++ b/src/examples/ClassDumper.java
@@ -63,6 +63,11 @@ class ClassDumper {
         this.file = file;
     }
 
+    private final String constantToString (final int index) {
+        final Constant c = constant_items[index];
+        return constant_pool.constantToString(c);
+    }
+
     /**
      * Parses the given Java class file and return an object that represents
      * the contained data, i.e., constants, methods, fields and commands.
@@ -104,33 +109,59 @@ class ClassDumper {
     }
 
     /**
-     * Checks whether the header of the file is ok.
-     * Of course, this has to be the first action on successive file reads.
+     * Processes information about the attributes of the class.
      * @throws  IOException
      * @throws  ClassFormatException
      */
-    private final void processID () throws IOException, ClassFormatException {
-        final int magic = file.readInt();
-        if (magic != Const.JVM_CLASSFILE_MAGIC) {
-            throw new ClassFormatException(file_name + " is not a Java .class file");
+    private final void processAttributes () throws IOException, ClassFormatException {
+        int attributes_count;
+        attributes_count = file.readUnsignedShort();
+        attributes = new Attribute[attributes_count];
+
+        System.out.printf("%nAttributes(%d):%n", attributes_count);
+
+        for (int i = 0; i < attributes_count; i++) {
+            attributes[i] = Attribute.readAttribute(file, constant_pool);
+            // indent all lines by two spaces
+            final String[] lines = attributes[i].toString().split("\\r?\\n");
+            for (final String line : lines) {
+                System.out.println("  " + line);
+            }
         }
-        System.out.println("Java Class Dump");
-        System.out.println("  file: " + file_name);
-        System.out.printf("%nClass header:%n");
-        System.out.printf("  magic: %X%n", magic);
     }
 
     /**
-     * Processes major and minor version of compiler which created the file.
+     * Processes information about the class and its super class.
      * @throws  IOException
      * @throws  ClassFormatException
      */
-    private final void processVersion () throws IOException, ClassFormatException {
-        minor = file.readUnsignedShort();
-        System.out.printf("  minor version: %s%n", minor);
+    private final void processClassInfo () throws IOException, ClassFormatException {
+        access_flags = file.readUnsignedShort();
+        /* Interfaces are implicitely abstract, the flag should be set
+         * according to the JVM specification.
+         */
+        if ((access_flags & Const.ACC_INTERFACE) != 0) {
+            access_flags |= Const.ACC_ABSTRACT;
+        }
+        if (((access_flags & Const.ACC_ABSTRACT) != 0)
+                && ((access_flags & Const.ACC_FINAL) != 0)) {
+            throw new ClassFormatException("Class " + file_name +
+                    " can't be both final and abstract");
+        }
 
-        major = file.readUnsignedShort();
-        System.out.printf("  major version: %s%n", major);
+        System.out.printf("%nClass info:%n");
+        System.out.println("  flags: " + BCELifier.printFlags(access_flags,
+                BCELifier.FLAGS.CLASS));
+        class_name_index = file.readUnsignedShort();
+        System.out.printf("  this_class: %d (", class_name_index);
+        System.out.println(constantToString(class_name_index) + ")");
+
+        superclass_name_index = file.readUnsignedShort();
+        System.out.printf("  super_class: %d (", superclass_name_index);
+        if (superclass_name_index > 0) {
+            System.out.printf("%s", constantToString(superclass_name_index));
+        }
+        System.out.println(")");
     }
 
     /**
@@ -169,37 +200,91 @@ class ClassDumper {
     }
 
     /**
-     * Processes information about the class and its super class.
+     * Constructs object from file stream.
+     * @param file Input stream
+     * @throws IOException
+     * @throws ClassFormatException
+     */
+    private final void processFieldOrMethod () throws IOException, ClassFormatException {
+        final int access_flags = file.readUnsignedShort();
+        final int name_index = file.readUnsignedShort();
+        System.out.printf("  name_index: %d (", name_index);
+        System.out.println(constantToString(name_index) + ")");
+        System.out.println("  access_flags: " + BCELifier.printFlags(access_flags,
+                BCELifier.FLAGS.METHOD));
+        final int descriptor_index = file.readUnsignedShort();
+        System.out.printf("  descriptor_index: %d (", descriptor_index);
+        System.out.println(constantToString(descriptor_index) + ")");
+
+        final int attributes_count = file.readUnsignedShort();
+        final Attribute[] attributes = new Attribute[attributes_count];
+        System.out.println("  attribute count: " + attributes_count);
+
+        for (int i = 0; i < attributes_count; i++) {
+            // going to peek ahead a bit
+            file.mark();
+            final int attribute_name_index = file.readUnsignedShort();
+            final int attribute_length = file.readInt();
+            // restore file location
+            file.reset();
+            // Usefull for debugging
+            // System.out.printf("  attribute_name_index: %d (", attribute_name_index);
+            // System.out.println(constantToString(attribute_name_index) + ")");
+            // System.out.printf("  atribute offset in file: %x%n", + file.getStreamPosition());
+            // System.out.println("  atribute_length: " + attribute_length);
+
+            // A stronger verification test would be to read attribute_length bytes
+            // into a buffer.  Then pass that buffer to readAttribute and also
+            // verify we're at EOF of the buffer on return.
+
+            final long pos1 = file.getStreamPosition();
+            attributes[i] = Attribute.readAttribute(file, constant_pool);
+            final long pos2 = file.getStreamPosition();
+            if ((pos2 - pos1) != (attribute_length + 6)) {
+                System.out.printf("%nattribute_length: %d pos2-pos1-6: %d pos1: %x(%d) pos2: %x(%d)%n",
+                        attribute_length, pos2-pos1-6, pos1, pos1, pos2, pos2);
+            }
+            System.out.printf("  ");
+            System.out.println(attributes[i]);
+        }
+    }
+
+    /**
+     * Processes information about the fields of the class, i.e., its variables.
      * @throws  IOException
      * @throws  ClassFormatException
      */
-    private final void processClassInfo () throws IOException, ClassFormatException {
-        access_flags = file.readUnsignedShort();
-        /* Interfaces are implicitely abstract, the flag should be set
-         * according to the JVM specification.
-         */
-        if ((access_flags & Const.ACC_INTERFACE) != 0) {
-            access_flags |= Const.ACC_ABSTRACT;
-        }
-        if (((access_flags & Const.ACC_ABSTRACT) != 0)
-                && ((access_flags & Const.ACC_FINAL) != 0)) {
-            throw new ClassFormatException("Class " + file_name +
-                    " can't be both final and abstract");
-        }
+    private final void processFields () throws IOException, ClassFormatException {
+        int fields_count;
+        fields_count = file.readUnsignedShort();
+        fields = new Field[fields_count];
 
-        System.out.printf("%nClass info:%n");
-        System.out.println("  flags: " + BCELifier.printFlags(access_flags,
-                BCELifier.FLAGS.CLASS));
-        class_name_index = file.readUnsignedShort();
-        System.out.printf("  this_class: %d (", class_name_index);
-        System.out.println(constantToString(class_name_index) + ")");
+        // sometimes fields[0] is magic used for serialization
+        System.out.printf("%nFields(%d):%n", fields_count);
 
-        superclass_name_index = file.readUnsignedShort();
-        System.out.printf("  super_class: %d (", superclass_name_index);
-        if (superclass_name_index > 0) {
-            System.out.printf("%s", constantToString(superclass_name_index));
+        for (int i = 0; i < fields_count; i++) {
+            processFieldOrMethod();
+            if (i < fields_count - 1) {
+                System.out.println();
+            }
         }
-        System.out.println(")");
+    }
+
+    /**
+     * Checks whether the header of the file is ok.
+     * Of course, this has to be the first action on successive file reads.
+     * @throws  IOException
+     * @throws  ClassFormatException
+     */
+    private final void processID () throws IOException, ClassFormatException {
+        final int magic = file.readInt();
+        if (magic != Const.JVM_CLASSFILE_MAGIC) {
+            throw new ClassFormatException(file_name + " is not a Java .class file");
+        }
+        System.out.println("Java Class Dump");
+        System.out.println("  file: " + file_name);
+        System.out.printf("%nClass header:%n");
+        System.out.printf("  magic: %X%n", magic);
     }
 
     /**
@@ -230,27 +315,6 @@ class ClassDumper {
         }
     }
 
-    /**
-     * Processes information about the fields of the class, i.e., its variables.
-     * @throws  IOException
-     * @throws  ClassFormatException
-     */
-    private final void processFields () throws IOException, ClassFormatException {
-        int fields_count;
-        fields_count = file.readUnsignedShort();
-        fields = new Field[fields_count];
-
-        // sometimes fields[0] is magic used for serialization
-        System.out.printf("%nFields(%d):%n", fields_count);
-
-        for (int i = 0; i < fields_count; i++) {
-            processFieldOrMethod();
-            if (i < fields_count - 1) {
-                System.out.println();
-            }
-        }
-    }
-
     /**
      * Processes information about the methods of the class.
      * @throws  IOException
@@ -272,80 +336,16 @@ class ClassDumper {
     }
 
     /**
-     * Processes information about the attributes of the class.
+     * Processes major and minor version of compiler which created the file.
      * @throws  IOException
      * @throws  ClassFormatException
      */
-    private final void processAttributes () throws IOException, ClassFormatException {
-        int attributes_count;
-        attributes_count = file.readUnsignedShort();
-        attributes = new Attribute[attributes_count];
-
-        System.out.printf("%nAttributes(%d):%n", attributes_count);
-
-        for (int i = 0; i < attributes_count; i++) {
-            attributes[i] = Attribute.readAttribute(file, constant_pool);
-            // indent all lines by two spaces
-            final String[] lines = attributes[i].toString().split("\\r?\\n");
-            for (final String line : lines) {
-                System.out.println("  " + line);
-            }
-        }
-    }
-
-    /**
-     * Constructs object from file stream.
-     * @param file Input stream
-     * @throws IOException
-     * @throws ClassFormatException
-     */
-    private final void processFieldOrMethod () throws IOException, ClassFormatException {
-        final int access_flags = file.readUnsignedShort();
-        final int name_index = file.readUnsignedShort();
-        System.out.printf("  name_index: %d (", name_index);
-        System.out.println(constantToString(name_index) + ")");
-        System.out.println("  access_flags: " + BCELifier.printFlags(access_flags,
-                BCELifier.FLAGS.METHOD));
-        final int descriptor_index = file.readUnsignedShort();
-        System.out.printf("  descriptor_index: %d (", descriptor_index);
-        System.out.println(constantToString(descriptor_index) + ")");
-
-        final int attributes_count = file.readUnsignedShort();
-        final Attribute[] attributes = new Attribute[attributes_count];
-        System.out.println("  attribute count: " + attributes_count);
-
-        for (int i = 0; i < attributes_count; i++) {
-            // going to peek ahead a bit
-            file.mark();
-            final int attribute_name_index = file.readUnsignedShort();
-            final int attribute_length = file.readInt();
-            // restore file location
-            file.reset();
-            // Usefull for debugging
-            // System.out.printf("  attribute_name_index: %d (", attribute_name_index);
-            // System.out.println(constantToString(attribute_name_index) + ")");
-            // System.out.printf("  atribute offset in file: %x%n", + file.getStreamPosition());
-            // System.out.println("  atribute_length: " + attribute_length);
-
-            // A stronger verification test would be to read attribute_length bytes
-            // into a buffer.  Then pass that buffer to readAttribute and also
-            // verify we're at EOF of the buffer on return.
-
-            final long pos1 = file.getStreamPosition();
-            attributes[i] = Attribute.readAttribute(file, constant_pool);
-            final long pos2 = file.getStreamPosition();
-            if ((pos2 - pos1) != (attribute_length + 6)) {
-                System.out.printf("%nattribute_length: %d pos2-pos1-6: %d pos1: %x(%d) pos2: %x(%d)%n",
-                        attribute_length, pos2-pos1-6, pos1, pos1, pos2, pos2);
-            }
-            System.out.printf("  ");
-            System.out.println(attributes[i]);
-        }
-    }
+    private final void processVersion () throws IOException, ClassFormatException {
+        minor = file.readUnsignedShort();
+        System.out.printf("  minor version: %s%n", minor);
 
-    private final String constantToString (final int index) {
-        final Constant c = constant_items[index];
-        return constant_pool.constantToString(c);
+        major = file.readUnsignedShort();
+        System.out.printf("  major version: %s%n", major);
     }
 
 }
diff --git a/src/examples/JasminVisitor.java b/src/examples/JasminVisitor.java
index 12425b92..bec91309 100644
--- a/src/examples/JasminVisitor.java
+++ b/src/examples/JasminVisitor.java
@@ -57,11 +57,45 @@ import org.apache.bcel.generic.TABLESWITCH;
  *
  */
 public class JasminVisitor extends org.apache.bcel.classfile.EmptyVisitor {
+    public static void main(final String[] argv) throws Exception {
+        JavaClass java_class;
+
+        if (argv.length == 0) {
+            System.err.println("disassemble: No input files specified");
+            return;
+        }
+
+        for (final String arg : argv) {
+            if ((java_class = Repository.lookupClass(arg)) == null) {
+                java_class = new ClassParser(arg).parse();
+            }
+
+            String class_name = java_class.getClassName();
+            final int index = class_name.lastIndexOf('.');
+            final String path = class_name.substring(0, index + 1).replace('.', File.separatorChar);
+            class_name = class_name.substring(index + 1);
+
+            if (!path.equals("")) {
+                final File f = new File(path);
+                f.mkdirs();
+            }
+
+            final String name = path + class_name + ".j";
+            final FileOutputStream out = new FileOutputStream(name);
+            new JasminVisitor(java_class, out).disassemble();
+            System.out.println("File dumped to: " + name);
+        }
+    }
     private final JavaClass clazz;
     private final PrintWriter out;
     private final String class_name;
+
     private final ConstantPoolGen cp;
 
+    private Method _method;
+
+    private Hashtable<InstructionHandle, String> map;
+
     public JasminVisitor(final JavaClass clazz, final OutputStream out) {
         this.clazz = clazz;
         this.out = new PrintWriter(out);
@@ -77,41 +111,11 @@ public class JasminVisitor extends org.apache.bcel.classfile.EmptyVisitor {
         out.close();
     }
 
-    @Override
-    public void visitJavaClass(final JavaClass clazz) {
-        out.println(";; Produced by JasminVisitor (BCEL)");
-        out.println(";; https://commons.apache.org/bcel/");
-        out.println(";; " + new Date() + "\n");
-
-        out.println(".source " + clazz.getSourceFileName());
-        out.println("." + Utility.classOrInterface(clazz.getAccessFlags()) + " " +
-                Utility.accessToString(clazz.getAccessFlags(), true) +
-                " " + clazz.getClassName().replace('.', '/'));
-        out.println(".super " + clazz.getSuperclassName().replace('.', '/'));
-
-        for (final String iface : clazz.getInterfaceNames()) {
-            out.println(".implements " + iface.replace('.', '/'));
-        }
-
-        out.print("\n");
-    }
-
-    @Override
-    public void visitField(final Field field) {
-        out.print(".field " + Utility.accessToString(field.getAccessFlags()) +
-                " \"" + field.getName() + "\"" + field.getSignature());
-        if (field.getAttributes().length == 0) {
-            out.print("\n");
-        }
-    }
-
-    @Override
-    public void visitConstantValue(final ConstantValue cv) {
-        out.println(" = " + cv);
+    private String get(final InstructionHandle ih) {
+        final String str = new StringTokenizer(map.get(ih), "\n").nextToken();
+        return str.substring(0, str.length() - 1);
     }
 
-    private Method _method;
-
     /**
      * Unfortunately Jasmin expects ".end method" after each method. Thus we've to check
      * for every of the method's attributes if it's the last one and print ".end method"
@@ -125,42 +129,20 @@ public class JasminVisitor extends org.apache.bcel.classfile.EmptyVisitor {
         }
     }
 
-    @Override
-    public void visitDeprecated(final Deprecated attribute) {
-        printEndMethod(attribute);
-    }
-
-    @Override
-    public void visitSynthetic(final Synthetic attribute) {
-        if (_method != null) {
-            printEndMethod(attribute);
-        }
-    }
-
-    @Override
-    public void visitMethod(final Method method) {
-        this._method = method; // Remember for use in subsequent visitXXX calls
-
-        out.println("\n.method " + Utility.accessToString(_method.getAccessFlags()) +
-                " " + _method.getName() + _method.getSignature());
+    private void put(final InstructionHandle ih, final String line) {
+        final String str = map.get(ih);
 
-        final Attribute[] attributes = _method.getAttributes();
-        if ((attributes == null) || (attributes.length == 0)) {
-            out.println(".end method");
-        }
-    }
+        if (str == null) {
+            map.put(ih, line);
+        } else {
+            if (line.startsWith("Label") || str.endsWith(line)) {
+                return;
+            }
 
-    @Override
-    public void visitExceptionTable(final ExceptionTable e) {
-        for (final String name : e.getExceptionNames()) {
-            out.println(".throws " + name.replace('.', '/'));
+            map.put(ih, str + "\n" + line); // append
         }
-
-        printEndMethod(e);
     }
 
-    private Hashtable<InstructionHandle, String> map;
-
     @Override
     public void visitCode(final Code code) {
         int label_counter = 0;
@@ -283,52 +265,70 @@ public class JasminVisitor extends org.apache.bcel.classfile.EmptyVisitor {
         printEndMethod(code);
     }
 
-    private String get(final InstructionHandle ih) {
-        final String str = new StringTokenizer(map.get(ih), "\n").nextToken();
-        return str.substring(0, str.length() - 1);
+    @Override
+    public void visitConstantValue(final ConstantValue cv) {
+        out.println(" = " + cv);
     }
 
-    private void put(final InstructionHandle ih, final String line) {
-        final String str = map.get(ih);
+    @Override
+    public void visitDeprecated(final Deprecated attribute) {
+        printEndMethod(attribute);
+    }
 
-        if (str == null) {
-            map.put(ih, line);
-        } else {
-            if (line.startsWith("Label") || str.endsWith(line)) {
-                return;
-            }
+    @Override
+    public void visitExceptionTable(final ExceptionTable e) {
+        for (final String name : e.getExceptionNames()) {
+            out.println(".throws " + name.replace('.', '/'));
+        }
 
-            map.put(ih, str + "\n" + line); // append
+        printEndMethod(e);
+    }
+
+    @Override
+    public void visitField(final Field field) {
+        out.print(".field " + Utility.accessToString(field.getAccessFlags()) +
+                " \"" + field.getName() + "\"" + field.getSignature());
+        if (field.getAttributes().length == 0) {
+            out.print("\n");
         }
     }
 
-    public static void main(final String[] argv) throws Exception {
-        JavaClass java_class;
+    @Override
+    public void visitJavaClass(final JavaClass clazz) {
+        out.println(";; Produced by JasminVisitor (BCEL)");
+        out.println(";; https://commons.apache.org/bcel/");
+        out.println(";; " + new Date() + "\n");
 
-        if (argv.length == 0) {
-            System.err.println("disassemble: No input files specified");
-            return;
+        out.println(".source " + clazz.getSourceFileName());
+        out.println("." + Utility.classOrInterface(clazz.getAccessFlags()) + " " +
+                Utility.accessToString(clazz.getAccessFlags(), true) +
+                " " + clazz.getClassName().replace('.', '/'));
+        out.println(".super " + clazz.getSuperclassName().replace('.', '/'));
+
+        for (final String iface : clazz.getInterfaceNames()) {
+            out.println(".implements " + iface.replace('.', '/'));
         }
 
-        for (final String arg : argv) {
-            if ((java_class = Repository.lookupClass(arg)) == null) {
-                java_class = new ClassParser(arg).parse();
-            }
+        out.print("\n");
+    }
 
-            String class_name = java_class.getClassName();
-            final int index = class_name.lastIndexOf('.');
-            final String path = class_name.substring(0, index + 1).replace('.', File.separatorChar);
-            class_name = class_name.substring(index + 1);
+    @Override
+    public void visitMethod(final Method method) {
+        this._method = method; // Remember for use in subsequent visitXXX calls
 
-            if (!path.equals("")) {
-                final File f = new File(path);
-                f.mkdirs();
-            }
+        out.println("\n.method " + Utility.accessToString(_method.getAccessFlags()) +
+                " " + _method.getName() + _method.getSignature());
 
-            final String name = path + class_name + ".j";
-            final FileOutputStream out = new FileOutputStream(name);
-            new JasminVisitor(java_class, out).disassemble();
-            System.out.println("File dumped to: " + name);
+        final Attribute[] attributes = _method.getAttributes();
+        if ((attributes == null) || (attributes.length == 0)) {
+            out.println(".end method");
+        }
+    }
+
+    @Override
+    public void visitSynthetic(final Synthetic attribute) {
+        if (_method != null) {
+            printEndMethod(attribute);
         }
     }
 }
diff --git a/src/examples/Mini/ASCII_CharStream.java b/src/examples/Mini/ASCII_CharStream.java
index 6797aa41..c72f35c9 100644
--- a/src/examples/Mini/ASCII_CharStream.java
+++ b/src/examples/Mini/ASCII_CharStream.java
@@ -47,6 +47,79 @@ public final class ASCII_CharStream
   static private int maxNextCharInd = 0;
   static private int inBuf = 0;
 
+  /**
+   * Method to adjust line and column numbers for the start of a token.<BR>
+   */
+  static public void adjustBeginLineColumn(int newLine, final int newCol)
+  {
+     int start = tokenBegin;
+     int len;
+
+     if (bufpos >= tokenBegin)
+     {
+        len = bufpos - tokenBegin + inBuf + 1;
+     }
+     else
+     {
+        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+     }
+
+     int i = 0, j = 0, k = 0;
+     int nextColDiff = 0, columnDiff = 0;
+
+     while (i < len &&
+            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+     {
+        bufline[j] = newLine;
+        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+        bufcolumn[j] = newCol + columnDiff;
+        columnDiff = nextColDiff;
+        i++;
+     }
+
+     if (i < len)
+     {
+        bufline[j] = newLine++;
+        bufcolumn[j] = newCol + columnDiff;
+
+        while (i++ < len)
+        {
+           if (bufline[j = start % bufsize] != bufline[++start % bufsize]) {
+            bufline[j] = newLine++;
+        } else {
+            bufline[j] = newLine;
+        }
+        }
+     }
+
+     line = bufline[j];
+     column = bufcolumn[j];
+  }
+
+  static public void backup(final int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0) {
+        bufpos += bufsize;
+    }
+  }
+
+  static public char BeginToken() throws IOException
+  {
+     tokenBegin = -1;
+     final char c = readChar();
+     tokenBegin = bufpos;
+
+     return c;
+  }
+
+  static public void Done()
+  {
+     buffer = null;
+     bufline = null;
+     bufcolumn = null;
+  }
+
   static private void ExpandBuff(final boolean wrapAround)
   {
      final char[] newbuffer = new char[bufsize + 2048];
@@ -143,55 +216,46 @@ public final class ASCII_CharStream
      }
   }
 
-  static public char BeginToken() throws IOException
-  {
-     tokenBegin = -1;
-     final char c = readChar();
-     tokenBegin = bufpos;
+  static public int getBeginColumn() {
+     return bufcolumn[tokenBegin];
+  }
 
-     return c;
+  static public int getBeginLine() {
+     return bufline[tokenBegin];
   }
 
-  static private void UpdateLineColumn(final char c)
+  static public int getEndColumn() {
+     return bufcolumn[bufpos];
+  }
+
+  static public int getEndLine() {
+     return bufline[bufpos];
+  }
+
+  static public String GetImage()
   {
-     column++;
+     if (bufpos >= tokenBegin) {
+        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+    }
+    return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                          new String(buffer, 0, bufpos + 1);
+  }
 
-     if (prevCharIsLF)
-     {
-        prevCharIsLF = false;
-        line += (column = 1);
-     }
-     else if (prevCharIsCR)
-     {
-        prevCharIsCR = false;
-        if (c == '\n')
-        {
-           prevCharIsLF = true;
-        } else {
-            line += (column = 1);
-        }
-     }
+  static public char[] GetSuffix(final int len)
+  {
+     final char[] ret = new char[len];
 
-     switch (c)
+     if ((bufpos + 1) >= len) {
+        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+    } else
      {
-        case '\r' :
-           prevCharIsCR = true;
-           break;
-        case '\n' :
-           prevCharIsLF = true;
-           break;
-        case '\t' :
-           column--;
-           column += (8 - (column & 07));
-           break;
-        default :
-           break;
+        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                          len - bufpos - 1);
+        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
      }
 
-     bufline[bufpos] = line;
-     bufcolumn[bufpos] = column;
+     return ret;
   }
-
   static public char readChar() throws IOException
   {
      if (inBuf > 0)
@@ -210,53 +274,23 @@ public final class ASCII_CharStream
      return (c);
   }
 
-  static public int getEndColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  static public int getEndLine() {
-     return bufline[bufpos];
-  }
-
-  static public int getBeginColumn() {
-     return bufcolumn[tokenBegin];
-  }
-
-  static public int getBeginLine() {
-     return bufline[tokenBegin];
-  }
-
-  static public void backup(final int amount) {
-
-    inBuf += amount;
-    if ((bufpos -= amount) < 0) {
-        bufpos += bufsize;
-    }
+  static public void ReInit(final java.io.InputStream dstream, final int startline,
+                                                           final int startcolumn)
+  {
+     ReInit(dstream, startline, startcolumn, 4096);
   }
-
-  public ASCII_CharStream(final java.io.Reader dstream, final int startline,
+  static public void ReInit(final java.io.InputStream dstream, final int startline,
   final int startcolumn, final int buffersize)
   {
-    if (inputStream != null) {
-        throw new Error("\n   ERROR: Second call to the constructor of a static ASCII_CharStream.  You must\n" +
-           "       either use ReInit() or set the JavaCC option STATIC to false\n" +
-           "       during the generation of this class.");
-    }
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    available = bufsize = buffersize;
-    buffer = new char[buffersize];
-    bufline = new int[buffersize];
-    bufcolumn = new int[buffersize];
+     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
   }
 
-  public ASCII_CharStream(final java.io.Reader dstream, final int startline,
+  static public void ReInit(final java.io.Reader dstream, final int startline,
                                                            final int startcolumn)
   {
-     this(dstream, startline, startcolumn, 4096);
+     ReInit(dstream, startline, startcolumn, 4096);
   }
+
   static public void ReInit(final java.io.Reader dstream, final int startline,
   final int startcolumn, final int buffersize)
   {
@@ -275,113 +309,79 @@ public final class ASCII_CharStream
     tokenBegin = inBuf = maxNextCharInd = 0;
     bufpos = -1;
   }
+  static private void UpdateLineColumn(final char c)
+  {
+     column++;
 
-  static public void ReInit(final java.io.Reader dstream, final int startline,
+     if (prevCharIsLF)
+     {
+        prevCharIsLF = false;
+        line += (column = 1);
+     }
+     else if (prevCharIsCR)
+     {
+        prevCharIsCR = false;
+        if (c == '\n')
+        {
+           prevCharIsLF = true;
+        } else {
+            line += (column = 1);
+        }
+     }
+
+     switch (c)
+     {
+        case '\r' :
+           prevCharIsCR = true;
+           break;
+        case '\n' :
+           prevCharIsLF = true;
+           break;
+        case '\t' :
+           column--;
+           column += (8 - (column & 07));
+           break;
+        default :
+           break;
+     }
+
+     bufline[bufpos] = line;
+     bufcolumn[bufpos] = column;
+  }
+  public ASCII_CharStream(final java.io.InputStream dstream, final int startline,
                                                            final int startcolumn)
   {
-     ReInit(dstream, startline, startcolumn, 4096);
+     this(dstream, startline, startcolumn, 4096);
   }
+
   public ASCII_CharStream(final java.io.InputStream dstream, final int startline,
   final int startcolumn, final int buffersize)
   {
      this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
   }
 
-  public ASCII_CharStream(final java.io.InputStream dstream, final int startline,
+  public ASCII_CharStream(final java.io.Reader dstream, final int startline,
                                                            final int startcolumn)
   {
      this(dstream, startline, startcolumn, 4096);
   }
 
-  static public void ReInit(final java.io.InputStream dstream, final int startline,
+  public ASCII_CharStream(final java.io.Reader dstream, final int startline,
   final int startcolumn, final int buffersize)
   {
-     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
-  }
-  static public void ReInit(final java.io.InputStream dstream, final int startline,
-                                                           final int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-  static public String GetImage()
-  {
-     if (bufpos >= tokenBegin) {
-        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+    if (inputStream != null) {
+        throw new Error("\n   ERROR: Second call to the constructor of a static ASCII_CharStream.  You must\n" +
+           "       either use ReInit() or set the JavaCC option STATIC to false\n" +
+           "       during the generation of this class.");
     }
-    return new String(buffer, tokenBegin, bufsize - tokenBegin) +
-                          new String(buffer, 0, bufpos + 1);
-  }
-
-  static public char[] GetSuffix(final int len)
-  {
-     final char[] ret = new char[len];
-
-     if ((bufpos + 1) >= len) {
-        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
-    } else
-     {
-        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
-                                                          len - bufpos - 1);
-        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
-     }
-
-     return ret;
-  }
-
-  static public void Done()
-  {
-     buffer = null;
-     bufline = null;
-     bufcolumn = null;
-  }
-
-  /**
-   * Method to adjust line and column numbers for the start of a token.<BR>
-   */
-  static public void adjustBeginLineColumn(int newLine, final int newCol)
-  {
-     int start = tokenBegin;
-     int len;
-
-     if (bufpos >= tokenBegin)
-     {
-        len = bufpos - tokenBegin + inBuf + 1;
-     }
-     else
-     {
-        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
-     }
-
-     int i = 0, j = 0, k = 0;
-     int nextColDiff = 0, columnDiff = 0;
-
-     while (i < len &&
-            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
-     {
-        bufline[j] = newLine;
-        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
-        bufcolumn[j] = newCol + columnDiff;
-        columnDiff = nextColDiff;
-        i++;
-     }
-
-     if (i < len)
-     {
-        bufline[j] = newLine++;
-        bufcolumn[j] = newCol + columnDiff;
-
-        while (i++ < len)
-        {
-           if (bufline[j = start % bufsize] != bufline[++start % bufsize]) {
-            bufline[j] = newLine++;
-        } else {
-            bufline[j] = newLine;
-        }
-        }
-     }
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
 
-     line = bufline[j];
-     column = bufcolumn[j];
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
   }
 
 }
diff --git a/src/examples/Mini/ASTExpr.java b/src/examples/Mini/ASTExpr.java
index 80678e38..ad3f7afd 100644
--- a/src/examples/Mini/ASTExpr.java
+++ b/src/examples/Mini/ASTExpr.java
@@ -49,31 +49,44 @@ import org.apache.bcel.generic.PUSH;
 */
 public class ASTExpr extends SimpleNode
 implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constants {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTExpr(p, id);
+  }
+  private static String toBool(final String i) {
+    return "(" + i + " != 0)";
+  }
+  private static String toInt(final String i) {
+    return "((" + i + ")? 1 : 0)";
+  }
   protected int         kind=-1;    // Single twig to leaf?
   private   int         unop=-1;    // Special case: Unary operand applied
   protected ASTExpr[]   exprs;      // Sub expressions
-  protected Environment env;        // Needed in all passes
+
+ protected Environment env;        // Needed in all passes
+
   protected int         line, column;
+
   protected boolean     is_simple;  // true, if simple expression like `12 + f(a)'
 
- /* Not all children shall inherit this, exceptions are ASTIdent and ASTFunAppl, which
+  /* Not all children shall inherit this, exceptions are ASTIdent and ASTFunAppl, which
   * look up the type in the corresponding environment entry.
   */
   protected int         type = T_UNKNOWN;
 
+  /* Special constructor, called from ASTTerm.traverse() and
+   * ASTFactor.traverse(), when traverse()ing the parse tree replace
+   * themselves with Expr nodes.
+   */
+  ASTExpr(final ASTExpr[] children, final int kind, final int line, final int column) {
+    this(line, column, kind, JJTEXPR);
+    exprs = children;
+  }
+
   // Generated methods
   ASTExpr(final int id) {
     super(id);
   }
 
-  ASTExpr(final MiniParser p, final int id) {
-    super(p, id);
-  }
-
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTExpr(p, id);
-  }
-
   ASTExpr(final int line, final int column, final int id) {
     super(id);
     this.line   = line;
@@ -85,30 +98,61 @@ implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constan
     this.kind = kind;
   }
 
-  /* Special constructor, called from ASTTerm.traverse() and
-   * ASTFactor.traverse(), when traverse()ing the parse tree replace
-   * themselves with Expr nodes.
-   */
-  ASTExpr(final ASTExpr[] children, final int kind, final int line, final int column) {
-    this(line, column, kind, JJTEXPR);
-    exprs = children;
+  ASTExpr(final MiniParser p, final int id) {
+    super(p, id);
   }
 
   /**
-   * @return name of node, its kind and the number of children.
+   * Fifth pass, produce Java byte code.
    */
-  @Override
-  public String toString() {
-    String op="";
-    final int    len = (children != null)? children.length : 0;
-    if(unop != -1) {
-        op = tokenImage[unop];
-    } else if(kind != -1) {
-        op = tokenImage[kind];
+  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
+    exprs[0].byte_code(il, method, cp);
+
+    if(unop != -1) { // Apply unary operand
+      if(unop == MINUS) {
+        il.append(InstructionConstants.INEG);
+    } else { // == NOT
+        il.append(new PUSH(cp, 1)); ASTFunDecl.push(); // Push TRUE
+        il.append(InstructionConstants.IXOR); ASTFunDecl.pop();
+      }
     }
+    else { // Apply binary operand
+      BranchHandle bh=null;
 
-    return jjtNodeName[id] + "(" + op + ")[" + len + "]<" +
-      TYPE_NAMES[type] + "> @" + line + ", " + column;
+      exprs[1].byte_code(il, method, cp);
+
+      switch(kind) {
+      case PLUS:  il.append(InstructionConstants.IADD); ASTFunDecl.pop();  break;
+      case MINUS: il.append(InstructionConstants.ISUB); ASTFunDecl.pop();  break;
+      case MULT:  il.append(InstructionConstants.IMUL); ASTFunDecl.pop();  break;
+      case DIV:   il.append(InstructionConstants.IDIV); ASTFunDecl.pop();  break;
+      case AND:   il.append(InstructionConstants.IAND); ASTFunDecl.pop();  break;
+      case OR:    il.append(InstructionConstants.IOR);  ASTFunDecl.pop();  break;
+
+        /* Use negated operands */
+      case EQ:    bh = il.append(new IF_ICMPNE(null)); ASTFunDecl.pop(2); break;
+      case LEQ:   bh = il.append(new IF_ICMPGT(null)); ASTFunDecl.pop(2); break;
+      case GEQ:   bh = il.append(new IF_ICMPLT(null)); ASTFunDecl.pop(2); break;
+      case NEQ:   bh = il.append(new IF_ICMPEQ(null)); ASTFunDecl.pop(2); break;
+      case LT:    bh = il.append(new IF_ICMPGE(null)); ASTFunDecl.pop(2); break;
+      case GT:    bh = il.append(new IF_ICMPLE(null)); ASTFunDecl.pop(2); break;
+      default: System.err.println("Unhandled case: " + kind);
+      }
+
+      switch(kind) {
+      case EQ: case LEQ: case GEQ: case NEQ: case LT: case GT:
+        BranchHandle g;
+
+        il.append(new PUSH(cp, 1));
+        g = il.append(new GOTO(null));
+        bh.setTarget(il.append(new PUSH(cp, 0)));
+        g.setTarget(il.append(InstructionConstants.NOP)); // May be optimized away later
+        ASTFunDecl.push();
+        break;
+
+      default: break;
+      }
+    }
   }
 
   /**
@@ -126,76 +170,6 @@ implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constan
     }
   }
 
-  /**
-   * First pass
-   * Overridden by subclasses. Traverse the whole parse tree recursively and
-   * drop redundant nodes.
-   */
-  public ASTExpr traverse(final Environment env) {
-    this.env = env;
-
-    if((kind == -1) && (unop == -1)) {
-        return exprs[0].traverse(env);  // --> Replaced by successor
-    }
-    for(int i=0; i < exprs.length; i++) {
-        exprs[i] = exprs[i].traverse(env); // References may change
-    }
-
-      return this;
-  }
-
-  /**
-   * Second and third pass
-   * @return type of expression
-   * @param expected type
-   */
-  public int eval(final int expected) {
-    int child_type = T_UNKNOWN, t;
-
-    is_simple = true;
-
-    // Determine expected node type depending on used operator.
-    if(unop != -1) {
-      if(unop == MINUS) {
-        child_type = type = T_INT;  // -
-    } else {
-        child_type = type = T_BOOLEAN; // !
-    }
-    } else // Compute expected type
-      if((kind == PLUS) || (kind == MINUS) || (kind == MULT) ||
-       (kind == MOD)  || (kind == DIV)) {
-        child_type = type = T_INT;
-    } else if((kind == AND) || (kind == OR)) {
-        child_type = type = T_BOOLEAN;
-    } else { // LEQ, GT, etc.
-        child_type = T_INT;
-        type       = T_BOOLEAN;
-      }
-
-    // Get type of subexpressions
-    for (final ASTExpr expr : exprs) {
-      t = expr.eval(child_type);
-
-      if(t != child_type) {
-        MiniC.addError(expr.getLine(), expr.getColumn(),
-                       "Expression has not expected type " + TYPE_NAMES[child_type] +
-                       " but " + TYPE_NAMES[t] + ".");
-    }
-
-      is_simple = is_simple && expr.isSimple();
-    }
-
-    return type;
-  }
-
-  private static String toBool(final String i) {
-    return "(" + i + " != 0)";
-  }
-
-  private static String toInt(final String i) {
-    return "((" + i + ")? 1 : 0)";
-  }
-
   /**
    * Fourth pass, produce Java code.
    */
@@ -244,83 +218,109 @@ implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constan
     }
   }
 
-  /**
-   * Fifth pass, produce Java byte code.
-   */
-  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
-    exprs[0].byte_code(il, method, cp);
+  @Override
+  public void dump(final String prefix) {
+    System.out.println(toString(prefix));
 
-    if(unop != -1) { // Apply unary operand
-      if(unop == MINUS) {
-        il.append(InstructionConstants.INEG);
-    } else { // == NOT
-        il.append(new PUSH(cp, 1)); ASTFunDecl.push(); // Push TRUE
-        il.append(InstructionConstants.IXOR); ASTFunDecl.pop();
-      }
+    if(exprs != null) {
+        for (final ASTExpr expr : exprs) {
+            expr.dump(prefix + " ");
+        }
     }
-    else { // Apply binary operand
-      BranchHandle bh=null;
+  }
 
-      exprs[1].byte_code(il, method, cp);
+  /**
+   * Second and third pass
+   * @return type of expression
+   * @param expected type
+   */
+  public int eval(final int expected) {
+    int child_type = T_UNKNOWN, t;
 
-      switch(kind) {
-      case PLUS:  il.append(InstructionConstants.IADD); ASTFunDecl.pop();  break;
-      case MINUS: il.append(InstructionConstants.ISUB); ASTFunDecl.pop();  break;
-      case MULT:  il.append(InstructionConstants.IMUL); ASTFunDecl.pop();  break;
-      case DIV:   il.append(InstructionConstants.IDIV); ASTFunDecl.pop();  break;
-      case AND:   il.append(InstructionConstants.IAND); ASTFunDecl.pop();  break;
-      case OR:    il.append(InstructionConstants.IOR);  ASTFunDecl.pop();  break;
+    is_simple = true;
 
-        /* Use negated operands */
-      case EQ:    bh = il.append(new IF_ICMPNE(null)); ASTFunDecl.pop(2); break;
-      case LEQ:   bh = il.append(new IF_ICMPGT(null)); ASTFunDecl.pop(2); break;
-      case GEQ:   bh = il.append(new IF_ICMPLT(null)); ASTFunDecl.pop(2); break;
-      case NEQ:   bh = il.append(new IF_ICMPEQ(null)); ASTFunDecl.pop(2); break;
-      case LT:    bh = il.append(new IF_ICMPGE(null)); ASTFunDecl.pop(2); break;
-      case GT:    bh = il.append(new IF_ICMPLE(null)); ASTFunDecl.pop(2); break;
-      default: System.err.println("Unhandled case: " + kind);
+    // Determine expected node type depending on used operator.
+    if(unop != -1) {
+      if(unop == MINUS) {
+        child_type = type = T_INT;  // -
+    } else {
+        child_type = type = T_BOOLEAN; // !
+    }
+    } else // Compute expected type
+      if((kind == PLUS) || (kind == MINUS) || (kind == MULT) ||
+       (kind == MOD)  || (kind == DIV)) {
+        child_type = type = T_INT;
+    } else if((kind == AND) || (kind == OR)) {
+        child_type = type = T_BOOLEAN;
+    } else { // LEQ, GT, etc.
+        child_type = T_INT;
+        type       = T_BOOLEAN;
       }
 
-      switch(kind) {
-      case EQ: case LEQ: case GEQ: case NEQ: case LT: case GT:
-        BranchHandle g;
+    // Get type of subexpressions
+    for (final ASTExpr expr : exprs) {
+      t = expr.eval(child_type);
 
-        il.append(new PUSH(cp, 1));
-        g = il.append(new GOTO(null));
-        bh.setTarget(il.append(new PUSH(cp, 0)));
-        g.setTarget(il.append(InstructionConstants.NOP)); // May be optimized away later
-        ASTFunDecl.push();
-        break;
+      if(t != child_type) {
+        MiniC.addError(expr.getLine(), expr.getColumn(),
+                       "Expression has not expected type " + TYPE_NAMES[child_type] +
+                       " but " + TYPE_NAMES[t] + ".");
+    }
 
-      default: break;
-      }
+      is_simple = is_simple && expr.isSimple();
     }
+
+    return type;
   }
 
-  public boolean isSimple()         { return is_simple; }
-  public void setType(final int type)     { this.type = type; }
-  public int  getType()             { return type; }
-  public void setKind(final int kind)     { this.kind = kind; }
+  public int  getColumn()           { return column; }
+
   public int  getKind()             { return kind; }
-  public void setUnOp(final int unop)     { this.unop = unop; }
-  public int  getUnOp()             { return unop; }
-  public void setLine(final int line)     { this.line = line; }
   public int  getLine()             { return line; }
+  public int  getType()             { return type; }
+  public int  getUnOp()             { return unop; }
+  public boolean isSimple()         { return is_simple; }
   public void setColumn(final int column) { this.column = column; }
-  public int  getColumn()           { return column; }
+  public void setKind(final int kind)     { this.kind = kind; }
+  public void setLine(final int line)     { this.line = line; }
   public void setPosition(final int line, final int column) {
     this.line = line;
     this.column = column;
   }
-
+  public void setType(final int type)     { this.type = type; }
+  public void setUnOp(final int unop)     { this.unop = unop; }
+  /**
+   * @return name of node, its kind and the number of children.
+   */
   @Override
-  public void dump(final String prefix) {
-    System.out.println(toString(prefix));
+  public String toString() {
+    String op="";
+    final int    len = (children != null)? children.length : 0;
+    if(unop != -1) {
+        op = tokenImage[unop];
+    } else if(kind != -1) {
+        op = tokenImage[kind];
+    }
 
-    if(exprs != null) {
-        for (final ASTExpr expr : exprs) {
-            expr.dump(prefix + " ");
-        }
+    return jjtNodeName[id] + "(" + op + ")[" + len + "]<" +
+      TYPE_NAMES[type] + "> @" + line + ", " + column;
+  }
+
+  /**
+   * First pass
+   * Overridden by subclasses. Traverse the whole parse tree recursively and
+   * drop redundant nodes.
+   */
+  public ASTExpr traverse(final Environment env) {
+    this.env = env;
+
+    if((kind == -1) && (unop == -1)) {
+        return exprs[0].traverse(env);  // --> Replaced by successor
     }
+    for(int i=0; i < exprs.length; i++) {
+        exprs[i] = exprs[i].traverse(env); // References may change
+    }
+
+      return this;
   }
 }
diff --git a/src/examples/Mini/ASTFactor.java b/src/examples/Mini/ASTFactor.java
index 305e78b0..b41bb74c 100644
--- a/src/examples/Mini/ASTFactor.java
+++ b/src/examples/Mini/ASTFactor.java
@@ -24,6 +24,10 @@ package Mini;
  *
  */
 public class ASTFactor extends ASTExpr {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTFactor(p, id);
+  }
+
   // Generated methods
   ASTFactor(final int id) {
     super(id);
@@ -33,10 +37,6 @@ public class ASTFactor extends ASTExpr {
     super(p, id);
   }
 
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTFactor(p, id);
-  }
-
   // Inherited closeNode(), dump()
 
   /**
diff --git a/src/examples/Mini/ASTFunAppl.java b/src/examples/Mini/ASTFunAppl.java
index dd9994f5..c0b9902c 100644
--- a/src/examples/Mini/ASTFunAppl.java
+++ b/src/examples/Mini/ASTFunAppl.java
@@ -30,9 +30,21 @@ import org.apache.bcel.generic.Type;
  */
 public class ASTFunAppl extends ASTExpr implements MiniParserTreeConstants,
   org.apache.bcel.Constants {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTFunAppl(p, id);
+  }
   private ASTIdent name;
+
   private Function function; // Points to Function in environment
 
+  ASTFunAppl(final ASTIdent name, final Function function, final ASTExpr[] exprs) {
+    this(JJTFUNAPPL);
+
+    this.name     = name;
+    this.function = function;
+    this.exprs    = exprs;
+  }
+
   // Generated methods
   ASTFunAppl(final int id) {
     super(id);
@@ -42,21 +54,53 @@ public class ASTFunAppl extends ASTExpr implements MiniParserTreeConstants,
     super(p, id);
   }
 
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTFunAppl(p, id);
-  }
+  /**
+   * Fifth pass, produce Java byte code.
+   */
+  @Override
+  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
+    final String     fname = name.getName();
+//    Function   f     = function;
+    //ASTIdent   fun   = f.getName();
+//    ASTIdent[] args  = f.getArgs();
+    final String     class_name = method.getClassName();
 
-  ASTFunAppl(final ASTIdent name, final Function function, final ASTExpr[] exprs) {
-    this(JJTFUNAPPL);
+    if(fname.equals("READ")) {
+        il.append(new INVOKESTATIC(cp.addMethodref(class_name,
+                                                 "_readInt",
+                                                 "()I")));
+    } else if(fname.equals("WRITE")) {
+      exprs[0].byte_code(il, method, cp);
+      ASTFunDecl.pop();
+      il.append(new INVOKESTATIC(cp.addMethodref(class_name,
+                                                 "_writeInt",
+                                                 "(I)I")));
+    }
+    else { // Normal function
+      final int size    = exprs.length;
+      Type[] argv = null;
 
-    this.name     = name;
-    this.function = function;
-    this.exprs    = exprs;
-  }
+      if(exprs != null) {
+        argv = new Type[size];
 
-  @Override
-  public String toString() {
-    return jjtNodeName[id] + " " + name.getName();
+        for(int i=0; i < size; i++) {
+          argv[i] = Type.INT;
+          exprs[i].byte_code(il, method, cp);
+        }
+
+        //ASTFunDecl.push(size);
+      }
+
+      ASTFunDecl.pop(size);
+
+      // Function call
+      il.append(new INVOKESTATIC(cp.addMethodref(class_name,
+                                                 fname,
+                                                 Type.getMethodSignature(Type.INT,
+                                                                         argv))));
+    }
+
+    ASTFunDecl.push();
   }
 
   /**
@@ -75,42 +119,42 @@ public class ASTFunAppl extends ASTExpr implements MiniParserTreeConstants,
   }
 
   /**
-   * Overrides ASTExpr.traverse()
+   * Fourth pass, produce Java code.
    */
   @Override
-  public ASTExpr traverse(final Environment env) {
-    final String   fname = name.getName();
-    final EnvEntry entry = env.get(fname);
+  public void code(final StringBuffer buf) {
+    final String     fname = name.getName();
+//    Function   f     = function;
+//    ASTIdent[] args  = f.getArgs();
 
-    this.env = env;
+    if(fname.equals("READ")) {
+        ASTFunDecl.push(buf, "_readInt()");
+    } else if(fname.equals("WRITE")) {
+      exprs[0].code(buf);
+      ASTFunDecl.push(buf, "_writeInt(" + ASTFunDecl.pop() + ")");
+    }
+    else { // Normal function
+      if(exprs != null) { // Output in reverse odrder
+        for(int i = exprs.length - 1; i >= 0; i--) {
+        exprs[i].code(buf);
+    }
+      }
 
-    if(entry == null) {
-        MiniC.addError(name.getLine(), name.getColumn(),
-                 "Applying unknown function " + fname + ".");
-    } else if(!(entry instanceof Function)) {
-        MiniC.addError(name.getLine(), name.getColumn(),
-                 "Applying non-function " + fname + ".");
-    } else {
-        final int      len = (exprs != null)? exprs.length : 0;
-        final Function fun = (Function)entry;
+      final StringBuilder call = new StringBuilder(fname + "(");
+      // Function call
 
-        if(len != fun.getNoArgs()) {
-        MiniC.addError(name.getLine(), name.getColumn(),
-                   "Function " + fname + " expects " + fun.getNoArgs() +
-                   " arguments, you supplied " + len + ".");
-    } else { // Adjust references
-          function = fun;
-          name     = fun.getName();
+      if(exprs != null) {
+        for(int i=0; i < exprs.length; i++) {
+          call.append(ASTFunDecl.pop());
+          if(i < exprs.length - 1) {
+        call.append(", ");
+    }
         }
       }
+      call.append(")");
 
-    if(exprs != null) {
-        for(int i=0; i < exprs.length; i++) {
-            exprs[i] = exprs[i].traverse(env);
-        }
+      ASTFunDecl.push(buf, call.toString());
     }
-
-    return this;
   }
 
   /**
@@ -155,95 +199,51 @@ public class ASTFunAppl extends ASTExpr implements MiniParserTreeConstants,
     return type = t;
   }
 
-  /**
-   * Fourth pass, produce Java code.
-   */
-  @Override
-  public void code(final StringBuffer buf) {
-    final String     fname = name.getName();
-//    Function   f     = function;
-//    ASTIdent[] args  = f.getArgs();
-
-    if(fname.equals("READ")) {
-        ASTFunDecl.push(buf, "_readInt()");
-    } else if(fname.equals("WRITE")) {
-      exprs[0].code(buf);
-      ASTFunDecl.push(buf, "_writeInt(" + ASTFunDecl.pop() + ")");
-    }
-    else { // Normal function
-      if(exprs != null) { // Output in reverse odrder
-        for(int i = exprs.length - 1; i >= 0; i--) {
-        exprs[i].code(buf);
-    }
-      }
-
-      final StringBuilder call = new StringBuilder(fname + "(");
-      // Function call
+  public Function getFunction() { return function; }
 
-      if(exprs != null) {
-        for(int i=0; i < exprs.length; i++) {
-          call.append(ASTFunDecl.pop());
-          if(i < exprs.length - 1) {
-        call.append(", ");
-    }
-        }
-      }
-      call.append(")");
+  // dump() inherited
+  public ASTIdent getName()     { return name; }
 
-      ASTFunDecl.push(buf, call.toString());
-    }
+  @Override
+  public String toString() {
+    return jjtNodeName[id] + " " + name.getName();
   }
-
   /**
-   * Fifth pass, produce Java byte code.
+   * Overrides ASTExpr.traverse()
    */
   @Override
-  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
-    final String     fname = name.getName();
-//    Function   f     = function;
-    //ASTIdent   fun   = f.getName();
-//    ASTIdent[] args  = f.getArgs();
-    final String     class_name = method.getClassName();
+  public ASTExpr traverse(final Environment env) {
+    final String   fname = name.getName();
+    final EnvEntry entry = env.get(fname);
 
-    if(fname.equals("READ")) {
-        il.append(new INVOKESTATIC(cp.addMethodref(class_name,
-                                                 "_readInt",
-                                                 "()I")));
-    } else if(fname.equals("WRITE")) {
-      exprs[0].byte_code(il, method, cp);
-      ASTFunDecl.pop();
-      il.append(new INVOKESTATIC(cp.addMethodref(class_name,
-                                                 "_writeInt",
-                                                 "(I)I")));
-    }
-    else { // Normal function
-      final int size    = exprs.length;
-      Type[] argv = null;
+    this.env = env;
 
-      if(exprs != null) {
-        argv = new Type[size];
+    if(entry == null) {
+        MiniC.addError(name.getLine(), name.getColumn(),
+                 "Applying unknown function " + fname + ".");
+    } else if(!(entry instanceof Function)) {
+        MiniC.addError(name.getLine(), name.getColumn(),
+                 "Applying non-function " + fname + ".");
+    } else {
+        final int      len = (exprs != null)? exprs.length : 0;
+        final Function fun = (Function)entry;
 
-        for(int i=0; i < size; i++) {
-          argv[i] = Type.INT;
-          exprs[i].byte_code(il, method, cp);
+        if(len != fun.getNoArgs()) {
+        MiniC.addError(name.getLine(), name.getColumn(),
+                   "Function " + fname + " expects " + fun.getNoArgs() +
+                   " arguments, you supplied " + len + ".");
+    } else { // Adjust references
+          function = fun;
+          name     = fun.getName();
         }
-
-        //ASTFunDecl.push(size);
       }
 
-      ASTFunDecl.pop(size);
-
-      // Function call
-      il.append(new INVOKESTATIC(cp.addMethodref(class_name,
-                                                 fname,
-                                                 Type.getMethodSignature(Type.INT,
-                                                                         argv))));
+    if(exprs != null) {
+        for(int i=0; i < exprs.length; i++) {
+            exprs[i] = exprs[i].traverse(env);
+        }
     }
 
-    ASTFunDecl.push();
+    return this;
   }
-
-  // dump() inherited
-  public ASTIdent getName()     { return name; }
-  public Function getFunction() { return function; }
 }
diff --git a/src/examples/Mini/ASTFunDecl.java b/src/examples/Mini/ASTFunDecl.java
index ea609e30..138d9a21 100644
--- a/src/examples/Mini/ASTFunDecl.java
+++ b/src/examples/Mini/ASTFunDecl.java
@@ -48,162 +48,141 @@ import org.apache.bcel.util.InstructionFinder;
  *
  */
 public class ASTFunDecl extends SimpleNode implements MiniParserTreeConstants, org.apache.bcel.Constants {
-    private ASTIdent name;
-    private ASTIdent[] argv;
-    private ASTExpr body;
-    private int type = T_UNKNOWN;
-    private int line, column;
-    private boolean is_simple; // true, if simple expression like `12 + f(a)'
-    private boolean is_recursive; // Not used yet, TODO
-//  private int         max_depth; // max. expression tree depth
-    private Environment env;
+    private static final InstructionFinder.CodeConstraint my_constraint = match -> {
+        final BranchInstruction if_icmp = (BranchInstruction) match[0].getInstruction();
+        final GOTO goto_ = (GOTO) match[2].getInstruction();
+        return (if_icmp.getTarget() == match[3]) && (goto_.getTarget() == match[4]);
+    };
+    /*
+     * Used to simpulate stack with local vars and compute maximum stack size.
+     */
+    static int size, max_size;
+    private static String getVarDecls() {
+        final StringBuilder buf = new StringBuilder("    int ");
 
-    // Generated methods
-    ASTFunDecl(final int id) {
-        super(id);
-    }
+        for (int i = 0; i < max_size; i++) {
+            buf.append("_s" + i);
 
-    ASTFunDecl(final MiniParser p, final int id) {
-        super(p, id);
-    }
+            if (i < max_size - 1) {
+                buf.append(", ");
+            }
+        }
 
+        buf.append(";\n");
+        return buf.toString();
+    }
     public static Node jjtCreate(final MiniParser p, final int id) {
         return new ASTFunDecl(p, id);
     }
-
-    ASTFunDecl(final ASTIdent name, final ASTIdent[] argv, final ASTExpr body, final int type) {
-        this(JJTFUNDECL);
-
-        this.name = name;
-        this.argv = argv;
-        this.body = body;
-        this.type = type;
-    }
-
     /**
-     * Overrides SimpleNode.closeNode() Cast children to appropiate type.
+     * Replaces instruction sequences (typically generated by ASTIfExpr) of the form
+     *
+     * IF_ICMP__, ICONST_1, GOTO, ICONST_0, IFEQ, Instruction
+     *
+     * where the IF_ICMP__ branches to the ICONST_0 (else part) and the GOTO branches to the IFEQ with the simpler
+     * expression
+     *
+     * IF_ICMP__, Instruction
+     *
+     * where the IF_ICMP__ now branches to the target of the previous IFEQ instruction.
      */
-    @Override
-    public void closeNode() {
-        name = (ASTIdent) children[0];
-        body = (ASTExpr) children[children.length - 1];
+    private static void optimizeIFs(final InstructionList il) {
+        final InstructionFinder f = new InstructionFinder(il);
+        final String pat = "IF_ICMP ICONST_1 GOTO ICONST_0 IFEQ Instruction";
 
-        argv = new ASTIdent[children.length - 2]; // May be 0-size array
-        for (int i = 1; i < children.length - 1; i++) {
-            argv[i - 1] = (ASTIdent) children[i];
-        }
+        for (final Iterator<InstructionHandle[]> it = f.search(pat, my_constraint); it.hasNext();) {
+            final InstructionHandle[] match = it.next();
+            // Everything ok, update code
+            final BranchInstruction ifeq = (BranchInstruction) (match[4].getInstruction());
+            final BranchHandle if_icmp = (BranchHandle) match[0];
 
-        children = null; // Throw away old reference
-    }
+            if_icmp.setTarget(ifeq.getTarget());
 
-    /**
-     * First pass of parse tree.
-     */
-    public ASTFunDecl traverse(final Environment env) {
-        this.env = env;
+            try {
+                il.delete(match[1], match[4]);
+            } catch (final TargetLostException e) {
+                final InstructionHandle[] targets = e.getTargets();
 
-        // Put arguments into hash table aka environment
-        for (final ASTIdent element : argv) {
-            final EnvEntry entry = env.get(element.getName());
+                System.err.println(targets[0]);
 
-            if (entry != null) {
-                MiniC.addError(element.getLine(), element.getColumn(), "Redeclaration of " + entry + ".");
-            } else {
-                env.put(new Variable(element));
+                for (final InstructionHandle target : targets) {
+                    final InstructionTargeter[] targeters = target.getTargeters();
+
+                    for (final InstructionTargeter targeter : targeters) {
+                        if ((target != match[4]) || (targeter != match[2])) {
+                            System.err.println("Unexpected: " + e);
+                        }
+                    }
+                }
             }
         }
-
-        /*
-         * Update entry of this function, i.e. set argument references. The entry is already in there by garantuee, but
-         * may be of wrong type, i.e. the user defined a function `TRUE', e.g. and `TRUE' is of type `Variable'.
-         */
-        try {
-            final Function fun = (Function) env.get(name.getName());
-            fun.setArgs(argv);
-        } catch (final ClassCastException e) {
-        } // Who cares?
-
-        body = body.traverse(env); // Traverse expression body
-
-        return this;
     }
-
+    static String pop() {
+        return "_s" + (--size);
+    }
     /**
-     * Second pass
-     *
-     * @return type of expression
+     * Used by byte_code()
      */
-    public int eval(final int pass) {
-        final int expected = name.getType(); // Maybe other function has already called us
-        type = body.eval(expected); // And updated the env
-
-        if ((expected != T_UNKNOWN) && (type != expected)) {
-            MiniC.addError(line, column, "Function f ist not of type " + TYPE_NAMES[expected]
-                + " as previously assumed, but " + TYPE_NAMES[type]);
-        }
-
-        name.setType(type);
+    static void pop(final int s) {
+        size -= s;
+    }
+static void push() {
+        push(1);
+    }
 
-        is_simple = body.isSimple();
+    static void push(final int s) {
+        size += s;
 
-        if (pass == 2 && type == T_UNKNOWN) {
-            is_recursive = true;
+        if (size > max_size) {
+            max_size = size;
         }
-
-        return type;
     }
 
     /**
-     * Fourth pass, produce Java code.
+     * Used byte code()
      */
-    public void code(final PrintWriter out) {
-        String expr;
-        boolean main = false, ignore = false;
+    static void push(final StringBuffer buf, final String str) {
+        buf.append("    _s" + size + " = " + str + ";\n");
+        push(1);
+    }
 
-        final String fname = name.getName();
+    static void reset() {
+        size = max_size = 0;
+    }
 
-        if (fname.equals("main")) {
-            out.println("  public static void main(String[] _argv) {");
-            main = true;
-        } else if (fname.equals("READ") || fname.equals("WRITE")) { // Do nothing
-            ignore = true;
-        } else {
-            out.print("  public static final " + "int" + // type_names[type] +
-                " " + fname + "(");
+    private ASTIdent name;
 
-            for (int i = 0; i < argv.length; i++) {
-                out.print("int " + argv[i].getName());
+    private ASTIdent[] argv;
 
-                if (i < argv.length - 1) {
-                    out.print(", ");
-                }
-            }
+    private ASTExpr body;
 
-            out.println(")\n    throws IOException\n  {");
-        }
+    private int type = T_UNKNOWN;
 
-        if (!ignore) {
-            final StringBuffer buf = new StringBuffer();
+    private int line, column;
 
-            body.code(buf);
-            out.println(getVarDecls());
+    private boolean is_simple; // true, if simple expression like `12 + f(a)'
 
-            expr = buf.toString();
+    private boolean is_recursive; // Not used yet, TODO
 
-            if (main) {
-                out.println("    try {");
-            }
+    //  private int         max_depth; // max. expression tree depth
+    private Environment env;
 
-            out.println(expr);
+    ASTFunDecl(final ASTIdent name, final ASTIdent[] argv, final ASTExpr body, final int type) {
+        this(JJTFUNDECL);
 
-            if (main) {
-                out.println("    } catch(Exception e) { System.err.println(e); }\n  }\n");
-            } else {
-                out.println("\n    return " + pop() + ";\n  }\n");
-            }
-        }
+        this.name = name;
+        this.argv = argv;
+        this.body = body;
+        this.type = type;
+    }
 
-        reset();
+    // Generated methods
+    ASTFunDecl(final int id) {
+        super(id);
+    }
+
+    ASTFunDecl(final MiniParser p, final int id) {
+        super(p, id);
     }
 
     /**
@@ -289,81 +268,124 @@ public class ASTFunDecl extends SimpleNode implements MiniParserTreeConstants, o
         reset();
     }
 
-    private static final InstructionFinder.CodeConstraint my_constraint = match -> {
-        final BranchInstruction if_icmp = (BranchInstruction) match[0].getInstruction();
-        final GOTO goto_ = (GOTO) match[2].getInstruction();
-        return (if_icmp.getTarget() == match[3]) && (goto_.getTarget() == match[4]);
-    };
-
     /**
-     * Replaces instruction sequences (typically generated by ASTIfExpr) of the form
-     *
-     * IF_ICMP__, ICONST_1, GOTO, ICONST_0, IFEQ, Instruction
-     *
-     * where the IF_ICMP__ branches to the ICONST_0 (else part) and the GOTO branches to the IFEQ with the simpler
-     * expression
-     *
-     * IF_ICMP__, Instruction
-     *
-     * where the IF_ICMP__ now branches to the target of the previous IFEQ instruction.
+     * Overrides SimpleNode.closeNode() Cast children to appropiate type.
      */
-    private static void optimizeIFs(final InstructionList il) {
-        final InstructionFinder f = new InstructionFinder(il);
-        final String pat = "IF_ICMP ICONST_1 GOTO ICONST_0 IFEQ Instruction";
+    @Override
+    public void closeNode() {
+        name = (ASTIdent) children[0];
+        body = (ASTExpr) children[children.length - 1];
 
-        for (final Iterator<InstructionHandle[]> it = f.search(pat, my_constraint); it.hasNext();) {
-            final InstructionHandle[] match = it.next();
-            // Everything ok, update code
-            final BranchInstruction ifeq = (BranchInstruction) (match[4].getInstruction());
-            final BranchHandle if_icmp = (BranchHandle) match[0];
+        argv = new ASTIdent[children.length - 2]; // May be 0-size array
+        for (int i = 1; i < children.length - 1; i++) {
+            argv[i - 1] = (ASTIdent) children[i];
+        }
 
-            if_icmp.setTarget(ifeq.getTarget());
+        children = null; // Throw away old reference
+    }
 
-            try {
-                il.delete(match[1], match[4]);
-            } catch (final TargetLostException e) {
-                final InstructionHandle[] targets = e.getTargets();
+    /**
+     * Fourth pass, produce Java code.
+     */
+    public void code(final PrintWriter out) {
+        String expr;
+        boolean main = false, ignore = false;
 
-                System.err.println(targets[0]);
+        final String fname = name.getName();
 
-                for (final InstructionHandle target : targets) {
-                    final InstructionTargeter[] targeters = target.getTargeters();
+        if (fname.equals("main")) {
+            out.println("  public static void main(String[] _argv) {");
+            main = true;
+        } else if (fname.equals("READ") || fname.equals("WRITE")) { // Do nothing
+            ignore = true;
+        } else {
+            out.print("  public static final " + "int" + // type_names[type] +
+                " " + fname + "(");
 
-                    for (final InstructionTargeter targeter : targeters) {
-                        if ((target != match[4]) || (targeter != match[2])) {
-                            System.err.println("Unexpected: " + e);
-                        }
-                    }
+            for (int i = 0; i < argv.length; i++) {
+                out.print("int " + argv[i].getName());
+
+                if (i < argv.length - 1) {
+                    out.print(", ");
                 }
             }
+
+            out.println(")\n    throws IOException\n  {");
+        }
+
+        if (!ignore) {
+            final StringBuffer buf = new StringBuffer();
+
+            body.code(buf);
+            out.println(getVarDecls());
+
+            expr = buf.toString();
+
+            if (main) {
+                out.println("    try {");
+            }
+
+            out.println(expr);
+
+            if (main) {
+                out.println("    } catch(Exception e) { System.err.println(e); }\n  }\n");
+            } else {
+                out.println("\n    return " + pop() + ";\n  }\n");
+            }
         }
+
+        reset();
     }
 
     /**
-     * Overrides SimpleNode.toString()
+     * Overrides SimpleNode.dump()
      */
     @Override
-    public String toString() {
-        final StringBuilder buf = new StringBuilder();
-        buf.append(jjtNodeName[id] + " " + name + "(");
+    public void dump(final String prefix) {
+        System.out.println(toString(prefix));
 
-        for (int i = 0; i < argv.length; i++) {
-            buf.append(argv[i].getName());
-            if (i < argv.length - 1) {
-                buf.append(", ");
-            }
+        for (final ASTIdent element : argv) {
+            element.dump(prefix + " ");
         }
 
-        buf.append(")");
-        return buf.toString();
+        body.dump(prefix + " ");
     }
 
-    public boolean isrecursive() {
-        return is_recursive;
+    /**
+     * Second pass
+     *
+     * @return type of expression
+     */
+    public int eval(final int pass) {
+        final int expected = name.getType(); // Maybe other function has already called us
+        type = body.eval(expected); // And updated the env
+
+        if ((expected != T_UNKNOWN) && (type != expected)) {
+            MiniC.addError(line, column, "Function f ist not of type " + TYPE_NAMES[expected]
+                + " as previously assumed, but " + TYPE_NAMES[type]);
+        }
+
+        name.setType(type);
+
+        is_simple = body.isSimple();
+
+        if (pass == 2 && type == T_UNKNOWN) {
+            is_recursive = true;
+        }
+
+        return type;
     }
 
-    public boolean isSimple() {
-        return is_simple;
+    public ASTIdent[] getArgs() {
+        return argv;
+    }
+
+    public int getColumn() {
+        return column;
+    }
+
+    public int getLine() {
+        return line;
     }
 
     public ASTIdent getName() {
@@ -374,32 +396,24 @@ public class ASTFunDecl extends SimpleNode implements MiniParserTreeConstants, o
         return argv.length;
     }
 
-    public ASTIdent[] getArgs() {
-        return argv;
-    }
-
     public int getType() {
         return type;
     }
 
-    public void setType(final int type) {
-        this.type = type;
-    }
-
-    public void setLine(final int line) {
-        this.line = line;
+    public boolean isrecursive() {
+        return is_recursive;
     }
 
-    public int getLine() {
-        return line;
+    public boolean isSimple() {
+        return is_simple;
     }
 
     public void setColumn(final int column) {
         this.column = column;
     }
 
-    public int getColumn() {
-        return column;
+    public void setLine(final int line) {
+        this.line = line;
     }
 
     public void setPosition(final int line, final int column) {
@@ -407,72 +421,58 @@ public class ASTFunDecl extends SimpleNode implements MiniParserTreeConstants, o
         this.column = column;
     }
 
-    /**
-     * Overrides SimpleNode.dump()
-     */
-    @Override
-    public void dump(final String prefix) {
-        System.out.println(toString(prefix));
-
-        for (final ASTIdent element : argv) {
-            element.dump(prefix + " ");
-        }
-
-        body.dump(prefix + " ");
+    public void setType(final int type) {
+        this.type = type;
     }
 
-    /*
-     * Used to simpulate stack with local vars and compute maximum stack size.
+    /**
+     * Overrides SimpleNode.toString()
      */
-    static int size, max_size;
-
-    static void reset() {
-        size = max_size = 0;
-    }
-
-    private static String getVarDecls() {
-        final StringBuilder buf = new StringBuilder("    int ");
-
-        for (int i = 0; i < max_size; i++) {
-            buf.append("_s" + i);
+    @Override
+    public String toString() {
+        final StringBuilder buf = new StringBuilder();
+        buf.append(jjtNodeName[id] + " " + name + "(");
 
-            if (i < max_size - 1) {
+        for (int i = 0; i < argv.length; i++) {
+            buf.append(argv[i].getName());
+            if (i < argv.length - 1) {
                 buf.append(", ");
             }
         }
 
-        buf.append(";\n");
+        buf.append(")");
         return buf.toString();
     }
 
     /**
-     * Used by byte_code()
+     * First pass of parse tree.
      */
-    static void pop(final int s) {
-        size -= s;
-    }
+    public ASTFunDecl traverse(final Environment env) {
+        this.env = env;
 
-    static void push(final int s) {
-        size += s;
+        // Put arguments into hash table aka environment
+        for (final ASTIdent element : argv) {
+            final EnvEntry entry = env.get(element.getName());
 
-        if (size > max_size) {
-            max_size = size;
+            if (entry != null) {
+                MiniC.addError(element.getLine(), element.getColumn(), "Redeclaration of " + entry + ".");
+            } else {
+                env.put(new Variable(element));
+            }
         }
-    }
 
-    static void push() {
-        push(1);
-    }
+        /*
+         * Update entry of this function, i.e. set argument references. The entry is already in there by garantuee, but
+         * may be of wrong type, i.e. the user defined a function `TRUE', e.g. and `TRUE' is of type `Variable'.
+         */
+        try {
+            final Function fun = (Function) env.get(name.getName());
+            fun.setArgs(argv);
+        } catch (final ClassCastException e) {
+        } // Who cares?
 
-    /**
-     * Used byte code()
-     */
-    static void push(final StringBuffer buf, final String str) {
-        buf.append("    _s" + size + " = " + str + ";\n");
-        push(1);
-    }
+        body = body.traverse(env); // Traverse expression body
 
-    static String pop() {
-        return "_s" + (--size);
+        return this;
     }
 }
diff --git a/src/examples/Mini/ASTIdent.java b/src/examples/Mini/ASTIdent.java
index fb639d32..67420e44 100644
--- a/src/examples/Mini/ASTIdent.java
+++ b/src/examples/Mini/ASTIdent.java
@@ -30,7 +30,11 @@ import org.apache.bcel.generic.PUSH;
  *
  */
 public class ASTIdent extends ASTExpr implements org.apache.bcel.Constants {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTIdent(p, id);
+  }
   private String   name;
+
   private Variable reference; // Reference in environment to decl of this ident
 
   // Generated methods
@@ -42,10 +46,6 @@ public class ASTIdent extends ASTExpr implements org.apache.bcel.Constants {
     super(p, id);
   }
 
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTIdent(p, id);
-  }
-
   public ASTIdent(final String name, final int type, final int line, final int column) {
     super(line, column, JJTIDENT);
 
@@ -56,30 +56,33 @@ public class ASTIdent extends ASTExpr implements org.apache.bcel.Constants {
   // closeNode, dump inherited
 
   /**
-   * @return identifier and line/column number of appearance
+   * Fifth pass, produce Java byte code.
    */
   @Override
-  public String toString() {
-    return super.toString() + " = " + name;
+  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
+    if(name.equals("TRUE")) {
+        il.append(new PUSH(cp, 1));
+    } else if(name.equals("FALSE")) {
+        il.append(new PUSH(cp, 0));
+    } else {
+      final LocalVariableGen local_var = reference.getLocalVariable();
+      il.append(new ILOAD(local_var.getIndex()));
+    }
+    ASTFunDecl.push();
   }
 
   /**
-   * Overrides ASTExpr.traverse()
+   * Fourth pass, produce Java code.
    */
   @Override
-  public ASTExpr traverse(final Environment env) {
-    final EnvEntry entry = env.get(name);
-
-    if(entry == null) {
-        MiniC.addError(line, column, "Undeclared identifier " + name);
-    } else if(entry instanceof Function) {
-        MiniC.addError(line, column,
-                     "Function " + name + " used as an identifier.");
+  public void code(final StringBuffer buf) {
+    if(name.equals("TRUE")) {
+        ASTFunDecl.push(buf, "1");
+    } else if(name.equals("FALSE")) {
+        ASTFunDecl.push(buf, "0");
     } else {
-        reference = (Variable)entry;
+        ASTFunDecl.push(buf, name);
     }
-
-    return this; // Nothing to reduce/traverse further here
   }
 
   /**
@@ -108,37 +111,34 @@ public class ASTIdent extends ASTExpr implements org.apache.bcel.Constants {
     return type;
   }
 
+  public String getName()            { return name; }
+
+  public void   setName(final String name) { this.name = name; }
+
+
   /**
-   * Fourth pass, produce Java code.
+   * @return identifier and line/column number of appearance
    */
   @Override
-  public void code(final StringBuffer buf) {
-    if(name.equals("TRUE")) {
-        ASTFunDecl.push(buf, "1");
-    } else if(name.equals("FALSE")) {
-        ASTFunDecl.push(buf, "0");
-    } else {
-        ASTFunDecl.push(buf, name);
-    }
+  public String toString() {
+    return super.toString() + " = " + name;
   }
-
   /**
-   * Fifth pass, produce Java byte code.
+   * Overrides ASTExpr.traverse()
    */
   @Override
-  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
-    if(name.equals("TRUE")) {
-        il.append(new PUSH(cp, 1));
-    } else if(name.equals("FALSE")) {
-        il.append(new PUSH(cp, 0));
+  public ASTExpr traverse(final Environment env) {
+    final EnvEntry entry = env.get(name);
+
+    if(entry == null) {
+        MiniC.addError(line, column, "Undeclared identifier " + name);
+    } else if(entry instanceof Function) {
+        MiniC.addError(line, column,
+                     "Function " + name + " used as an identifier.");
     } else {
-      final LocalVariableGen local_var = reference.getLocalVariable();
-      il.append(new ILOAD(local_var.getIndex()));
+        reference = (Variable)entry;
     }
-    ASTFunDecl.push();
-  }
 
-
-  public void   setName(final String name) { this.name = name; }
-  public String getName()            { return name; }
+    return this; // Nothing to reduce/traverse further here
+  }
 }
diff --git a/src/examples/Mini/ASTIfExpr.java b/src/examples/Mini/ASTIfExpr.java
index a04f4edc..eca5f144 100644
--- a/src/examples/Mini/ASTIfExpr.java
+++ b/src/examples/Mini/ASTIfExpr.java
@@ -31,6 +31,10 @@ import org.apache.bcel.generic.MethodGen;
  *
  */
 public class ASTIfExpr extends ASTExpr implements org.apache.bcel.Constants {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTIfExpr(p, id);
+  }
+
   private ASTExpr if_expr, then_expr, else_expr;
 
   // Generated methods
@@ -42,8 +46,27 @@ public class ASTIfExpr extends ASTExpr implements org.apache.bcel.Constants {
     super(p, id);
   }
 
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTIfExpr(p, id);
+  /**
+   * Fifth pass, produce Java byte code.
+   */
+  @Override
+  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
+    if_expr.byte_code(il, method, cp);
+
+    final InstructionList then_code = new InstructionList();
+    final InstructionList else_code = new InstructionList();
+
+    then_expr.byte_code(then_code, method, cp);
+    else_expr.byte_code(else_code, method, cp);
+
+    BranchHandle i, g;
+
+    i = il.append(new IFEQ(null)); // If POP() == FALSE(i.e. 0) then branch to ELSE
+    ASTFunDecl.pop();
+    il.append(then_code);
+    g = il.append(new GOTO(null));
+    i.setTarget(il.append(else_code));
+    g.setTarget(il.append(InstructionConstants.NOP)); // May be optimized away later
   }
 
   /**
@@ -66,20 +89,30 @@ public class ASTIfExpr extends ASTExpr implements org.apache.bcel.Constants {
   }
 
   /**
-   * Overrides ASTExpr.traverse()
+   * Fourth pass, produce Java code.
    */
   @Override
-  public ASTExpr traverse(final Environment env) {
-    this.env = env;
+  public void code(final StringBuffer buf) {
+    if_expr.code(buf);
 
-    if_expr   = if_expr.traverse(env);
-    then_expr = then_expr.traverse(env);
+    buf.append("    if(" + ASTFunDecl.pop() + " == 1) {\n");
+    final int size = ASTFunDecl.size;
+    then_expr.code(buf);
+    ASTFunDecl.size = size; // reset stack
+    buf.append("    } else {\n");
+    else_expr.code(buf);
+    buf.append("    }\n");
+  }
+
+  @Override
+  public void dump(final String prefix) {
+    System.out.println(toString(prefix));
 
+    if_expr.dump(prefix + " ");
+    then_expr.dump(prefix + " ");
     if(else_expr != null) {
-        else_expr = else_expr.traverse(env);
+        else_expr.dump(prefix + " ");
     }
-
-    return this;
   }
 
   /**
@@ -137,52 +170,19 @@ public class ASTIfExpr extends ASTExpr implements org.apache.bcel.Constants {
   }
 
   /**
-   * Fourth pass, produce Java code.
-   */
-  @Override
-  public void code(final StringBuffer buf) {
-    if_expr.code(buf);
-
-    buf.append("    if(" + ASTFunDecl.pop() + " == 1) {\n");
-    final int size = ASTFunDecl.size;
-    then_expr.code(buf);
-    ASTFunDecl.size = size; // reset stack
-    buf.append("    } else {\n");
-    else_expr.code(buf);
-    buf.append("    }\n");
-  }
-
-  /**
-   * Fifth pass, produce Java byte code.
+   * Overrides ASTExpr.traverse()
    */
   @Override
-  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
-    if_expr.byte_code(il, method, cp);
-
-    final InstructionList then_code = new InstructionList();
-    final InstructionList else_code = new InstructionList();
-
-    then_expr.byte_code(then_code, method, cp);
-    else_expr.byte_code(else_code, method, cp);
-
-    BranchHandle i, g;
-
-    i = il.append(new IFEQ(null)); // If POP() == FALSE(i.e. 0) then branch to ELSE
-    ASTFunDecl.pop();
-    il.append(then_code);
-    g = il.append(new GOTO(null));
-    i.setTarget(il.append(else_code));
-    g.setTarget(il.append(InstructionConstants.NOP)); // May be optimized away later
-  }
+  public ASTExpr traverse(final Environment env) {
+    this.env = env;
 
-  @Override
-  public void dump(final String prefix) {
-    System.out.println(toString(prefix));
+    if_expr   = if_expr.traverse(env);
+    then_expr = then_expr.traverse(env);
 
-    if_expr.dump(prefix + " ");
-    then_expr.dump(prefix + " ");
     if(else_expr != null) {
-        else_expr.dump(prefix + " ");
+        else_expr = else_expr.traverse(env);
     }
+
+    return this;
   }
 }
diff --git a/src/examples/Mini/ASTInteger.java b/src/examples/Mini/ASTInteger.java
index 70c20463..6be5f58c 100644
--- a/src/examples/Mini/ASTInteger.java
+++ b/src/examples/Mini/ASTInteger.java
@@ -28,6 +28,10 @@ import org.apache.bcel.generic.PUSH;
  *
  */
 public class ASTInteger extends ASTExpr {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTInteger(p, id);
+  }
+
   private int value;
 
   // Generated methods
@@ -39,27 +43,22 @@ public class ASTInteger extends ASTExpr {
     super(p, id);
   }
 
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTInteger(p, id);
-  }
-
   // closeNode, dump inherited from Expr
 
   /**
-   * @return identifier and line/column number of appearance
+   * Fifth pass, produce Java byte code.
    */
   @Override
-  public String toString() {
-    return super.toString() + " = " + value;
+  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
+    il.append(new PUSH(cp, value)); ASTFunDecl.push();
   }
 
   /**
-   * Overrides ASTExpr.traverse()
+   * Fourth pass, produce Java code.
    */
   @Override
-  public ASTExpr traverse(final Environment env) {
-    this.env = env;
-    return this; // Nothing to reduce/traverse here
+  public void code(final StringBuffer buf) {
+    ASTFunDecl.push(buf, "" + value);
   }
 
   /**
@@ -74,22 +73,23 @@ public class ASTInteger extends ASTExpr {
     return type = T_INT;
   }
 
+  int  getValue()          { return value; }
+
+  void setValue(final int value) { this.value = value; }
+
   /**
-   * Fourth pass, produce Java code.
+   * @return identifier and line/column number of appearance
    */
   @Override
-  public void code(final StringBuffer buf) {
-    ASTFunDecl.push(buf, "" + value);
+  public String toString() {
+    return super.toString() + " = " + value;
   }
-
   /**
-   * Fifth pass, produce Java byte code.
+   * Overrides ASTExpr.traverse()
    */
   @Override
-  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
-    il.append(new PUSH(cp, value)); ASTFunDecl.push();
+  public ASTExpr traverse(final Environment env) {
+    this.env = env;
+    return this; // Nothing to reduce/traverse here
   }
-
-  void setValue(final int value) { this.value = value; }
-  int  getValue()          { return value; }
 }
diff --git a/src/examples/Mini/ASTLetExpr.java b/src/examples/Mini/ASTLetExpr.java
index 387229e2..ae840496 100644
--- a/src/examples/Mini/ASTLetExpr.java
+++ b/src/examples/Mini/ASTLetExpr.java
@@ -32,8 +32,12 @@ import org.apache.bcel.generic.Type;
  *
  */
 public class ASTLetExpr extends ASTExpr implements org.apache.bcel.Constants {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTLetExpr(p, id);
+  }
   private ASTIdent[]  idents;
   private ASTExpr[]   exprs;
+
   private ASTExpr     body;
 
   // Generated methods
@@ -45,10 +49,37 @@ public class ASTLetExpr extends ASTExpr implements org.apache.bcel.Constants {
     super(p, id);
   }
 
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTLetExpr(p, id);
-  }
 
+  /**
+   * Fifth pass, produce Java byte code.
+   */
+  @Override
+  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
+    final int size = idents.length;
+    final LocalVariableGen[] l = new LocalVariableGen[size];
+
+    for(int i=0; i < size; i++) {
+      final String           ident = idents[i].getName();
+      final Variable         entry = (Variable)env.get(ident);
+      final Type             t     = BasicType.getType((byte)idents[i].getType());
+      final LocalVariableGen lg    = method.addLocalVariable(ident, t, null, null);
+      final int              slot  = lg.getIndex();
+
+      entry.setLocalVariable(lg);
+      InstructionHandle start = il.getEnd();
+      exprs[i].byte_code(il, method, cp);
+      start = (start == null)? il.getStart() : start.getNext();
+      lg.setStart(start);
+      il.append(new ISTORE(slot));     ASTFunDecl.pop();
+      l[i] = lg;
+    }
+
+    body.byte_code(il, method, cp);
+    final InstructionHandle end = il.getEnd();
+    for(int i=0; i < size; i++) {
+        l[i].setEnd(end);
+    }
+  }
 
   /**
    * Overrides ASTExpr.closeNode()
@@ -73,33 +104,36 @@ public class ASTLetExpr extends ASTExpr implements org.apache.bcel.Constants {
   }
 
   /**
-   * Overrides ASTExpr.traverse()
+   * Fifth pass, produce Java code.
    */
   @Override
-  public ASTExpr traverse(final Environment env) {
-    this.env = env;
+  public void code(final StringBuffer buf) {
+    for(int i = 0; i < idents.length; i++) {
+      final String ident = idents[i].getName();
+      final int    t     = idents[i].getType(); // can only be int
 
-    // Traverse RHS exprs first, so no references to LHS vars are allowed
-    for(int i=0; i < exprs.length; i++) {
-        exprs[i] = exprs[i].traverse((Environment)env.clone());
+      /* Idents have to be declared at start of function for later use.
+       * Each name is unique, so there shouldn't be a problem in application.
+       */
+      exprs[i].code(buf);
+
+      buf.append("    " + TYPE_NAMES[t] + " " + ident + " = " +
+                 ASTFunDecl.pop() + ";\n");
     }
 
-    // Put argument names into hash table aka. environment
-    for (final ASTIdent id : idents) {
-      final String   name  = id.getName();
-      final EnvEntry entry = env.get(name);
+    body.code(buf);
+  }
 
-      if(entry != null) {
-        MiniC.addError(id.getLine(), id.getColumn(),
-                       "Redeclaration of " + entry + ".");
-    } else {
-        env.put(new Variable(id));
-    }
-    }
+  @Override
+  public void dump(final String prefix) {
+    System.out.println(toString(prefix));
 
-    body = body.traverse(env);
+    for(int i=0; i < idents.length; i++) {
+      idents[i].dump(prefix + " ");
+      exprs[i].dump(prefix + " ");
+    }
 
-    return this;
+    body.dump(prefix + " ");
   }
 
   /**
@@ -123,67 +157,33 @@ public class ASTLetExpr extends ASTExpr implements org.apache.bcel.Constants {
   }
 
   /**
-   * Fifth pass, produce Java code.
+   * Overrides ASTExpr.traverse()
    */
   @Override
-  public void code(final StringBuffer buf) {
-    for(int i = 0; i < idents.length; i++) {
-      final String ident = idents[i].getName();
-      final int    t     = idents[i].getType(); // can only be int
-
-      /* Idents have to be declared at start of function for later use.
-       * Each name is unique, so there shouldn't be a problem in application.
-       */
-      exprs[i].code(buf);
+  public ASTExpr traverse(final Environment env) {
+    this.env = env;
 
-      buf.append("    " + TYPE_NAMES[t] + " " + ident + " = " +
-                 ASTFunDecl.pop() + ";\n");
+    // Traverse RHS exprs first, so no references to LHS vars are allowed
+    for(int i=0; i < exprs.length; i++) {
+        exprs[i] = exprs[i].traverse((Environment)env.clone());
     }
 
-    body.code(buf);
-  }
-
-  /**
-   * Fifth pass, produce Java byte code.
-   */
-  @Override
-  public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
-    final int size = idents.length;
-    final LocalVariableGen[] l = new LocalVariableGen[size];
-
-    for(int i=0; i < size; i++) {
-      final String           ident = idents[i].getName();
-      final Variable         entry = (Variable)env.get(ident);
-      final Type             t     = BasicType.getType((byte)idents[i].getType());
-      final LocalVariableGen lg    = method.addLocalVariable(ident, t, null, null);
-      final int              slot  = lg.getIndex();
+    // Put argument names into hash table aka. environment
+    for (final ASTIdent id : idents) {
+      final String   name  = id.getName();
+      final EnvEntry entry = env.get(name);
 
-      entry.setLocalVariable(lg);
-      InstructionHandle start = il.getEnd();
-      exprs[i].byte_code(il, method, cp);
-      start = (start == null)? il.getStart() : start.getNext();
-      lg.setStart(start);
-      il.append(new ISTORE(slot));     ASTFunDecl.pop();
-      l[i] = lg;
+      if(entry != null) {
+        MiniC.addError(id.getLine(), id.getColumn(),
+                       "Redeclaration of " + entry + ".");
+    } else {
+        env.put(new Variable(id));
     }
-
-    body.byte_code(il, method, cp);
-    final InstructionHandle end = il.getEnd();
-    for(int i=0; i < size; i++) {
-        l[i].setEnd(end);
     }
-  }
-
-  @Override
-  public void dump(final String prefix) {
-    System.out.println(toString(prefix));
 
-    for(int i=0; i < idents.length; i++) {
-      idents[i].dump(prefix + " ");
-      exprs[i].dump(prefix + " ");
-    }
+    body = body.traverse(env);
 
-    body.dump(prefix + " ");
+    return this;
   }
 
 }
diff --git a/src/examples/Mini/ASTProgram.java b/src/examples/Mini/ASTProgram.java
index 5d19b1b5..d89bf41b 100644
--- a/src/examples/Mini/ASTProgram.java
+++ b/src/examples/Mini/ASTProgram.java
@@ -45,7 +45,11 @@ import org.apache.bcel.generic.Type;
  */
 public class ASTProgram extends SimpleNode
 implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constants {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTProgram(p, id);
+  }
   private ASTFunDecl[] fun_decls; // Children: Function declarations
+
   private Environment  env;       // Environment contains variables and functions
 
   ASTProgram(final int id) {
@@ -81,125 +85,6 @@ implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constan
     super(p, id);
   }
 
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTProgram(p, id);
-  }
-
-  /**
-   * Overrides SimpleNode.closeNode().
-   * Cast children to appropiate type.
-   */
-  @Override
-  public void closeNode() {
-    if(children != null) { // Non-empty program ?
-      fun_decls = new ASTFunDecl[children.length];
-      System.arraycopy(children, 0, fun_decls, 0, children.length);
-      children=null; // Throw away old reference
-    }
-  }
-
-  /**
-   * First pass of parse tree.
-   *
-   * Put everything into the environment, which is copied appropiately to each
-   * recursion level, i.e. each FunDecl gets its own copy that it can further
-   * manipulate.
-   *
-   * Checks for name clashes of function declarations.
-   */
-  public ASTProgram traverse() {
-    ASTFunDecl f;
-    ASTIdent   name;
-    String     fname;
-    EnvEntry   fun;
-    Function   main=null;
-
-    if(fun_decls != null) {
-      // Put function names into hash table aka. environment
-      for (final ASTFunDecl fun_decl : fun_decls) {
-        f     = fun_decl;
-        name  = f.getName();
-        fname = name.getName();
-        fun   = env.get(fname); // Lookup in env
-
-        if(fun != null) {
-        MiniC.addError(f.getLine(), f.getColumn(),
-                         "Redeclaration of " + fun + ".");
-    } else {
-        env.put(new Function(name, null)); // `args' will be set by FunDecl.traverse()
-    }
-
-
-      }
-
-      // Go for it
-      for(int i=0; i < fun_decls.length; i++) {
-        fun_decls[i] = fun_decls[i].traverse((Environment)env.clone());
-
-        // Look for `main' routine
-        fname = fun_decls[i].getName().getName();
-        if(fname.equals("main")) {
-        main = (Function)env.get(fname);
-    }
-      }
-
-      if(main == null) {
-        MiniC.addError(0, 0, "You didn't declare a `main' function.");
-    } else if(main.getNoArgs() != 0) {
-        MiniC.addError(main.getLine(), main.getColumn(),
-                        "Main function has too many arguments declared.");
-    }
-    }
-
-    return this;
-  }
-
-  /**
-   * Second pass, determine type of each node, if possible.
-   */
-  public void eval(final int pass) {
-
-    for (final ASTFunDecl fun_decl : fun_decls) {
-      fun_decl.eval(pass);
-
-      if(pass == 3) { // Final check for unresolved types
-        final ASTIdent name = fun_decl.getName();
-
-        if(name.getType() == T_UNKNOWN) {
-        MiniC.addError(name.getColumn(), name.getLine(),
-                         "Type of function " + name.getName() +
-                         " can not be determined (infinite recursion?).");
-    }
-      }
-    }
-  }
-
-  /**
-   * Fifth pass, produce Java code.
-   */
-  public void code(final PrintWriter out, final String name) {
-    out.println("import java.io.BufferedReader;");
-    out.println("import java.io.InputStreamReader;");
-    out.println("import java.io.IOException;\n");
-
-    out.println("public final class " + name + " {");
-    out.println("  private static BufferedReader _in = new BufferedReader" +
-                "(new InputStreamReader(System.in));\n");
-
-    out.println("  private static int _readInt() throws IOException {\n" +
-                "    System.out.print(\"Please enter a number> \");\n" +
-                "    return Integer.parseInt(_in.readLine());\n  }\n");
-
-    out.println("  private static int _writeInt(int n) {\n" +
-                "    System.out.println(\"Result: \" + n);\n    return 0;\n  }\n");
-
-    for (final ASTFunDecl fun_decl : fun_decls) {
-        fun_decl.code(out);
-    }
-
-    out.println("}");
-  }
-
   /**
    * Fifth pass, produce Java byte code.
    */
@@ -326,6 +211,45 @@ implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constan
     }
   }
 
+  /**
+   * Overrides SimpleNode.closeNode().
+   * Cast children to appropiate type.
+   */
+  @Override
+  public void closeNode() {
+    if(children != null) { // Non-empty program ?
+      fun_decls = new ASTFunDecl[children.length];
+      System.arraycopy(children, 0, fun_decls, 0, children.length);
+      children=null; // Throw away old reference
+    }
+  }
+
+  /**
+   * Fifth pass, produce Java code.
+   */
+  public void code(final PrintWriter out, final String name) {
+    out.println("import java.io.BufferedReader;");
+    out.println("import java.io.InputStreamReader;");
+    out.println("import java.io.IOException;\n");
+
+    out.println("public final class " + name + " {");
+    out.println("  private static BufferedReader _in = new BufferedReader" +
+                "(new InputStreamReader(System.in));\n");
+
+    out.println("  private static int _readInt() throws IOException {\n" +
+                "    System.out.print(\"Please enter a number> \");\n" +
+                "    return Integer.parseInt(_in.readLine());\n  }\n");
+
+    out.println("  private static int _writeInt(int n) {\n" +
+                "    System.out.println(\"Result: \" + n);\n    return 0;\n  }\n");
+
+    for (final ASTFunDecl fun_decl : fun_decls) {
+        fun_decl.code(out);
+    }
+
+    out.println("}");
+  }
+
   @Override
   public void dump(final String prefix) {
     System.out.println(toString(prefix));
@@ -334,4 +258,80 @@ implements MiniParserConstants, MiniParserTreeConstants, org.apache.bcel.Constan
         fun_decl.dump(prefix + " ");
     }
   }
+
+  /**
+   * Second pass, determine type of each node, if possible.
+   */
+  public void eval(final int pass) {
+
+    for (final ASTFunDecl fun_decl : fun_decls) {
+      fun_decl.eval(pass);
+
+      if(pass == 3) { // Final check for unresolved types
+        final ASTIdent name = fun_decl.getName();
+
+        if(name.getType() == T_UNKNOWN) {
+        MiniC.addError(name.getColumn(), name.getLine(),
+                         "Type of function " + name.getName() +
+                         " can not be determined (infinite recursion?).");
+    }
+      }
+    }
+  }
+
+  /**
+   * First pass of parse tree.
+   *
+   * Put everything into the environment, which is copied appropiately to each
+   * recursion level, i.e. each FunDecl gets its own copy that it can further
+   * manipulate.
+   *
+   * Checks for name clashes of function declarations.
+   */
+  public ASTProgram traverse() {
+    ASTFunDecl f;
+    ASTIdent   name;
+    String     fname;
+    EnvEntry   fun;
+    Function   main=null;
+
+    if(fun_decls != null) {
+      // Put function names into hash table aka. environment
+      for (final ASTFunDecl fun_decl : fun_decls) {
+        f     = fun_decl;
+        name  = f.getName();
+        fname = name.getName();
+        fun   = env.get(fname); // Lookup in env
+
+        if(fun != null) {
+        MiniC.addError(f.getLine(), f.getColumn(),
+                         "Redeclaration of " + fun + ".");
+    } else {
+        env.put(new Function(name, null)); // `args' will be set by FunDecl.traverse()
+    }
+
+
+      }
+
+      // Go for it
+      for(int i=0; i < fun_decls.length; i++) {
+        fun_decls[i] = fun_decls[i].traverse((Environment)env.clone());
+
+        // Look for `main' routine
+        fname = fun_decls[i].getName().getName();
+        if(fname.equals("main")) {
+        main = (Function)env.get(fname);
+    }
+      }
+
+      if(main == null) {
+        MiniC.addError(0, 0, "You didn't declare a `main' function.");
+    } else if(main.getNoArgs() != 0) {
+        MiniC.addError(main.getLine(), main.getColumn(),
+                        "Main function has too many arguments declared.");
+    }
+    }
+
+    return this;
+  }
 }
diff --git a/src/examples/Mini/ASTTerm.java b/src/examples/Mini/ASTTerm.java
index 60065a33..202fa083 100644
--- a/src/examples/Mini/ASTTerm.java
+++ b/src/examples/Mini/ASTTerm.java
@@ -24,6 +24,10 @@ package Mini;
  *
  */
 public class ASTTerm extends ASTExpr {
+  public static Node jjtCreate(final MiniParser p, final int id) {
+    return new ASTTerm(p, id);
+  }
+
   // Generated methods
   ASTTerm(final int id) {
     super(id);
@@ -33,10 +37,6 @@ public class ASTTerm extends ASTExpr {
     super(p, id);
   }
 
-  public static Node jjtCreate(final MiniParser p, final int id) {
-    return new ASTTerm(p, id);
-  }
-
   // Inherited closeNode(), dump()
 
   /**
diff --git a/src/examples/Mini/EnvEntry.java b/src/examples/Mini/EnvEntry.java
index 16637b7d..e441168f 100644
--- a/src/examples/Mini/EnvEntry.java
+++ b/src/examples/Mini/EnvEntry.java
@@ -22,7 +22,7 @@ package Mini;
  *
  */
 public interface EnvEntry {
+  int    getColumn();
   String getHashKey();
   int    getLine();
-  int    getColumn();
 }
diff --git a/src/examples/Mini/Environment.java b/src/examples/Mini/Environment.java
index 93fbaa8f..c4fb637d 100644
--- a/src/examples/Mini/Environment.java
+++ b/src/examples/Mini/Environment.java
@@ -34,10 +34,30 @@ public class Environment implements Cloneable {
   private static final int SIZE  = 127; // Prime number large enough for most cases
   private static final int SLOTS = 3;   // Number of slots of each field
 
+  private static int lookup(final Vector<EnvEntry> v, final String key)
+       throws ArrayIndexOutOfBoundsException
+  {
+    final int len = v.size();
+
+    for(int i=0; i < len; i++) {
+      final EnvEntry entry = v.elementAt(i);
+
+      if(entry.getHashKey().equals(key)) {
+        return i;
+    }
+    }
+
+    return -1;
+  }
   private final int       size;               // The table is an array of
   private final Vector<EnvEntry>[]  table;              // Vectors
+
   private int       elements=0;
 
+  public Environment() {
+    this(SIZE);
+  }
+
   public Environment(final int size) {
     this.size = size;
     table     = new Vector[size];
@@ -48,130 +68,129 @@ public class Environment implements Cloneable {
     this.table = table;
   }
 
-  public Environment() {
-    this(SIZE);
-  }
-
-  private int hashCode(final String key) {
-    return Math.abs(key.hashCode()) % size;
-  }
-
-  /**
-   * Inserts macro into table or overwrite old contents if it
-   * was already stored.
-   */
-  public void put(final EnvEntry obj) {
-    int    hash;
-    Vector<EnvEntry> v;
-    final String key = obj.getHashKey();
-
-    hash = hashCode(key);
-    v    = table[hash];
+  @Override
+  public Object clone() {
+    final Vector<EnvEntry>[] copy = new Vector[size];
 
-    elements++; // Count
+    for(int i=0; i < size; i++) {
+      if(table[i] != null) {
+        copy[i] = (Vector)table[i].clone(); // Copies references
 
-    if(v == null) {
-        table[hash] = v = new Vector<>(SLOTS);
-    } else {
-      try {
-        final int index = lookup(v, key);
+        /*
+        int len = table[i].size();
 
-        if(index >= 0) {
-          v.setElementAt(obj, index); // Overwrite
-          return;
-        }
-      } catch(final ArrayIndexOutOfBoundsException e) {}
+        copy[i] = new Vector(len);
+        try {
+          for(int j=0; j < len; j++)
+            copy[i].addElement(table[i].elementAt(j));
+        } catch(ArrayIndexOutOfBoundsException e) {}*/
+      }
     }
 
-    // Not found in Vector -> add it
-    v.addElement(obj);
+    return new Environment(copy);
   }
 
-  /** Get entry from hash table.
+  /**
+   * Delete an object if it does exist.
    */
-  public EnvEntry get(final String key) {
+  public void delete(final String key) {
     int       hash;
     Vector<EnvEntry>    v;
-    EnvEntry entry = null;
 
     hash = hashCode(key);
     v    = table[hash];
 
     if(v == null) {
-        return null;
+        return;
     }
 
     try {
       final int index = lookup(v, key);
 
       if(index >= 0) {
-        entry = v.elementAt(index);
-    }
+        elements--; // Count
+        v.removeElementAt(index);
+      }
     } catch(final ArrayIndexOutOfBoundsException e) {}
-
-    return entry;
   }
 
-  /**
-   * Delete an object if it does exist.
+  /** Get entry from hash table.
    */
-  public void delete(final String key) {
+  public EnvEntry get(final String key) {
     int       hash;
     Vector<EnvEntry>    v;
+    EnvEntry entry = null;
 
     hash = hashCode(key);
     v    = table[hash];
 
     if(v == null) {
-        return;
+        return null;
     }
 
     try {
       final int index = lookup(v, key);
 
       if(index >= 0) {
-        elements--; // Count
-        v.removeElementAt(index);
-      }
+        entry = v.elementAt(index);
+    }
     } catch(final ArrayIndexOutOfBoundsException e) {}
-  }
 
-  private static int lookup(final Vector<EnvEntry> v, final String key)
-       throws ArrayIndexOutOfBoundsException
-  {
-    final int len = v.size();
+    return entry;
+  }
 
-    for(int i=0; i < len; i++) {
-      final EnvEntry entry = v.elementAt(i);
+  public EnvEntry[] getEntries() {
+    final EnvEntry[] entries = new EnvEntry[elements];
+    int        k       = 0;
+    Vector<EnvEntry>     v;
 
-      if(entry.getHashKey().equals(key)) {
-        return i;
+    for(int i=0; i < size; i++) {
+      if((v = table[i]) != null) {
+        final int len = v.size();
+        try {
+          for(int j=0; j < len; j++) {
+        entries[k++] = v.elementAt(j);
     }
+        } catch(final ArrayIndexOutOfBoundsException e) {}
+      }
     }
 
-    return -1;
+    return entries;
   }
 
-  @Override
-  public Object clone() {
-    final Vector<EnvEntry>[] copy = new Vector[size];
+  private int hashCode(final String key) {
+    return Math.abs(key.hashCode()) % size;
+  }
 
-    for(int i=0; i < size; i++) {
-      if(table[i] != null) {
-        copy[i] = (Vector)table[i].clone(); // Copies references
+  /**
+   * Inserts macro into table or overwrite old contents if it
+   * was already stored.
+   */
+  public void put(final EnvEntry obj) {
+    int    hash;
+    Vector<EnvEntry> v;
+    final String key = obj.getHashKey();
 
-        /*
-        int len = table[i].size();
+    hash = hashCode(key);
+    v    = table[hash];
 
-        copy[i] = new Vector(len);
-        try {
-          for(int j=0; j < len; j++)
-            copy[i].addElement(table[i].elementAt(j));
-        } catch(ArrayIndexOutOfBoundsException e) {}*/
-      }
+    elements++; // Count
+
+    if(v == null) {
+        table[hash] = v = new Vector<>(SLOTS);
+    } else {
+      try {
+        final int index = lookup(v, key);
+
+        if(index >= 0) {
+          v.setElementAt(obj, index); // Overwrite
+          return;
+        }
+      } catch(final ArrayIndexOutOfBoundsException e) {}
     }
 
-    return new Environment(copy);
+    // Not found in Vector -> add it
+    v.addElement(obj);
   }
 
   @Override
@@ -186,23 +205,4 @@ public class Environment implements Cloneable {
 
     return buf.toString();
   }
-
-  public EnvEntry[] getEntries() {
-    final EnvEntry[] entries = new EnvEntry[elements];
-    int        k       = 0;
-    Vector<EnvEntry>     v;
-
-    for(int i=0; i < size; i++) {
-      if((v = table[i]) != null) {
-        final int len = v.size();
-        try {
-          for(int j=0; j < len; j++) {
-        entries[k++] = v.elementAt(j);
-    }
-        } catch(final ArrayIndexOutOfBoundsException e) {}
-      }
-    }
-
-    return entries;
-  }
 }
diff --git a/src/examples/Mini/Function.java b/src/examples/Mini/Function.java
index 0be5ea4a..07ea3a1b 100644
--- a/src/examples/Mini/Function.java
+++ b/src/examples/Mini/Function.java
@@ -46,6 +46,21 @@ public class Function implements org.apache.bcel.Constants, EnvEntry {
     setArgs(args);
   }
 
+  public ASTIdent   getArg(final int i)     { return args[i]; }
+
+  public ASTIdent[] getArgs()         { return args; }
+  @Override
+  public int        getColumn()       { return column; }
+  @Override
+  public String     getHashKey()      { return fun_name; }
+  @Override
+  public int        getLine()         { return line; }
+  public ASTIdent   getName()         { return name; }
+  public int        getNoArgs()       { return no_args; }
+  public void       setArgs(final ASTIdent[] args) {
+    this.args = args;
+    no_args   = (args == null)? 0 : args.length;
+  }
   @Override
   public String toString() {
     final StringBuilder buf = new StringBuilder();
@@ -65,19 +80,4 @@ public class Function implements org.apache.bcel.Constants, EnvEntry {
     }
     return prefix + " <predefined function>";
   }
-
-  public int        getNoArgs()       { return no_args; }
-  public ASTIdent   getName()         { return name; }
-  @Override
-  public String     getHashKey()      { return fun_name; }
-  @Override
-  public int        getLine()         { return line; }
-  @Override
-  public int        getColumn()       { return column; }
-  public ASTIdent   getArg(final int i)     { return args[i]; }
-  public ASTIdent[] getArgs()         { return args; }
-  public void       setArgs(final ASTIdent[] args) {
-    this.args = args;
-    no_args   = (args == null)? 0 : args.length;
-  }
 }
diff --git a/src/examples/Mini/JJTMiniParserState.java b/src/examples/Mini/JJTMiniParserState.java
index 67c35800..39d24c4a 100644
--- a/src/examples/Mini/JJTMiniParserState.java
+++ b/src/examples/Mini/JJTMiniParserState.java
@@ -34,55 +34,6 @@ class JJTMiniParserState {
     mk = 0;
   }
 
-  /* Determines whether the current node was actually closed and
-     pushed.  This should only be called in the final user action of a
-     node scope.  */
-  boolean nodeCreated() {
-    return node_created;
-  }
-
-  /* Call this to reinitialize the node stack.  It is called
-     automatically by the parser's ReInit() method. */
-  void reset() {
-    nodes.removeAllElements();
-    marks.removeAllElements();
-    sp = 0;
-    mk = 0;
-  }
-
-  /* Returns the root node of the AST.  It only makes sense to call
-     this after a successful parse. */
-  Node rootNode() {
-    return nodes.elementAt(0);
-  }
-
-  /* Pushes a node on to the stack. */
-  void pushNode(final Node n) {
-    nodes.push(n);
-    ++sp;
-  }
-
-  /* Returns the node on the top of the stack, and remove it from the
-     stack.  */
-  Node popNode() {
-    if (--sp < mk) {
-      mk = marks.pop().intValue();
-    }
-    return nodes.pop();
-  }
-
-  /* Returns the node currently on the top of the stack. */
-  Node peekNode() {
-    return nodes.peek();
-  }
-
-  /* Returns the number of children on the stack in the current node
-     scope. */
-  int nodeArity() {
-    return sp - mk;
-  }
-
-
   void clearNodeScope(final Node n) {
     while (sp > mk) {
       popNode();
@@ -90,31 +41,6 @@ class JJTMiniParserState {
     mk = marks.pop().intValue();
   }
 
-
-  void openNodeScope(final Node n) {
-    marks.push(Integer.valueOf(mk));
-    mk = sp;
-    n.jjtOpen();
-  }
-
-
-  /* A definite node is constructed from a specified number of
-     children.  That number of nodes are popped from the stack and
-     made the children of the definite node.  Then the definite node
-     is pushed on to the stack. */
-  void closeNodeScope(final Node n, int num) {
-    mk = marks.pop().intValue();
-    while (num-- > 0) {
-      final Node c = popNode();
-      c.jjtSetParent(n);
-      n.jjtAddChild(c, num);
-    }
-    n.jjtClose();
-    pushNode(n);
-    node_created = true;
-  }
-
-
   /* A conditional node is constructed if its condition is true.  All
      the nodes that have been pushed since the node was opened are
      made children of the the conditional node, which is then pushed
@@ -137,4 +63,78 @@ class JJTMiniParserState {
       node_created = false;
     }
   }
+
+  /* A definite node is constructed from a specified number of
+     children.  That number of nodes are popped from the stack and
+     made the children of the definite node.  Then the definite node
+     is pushed on to the stack. */
+  void closeNodeScope(final Node n, int num) {
+    mk = marks.pop().intValue();
+    while (num-- > 0) {
+      final Node c = popNode();
+      c.jjtSetParent(n);
+      n.jjtAddChild(c, num);
+    }
+    n.jjtClose();
+    pushNode(n);
+    node_created = true;
+  }
+
+  /* Returns the number of children on the stack in the current node
+     scope. */
+  int nodeArity() {
+    return sp - mk;
+  }
+
+  /* Determines whether the current node was actually closed and
+     pushed.  This should only be called in the final user action of a
+     node scope.  */
+  boolean nodeCreated() {
+    return node_created;
+  }
+
+  void openNodeScope(final Node n) {
+    marks.push(Integer.valueOf(mk));
+    mk = sp;
+    n.jjtOpen();
+  }
+
+  /* Returns the node currently on the top of the stack. */
+  Node peekNode() {
+    return nodes.peek();
+  }
+
+
+  /* Returns the node on the top of the stack, and remove it from the
+     stack.  */
+  Node popNode() {
+    if (--sp < mk) {
+      mk = marks.pop().intValue();
+    }
+    return nodes.pop();
+  }
+
+
+  /* Pushes a node on to the stack. */
+  void pushNode(final Node n) {
+    nodes.push(n);
+    ++sp;
+  }
+
+
+  /* Call this to reinitialize the node stack.  It is called
+     automatically by the parser's ReInit() method. */
+  void reset() {
+    nodes.removeAllElements();
+    marks.removeAllElements();
+    sp = 0;
+    mk = 0;
+  }
+
+
+  /* Returns the root node of the AST.  It only makes sense to call
+     this after a successful parse. */
+  Node rootNode() {
+    return nodes.elementAt(0);
+  }
 }
diff --git a/src/examples/Mini/MiniC.java b/src/examples/Mini/MiniC.java
index 5d2e1336..b9a73738 100644
--- a/src/examples/Mini/MiniC.java
+++ b/src/examples/Mini/MiniC.java
@@ -31,6 +31,37 @@ public class MiniC implements org.apache.bcel.Constants {
   private static String file     = null;
   private static int   pass      = 0;
 
+  final static void addError(final int line, final int column, final String err) {
+    if(pass != 2) {
+        errors.addElement(file + ":" + fillup(line, 3) + "," + fillup(column, 2) +
+                          ": " + err);
+    }
+  }
+
+
+  final static void addWarning(final int line, final int column, final String err) {
+    warnings.addElement("Warning: " + file + ":" + fillup(line, 3) + "," +
+                        fillup(column, 3) + ": " + err);
+  }
+
+  final static void addWarning(final String err) { warnings.addElement(err); }
+
+  final static String fillup(final int n, final int len) {
+    final String str  = Integer.toString(n);
+    final int    diff = len - str.length();
+
+    if(diff <= 0) {
+        return str;
+    }
+    final char[] chs = new char[diff];
+
+      for(int i=0; i < diff; i++) {
+        chs[i] = ' ';
+    }
+
+      return new String(chs) + str;
+  }
+
   public static void main(final String[] argv) {
     final String[]   file_name = new String[argv.length];
     int        files=0;
@@ -150,35 +181,4 @@ public class MiniC implements org.apache.bcel.Constants {
       }
     } catch(final Exception e) { e.printStackTrace(); }
   }
-
-
-  final static void addError(final int line, final int column, final String err) {
-    if(pass != 2) {
-        errors.addElement(file + ":" + fillup(line, 3) + "," + fillup(column, 2) +
-                          ": " + err);
-    }
-  }
-
-  final static void addWarning(final int line, final int column, final String err) {
-    warnings.addElement("Warning: " + file + ":" + fillup(line, 3) + "," +
-                        fillup(column, 3) + ": " + err);
-  }
-
-  final static String fillup(final int n, final int len) {
-    final String str  = Integer.toString(n);
-    final int    diff = len - str.length();
-
-    if(diff <= 0) {
-        return str;
-    }
-    final char[] chs = new char[diff];
-
-      for(int i=0; i < diff; i++) {
-        chs[i] = ' ';
-    }
-
-      return new String(chs) + str;
-  }
-
-  final static void addWarning(final String err) { warnings.addElement(err); }
 }
diff --git a/src/examples/Mini/MiniParser.java b/src/examples/Mini/MiniParser.java
index f1921ec6..ba43ec78 100644
--- a/src/examples/Mini/MiniParser.java
+++ b/src/examples/Mini/MiniParser.java
@@ -19,128 +19,145 @@
 package Mini;
 
 public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, MiniParserConstants {/*@bgen(jjtree)*/
-  protected static JJTMiniParserState jjtree = new JJTMiniParserState();private static Token expr_token;
+  private static final class JJCalls {
+    int gen;
+    Token first;
+    int arg;
+    JJCalls next;
+  }protected static JJTMiniParserState jjtree = new JJTMiniParserState();
 
-  final static void jjtreeOpenNodeScope(final Node n) {}
-  final static void jjtreeCloseNodeScope(final Node n) {((SimpleNode)n).closeNode();}
+  private static Token expr_token;
+  static private boolean jj_initialized_once = false;
 
-/* A program consists of a number of function declarations with a
- * distinguished function `main' that starts the program.
- */
-  static public void Program() throws ParseException {
-                  /*@bgen(jjtree) Program */
-  final ASTProgram jjtn000 = new ASTProgram(JJTPROGRAM);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      label_1:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 9:
-          break;
-        default:
-          jj_la1[0] = jj_gen;
-          break label_1;
-        }
-        FunDecl();
-      }
-      jj_consume_token(0);
-    } catch (final Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) {
-                throw (ParseException)jjte000;
-            }}
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) {
-                throw (RuntimeException)jjte000;
-            }}
-          }
-          {if (true) {
-            throw (Error)jjte000;
-        }}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
+static public MiniParserTokenManager token_source;
+
+static ASCII_CharStream jj_input_stream;
+
+  static public Token token, jj_nt;
+
+static private int jj_ntk;
+
+  static private Token jj_scanpos, jj_lastpos;
+
+  static private int jj_la;
+
+  static public boolean lookingAhead = false;
+
+  //  static private boolean jj_semLA;
+  static private int jj_gen;
+
+  static final private int[] jj_la1 = new int[17];
+
+  static final private int[] jj_la1_0 = {0x200,0x0,0x1800000,0x1c000000,0x11c04400,0x1000,0x1800000,0x0,0x11c04400,
+          0xe2000000,0x3f0000,0x1800000,0x1800000,0x1c000000,0xe2000000,0x3f0000,0x10400000,};
+
+  static final private int[] jj_la1_1 = {0x0,0x8,0x130,0x0,0x331,0x0,0x130,0x8,0x331,0x0,0x0,0x331,0x130,0x0,0x0,0x0,0x0,};
+
+  static final private JJCalls[] jj_2_rtns = new JJCalls[1];
+
+  static private boolean jj_rescan = false;
+
+  static private int jj_gc = 0;
+
+  static private java.util.Vector<int[]> jj_expentries = new java.util.Vector<>();
+
+  static private int[] jj_expentry;
+
+  static private int jj_kind = -1;
+
+  static private int[] jj_lasttokens = new int[100];
+
+  static private int jj_endpos;
+
+  static public int AddOp() throws ParseException {
+  Token t=null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case PLUS:
+      t = jj_consume_token(PLUS);
+      break;
+    case MINUS:
+      t = jj_consume_token(MINUS);
+      break;
+    case OR:
+      t = jj_consume_token(OR);
+      break;
+    default:
+      jj_la1[13] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
     }
+    {if (true) {
+        return t.kind;
+    }}
+    throw new Error("Missing return statement in function");
   }
 
-/* "FUN" Ident() "(" NameList() ")" = Expr()
- */
-  static public void FunDecl() throws ParseException {
- /*@bgen(jjtree) FunDecl */
-  final ASTFunDecl jjtn000 = new ASTFunDecl(JJTFUNDECL);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);Token    t;
-    try {
-      t = jj_consume_token(9);
-                     jjtn000.setPosition(t.beginLine, t.beginColumn);
-      Ident();
-      jj_consume_token(LPAREN);
+  static public int CmpOp() throws ParseException {
+  Token t=null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case EQ:
+      t = jj_consume_token(EQ);
+      break;
+    case NEQ:
+      t = jj_consume_token(NEQ);
+      break;
+    case LEQ:
+      t = jj_consume_token(LEQ);
+      break;
+    case GEQ:
+      t = jj_consume_token(GEQ);
+      break;
+    case GT:
+      t = jj_consume_token(GT);
+      break;
+    case LT:
+      t = jj_consume_token(LT);
+      break;
+    default:
+      jj_la1[15] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) {
+        return t.kind;
+    }}
+    throw new Error("Missing return statement in function");
+  }
+
+  static public void disable_tracing() {
+  }
+
+  static public void Element() throws ParseException {
+    if (jj_2_1(2)) {
+      expr_token = FunAppl();
+    } else {
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
       case FALSE:
       case TRUE:
       case READ:
       case WRITE:
       case IDENT:
-        Ident();
-        label_2:
-        while (true) {
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case COMMA:
-            break;
-          default:
-            jj_la1[1] = jj_gen;
-            break label_2;
-          }
-          jj_consume_token(COMMA);
-          Ident();
-        }
+        expr_token = Ident();
+        break;
+      case INTEGER:
+        expr_token = Integer();
+        break;
+      case LPAREN:
+        expr_token = jj_consume_token(LPAREN);
+        Expr();
+        jj_consume_token(RPAREN);
         break;
       default:
-        jj_la1[2] = jj_gen;
+        jj_la1[11] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
       }
-      jj_consume_token(RPAREN);
-      jj_consume_token(ASSIGN);
-      Expr();
-    } catch (final Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) {
-                throw (ParseException)jjte000;
-            }}
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) {
-                throw (RuntimeException)jjte000;
-            }}
-          }
-          {if (true) {
-            throw (Error)jjte000;
-        }}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
     }
   }
 
+  static public void enable_tracing() {
+  }
+
   static public void Expr() throws ParseException {
  /*@bgen(jjtree) Expr */
   final ASTExpr jjtn000 = new ASTExpr(JJTEXPR);
@@ -214,89 +231,32 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
           }
     }
   }
-
-/*
- * The disambiguating algorithm of JavaCC automatically binds dangling
- * else's to the innermost if statement. The LOOKAHEAD specification
- * is to tell JavaCC that we know what we are doing.
- */
-  static public void IfExpr() throws ParseException {
- /*@bgen(jjtree) IfExpr */
-  final ASTIfExpr jjtn000 = new ASTIfExpr(JJTIFEXPR);
+  static public void Factor() throws ParseException {
+ /*@bgen(jjtree) Factor */
+  final ASTFactor jjtn000 = new ASTFactor(JJTFACTOR);
   boolean jjtc000 = true;
   jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);Token t=null;
+  jjtreeOpenNodeScope(jjtn000);int kind=-1;
     try {
-      t = jj_consume_token(10);
-                    jjtn000.setPosition(t.beginLine, t.beginColumn);
-      Expr();
-      jj_consume_token(11);
-      Expr();
+      Element();
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 12:
-        jj_consume_token(12);
-        Expr();
+      case GT:
+      case LT:
+      case GEQ:
+      case LEQ:
+      case EQ:
+      case NEQ:
+        kind = CmpOp();
+                                    jjtn000.setKind(kind);
+        Factor();
         break;
       default:
-        jj_la1[5] = jj_gen;
+        jj_la1[10] = jj_gen;
       }
-      jj_consume_token(13);
-    } catch (final Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) {
-                throw (ParseException)jjte000;
-            }}
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) {
-                throw (RuntimeException)jjte000;
-            }}
-          }
-          {if (true) {
-            throw (Error)jjte000;
-        }}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  static public void LetExpr() throws ParseException {
- /*@bgen(jjtree) LetExpr */
-  final ASTLetExpr jjtn000 = new ASTLetExpr(JJTLETEXPR);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);Token t=null;
-    try {
-      t = jj_consume_token(14);
-                    jjtn000.setPosition(t.beginLine, t.beginColumn);
-      label_3:
-      while (true) {
-        Ident();
-        jj_consume_token(ASSIGN);
-        Expr();
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case FALSE:
-        case TRUE:
-        case READ:
-        case WRITE:
-        case IDENT:
-          break;
-        default:
-          jj_la1[6] = jj_gen;
-          break label_3;
-        }
-      }
-      jj_consume_token(15);
-      Expr();
+          jjtree.closeNodeScope(jjtn000, true);
+          jjtc000 = false;
+          jjtreeCloseNodeScope(jjtn000);
+          jjtn000.setPosition(expr_token.beginLine, expr_token.beginColumn);
     } catch (final Throwable jjte000) {
           if (jjtc000) {
             jjtree.clearNodeScope(jjtn000);
@@ -324,7 +284,6 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
           }
     }
   }
-
   static public Token FunAppl() throws ParseException {
  /*@bgen(jjtree) FunAppl */
   final ASTFunAppl jjtn000 = new ASTFunAppl(JJTFUNAPPL);
@@ -399,31 +358,45 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     }
     throw new Error("Missing return statement in function");
   }
-
-  static public void Term() throws ParseException {
- /*@bgen(jjtree) Term */
-  final ASTTerm jjtn000 = new ASTTerm(JJTTERM);
+  /* "FUN" Ident() "(" NameList() ")" = Expr()
+ */
+  static public void FunDecl() throws ParseException {
+ /*@bgen(jjtree) FunDecl */
+  final ASTFunDecl jjtn000 = new ASTFunDecl(JJTFUNDECL);
   boolean jjtc000 = true;
   jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);int kind=-1;
+  jjtreeOpenNodeScope(jjtn000);Token    t;
     try {
-      Factor();
+      t = jj_consume_token(9);
+                     jjtn000.setPosition(t.beginLine, t.beginColumn);
+      Ident();
+      jj_consume_token(LPAREN);
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case AND:
-      case MULT:
-      case MOD:
-      case DIV:
-        kind = MultOp();
-                                    jjtn000.setKind(kind);
-        Term();
+      case FALSE:
+      case TRUE:
+      case READ:
+      case WRITE:
+      case IDENT:
+        Ident();
+        label_2:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case COMMA:
+            break;
+          default:
+            jj_la1[1] = jj_gen;
+            break label_2;
+          }
+          jj_consume_token(COMMA);
+          Ident();
+        }
         break;
       default:
-        jj_la1[9] = jj_gen;
+        jj_la1[2] = jj_gen;
       }
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtreeCloseNodeScope(jjtn000);
-          jjtn000.setPosition(expr_token.beginLine, expr_token.beginColumn);
+      jj_consume_token(RPAREN);
+      jj_consume_token(ASSIGN);
+      Expr();
     } catch (final Throwable jjte000) {
           if (jjtc000) {
             jjtree.clearNodeScope(jjtn000);
@@ -451,114 +424,65 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
           }
     }
   }
-
-  static public void Factor() throws ParseException {
- /*@bgen(jjtree) Factor */
-  final ASTFactor jjtn000 = new ASTFactor(JJTFACTOR);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);int kind=-1;
-    try {
-      Element();
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case GT:
-      case LT:
-      case GEQ:
-      case LEQ:
-      case EQ:
-      case NEQ:
-        kind = CmpOp();
-                                    jjtn000.setKind(kind);
-        Factor();
-        break;
-      default:
-        jj_la1[10] = jj_gen;
-      }
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtreeCloseNodeScope(jjtn000);
-          jjtn000.setPosition(expr_token.beginLine, expr_token.beginColumn);
-    } catch (final Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) {
-                throw (ParseException)jjte000;
-            }}
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) {
-                throw (RuntimeException)jjte000;
-            }}
+  static public ParseException generateParseException() {
+    jj_expentries.removeAllElements();
+    final boolean[] la1tokens = new boolean[43];
+    for (int i = 0; i < 43; i++) {
+      la1tokens[i] = false;
+    }
+    if (jj_kind >= 0) {
+      la1tokens[jj_kind] = true;
+      jj_kind = -1;
+    }
+    for (int i = 0; i < 17; i++) {
+      if (jj_la1[i] == jj_gen) {
+        for (int j = 0; j < 32; j++) {
+          if ((jj_la1_0[i] & (1<<j)) != 0) {
+            la1tokens[j] = true;
           }
-          {if (true) {
-            throw (Error)jjte000;
-        }}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
+          if ((jj_la1_1[i] & (1<<j)) != 0) {
+            la1tokens[32+j] = true;
           }
+        }
+      }
     }
+    for (int i = 0; i < 43; i++) {
+      if (la1tokens[i]) {
+        jj_expentry = new int[1];
+        jj_expentry[0] = i;
+        jj_expentries.addElement(jj_expentry);
+      }
+    }
+    jj_endpos = 0;
+    jj_rescan_token();
+    jj_add_error_token(0, 0);
+    final int[][] exptokseq = new int[jj_expentries.size()][];
+    for (int i = 0; i < jj_expentries.size(); i++) {
+      exptokseq[i] = jj_expentries.elementAt(i);
+    }
+    return new ParseException(token, exptokseq, tokenImage);
   }
-
-  static public void Element() throws ParseException {
-    if (jj_2_1(2)) {
-      expr_token = FunAppl();
+  static public Token getNextToken() {
+    if (token.next != null) {
+        token = token.next;
     } else {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case FALSE:
-      case TRUE:
-      case READ:
-      case WRITE:
-      case IDENT:
-        expr_token = Ident();
-        break;
-      case INTEGER:
-        expr_token = Integer();
-        break;
-      case LPAREN:
-        expr_token = jj_consume_token(LPAREN);
-        Expr();
-        jj_consume_token(RPAREN);
-        break;
-      default:
-        jj_la1[11] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
+        token = token.next = MiniParserTokenManager.getNextToken();
     }
+    jj_ntk = -1;
+    jj_gen++;
+    return token;
   }
-
-  static public Token Integer() throws ParseException {
- /*@bgen(jjtree) Integer */
-  final ASTInteger jjtn000 = new ASTInteger(JJTINTEGER);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);Token t;
-    try {
-      t = jj_consume_token(INTEGER);
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtreeCloseNodeScope(jjtn000);
-          jjtn000.setValue(Integer.parseInt(t.image));
-          jjtn000.setPosition(t.beginLine, t.beginColumn);
-          {if (true) {
-            return t;
-        }}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
+  static public Token getToken(final int index) {
+    Token t = lookingAhead ? jj_scanpos : token;
+    for (int i = 0; i < index; i++) {
+      if (t.next != null) {
+        t = t.next;
+    } else {
+        t = t.next = MiniParserTokenManager.getNextToken();
     }
-    throw new Error("Missing return statement in function");
+    }
+    return t;
   }
-
   static public Token Ident() throws ParseException {
  /*@bgen(jjtree) Ident */
   final ASTIdent jjtn000 = new ASTIdent(JJTIDENT);
@@ -603,117 +527,100 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     }
     throw new Error("Missing return statement in function");
   }
-
-  static public int AddOp() throws ParseException {
-  Token t=null;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case PLUS:
-      t = jj_consume_token(PLUS);
-      break;
-    case MINUS:
-      t = jj_consume_token(MINUS);
-      break;
-    case OR:
-      t = jj_consume_token(OR);
-      break;
-    default:
-      jj_la1[13] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-    {if (true) {
-        return t.kind;
-    }}
-    throw new Error("Missing return statement in function");
-  }
-
-  static public int MultOp() throws ParseException {
-  Token t=null;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case MULT:
-      t = jj_consume_token(MULT);
-      break;
-    case DIV:
-      t = jj_consume_token(DIV);
-      break;
-    case MOD:
-      t = jj_consume_token(MOD);
-      break;
-    case AND:
-      t = jj_consume_token(AND);
-      break;
-    default:
-      jj_la1[14] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-    {if (true) {
-        return t.kind;
-    }}
-    throw new Error("Missing return statement in function");
-  }
-
-  static public int CmpOp() throws ParseException {
-  Token t=null;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case EQ:
-      t = jj_consume_token(EQ);
-      break;
-    case NEQ:
-      t = jj_consume_token(NEQ);
-      break;
-    case LEQ:
-      t = jj_consume_token(LEQ);
-      break;
-    case GEQ:
-      t = jj_consume_token(GEQ);
-      break;
-    case GT:
-      t = jj_consume_token(GT);
-      break;
-    case LT:
-      t = jj_consume_token(LT);
-      break;
-    default:
-      jj_la1[15] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
+/*
+ * The disambiguating algorithm of JavaCC automatically binds dangling
+ * else's to the innermost if statement. The LOOKAHEAD specification
+ * is to tell JavaCC that we know what we are doing.
+ */
+  static public void IfExpr() throws ParseException {
+ /*@bgen(jjtree) IfExpr */
+  final ASTIfExpr jjtn000 = new ASTIfExpr(JJTIFEXPR);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+  jjtreeOpenNodeScope(jjtn000);Token t=null;
+    try {
+      t = jj_consume_token(10);
+                    jjtn000.setPosition(t.beginLine, t.beginColumn);
+      Expr();
+      jj_consume_token(11);
+      Expr();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 12:
+        jj_consume_token(12);
+        Expr();
+        break;
+      default:
+        jj_la1[5] = jj_gen;
+      }
+      jj_consume_token(13);
+    } catch (final Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) {
+                throw (ParseException)jjte000;
+            }}
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) {
+                throw (RuntimeException)jjte000;
+            }}
+          }
+          {if (true) {
+            throw (Error)jjte000;
+        }}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+            jjtreeCloseNodeScope(jjtn000);
+          }
     }
-    {if (true) {
-        return t.kind;
-    }}
-    throw new Error("Missing return statement in function");
   }
-
-  static final public int UnOp() throws ParseException {
-  Token t=null;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case MINUS:
-      t = jj_consume_token(MINUS);
-      break;
-    case NOT:
-      t = jj_consume_token(NOT);
-      break;
-    default:
-      jj_la1[16] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
+  static public Token Integer() throws ParseException {
+ /*@bgen(jjtree) Integer */
+  final ASTInteger jjtn000 = new ASTInteger(JJTINTEGER);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+  jjtreeOpenNodeScope(jjtn000);Token t;
+    try {
+      t = jj_consume_token(INTEGER);
+          jjtree.closeNodeScope(jjtn000, true);
+          jjtc000 = false;
+          jjtreeCloseNodeScope(jjtn000);
+          jjtn000.setValue(Integer.parseInt(t.image));
+          jjtn000.setPosition(t.beginLine, t.beginColumn);
+          {if (true) {
+            return t;
+        }}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+            jjtreeCloseNodeScope(jjtn000);
+          }
     }
-    {if (true) {
-        return t.kind;
-    }}
     throw new Error("Missing return statement in function");
   }
-
   static private boolean jj_2_1(final int xla) {
     jj_la = xla; jj_lastpos = jj_scanpos = token;
     final boolean retval = !jj_3_1();
     jj_save(0, xla);
     return retval;
   }
-
-  static private boolean jj_3R_8() {
-    if (jj_scan_token(FALSE)) {
+  static private boolean jj_3_1() {
+    if (jj_3R_5()) {
+        return true;
+    }
+    if (jj_la == 0 && jj_scanpos == jj_lastpos) {
+        return false;
+    }
+    return false;
+  }
+  static private boolean jj_3R_10() {
+    if (jj_scan_token(WRITE)) {
         return true;
     }
     if (jj_la == 0 && jj_scanpos == jj_lastpos) {
@@ -721,7 +628,6 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     }
     return false;
   }
-
   static private boolean jj_3R_11() {
     if (jj_scan_token(IDENT)) {
         return true;
@@ -731,9 +637,14 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     }
     return false;
   }
-
-  static private boolean jj_3R_7() {
-    if (jj_scan_token(TRUE)) {
+  static private boolean jj_3R_5() {
+    if (jj_3R_6()) {
+        return true;
+    }
+    if (jj_la == 0 && jj_scanpos == jj_lastpos) {
+        return false;
+    }
+    if (jj_scan_token(LPAREN)) {
         return true;
     }
     if (jj_la == 0 && jj_scanpos == jj_lastpos) {
@@ -774,8 +685,8 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     return false;
   }
 
-  static private boolean jj_3_1() {
-    if (jj_3R_5()) {
+  static private boolean jj_3R_7() {
+    if (jj_scan_token(TRUE)) {
         return true;
     }
     if (jj_la == 0 && jj_scanpos == jj_lastpos) {
@@ -784,14 +695,8 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     return false;
   }
 
-  static private boolean jj_3R_5() {
-    if (jj_3R_6()) {
-        return true;
-    }
-    if (jj_la == 0 && jj_scanpos == jj_lastpos) {
-        return false;
-    }
-    if (jj_scan_token(LPAREN)) {
+  static private boolean jj_3R_8() {
+    if (jj_scan_token(FALSE)) {
         return true;
     }
     if (jj_la == 0 && jj_scanpos == jj_lastpos) {
@@ -800,8 +705,8 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     return false;
   }
 
-  static private boolean jj_3R_10() {
-    if (jj_scan_token(WRITE)) {
+  static private boolean jj_3R_9() {
+    if (jj_scan_token(READ)) {
         return true;
     }
     if (jj_la == 0 && jj_scanpos == jj_lastpos) {
@@ -810,33 +715,358 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     return false;
   }
 
-  static private boolean jj_3R_9() {
-    if (jj_scan_token(READ)) {
-        return true;
+  static private void jj_add_error_token(final int kind, final int pos) {
+    if (pos >= 100) {
+        return;
+    }
+    if (pos == jj_endpos + 1) {
+      jj_lasttokens[jj_endpos++] = kind;
+    } else if (jj_endpos != 0) {
+      jj_expentry = new int[jj_endpos];
+      for (int i = 0; i < jj_endpos; i++) {
+        jj_expentry[i] = jj_lasttokens[i];
+      }
+      boolean exists = false;
+      for (final int[] j : jj_expentries) {
+        final int[] oldentry = (j);
+        if (oldentry.length == jj_expentry.length) {
+          exists = true;
+          for (int i = 0; i < jj_expentry.length; i++) {
+            if (oldentry[i] != jj_expentry[i]) {
+              exists = false;
+              break;
+            }
+          }
+          if (exists) {
+            break;
+        }
+        }
+      }
+      if (!exists) {
+        jj_expentries.addElement(jj_expentry);
+    }
+      if (pos != 0) {
+        jj_lasttokens[(jj_endpos = pos) - 1] = kind;
     }
-    if (jj_la == 0 && jj_scanpos == jj_lastpos) {
-        return false;
     }
-    return false;
   }
 
-  static private boolean jj_initialized_once = false;
-  static public MiniParserTokenManager token_source;
-  static ASCII_CharStream jj_input_stream;
-  static public Token token, jj_nt;
-  static private int jj_ntk;
-  static private Token jj_scanpos, jj_lastpos;
-  static private int jj_la;
-  static public boolean lookingAhead = false;
-//  static private boolean jj_semLA;
-  static private int jj_gen;
-  static final private int[] jj_la1 = new int[17];
-  static final private int[] jj_la1_0 = {0x200,0x0,0x1800000,0x1c000000,0x11c04400,0x1000,0x1800000,0x0,0x11c04400,
-          0xe2000000,0x3f0000,0x1800000,0x1800000,0x1c000000,0xe2000000,0x3f0000,0x10400000,};
-  static final private int[] jj_la1_1 = {0x0,0x8,0x130,0x0,0x331,0x0,0x130,0x8,0x331,0x0,0x0,0x331,0x130,0x0,0x0,0x0,0x0,};
-  static final private JJCalls[] jj_2_rtns = new JJCalls[1];
-  static private boolean jj_rescan = false;
-  static private int jj_gc = 0;
+  static private Token jj_consume_token(final int kind) throws ParseException {
+    Token oldToken;
+    if ((oldToken = token).next != null) {
+        token = token.next;
+    } else {
+        token = token.next = MiniParserTokenManager.getNextToken();
+    }
+    jj_ntk = -1;
+    if (token.kind == kind) {
+      jj_gen++;
+      if (++jj_gc > 100) {
+        jj_gc = 0;
+        for (final JJCalls jj_2_rtn : jj_2_rtns) {
+          JJCalls c = jj_2_rtn;
+          while (c != null) {
+            if (c.gen < jj_gen) {
+                c.first = null;
+            }
+            c = c.next;
+          }
+        }
+      }
+      return token;
+    }
+    token = oldToken;
+    jj_kind = kind;
+    throw generateParseException();
+  }
+
+  static private int jj_ntk() {
+    if ((jj_nt=token.next) == null) {
+        return (jj_ntk = (token.next=MiniParserTokenManager.getNextToken()).kind);
+    }
+    return (jj_ntk = jj_nt.kind);
+  }
+
+  static private void jj_rescan_token() {
+    jj_rescan = true;
+    for (int i = 0; i < 1; i++) {
+      JJCalls p = jj_2_rtns[i];
+      do {
+        if (p.gen > jj_gen) {
+          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
+          switch (i) {
+            case 0: jj_3_1(); break;
+          }
+        }
+        p = p.next;
+      } while (p != null);
+    }
+    jj_rescan = false;
+  }
+
+  static private void jj_save(final int index, final int xla) {
+    JJCalls p = jj_2_rtns[index];
+    while (p.gen > jj_gen) {
+      if (p.next == null) { p = p.next = new JJCalls(); break; }
+      p = p.next;
+    }
+    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
+  }
+
+  static private boolean jj_scan_token(final int kind) {
+    if (jj_scanpos == jj_lastpos) {
+      jj_la--;
+      if (jj_scanpos.next == null) {
+        jj_lastpos = jj_scanpos = jj_scanpos.next = MiniParserTokenManager.getNextToken();
+      } else {
+        jj_lastpos = jj_scanpos = jj_scanpos.next;
+      }
+    } else {
+      jj_scanpos = jj_scanpos.next;
+    }
+    if (jj_rescan) {
+      int i = 0; Token tok = token;
+      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
+      if (tok != null) {
+        jj_add_error_token(kind, i);
+    }
+    }
+    return (jj_scanpos.kind != kind);
+  }
+
+  final static void jjtreeCloseNodeScope(final Node n) {((SimpleNode)n).closeNode();}
+
+  final static void jjtreeOpenNodeScope(final Node n) {}
+  static public void LetExpr() throws ParseException {
+ /*@bgen(jjtree) LetExpr */
+  final ASTLetExpr jjtn000 = new ASTLetExpr(JJTLETEXPR);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+  jjtreeOpenNodeScope(jjtn000);Token t=null;
+    try {
+      t = jj_consume_token(14);
+                    jjtn000.setPosition(t.beginLine, t.beginColumn);
+      label_3:
+      while (true) {
+        Ident();
+        jj_consume_token(ASSIGN);
+        Expr();
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case FALSE:
+        case TRUE:
+        case READ:
+        case WRITE:
+        case IDENT:
+          break;
+        default:
+          jj_la1[6] = jj_gen;
+          break label_3;
+        }
+      }
+      jj_consume_token(15);
+      Expr();
+    } catch (final Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) {
+                throw (ParseException)jjte000;
+            }}
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) {
+                throw (RuntimeException)jjte000;
+            }}
+          }
+          {if (true) {
+            throw (Error)jjte000;
+        }}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+            jjtreeCloseNodeScope(jjtn000);
+          }
+    }
+  }
+  static public int MultOp() throws ParseException {
+  Token t=null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case MULT:
+      t = jj_consume_token(MULT);
+      break;
+    case DIV:
+      t = jj_consume_token(DIV);
+      break;
+    case MOD:
+      t = jj_consume_token(MOD);
+      break;
+    case AND:
+      t = jj_consume_token(AND);
+      break;
+    default:
+      jj_la1[14] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) {
+        return t.kind;
+    }}
+    throw new Error("Missing return statement in function");
+  }
+  /* A program consists of a number of function declarations with a
+ * distinguished function `main' that starts the program.
+ */
+  static public void Program() throws ParseException {
+                  /*@bgen(jjtree) Program */
+  final ASTProgram jjtn000 = new ASTProgram(JJTPROGRAM);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+  jjtreeOpenNodeScope(jjtn000);
+    try {
+      label_1:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 9:
+          break;
+        default:
+          jj_la1[0] = jj_gen;
+          break label_1;
+        }
+        FunDecl();
+      }
+      jj_consume_token(0);
+    } catch (final Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) {
+                throw (ParseException)jjte000;
+            }}
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) {
+                throw (RuntimeException)jjte000;
+            }}
+          }
+          {if (true) {
+            throw (Error)jjte000;
+        }}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+            jjtreeCloseNodeScope(jjtn000);
+          }
+    }
+  }
+  static public void ReInit(final java.io.InputStream stream) {
+    ASCII_CharStream.ReInit(stream, 1, 1);
+    MiniParserTokenManager.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jjtree.reset();
+    jj_gen = 0;
+    for (int i = 0; i < 17; i++) {
+        jj_la1[i] = -1;
+    }
+    for (int i = 0; i < jj_2_rtns.length; i++) {
+        jj_2_rtns[i] = new JJCalls();
+    }
+  }
+
+  static public void ReInit(final java.io.Reader stream) {
+    ASCII_CharStream.ReInit(stream, 1, 1);
+    MiniParserTokenManager.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jjtree.reset();
+    jj_gen = 0;
+    for (int i = 0; i < 17; i++) {
+        jj_la1[i] = -1;
+    }
+    for (int i = 0; i < jj_2_rtns.length; i++) {
+        jj_2_rtns[i] = new JJCalls();
+    }
+  }
+
+  static public void Term() throws ParseException {
+ /*@bgen(jjtree) Term */
+  final ASTTerm jjtn000 = new ASTTerm(JJTTERM);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+  jjtreeOpenNodeScope(jjtn000);int kind=-1;
+    try {
+      Factor();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AND:
+      case MULT:
+      case MOD:
+      case DIV:
+        kind = MultOp();
+                                    jjtn000.setKind(kind);
+        Term();
+        break;
+      default:
+        jj_la1[9] = jj_gen;
+      }
+          jjtree.closeNodeScope(jjtn000, true);
+          jjtc000 = false;
+          jjtreeCloseNodeScope(jjtn000);
+          jjtn000.setPosition(expr_token.beginLine, expr_token.beginColumn);
+    } catch (final Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) {
+                throw (ParseException)jjte000;
+            }}
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) {
+                throw (RuntimeException)jjte000;
+            }}
+          }
+          {if (true) {
+            throw (Error)jjte000;
+        }}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+            jjtreeCloseNodeScope(jjtn000);
+          }
+    }
+  }
+
+  static final public int UnOp() throws ParseException {
+  Token t=null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case MINUS:
+      t = jj_consume_token(MINUS);
+      break;
+    case NOT:
+      t = jj_consume_token(NOT);
+      break;
+    default:
+      jj_la1[16] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) {
+        return t.kind;
+    }}
+    throw new Error("Missing return statement in function");
+  }
 
   public MiniParser(final java.io.InputStream stream) {
     if (jj_initialized_once) {
@@ -859,21 +1089,6 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     }
   }
 
-  static public void ReInit(final java.io.InputStream stream) {
-    ASCII_CharStream.ReInit(stream, 1, 1);
-    MiniParserTokenManager.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jjtree.reset();
-    jj_gen = 0;
-    for (int i = 0; i < 17; i++) {
-        jj_la1[i] = -1;
-    }
-    for (int i = 0; i < jj_2_rtns.length; i++) {
-        jj_2_rtns[i] = new JJCalls();
-    }
-  }
-
   public MiniParser(final java.io.Reader stream) {
     if (jj_initialized_once) {
       System.out.println("ERROR: Second call to constructor of static parser.  You must");
@@ -895,21 +1110,6 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     }
   }
 
-  static public void ReInit(final java.io.Reader stream) {
-    ASCII_CharStream.ReInit(stream, 1, 1);
-    MiniParserTokenManager.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jjtree.reset();
-    jj_gen = 0;
-    for (int i = 0; i < 17; i++) {
-        jj_la1[i] = -1;
-    }
-    for (int i = 0; i < jj_2_rtns.length; i++) {
-        jj_2_rtns[i] = new JJCalls();
-    }
-  }
-
   public MiniParser(final MiniParserTokenManager tm) {
     if (jj_initialized_once) {
       System.out.println("ERROR: Second call to constructor of static parser.  You must");
@@ -944,204 +1144,4 @@ public class MiniParser/*@bgen(jjtree)*/implements MiniParserTreeConstants, Mini
     }
   }
 
-  static private Token jj_consume_token(final int kind) throws ParseException {
-    Token oldToken;
-    if ((oldToken = token).next != null) {
-        token = token.next;
-    } else {
-        token = token.next = MiniParserTokenManager.getNextToken();
-    }
-    jj_ntk = -1;
-    if (token.kind == kind) {
-      jj_gen++;
-      if (++jj_gc > 100) {
-        jj_gc = 0;
-        for (final JJCalls jj_2_rtn : jj_2_rtns) {
-          JJCalls c = jj_2_rtn;
-          while (c != null) {
-            if (c.gen < jj_gen) {
-                c.first = null;
-            }
-            c = c.next;
-          }
-        }
-      }
-      return token;
-    }
-    token = oldToken;
-    jj_kind = kind;
-    throw generateParseException();
-  }
-
-  static private boolean jj_scan_token(final int kind) {
-    if (jj_scanpos == jj_lastpos) {
-      jj_la--;
-      if (jj_scanpos.next == null) {
-        jj_lastpos = jj_scanpos = jj_scanpos.next = MiniParserTokenManager.getNextToken();
-      } else {
-        jj_lastpos = jj_scanpos = jj_scanpos.next;
-      }
-    } else {
-      jj_scanpos = jj_scanpos.next;
-    }
-    if (jj_rescan) {
-      int i = 0; Token tok = token;
-      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
-      if (tok != null) {
-        jj_add_error_token(kind, i);
-    }
-    }
-    return (jj_scanpos.kind != kind);
-  }
-
-  static public Token getNextToken() {
-    if (token.next != null) {
-        token = token.next;
-    } else {
-        token = token.next = MiniParserTokenManager.getNextToken();
-    }
-    jj_ntk = -1;
-    jj_gen++;
-    return token;
-  }
-
-  static public Token getToken(final int index) {
-    Token t = lookingAhead ? jj_scanpos : token;
-    for (int i = 0; i < index; i++) {
-      if (t.next != null) {
-        t = t.next;
-    } else {
-        t = t.next = MiniParserTokenManager.getNextToken();
-    }
-    }
-    return t;
-  }
-
-  static private int jj_ntk() {
-    if ((jj_nt=token.next) == null) {
-        return (jj_ntk = (token.next=MiniParserTokenManager.getNextToken()).kind);
-    }
-    return (jj_ntk = jj_nt.kind);
-  }
-
-  static private java.util.Vector<int[]> jj_expentries = new java.util.Vector<>();
-  static private int[] jj_expentry;
-  static private int jj_kind = -1;
-  static private int[] jj_lasttokens = new int[100];
-  static private int jj_endpos;
-
-  static private void jj_add_error_token(final int kind, final int pos) {
-    if (pos >= 100) {
-        return;
-    }
-    if (pos == jj_endpos + 1) {
-      jj_lasttokens[jj_endpos++] = kind;
-    } else if (jj_endpos != 0) {
-      jj_expentry = new int[jj_endpos];
-      for (int i = 0; i < jj_endpos; i++) {
-        jj_expentry[i] = jj_lasttokens[i];
-      }
-      boolean exists = false;
-      for (final int[] j : jj_expentries) {
-        final int[] oldentry = (j);
-        if (oldentry.length == jj_expentry.length) {
-          exists = true;
-          for (int i = 0; i < jj_expentry.length; i++) {
-            if (oldentry[i] != jj_expentry[i]) {
-              exists = false;
-              break;
-            }
-          }
-          if (exists) {
-            break;
-        }
-        }
-      }
-      if (!exists) {
-        jj_expentries.addElement(jj_expentry);
-    }
-      if (pos != 0) {
-        jj_lasttokens[(jj_endpos = pos) - 1] = kind;
-    }
-    }
-  }
-
-  static public ParseException generateParseException() {
-    jj_expentries.removeAllElements();
-    final boolean[] la1tokens = new boolean[43];
-    for (int i = 0; i < 43; i++) {
-      la1tokens[i] = false;
-    }
-    if (jj_kind >= 0) {
-      la1tokens[jj_kind] = true;
-      jj_kind = -1;
-    }
-    for (int i = 0; i < 17; i++) {
-      if (jj_la1[i] == jj_gen) {
-        for (int j = 0; j < 32; j++) {
-          if ((jj_la1_0[i] & (1<<j)) != 0) {
-            la1tokens[j] = true;
-          }
-          if ((jj_la1_1[i] & (1<<j)) != 0) {
-            la1tokens[32+j] = true;
-          }
-        }
-      }
-    }
-    for (int i = 0; i < 43; i++) {
-      if (la1tokens[i]) {
-        jj_expentry = new int[1];
-        jj_expentry[0] = i;
-        jj_expentries.addElement(jj_expentry);
-      }
-    }
-    jj_endpos = 0;
-    jj_rescan_token();
-    jj_add_error_token(0, 0);
-    final int[][] exptokseq = new int[jj_expentries.size()][];
-    for (int i = 0; i < jj_expentries.size(); i++) {
-      exptokseq[i] = jj_expentries.elementAt(i);
-    }
-    return new ParseException(token, exptokseq, tokenImage);
-  }
-
-  static public void enable_tracing() {
-  }
-
-  static public void disable_tracing() {
-  }
-
-  static private void jj_rescan_token() {
-    jj_rescan = true;
-    for (int i = 0; i < 1; i++) {
-      JJCalls p = jj_2_rtns[i];
-      do {
-        if (p.gen > jj_gen) {
-          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
-          switch (i) {
-            case 0: jj_3_1(); break;
-          }
-        }
-        p = p.next;
-      } while (p != null);
-    }
-    jj_rescan = false;
-  }
-
-  static private void jj_save(final int index, final int xla) {
-    JJCalls p = jj_2_rtns[index];
-    while (p.gen > jj_gen) {
-      if (p.next == null) { p = p.next = new JJCalls(); break; }
-      p = p.next;
-    }
-    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
-  }
-
-  private static final class JJCalls {
-    int gen;
-    Token first;
-    int arg;
-    JJCalls next;
-  }
-
 }
diff --git a/src/examples/Mini/MiniParserTokenManager.java b/src/examples/Mini/MiniParserTokenManager.java
index f5ef6b6c..22f3fc01 100644
--- a/src/examples/Mini/MiniParserTokenManager.java
+++ b/src/examples/Mini/MiniParserTokenManager.java
@@ -20,17 +20,169 @@ package Mini;
 
 public class MiniParserTokenManager implements MiniParserConstants
 {
-static private int jjMoveStringLiteralDfa0_1()
-{
-   return jjMoveNfa_1(0, 0);
-}
-static private void jjCheckNAdd(final int state)
+static final long[] jjbitVec0 = {
+   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final int[] jjnextStates = {
+   4, 5,
+};
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, null, "\106\125\116",
+"\111\106", "\124\110\105\116", "\105\114\123\105", "\106\111", "\114\105\124",
+"\111\116", "\76", "\74", "\76\75", "\74\75", "\75\75", "\41\75", "\41",
+"\106\101\114\123\105", "\124\122\125\105", "\101\116\104", "\117\122", "\53", "\55", "\52", "\45",
+"\57", "\50", "\51", "\75", "\54", "\122\105\101\104", "\127\122\111\124\105", null,
+null, null, null, null, };
+public static final String[] lexStateNames = {
+   "DEFAULT",
+   "SINGLE_LINE_COMMENT_STATE",
+};
+public static final int[] jjnewLexState = {
+   -1, -1, -1, -1, -1, -1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+static final long[] jjtoToken = {
+   0x73ffffffe01L,
+};
+static final long[] jjtoSkip = {
+   0xbeL,
+};
+static final long[] jjtoSpecial = {
+   0x80L,
+};
+static final long[] jjtoMore = {
+   0x140L,
+};
+static private ASCII_CharStream input_stream;
+static private final int[] jjrounds = new int[6];
+static private final int[] jjstateSet = new int[12];
+static StringBuffer image;
+static int jjimageLen;
+static int lengthOfMatch;
+static protected char curChar;
+static int curLexState = 0;
+static int defaultLexState = 0;
+static int jjnewStateCnt;
+static int jjround;
+static int jjmatchedPos;
+static int jjmatchedKind;
+public static Token getNextToken()
 {
-   if (jjrounds[state] != jjround)
+  Token specialToken = null;
+  Token matchedToken;
+  int curPos = 0;
+
+  EOFLoop :
+  for (;;)
+  {
+   try
    {
-      jjstateSet[jjnewStateCnt++] = state;
-      jjrounds[state] = jjround;
+      curChar = ASCII_CharStream.BeginToken();
+   }
+   catch(final java.io.IOException e)
+   {
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      matchedToken.specialToken = specialToken;
+      return matchedToken;
+   }
+   image = null;
+   jjimageLen = 0;
+
+   for (;;)
+   {
+     switch(curLexState)
+     {
+       case 0:
+         try { ASCII_CharStream.backup(0);
+            while (curChar <= 32 && (0x100003600L & (1L << curChar)) != 0L) {
+                curChar = ASCII_CharStream.BeginToken();
+            }
+         }
+         catch (final java.io.IOException e1) { continue EOFLoop; }
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_0();
+         break;
+       case 1:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_1();
+         if (jjmatchedPos == 0 && jjmatchedKind > 8)
+         {
+            jjmatchedKind = 8;
+         }
+         break;
+     }
+     if (jjmatchedKind != 0x7fffffff)
+     {
+        if (jjmatchedPos + 1 < curPos) {
+            ASCII_CharStream.backup(curPos - jjmatchedPos - 1);
+        }
+        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           matchedToken = jjFillToken();
+           matchedToken.specialToken = specialToken;
+       if (jjnewLexState[jjmatchedKind] != -1) {
+        curLexState = jjnewLexState[jjmatchedKind];
+    }
+           return matchedToken;
+        }
+        if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+           {
+              matchedToken = jjFillToken();
+              if (specialToken == null) {
+                specialToken = matchedToken;
+            } else
+              {
+                 matchedToken.specialToken = specialToken;
+                 specialToken = (specialToken.next = matchedToken);
+              }
+              SkipLexicalActions(matchedToken);
+           } else {
+            SkipLexicalActions(null);
+        }
+         if (jjnewLexState[jjmatchedKind] != -1) {
+            curLexState = jjnewLexState[jjmatchedKind];
+        }
+           continue EOFLoop;
+        }
+        jjimageLen += jjmatchedPos + 1;
+      if (jjnewLexState[jjmatchedKind] != -1) {
+        curLexState = jjnewLexState[jjmatchedKind];
+    }
+        curPos = 0;
+        jjmatchedKind = 0x7fffffff;
+        try {
+           curChar = ASCII_CharStream.readChar();
+           continue;
+        }
+        catch (final java.io.IOException e1) { }
+     }
+     int error_line = ASCII_CharStream.getEndLine();
+     int error_column = ASCII_CharStream.getEndColumn();
+     String error_after = null;
+     boolean EOFSeen = false;
+     try { ASCII_CharStream.readChar(); ASCII_CharStream.backup(1); }
+     catch (final java.io.IOException e1) {
+        EOFSeen = true;
+        error_after = curPos <= 1 ? "" : ASCII_CharStream.GetImage();
+        if (curChar == '\n' || curChar == '\r') {
+           error_line++;
+           error_column = 0;
+        } else {
+            error_column++;
+        }
+     }
+     if (!EOFSeen) {
+        ASCII_CharStream.backup(1);
+        error_after = curPos <= 1 ? "" : ASCII_CharStream.GetImage();
+     }
+     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
    }
+  }
 }
 static private void jjAddStates(int start, final int end)
 {
@@ -38,26 +190,35 @@ static private void jjAddStates(int start, final int end)
       jjstateSet[jjnewStateCnt++] = jjnextStates[start];
    } while (start++ != end);
 }
+static private void jjCheckNAdd(final int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
 static private void jjCheckNAddTwoStates(final int state1, final int state2)
 {
    jjCheckNAdd(state1);
    jjCheckNAdd(state2);
 }
-//static private void jjCheckNAddStates(int start, int end)
-//{
-//   do {
-//      jjCheckNAdd(jjnextStates[start]);
-//   } while (start++ != end);
-//}
-//static private void jjCheckNAddStates(int start)
-//{
-//   jjCheckNAdd(jjnextStates[start]);
-//   jjCheckNAdd(jjnextStates[start + 1]);
-//}
-static private int jjMoveNfa_1(final int startState, int curPos)
+static private Token jjFillToken()
+{
+   final Token t = Token.newToken(jjmatchedKind);
+   t.kind = jjmatchedKind;
+   final String im = jjstrLiteralImages[jjmatchedKind];
+   t.image = (im == null) ? ASCII_CharStream.GetImage() : im;
+   t.beginLine = ASCII_CharStream.getBeginLine();
+   t.beginColumn = ASCII_CharStream.getBeginColumn();
+   t.endLine = ASCII_CharStream.getEndLine();
+   t.endColumn = ASCII_CharStream.getEndColumn();
+   return t;
+}
+static private int jjMoveNfa_0(final int startState, int curPos)
 {
    int startsAt = 0;
-   jjnewStateCnt = 3;
+   jjnewStateCnt = 6;
    int i = 1;
    jjstateSet[0] = startState;
    int kind = 0x7fffffff;
@@ -74,21 +235,48 @@ static private int jjMoveNfa_1(final int startState, int curPos)
             switch(jjstateSet[--i])
             {
                case 0:
-                  if (((0x2400L & l) != 0L) && (kind > 7)) {
-                    kind = 7;
-                }
-                  if (curChar == 13) {
-                    jjstateSet[jjnewStateCnt++] = 1;
+                  if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 41) {
+                        kind = 41;
+                    }
+                     jjCheckNAdd(2);
+                  }
+                  else if (curChar == 34) {
+                    jjCheckNAddTwoStates(4, 5);
                 }
                   break;
                case 1:
-                  if (curChar == 10 && kind > 7) {
-                    kind = 7;
+                  if ((0x3ff000000000000L & l) == 0L) {
+                    break;
+                }
+                  if (kind > 40) {
+                    kind = 40;
                 }
+                  jjstateSet[jjnewStateCnt++] = 1;
                   break;
                case 2:
-                  if (curChar == 13) {
-                    jjstateSet[jjnewStateCnt++] = 1;
+                  if ((0x3ff000000000000L & l) == 0L) {
+                    break;
+                }
+                  if (kind > 41) {
+                    kind = 41;
+                }
+                  jjCheckNAdd(2);
+                  break;
+               case 3:
+                  if (curChar == 34) {
+                    jjCheckNAddTwoStates(4, 5);
+                }
+                  break;
+               case 4:
+                  if ((0xfffffffbffffdbffL & l) != 0L) {
+                    jjCheckNAddTwoStates(4, 5);
+                }
+                  break;
+               case 5:
+                  if (curChar == 34 && kind > 42) {
+                    kind = 42;
                 }
                   break;
                default : break;
@@ -97,20 +285,49 @@ static private int jjMoveNfa_1(final int startState, int curPos)
       }
       else if (curChar < 128)
       {
+         final long l = 1L << (curChar & 077);
          do
          {
             switch(jjstateSet[--i])
             {
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         do
+               case 0:
+                  if ((0x7fffffe07fffffeL & l) == 0L) {
+                    break;
+                }
+                  if (kind > 40) {
+                    kind = 40;
+                }
+                  jjCheckNAdd(1);
+                  break;
+               case 1:
+                  if ((0x7fffffe87fffffeL & l) == 0L) {
+                    break;
+                }
+                  if (kind > 40) {
+                    kind = 40;
+                }
+                  jjCheckNAdd(1);
+                  break;
+               case 4:
+                  jjAddStates(0, 1);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         final int i2 = (curChar & 0xff) >> 6;
+         final long l2 = 1L << (curChar & 077);
+         do
          {
             switch(jjstateSet[--i])
             {
+               case 4:
+                  if ((jjbitVec0[i2] & l2) != 0L) {
+                    jjAddStates(0, 1);
+                }
+                  break;
                default : break;
             }
          } while(i != startsAt);
@@ -122,79 +339,99 @@ static private int jjMoveNfa_1(final int startState, int curPos)
          kind = 0x7fffffff;
       }
       ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt))) {
+      if ((i = jjnewStateCnt) == (startsAt = 6 - (jjnewStateCnt = startsAt))) {
         return curPos;
     }
       try { curChar = ASCII_CharStream.readChar(); }
       catch(final java.io.IOException e) { return curPos; }
    }
 }
-private static int jjStopStringLiteralDfa_0(final int pos, final long active0)
+//static private void jjCheckNAddStates(int start, int end)
+//{
+//   do {
+//      jjCheckNAdd(jjnextStates[start]);
+//   } while (start++ != end);
+//}
+//static private void jjCheckNAddStates(int start)
+//{
+//   jjCheckNAdd(jjnextStates[start]);
+//   jjCheckNAdd(jjnextStates[start + 1]);
+//}
+static private int jjMoveNfa_1(final int startState, int curPos)
 {
-   switch (pos)
+   int startsAt = 0;
+   jjnewStateCnt = 3;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
    {
-      case 0:
-         if ((active0 & 0x300780fe00L) != 0L)
-         {
-            jjmatchedKind = 40;
-            return 1;
-         }
-         return -1;
-      case 1:
-         if ((active0 & 0x400a400L) != 0L) {
-            return 1;
-        }
-         if ((active0 & 0x3003805a00L) != 0L)
+      if (++jjround == 0x7fffffff) {
+        ReInitRounds();
+    }
+      if (curChar < 64)
+      {
+         final long l = 1L << curChar;
+         do
          {
-            jjmatchedKind = 40;
-            jjmatchedPos = 1;
-            return 1;
-         }
-         return -1;
-      case 2:
-         if ((active0 & 0x2004200L) != 0L) {
-            return 1;
-        }
-         if ((active0 & 0x3001801800L) != 0L)
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (((0x2400L & l) != 0L) && (kind > 7)) {
+                    kind = 7;
+                }
+                  if (curChar == 13) {
+                    jjstateSet[jjnewStateCnt++] = 1;
+                }
+                  break;
+               case 1:
+                  if (curChar == 10 && kind > 7) {
+                    kind = 7;
+                }
+                  break;
+               case 2:
+                  if (curChar == 13) {
+                    jjstateSet[jjnewStateCnt++] = 1;
+                }
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         do
          {
-            jjmatchedKind = 40;
-            jjmatchedPos = 2;
-            return 1;
-         }
-         return -1;
-      case 3:
-         if ((active0 & 0x2000800000L) != 0L)
+            switch(jjstateSet[--i])
+            {
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         do
          {
-            jjmatchedKind = 40;
-            jjmatchedPos = 3;
-            return 1;
-         }
-         if ((active0 & 0x1001001800L) != 0L) {
-            return 1;
-        }
-         return -1;
-      default :
-         return -1;
+            switch(jjstateSet[--i])
+            {
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt))) {
+        return curPos;
+    }
+      try { curChar = ASCII_CharStream.readChar(); }
+      catch(final java.io.IOException e) { return curPos; }
    }
 }
-private static int jjStartNfa_0(final int pos, final long active0)
-{
-   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
-}
-static private int jjStopAtPos(final int pos, final int kind)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   return pos + 1;
-}
-static private int jjStartNfaWithStates_0(final int pos, final int kind, final int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = ASCII_CharStream.readChar(); }
-   catch(final java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_0(state, pos + 1);
-}
 static private int jjMoveStringLiteralDfa0_0()
 {
    switch(curChar)
@@ -250,6 +487,10 @@ static private int jjMoveStringLiteralDfa0_0()
          return jjMoveNfa_0(0, 0);
    }
 }
+static private int jjMoveStringLiteralDfa0_1()
+{
+   return jjMoveNfa_1(0, 0);
+}
 static private int jjMoveStringLiteralDfa1_0(final long active0)
 {
    try { curChar = ASCII_CharStream.readChar(); }
@@ -421,191 +662,74 @@ static private int jjMoveStringLiteralDfa4_0(final long old0, long active0)
    }
    return jjStartNfa_0(3, active0);
 }
-static final long[] jjbitVec0 = {
-   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-static private int jjMoveNfa_0(final int startState, int curPos)
+private static int jjStartNfa_0(final int pos, final long active0)
 {
-   int startsAt = 0;
-   jjnewStateCnt = 6;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int kind = 0x7fffffff;
-   for (;;)
+   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
+}
+static private int jjStartNfaWithStates_0(final int pos, final int kind, final int state)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   try { curChar = ASCII_CharStream.readChar(); }
+   catch(final java.io.IOException e) { return pos + 1; }
+   return jjMoveNfa_0(state, pos + 1);
+}
+
+static private int jjStopAtPos(final int pos, final int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+
+private static int jjStopStringLiteralDfa_0(final int pos, final long active0)
+{
+   switch (pos)
    {
-      if (++jjround == 0x7fffffff) {
-        ReInitRounds();
-    }
-      if (curChar < 64)
-      {
-         final long l = 1L << curChar;
-         do
+      case 0:
+         if ((active0 & 0x300780fe00L) != 0L)
          {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0x3ff000000000000L & l) != 0L)
-                  {
-                     if (kind > 41) {
-                        kind = 41;
-                    }
-                     jjCheckNAdd(2);
-                  }
-                  else if (curChar == 34) {
-                    jjCheckNAddTwoStates(4, 5);
-                }
-                  break;
-               case 1:
-                  if ((0x3ff000000000000L & l) == 0L) {
-                    break;
-                }
-                  if (kind > 40) {
-                    kind = 40;
-                }
-                  jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 2:
-                  if ((0x3ff000000000000L & l) == 0L) {
-                    break;
-                }
-                  if (kind > 41) {
-                    kind = 41;
-                }
-                  jjCheckNAdd(2);
-                  break;
-               case 3:
-                  if (curChar == 34) {
-                    jjCheckNAddTwoStates(4, 5);
-                }
-                  break;
-               case 4:
-                  if ((0xfffffffbffffdbffL & l) != 0L) {
-                    jjCheckNAddTwoStates(4, 5);
-                }
-                  break;
-               case 5:
-                  if (curChar == 34 && kind > 42) {
-                    kind = 42;
-                }
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         final long l = 1L << (curChar & 077);
-         do
+            jjmatchedKind = 40;
+            return 1;
+         }
+         return -1;
+      case 1:
+         if ((active0 & 0x400a400L) != 0L) {
+            return 1;
+        }
+         if ((active0 & 0x3003805a00L) != 0L)
          {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0x7fffffe07fffffeL & l) == 0L) {
-                    break;
-                }
-                  if (kind > 40) {
-                    kind = 40;
-                }
-                  jjCheckNAdd(1);
-                  break;
-               case 1:
-                  if ((0x7fffffe87fffffeL & l) == 0L) {
-                    break;
-                }
-                  if (kind > 40) {
-                    kind = 40;
-                }
-                  jjCheckNAdd(1);
-                  break;
-               case 4:
-                  jjAddStates(0, 1);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         final int i2 = (curChar & 0xff) >> 6;
-         final long l2 = 1L << (curChar & 077);
-         do
+            jjmatchedKind = 40;
+            jjmatchedPos = 1;
+            return 1;
+         }
+         return -1;
+      case 2:
+         if ((active0 & 0x2004200L) != 0L) {
+            return 1;
+        }
+         if ((active0 & 0x3001801800L) != 0L)
          {
-            switch(jjstateSet[--i])
-            {
-               case 4:
-                  if ((jjbitVec0[i2] & l2) != 0L) {
-                    jjAddStates(0, 1);
-                }
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 6 - (jjnewStateCnt = startsAt))) {
-        return curPos;
-    }
-      try { curChar = ASCII_CharStream.readChar(); }
-      catch(final java.io.IOException e) { return curPos; }
+            jjmatchedKind = 40;
+            jjmatchedPos = 2;
+            return 1;
+         }
+         return -1;
+      case 3:
+         if ((active0 & 0x2000800000L) != 0L)
+         {
+            jjmatchedKind = 40;
+            jjmatchedPos = 3;
+            return 1;
+         }
+         if ((active0 & 0x1001001800L) != 0L) {
+            return 1;
+        }
+         return -1;
+      default :
+         return -1;
    }
 }
-static final int[] jjnextStates = {
-   4, 5,
-};
-public static final String[] jjstrLiteralImages = {
-"", null, null, null, null, null, null, null, null, "\106\125\116",
-"\111\106", "\124\110\105\116", "\105\114\123\105", "\106\111", "\114\105\124",
-"\111\116", "\76", "\74", "\76\75", "\74\75", "\75\75", "\41\75", "\41",
-"\106\101\114\123\105", "\124\122\125\105", "\101\116\104", "\117\122", "\53", "\55", "\52", "\45",
-"\57", "\50", "\51", "\75", "\54", "\122\105\101\104", "\127\122\111\124\105", null,
-null, null, null, null, };
-public static final String[] lexStateNames = {
-   "DEFAULT",
-   "SINGLE_LINE_COMMENT_STATE",
-};
-public static final int[] jjnewLexState = {
-   -1, -1, -1, -1, -1, -1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-};
-static final long[] jjtoToken = {
-   0x73ffffffe01L,
-};
-static final long[] jjtoSkip = {
-   0xbeL,
-};
-static final long[] jjtoSpecial = {
-   0x80L,
-};
-static final long[] jjtoMore = {
-   0x140L,
-};
-static private ASCII_CharStream input_stream;
-static private final int[] jjrounds = new int[6];
-static private final int[] jjstateSet = new int[12];
-static StringBuffer image;
-static int jjimageLen;
-static int lengthOfMatch;
-static protected char curChar;
-public MiniParserTokenManager(final ASCII_CharStream stream)
-{
-   if (input_stream != null) {
-    throw new TokenMgrError(
-        "ERROR: Second call to constructor of static lexer. You must use ReInit() to initialize the static variables.",
-        TokenMgrError.STATIC_LEXER_ERROR);
-}
-   input_stream = stream;
-}
-public MiniParserTokenManager(final ASCII_CharStream stream, final int lexState)
-{
-   this(stream);
-   SwitchTo(lexState);
-}
 static public void ReInit(final ASCII_CharStream stream)
 {
    jjmatchedPos = jjnewStateCnt = 0;
@@ -613,6 +737,11 @@ static public void ReInit(final ASCII_CharStream stream)
    input_stream = stream;
    ReInitRounds();
 }
+static public void ReInit(final ASCII_CharStream stream, final int lexState)
+{
+   ReInit(stream);
+   SwitchTo(lexState);
+}
 static private void ReInitRounds()
 {
    int i;
@@ -621,10 +750,13 @@ static private void ReInitRounds()
     jjrounds[i] = 0x80000000;
 }
 }
-static public void ReInit(final ASCII_CharStream stream, final int lexState)
+static void SkipLexicalActions(final Token matchedToken)
 {
-   ReInit(stream);
-   SwitchTo(lexState);
+   switch(jjmatchedKind)
+   {
+      default :
+         break;
+   }
 }
 static public void SwitchTo(final int lexState)
 {
@@ -635,151 +767,19 @@ static public void SwitchTo(final int lexState)
 curLexState = lexState;
 }
 
-static private Token jjFillToken()
+public MiniParserTokenManager(final ASCII_CharStream stream)
 {
-   final Token t = Token.newToken(jjmatchedKind);
-   t.kind = jjmatchedKind;
-   final String im = jjstrLiteralImages[jjmatchedKind];
-   t.image = (im == null) ? ASCII_CharStream.GetImage() : im;
-   t.beginLine = ASCII_CharStream.getBeginLine();
-   t.beginColumn = ASCII_CharStream.getBeginColumn();
-   t.endLine = ASCII_CharStream.getEndLine();
-   t.endColumn = ASCII_CharStream.getEndColumn();
-   return t;
+   if (input_stream != null) {
+    throw new TokenMgrError(
+        "ERROR: Second call to constructor of static lexer. You must use ReInit() to initialize the static variables.",
+        TokenMgrError.STATIC_LEXER_ERROR);
 }
-
-static int curLexState = 0;
-static int defaultLexState = 0;
-static int jjnewStateCnt;
-static int jjround;
-static int jjmatchedPos;
-static int jjmatchedKind;
-
-public static Token getNextToken()
-{
-  Token specialToken = null;
-  Token matchedToken;
-  int curPos = 0;
-
-  EOFLoop :
-  for (;;)
-  {
-   try
-   {
-      curChar = ASCII_CharStream.BeginToken();
-   }
-   catch(final java.io.IOException e)
-   {
-      jjmatchedKind = 0;
-      matchedToken = jjFillToken();
-      matchedToken.specialToken = specialToken;
-      return matchedToken;
-   }
-   image = null;
-   jjimageLen = 0;
-
-   for (;;)
-   {
-     switch(curLexState)
-     {
-       case 0:
-         try { ASCII_CharStream.backup(0);
-            while (curChar <= 32 && (0x100003600L & (1L << curChar)) != 0L) {
-                curChar = ASCII_CharStream.BeginToken();
-            }
-         }
-         catch (final java.io.IOException e1) { continue EOFLoop; }
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_0();
-         break;
-       case 1:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_1();
-         if (jjmatchedPos == 0 && jjmatchedKind > 8)
-         {
-            jjmatchedKind = 8;
-         }
-         break;
-     }
-     if (jjmatchedKind != 0x7fffffff)
-     {
-        if (jjmatchedPos + 1 < curPos) {
-            ASCII_CharStream.backup(curPos - jjmatchedPos - 1);
-        }
-        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           matchedToken = jjFillToken();
-           matchedToken.specialToken = specialToken;
-       if (jjnewLexState[jjmatchedKind] != -1) {
-        curLexState = jjnewLexState[jjmatchedKind];
-    }
-           return matchedToken;
-        }
-        if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-           {
-              matchedToken = jjFillToken();
-              if (specialToken == null) {
-                specialToken = matchedToken;
-            } else
-              {
-                 matchedToken.specialToken = specialToken;
-                 specialToken = (specialToken.next = matchedToken);
-              }
-              SkipLexicalActions(matchedToken);
-           } else {
-            SkipLexicalActions(null);
-        }
-         if (jjnewLexState[jjmatchedKind] != -1) {
-            curLexState = jjnewLexState[jjmatchedKind];
-        }
-           continue EOFLoop;
-        }
-        jjimageLen += jjmatchedPos + 1;
-      if (jjnewLexState[jjmatchedKind] != -1) {
-        curLexState = jjnewLexState[jjmatchedKind];
-    }
-        curPos = 0;
-        jjmatchedKind = 0x7fffffff;
-        try {
-           curChar = ASCII_CharStream.readChar();
-           continue;
-        }
-        catch (final java.io.IOException e1) { }
-     }
-     int error_line = ASCII_CharStream.getEndLine();
-     int error_column = ASCII_CharStream.getEndColumn();
-     String error_after = null;
-     boolean EOFSeen = false;
-     try { ASCII_CharStream.readChar(); ASCII_CharStream.backup(1); }
-     catch (final java.io.IOException e1) {
-        EOFSeen = true;
-        error_after = curPos <= 1 ? "" : ASCII_CharStream.GetImage();
-        if (curChar == '\n' || curChar == '\r') {
-           error_line++;
-           error_column = 0;
-        } else {
-            error_column++;
-        }
-     }
-     if (!EOFSeen) {
-        ASCII_CharStream.backup(1);
-        error_after = curPos <= 1 ? "" : ASCII_CharStream.GetImage();
-     }
-     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
-   }
-  }
+   input_stream = stream;
 }
 
-static void SkipLexicalActions(final Token matchedToken)
+public MiniParserTokenManager(final ASCII_CharStream stream, final int lexState)
 {
-   switch(jjmatchedKind)
-   {
-      default :
-         break;
-   }
+   this(stream);
+   SwitchTo(lexState);
 }
 }
diff --git a/src/examples/Mini/Node.java b/src/examples/Mini/Node.java
index 3a0ade2c..c021f2d9 100644
--- a/src/examples/Mini/Node.java
+++ b/src/examples/Mini/Node.java
@@ -25,28 +25,28 @@ package Mini;
    between nodes. */
 public interface Node {
 
-  /** This method is called after the node has been made the current
-    node.  It indicates that child nodes can now be added to it. */
-  void jjtOpen();
+  /** This method tells the node to add its argument to the node's
+    list of children.  */
+  void jjtAddChild(Node n, int i);
 
   /** This method is called after all the child nodes have been
     added. */
   void jjtClose();
 
-  /** This pair of methods are used to inform the node of its
-    parent. */
-  void jjtSetParent(Node n);
-
-  Node jjtGetParent();
-
-  /** This method tells the node to add its argument to the node's
-    list of children.  */
-  void jjtAddChild(Node n, int i);
-
   /** This method returns a child node.  The children are numbered
      from zero, left to right. */
   Node jjtGetChild(int i);
 
   /** Return the number of children the node has. */
   int jjtGetNumChildren();
+
+  Node jjtGetParent();
+
+  /** This method is called after the node has been made the current
+    node.  It indicates that child nodes can now be added to it. */
+  void jjtOpen();
+
+  /** This pair of methods are used to inform the node of its
+    parent. */
+  void jjtSetParent(Node n);
 }
diff --git a/src/examples/Mini/ParseException.java b/src/examples/Mini/ParseException.java
index 67619b70..99079d84 100644
--- a/src/examples/Mini/ParseException.java
+++ b/src/examples/Mini/ParseException.java
@@ -29,49 +29,6 @@ package Mini;
  */
 public class ParseException extends Exception {
 
-  /**
-   * This constructor is used by the method "generateParseException"
-   * in the generated parser.  Calling this constructor generates
-   * a new object of this type with the fields "currentToken",
-   * "expectedTokenSequences", and "tokenImage" set.  The boolean
-   * flag "specialConstructor" is also set to true to indicate that
-   * this constructor was used to create this object.
-   * This constructor calls its super class with the empty string
-   * to force the "toString" method of parent class "Throwable" to
-   * print the error message in the form:
-   *     ParseException: <result of getMessage>
-   */
-  public ParseException(final Token currentTokenVal,
-                        final int[][] expectedTokenSequencesVal,
-                        final String[] tokenImageVal
-                       )
-  {
-    super("");
-    specialConstructor = true;
-    currentToken = currentTokenVal;
-    expectedTokenSequences = expectedTokenSequencesVal;
-    tokenImage = tokenImageVal;
-  }
-
-  /**
-   * The following constructors are for use by you for whatever
-   * purpose you can think of.  Constructing the exception in this
-   * manner makes the exception behave in the normal way - i.e., as
-   * documented in the class "Throwable".  The fields "errorToken",
-   * "expectedTokenSequences", and "tokenImage" do not contain
-   * relevant information.  The JavaCC generated code does not use
-   * these constructors.
-   */
-
-  public ParseException() {
-    specialConstructor = false;
-  }
-
-  public ParseException(final String message) {
-    super(message);
-    specialConstructor = false;
-  }
-
   /**
    * This variable determines which constructor was used to create
    * this object and thereby affects the semantics of the
@@ -101,61 +58,52 @@ public class ParseException extends Exception {
   public String[] tokenImage;
 
   /**
-   * This method has the standard behavior when this object has been
-   * created using the standard constructors.  Otherwise, it uses
-   * "currentToken" and "expectedTokenSequences" to generate a parse
-   * error message and returns it.  If this object has been created
-   * due to a parse error, and you do not catch it (it gets thrown
-   * from the parser), then this method is called during the printing
-   * of the final stack trace, and hence the correct error message
-   * gets displayed.
+   * The end of line string for this machine.
    */
-  @Override
-  public String getMessage() {
-    if (!specialConstructor) {
-      return super.getMessage();
-    }
-    String expected = "";
-    int maxSize = 0;
-    for (final int[] expectedTokenSequence : expectedTokenSequences) {
-      if (maxSize < expectedTokenSequence.length) {
-        maxSize = expectedTokenSequence.length;
-      }
-      for (final int element : expectedTokenSequence) {
-        expected += tokenImage[element] + " ";
-      }
-      if (expectedTokenSequence[expectedTokenSequence.length - 1] != 0) {
-        expected += "...";
-      }
-      expected += eol + "    ";
-    }
-    String retval = "Encountered \"";
-    Token tok = currentToken.next;
-    for (int i = 0; i < maxSize; i++) {
-      if (i != 0) {
-        retval += " ";
-    }
-      if (tok.kind == 0) {
-        retval += tokenImage[0];
-        break;
-      }
-      retval += add_escapes(tok.image);
-      tok = tok.next;
-    }
-    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn + "." + eol;
-    if (expectedTokenSequences.length == 1) {
-      retval += "Was expecting:" + eol + "    ";
-    } else {
-      retval += "Was expecting one of:" + eol + "    ";
-    }
-    retval += expected;
-    return retval;
+  protected String eol = System.getProperty("line.separator", "\n");
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    specialConstructor = false;
+  }
+
+  public ParseException(final String message) {
+    super(message);
+    specialConstructor = false;
   }
 
   /**
-   * The end of line string for this machine.
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.  The boolean
+   * flag "specialConstructor" is also set to true to indicate that
+   * this constructor was used to create this object.
+   * This constructor calls its super class with the empty string
+   * to force the "toString" method of parent class "Throwable" to
+   * print the error message in the form:
+   *     ParseException: <result of getMessage>
    */
-  protected String eol = System.getProperty("line.separator", "\n");
+  public ParseException(final Token currentTokenVal,
+                        final int[][] expectedTokenSequencesVal,
+                        final String[] tokenImageVal
+                       )
+  {
+    super("");
+    specialConstructor = true;
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
 
   /**
    * Used to convert raw characters to their escaped version
@@ -207,4 +155,56 @@ public class ParseException extends Exception {
       return retval.toString();
    }
 
+  /**
+   * This method has the standard behavior when this object has been
+   * created using the standard constructors.  Otherwise, it uses
+   * "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser), then this method is called during the printing
+   * of the final stack trace, and hence the correct error message
+   * gets displayed.
+   */
+  @Override
+  public String getMessage() {
+    if (!specialConstructor) {
+      return super.getMessage();
+    }
+    String expected = "";
+    int maxSize = 0;
+    for (final int[] expectedTokenSequence : expectedTokenSequences) {
+      if (maxSize < expectedTokenSequence.length) {
+        maxSize = expectedTokenSequence.length;
+      }
+      for (final int element : expectedTokenSequence) {
+        expected += tokenImage[element] + " ";
+      }
+      if (expectedTokenSequence[expectedTokenSequence.length - 1] != 0) {
+        expected += "...";
+      }
+      expected += eol + "    ";
+    }
+    String retval = "Encountered \"";
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      if (i != 0) {
+        retval += " ";
+    }
+      if (tok.kind == 0) {
+        retval += tokenImage[0];
+        break;
+      }
+      retval += add_escapes(tok.image);
+      tok = tok.next;
+    }
+    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn + "." + eol;
+    if (expectedTokenSequences.length == 1) {
+      retval += "Was expecting:" + eol + "    ";
+    } else {
+      retval += "Was expecting one of:" + eol + "    ";
+    }
+    retval += expected;
+    return retval;
+  }
+
 }
diff --git a/src/examples/Mini/SimpleNode.java b/src/examples/Mini/SimpleNode.java
index 9dc3fe09..d3ba92cf 100644
--- a/src/examples/Mini/SimpleNode.java
+++ b/src/examples/Mini/SimpleNode.java
@@ -38,17 +38,20 @@ public abstract class SimpleNode implements Node {
     parser = p;
   }
 
-  public void jjtOpen() {
-  }
-
-  public void jjtClose() {
-  }
-
   public void closeNode() {
   }
 
-  public void jjtSetParent(final Node n) { parent = n; }
-  public Node jjtGetParent() { return parent; }
+  public void dump(final String prefix) {
+    System.out.println(toString(prefix));
+    if (children != null) {
+      for (final Node element : children) {
+        final SimpleNode n = (SimpleNode)element;
+        if (n != null) {
+          n.dump(prefix + " ");
+        }
+      }
+    }
+  }
 
   public void jjtAddChild(final Node n, final int i) {
     if (children == null) {
@@ -61,6 +64,8 @@ public abstract class SimpleNode implements Node {
     children[i] = n;
   }
 
+  public void jjtClose() {
+  }
   public Node jjtGetChild(final int i) {
     return children[i];
   }
@@ -69,29 +74,24 @@ public abstract class SimpleNode implements Node {
     return (children == null) ? 0 : children.length;
   }
 
+  public Node jjtGetParent() { return parent; }
+
+  public void jjtOpen() {
+  }
+
   /* You can override these two methods in subclasses of SimpleNode to
      customize the way the node appears when the tree is dumped.  If
      your output uses more than one line you should override
      toString(String), otherwise overriding toString() is probably all
      you need to do. */
 
+  public void jjtSetParent(final Node n) { parent = n; }
   @Override
   public String toString() { return MiniParserTreeConstants.jjtNodeName[id]; }
-  public String toString(final String prefix) { return prefix + toString(); }
 
   /* Override this method if you want to customize how the node dumps
      out its children. */
 
-  public void dump(final String prefix) {
-    System.out.println(toString(prefix));
-    if (children != null) {
-      for (final Node element : children) {
-        final SimpleNode n = (SimpleNode)element;
-        if (n != null) {
-          n.dump(prefix + " ");
-        }
-      }
-    }
-  }
+  public String toString(final String prefix) { return prefix + toString(); }
 }
 
diff --git a/src/examples/Mini/Token.java b/src/examples/Mini/Token.java
index 2ed86dc6..6dfb3b1e 100644
--- a/src/examples/Mini/Token.java
+++ b/src/examples/Mini/Token.java
@@ -24,6 +24,26 @@ package Mini;
 
 public class Token {
 
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simlpy add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken();
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use it in your lexical actions.
+   */
+  public static Token newToken(final int ofKind)
+  {
+     switch(ofKind)
+     {
+       default : return new Token();
+     }
+  }
+
   /**
    * An integer that describes the kind of this token.  This numbering
    * system is determined by JavaCCParser, and a table of these numbers is
@@ -76,24 +96,4 @@ public class Token {
      return image;
   }
 
-  /**
-   * Returns a new Token object, by default. However, if you want, you
-   * can create and return subclass objects based on the value of ofKind.
-   * Simply add the cases to the switch for all those special cases.
-   * For example, if you have a subclass of Token called IDToken that
-   * you want to create if ofKind is ID, simlpy add something like :
-   *
-   *    case MyParserConstants.ID : return new IDToken();
-   *
-   * to the following switch statement. Then you can cast matchedToken
-   * variable to the appropriate type and use it in your lexical actions.
-   */
-  public static Token newToken(final int ofKind)
-  {
-     switch(ofKind)
-     {
-       default : return new Token();
-     }
-  }
-
 }
diff --git a/src/examples/Mini/TokenMgrError.java b/src/examples/Mini/TokenMgrError.java
index 49a90614..af6e515a 100644
--- a/src/examples/Mini/TokenMgrError.java
+++ b/src/examples/Mini/TokenMgrError.java
@@ -44,12 +44,6 @@ public class TokenMgrError extends Error
     */
    static final int LOOP_DETECTED = 3;
 
-   /**
-    * Indicates the reason why the exception is thrown. It will have
-    * one of the above 4 values.
-    */
-   int errorCode;
-
    /**
     * Replaces unprintable characters by their espaced (or unicode escaped)
     * equivalents in the given string
@@ -120,24 +114,20 @@ public class TokenMgrError extends Error
    }
 
    /**
-    * You can also modify the body of this method to customize your error messages.
-    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
-    * of end-users concern, so you can return something like :
-    *
-    *     "Internal Error : Please file a bug report .... "
-    *
-    * from this method for such cases in the release version of your parser.
+    * Indicates the reason why the exception is thrown. It will have
+    * one of the above 4 values.
     */
-   @Override
-   public String getMessage() {
-      return super.getMessage();
+   int errorCode;
+
+   public TokenMgrError() {
    }
 
    /*
     * Constructors of various flavors follow.
     */
 
-   public TokenMgrError() {
+   public TokenMgrError(final boolean EOFSeen, final int lexState, final int errorLine, final int errorColumn, final String errorAfter, final char curChar, final int reason) {
+      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
    }
 
    public TokenMgrError(final String message, final int reason) {
@@ -145,7 +135,17 @@ public class TokenMgrError extends Error
       errorCode = reason;
    }
 
-   public TokenMgrError(final boolean EOFSeen, final int lexState, final int errorLine, final int errorColumn, final String errorAfter, final char curChar, final int reason) {
-      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+   /**
+    * You can also modify the body of this method to customize your error messages.
+    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+    * of end-users concern, so you can return something like :
+    *
+    *     "Internal Error : Please file a bug report .... "
+    *
+    * from this method for such cases in the release version of your parser.
+    */
+   @Override
+   public String getMessage() {
+      return super.getMessage();
    }
 }
diff --git a/src/examples/Mini/Variable.java b/src/examples/Mini/Variable.java
index 7aa53792..5bb47f18 100644
--- a/src/examples/Mini/Variable.java
+++ b/src/examples/Mini/Variable.java
@@ -44,25 +44,25 @@ public class Variable implements EnvEntry {
   }
 
   @Override
-  public String toString() {
-    if(!reserved) {
-        return var_name + " declared at line " + line + ", column " + column;
-    }
-    return var_name + " <reserved key word>";
-  }
+  public int      getColumn()  { return column; }
 
-  public ASTIdent getName()    { return name; }
   @Override
   public String   getHashKey() { return var_name; }
   @Override
   public int      getLine()    { return line; }
-  @Override
-  public int      getColumn()  { return column; }
+  LocalVariableGen getLocalVariable() { return local_var; }
+  public ASTIdent getName()    { return name; }
   public int      getType()    { return name.getType(); }
 
   void setLocalVariable(final LocalVariableGen local_var) {
     this.local_var = local_var;
   }
-  LocalVariableGen getLocalVariable() { return local_var; }
+  @Override
+  public String toString() {
+    if(!reserved) {
+        return var_name + " declared at line " + line + ", column " + column;
+    }
+    return var_name + " <reserved key word>";
+  }
 }
 
diff --git a/src/examples/Package.java b/src/examples/Package.java
index 5576aebb..5bd0d691 100644
--- a/src/examples/Package.java
+++ b/src/examples/Package.java
@@ -103,24 +103,60 @@ public class Package {
      */
     boolean log = false;
 
-    public void usage() {
-        System.out.println(" This program packages classes and all their dependents");
-        System.out.println(" into one jar. Give all starting classes (your main)");
-        System.out.println(" on the command line. Use / as separator, the .class is");
-        System.out.println(" optional. We use the environments CLASSPATH to resolve");
-        System.out.println(" classes. Anything but java.* packages are packaged.");
-        System.out.println(" If you use Class.forName (or similar), be sure to");
-        System.out.println(" include the classes that you load dynamically on the");
-        System.out.println(" command line.\n");
-        System.out.println(" These options are recognized:");
-        System.out.println(" -e -error  Show errors, meaning classes that could not ");
-        System.out.println("   resolved + the classes that referenced them.");
-        System.out.println(" -l -log  Show classes as they are processed. This will");
-        System.out.println("   include doubles, java classes and is difficult to");
-        System.out.println("   read. I use it as a sort of progress monitor");
-        System.out.println(" -s -show  Prints all the classes that were packaged");
-        System.out.println("   in alphabetical order, which is ordered by package");
-        System.out.println("   for the most part.");
+    /**
+     * add given class to dependents (from is where its dependent from)
+     * some fiddeling to be done because of array class notation
+     */
+    void addClassString(final String clas, final String from) throws IOException {
+        if (log) {
+            System.out.println("processing: " + clas + " referenced by " + from);
+        }
+
+        // must check if it's an arrary (start with "[")
+        if (clas.startsWith("[")) {
+            if (clas.length() == 2) {
+                // it's an array of built in type, ignore
+                return;
+            }
+            if ('L' == clas.charAt(1)) {
+                // it's an array of objects, the class name is between [L and ;
+                // like    [Ljava/lang/Object;
+                addClassString(clas.substring(2, clas.length() - 1), from);
+                return;
+            }
+            if ('[' == clas.charAt(1)) {
+                // it's an array of arrays, call recursive
+                addClassString(clas.substring(1), from);
+                return;
+            }
+            throw new IllegalArgumentException("Can't recognize class name =" + clas);
+        }
+
+        if (!clas.startsWith("java/") && allClasses.get(clas) == null) {
+            dependents.put(clas, from);
+            //      System.out.println("       yes" );
+        } else {
+            //      System.out.println("       no" );
+        }
+    }
+
+    /**
+     * Add this class to allClasses. Then go through all its dependents
+     * and add them to the dependents list if they are not in allClasses
+     */
+    void addDependents(final JavaClass clazz) throws IOException {
+        final String name = clazz.getClassName().replace('.', '/');
+        allClasses.put(name, clazz);
+        final ConstantPool pool = clazz.getConstantPool();
+        for (int i = 1; i < pool.getLength(); i++) {
+            final Constant cons = pool.getConstant(i);
+            //System.out.println("("+i+") " + cons );
+            if (cons != null && cons.getTag() == Constants.CONSTANT_Class) {
+                final int idx = ((ConstantClass) pool.getConstant(i)).getNameIndex();
+                final String clas = ((ConstantUtf8) pool.getConstant(idx)).getBytes();
+                addClassString(clas, name);
+            }
+        }
     }
 
     /**
@@ -222,59 +258,23 @@ public class Package {
         }
     }
 
-    /**
-     * Add this class to allClasses. Then go through all its dependents
-     * and add them to the dependents list if they are not in allClasses
-     */
-    void addDependents(final JavaClass clazz) throws IOException {
-        final String name = clazz.getClassName().replace('.', '/');
-        allClasses.put(name, clazz);
-        final ConstantPool pool = clazz.getConstantPool();
-        for (int i = 1; i < pool.getLength(); i++) {
-            final Constant cons = pool.getConstant(i);
-            //System.out.println("("+i+") " + cons );
-            if (cons != null && cons.getTag() == Constants.CONSTANT_Class) {
-                final int idx = ((ConstantClass) pool.getConstant(i)).getNameIndex();
-                final String clas = ((ConstantUtf8) pool.getConstant(idx)).getBytes();
-                addClassString(clas, name);
-            }
-        }
-    }
-
-    /**
-     * add given class to dependents (from is where its dependent from)
-     * some fiddeling to be done because of array class notation
-     */
-    void addClassString(final String clas, final String from) throws IOException {
-        if (log) {
-            System.out.println("processing: " + clas + " referenced by " + from);
-        }
-
-        // must check if it's an arrary (start with "[")
-        if (clas.startsWith("[")) {
-            if (clas.length() == 2) {
-                // it's an array of built in type, ignore
-                return;
-            }
-            if ('L' == clas.charAt(1)) {
-                // it's an array of objects, the class name is between [L and ;
-                // like    [Ljava/lang/Object;
-                addClassString(clas.substring(2, clas.length() - 1), from);
-                return;
-            }
-            if ('[' == clas.charAt(1)) {
-                // it's an array of arrays, call recursive
-                addClassString(clas.substring(1), from);
-                return;
-            }
-            throw new IllegalArgumentException("Can't recognize class name =" + clas);
-        }
-
-        if (!clas.startsWith("java/") && allClasses.get(clas) == null) {
-            dependents.put(clas, from);
-            //      System.out.println("       yes" );
-        } else {
-            //      System.out.println("       no" );
-        }
+    public void usage() {
+        System.out.println(" This program packages classes and all their dependents");
+        System.out.println(" into one jar. Give all starting classes (your main)");
+        System.out.println(" on the command line. Use / as separator, the .class is");
+        System.out.println(" optional. We use the environments CLASSPATH to resolve");
+        System.out.println(" classes. Anything but java.* packages are packaged.");
+        System.out.println(" If you use Class.forName (or similar), be sure to");
+        System.out.println(" include the classes that you load dynamically on the");
+        System.out.println(" command line.\n");
+        System.out.println(" These options are recognized:");
+        System.out.println(" -e -error  Show errors, meaning classes that could not ");
+        System.out.println("   resolved + the classes that referenced them.");
+        System.out.println(" -l -log  Show classes as they are processed. This will");
+        System.out.println("   include doubles, java classes and is difficult to");
+        System.out.println("   read. I use it as a sort of progress monitor");
+        System.out.println(" -s -show  Prints all the classes that were packaged");
+        System.out.println("   in alphabetical order, which is ordered by package");
+        System.out.println("   for the most part.");
     }
 }
diff --git a/src/examples/TransitiveHull.java b/src/examples/TransitiveHull.java
index 8e17a8dd..31bba84a 100644
--- a/src/examples/TransitiveHull.java
+++ b/src/examples/TransitiveHull.java
@@ -55,13 +55,34 @@ import org.apache.bcel.util.ClassSet;
  */
 public class TransitiveHull extends org.apache.bcel.classfile.EmptyVisitor {
 
+    public static final String[] IGNORED = {"java[.].*", "javax[.].*", "sun[.].*", "sunw[.].*",
+            "com[.]sun[.].*", "org[.]omg[.].*", "org[.]w3c[.].*", "org[.]xml[.].*", "net[.]jini[.].*"};
+    public static void main(final String[] argv) {
+        JavaClass java_class;
+
+        try {
+            if (argv.length == 0) {
+                System.err.println("transitive: No input files specified");
+            } else {
+                if ((java_class = Repository.lookupClass(argv[0])) == null) {
+                    java_class = new ClassParser(argv[0]).parse();
+                }
+
+                final TransitiveHull hull = new TransitiveHull(java_class);
+
+                hull.start();
+                System.out.println(Arrays.asList(hull.getClassNames()));
+            }
+        } catch (final Exception e) {
+            e.printStackTrace();
+        }
+    }
     private final ClassQueue queue;
     private final ClassSet set;
+
     private ConstantPool cp;
-    private String[] ignored = IGNORED;
 
-    public static final String[] IGNORED = {"java[.].*", "javax[.].*", "sun[.].*", "sunw[.].*",
-            "com[.]sun[.].*", "org[.]omg[.].*", "org[.]w3c[.].*", "org[.]xml[.].*", "net[.]jini[.].*"};
+    private String[] ignored = IGNORED;
 
     public TransitiveHull(final JavaClass clazz) {
         queue = new ClassQueue();
@@ -70,26 +91,6 @@ public class TransitiveHull extends org.apache.bcel.classfile.EmptyVisitor {
         set.add(clazz);
     }
 
-    public JavaClass[] getClasses() {
-        return set.toArray();
-    }
-
-    public String[] getClassNames() {
-        return set.getClassNames();
-    }
-
-    /**
-     * Start traversal using DescendingVisitor pattern.
-     */
-    public void start() {
-        while (!queue.empty()) {
-            final JavaClass clazz = queue.dequeue();
-            cp = clazz.getConstantPool();
-
-            new org.apache.bcel.classfile.DescendingVisitor(clazz, this).visit();
-        }
-    }
-
     private void add(String class_name) {
         class_name = class_name.replace('/', '.');
 
@@ -110,12 +111,6 @@ public class TransitiveHull extends org.apache.bcel.classfile.EmptyVisitor {
         }
     }
 
-    @Override
-    public void visitConstantClass(final ConstantClass cc) {
-        final String class_name = (String) cc.getConstantValue(cp);
-        add(class_name);
-    }
-
     private void checkType(Type type) {
         if (type instanceof ArrayType) {
             type = ((ArrayType) type).getBasicType();
@@ -126,31 +121,48 @@ public class TransitiveHull extends org.apache.bcel.classfile.EmptyVisitor {
         }
     }
 
-    private void visitRef(final ConstantCP ccp, final boolean method) {
-        final String class_name = ccp.getClass(cp);
-        add(class_name);
+    public JavaClass[] getClasses() {
+        return set.toArray();
+    }
 
-        final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(ccp.getNameAndTypeIndex(),
-                Constants.CONSTANT_NameAndType);
+    public String[] getClassNames() {
+        return set.getClassNames();
+    }
 
-        final String signature = cnat.getSignature(cp);
+    public String[] getIgnored() {
+        return ignored;
+    }
 
-        if (method) {
-            final Type type = Type.getReturnType(signature);
+    /**
+     * Set the value of ignored.
+     *
+     * @param v Value to assign to ignored.
+     */
+    public void setIgnored(final String[] v) {
+        ignored = v;
+    }
 
-            checkType(type);
+    /**
+     * Start traversal using DescendingVisitor pattern.
+     */
+    public void start() {
+        while (!queue.empty()) {
+            final JavaClass clazz = queue.dequeue();
+            cp = clazz.getConstantPool();
 
-            for (final Type type1 : Type.getArgumentTypes(signature)) {
-                checkType(type1);
-            }
-        } else {
-            checkType(Type.getType(signature));
+            new org.apache.bcel.classfile.DescendingVisitor(clazz, this).visit();
         }
     }
 
     @Override
-    public void visitConstantMethodref(final ConstantMethodref cmr) {
-        visitRef(cmr, true);
+    public void visitConstantClass(final ConstantClass cc) {
+        final String class_name = (String) cc.getConstantValue(cp);
+        add(class_name);
+    }
+
+    @Override
+    public void visitConstantFieldref(final ConstantFieldref cfr) {
+        visitRef(cfr, false);
     }
 
     @Override
@@ -159,41 +171,29 @@ public class TransitiveHull extends org.apache.bcel.classfile.EmptyVisitor {
     }
 
     @Override
-    public void visitConstantFieldref(final ConstantFieldref cfr) {
-        visitRef(cfr, false);
+    public void visitConstantMethodref(final ConstantMethodref cmr) {
+        visitRef(cmr, true);
     }
 
-    public String[] getIgnored() {
-        return ignored;
-    }
+    private void visitRef(final ConstantCP ccp, final boolean method) {
+        final String class_name = ccp.getClass(cp);
+        add(class_name);
 
-    /**
-     * Set the value of ignored.
-     *
-     * @param v Value to assign to ignored.
-     */
-    public void setIgnored(final String[] v) {
-        ignored = v;
-    }
+        final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(ccp.getNameAndTypeIndex(),
+                Constants.CONSTANT_NameAndType);
 
-    public static void main(final String[] argv) {
-        JavaClass java_class;
+        final String signature = cnat.getSignature(cp);
 
-        try {
-            if (argv.length == 0) {
-                System.err.println("transitive: No input files specified");
-            } else {
-                if ((java_class = Repository.lookupClass(argv[0])) == null) {
-                    java_class = new ClassParser(argv[0]).parse();
-                }
+        if (method) {
+            final Type type = Type.getReturnType(signature);
 
-                final TransitiveHull hull = new TransitiveHull(java_class);
+            checkType(type);
 
-                hull.start();
-                System.out.println(Arrays.asList(hull.getClassNames()));
+            for (final Type type1 : Type.getArgumentTypes(signature)) {
+                checkType(type1);
             }
-        } catch (final Exception e) {
-            e.printStackTrace();
+        } else {
+            checkType(Type.getType(signature));
         }
     }
 }
diff --git a/src/examples/helloify.java b/src/examples/helloify.java
index 44c05cc3..3ebb35f4 100644
--- a/src/examples/helloify.java
+++ b/src/examples/helloify.java
@@ -46,32 +46,6 @@ public final class helloify implements Constants {
     private static int out;     // reference to System.out
     private static int println; // reference to PrintStream.println
 
-    public static void main(final String[] argv) throws Exception {
-        for (final String arg : argv) {
-            if (arg.endsWith(".class")) {
-                final JavaClass java_class = new ClassParser(arg).parse();
-                final ConstantPool constants = java_class.getConstantPool();
-                final String file_name = arg.substring(0, arg.length() - 6) + "_hello.class";
-                cp = new ConstantPoolGen(constants);
-
-                helloifyClassName(java_class);
-
-                out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
-                println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V");
-                // Patch all methods.
-                final Method[] methods = java_class.getMethods();
-
-                for (int j = 0; j < methods.length; j++) {
-                    methods[j] = helloifyMethod(methods[j]);
-                }
-
-                // Finally dump it back to a file.
-                java_class.setConstantPool(cp.getFinalConstantPool());
-                java_class.dump(file_name);
-            }
-        }
-    }
-
     /**
      * Change class name to <old_name>_hello
      */
@@ -131,4 +105,30 @@ public final class helloify implements Constants {
 
         return m;
     }
+
+    public static void main(final String[] argv) throws Exception {
+        for (final String arg : argv) {
+            if (arg.endsWith(".class")) {
+                final JavaClass java_class = new ClassParser(arg).parse();
+                final ConstantPool constants = java_class.getConstantPool();
+                final String file_name = arg.substring(0, arg.length() - 6) + "_hello.class";
+                cp = new ConstantPoolGen(constants);
+
+                helloifyClassName(java_class);
+
+                out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
+                println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V");
+                // Patch all methods.
+                final Method[] methods = java_class.getMethods();
+
+                for (int j = 0; j < methods.length; j++) {
+                    methods[j] = helloifyMethod(methods[j]);
+                }
+
+                // Finally dump it back to a file.
+                java_class.setConstantPool(cp.getFinalConstantPool());
+                java_class.dump(file_name);
+            }
+        }
+    }
 }
diff --git a/src/examples/listclass.java b/src/examples/listclass.java
index 17969df7..3357a21d 100644
--- a/src/examples/listclass.java
+++ b/src/examples/listclass.java
@@ -82,15 +82,31 @@ import org.apache.bcel.classfile.Method;
  */
 public class listclass {
 
-    boolean code;
-    boolean constants;
-    boolean verbose;
-    boolean classDep;
-    boolean noContents;
-    boolean recurse;
-    Map<String, String> listedClasses;
-    List<String> excludeName;
+    public static String[] getClassDependencies(final ConstantPool pool) {
+        final String[] tempArray = new String[pool.getLength()];
+        int size = 0;
+        final StringBuilder buf = new StringBuilder();
 
+        for (int idx = 0; idx < pool.getLength(); idx++) {
+            final Constant c = pool.getConstant(idx);
+            if (c != null && c.getTag() == Constants.CONSTANT_Class) {
+                final ConstantUtf8 c1 = (ConstantUtf8) pool.getConstant(((ConstantClass) c).getNameIndex());
+                buf.setLength(0);
+                buf.append(c1.getBytes());
+                for (int n = 0; n < buf.length(); n++) {
+                    if (buf.charAt(n) == '/') {
+                        buf.setCharAt(n, '.');
+                    }
+                }
+
+                tempArray[size++] = buf.toString();
+            }
+        }
+
+        final String[] dependencies = new String[size];
+        System.arraycopy(tempArray, 0, dependencies, 0, size);
+        return dependencies;
+    }
     public static void main(final String[] argv) {
         final List<String> fileName = new ArrayList<>();
         final List<String> excludeName = new ArrayList<>();
@@ -156,6 +172,40 @@ public class listclass {
             }
         }
     }
+    /**
+     * Dump the list of classes this class is dependent on
+     */
+    public static void printClassDependencies(final ConstantPool pool) {
+        System.out.println("Dependencies:");
+        for (final String name : getClassDependencies(pool)) {
+            System.out.println("\t" + name);
+        }
+    }
+    /**
+     * Dump the disassembled code of all methods in the class.
+     */
+    public static void printCode(final Method[] methods, final boolean verbose) {
+        for (final Method method : methods) {
+            System.out.println(method);
+
+            final Code code = method.getCode();
+            if (code != null) {
+                System.out.println(code.toString(verbose));
+            }
+        }
+    }
+    boolean code;
+    boolean constants;
+    boolean verbose;
+    boolean classDep;
+
+    boolean noContents;
+
+    boolean recurse;
+
+    Map<String, String> listedClasses;
+
+    List<String> excludeName;
 
     public listclass(final boolean code, final boolean constants, final boolean verbose, final boolean classDep,
                      final boolean noContents, final boolean recurse, final List<String> excludeName) {
@@ -225,54 +275,4 @@ public class listclass {
             System.out.println("Error processing class " + name + " (" + e.getMessage() + ")");
         }
     }
-
-    /**
-     * Dump the list of classes this class is dependent on
-     */
-    public static void printClassDependencies(final ConstantPool pool) {
-        System.out.println("Dependencies:");
-        for (final String name : getClassDependencies(pool)) {
-            System.out.println("\t" + name);
-        }
-    }
-
-    public static String[] getClassDependencies(final ConstantPool pool) {
-        final String[] tempArray = new String[pool.getLength()];
-        int size = 0;
-        final StringBuilder buf = new StringBuilder();
-
-        for (int idx = 0; idx < pool.getLength(); idx++) {
-            final Constant c = pool.getConstant(idx);
-            if (c != null && c.getTag() == Constants.CONSTANT_Class) {
-                final ConstantUtf8 c1 = (ConstantUtf8) pool.getConstant(((ConstantClass) c).getNameIndex());
-                buf.setLength(0);
-                buf.append(c1.getBytes());
-                for (int n = 0; n < buf.length(); n++) {
-                    if (buf.charAt(n) == '/') {
-                        buf.setCharAt(n, '.');
-                    }
-                }
-
-                tempArray[size++] = buf.toString();
-            }
-        }
-
-        final String[] dependencies = new String[size];
-        System.arraycopy(tempArray, 0, dependencies, 0, size);
-        return dependencies;
-    }
-
-    /**
-     * Dump the disassembled code of all methods in the class.
-     */
-    public static void printCode(final Method[] methods, final boolean verbose) {
-        for (final Method method : methods) {
-            System.out.println(method);
-
-            final Code code = method.getCode();
-            if (code != null) {
-                System.out.println(code.toString(verbose));
-            }
-        }
-    }
 }