changeset 3:b0c5bfec8c2e

Initial sources!
author bkurotsu
date Thu, 18 Dec 2014 14:56:02 -0700
parents b321ffa4152c
children 81826dfc899a
files src/org/openjdk/asmtools/Main.java src/org/openjdk/asmtools/asmutils/HexUtils.java src/org/openjdk/asmtools/i18n.properties src/org/openjdk/asmtools/jasm/AnnotationData.java src/org/openjdk/asmtools/jasm/Argument.java src/org/openjdk/asmtools/jasm/AttrData.java src/org/openjdk/asmtools/jasm/BootstrapMethodData.java src/org/openjdk/asmtools/jasm/CPXAttr.java src/org/openjdk/asmtools/jasm/CheckedDataOutputStream.java src/org/openjdk/asmtools/jasm/ClassData.java src/org/openjdk/asmtools/jasm/CodeAttr.java src/org/openjdk/asmtools/jasm/ConstantPool.java src/org/openjdk/asmtools/jasm/Constants.java src/org/openjdk/asmtools/jasm/Data.java src/org/openjdk/asmtools/jasm/DataVector.java src/org/openjdk/asmtools/jasm/DataVectorAttr.java src/org/openjdk/asmtools/jasm/DefaultAnnotationAttr.java src/org/openjdk/asmtools/jasm/Environment.java src/org/openjdk/asmtools/jasm/FieldData.java src/org/openjdk/asmtools/jasm/InnerClassData.java src/org/openjdk/asmtools/jasm/Instr.java src/org/openjdk/asmtools/jasm/JasmTokens.java src/org/openjdk/asmtools/jasm/Main.java src/org/openjdk/asmtools/jasm/MemberData.java src/org/openjdk/asmtools/jasm/MethodData.java src/org/openjdk/asmtools/jasm/Modifiers.java src/org/openjdk/asmtools/jasm/OpcodeTables.java src/org/openjdk/asmtools/jasm/ParseBase.java src/org/openjdk/asmtools/jasm/Parser.java src/org/openjdk/asmtools/jasm/ParserAnnotation.java src/org/openjdk/asmtools/jasm/ParserCP.java src/org/openjdk/asmtools/jasm/ParserInstr.java src/org/openjdk/asmtools/jasm/RuntimeConstants.java src/org/openjdk/asmtools/jasm/Scanner.java src/org/openjdk/asmtools/jasm/StackMapData.java src/org/openjdk/asmtools/jasm/SwitchTable.java src/org/openjdk/asmtools/jasm/Tables.java src/org/openjdk/asmtools/jasm/TypeAnnotationData.java src/org/openjdk/asmtools/jasm/TypeAnnotationUtils.java src/org/openjdk/asmtools/jasm/i18n.properties src/org/openjdk/asmtools/jcdec/Main.java src/org/openjdk/asmtools/jcdec/i18n.properties src/org/openjdk/asmtools/jcoder/ByteBuffer.java src/org/openjdk/asmtools/jcoder/ErrorMessage.java src/org/openjdk/asmtools/jcoder/JcodTokens.java src/org/openjdk/asmtools/jcoder/Jcoder.java src/org/openjdk/asmtools/jcoder/Main.java src/org/openjdk/asmtools/jcoder/Scanner.java src/org/openjdk/asmtools/jcoder/SourceFile.java src/org/openjdk/asmtools/jcoder/SyntaxError.java src/org/openjdk/asmtools/jcoder/i18n.properties src/org/openjdk/asmtools/jdec/ClassData.java src/org/openjdk/asmtools/jdec/Main.java src/org/openjdk/asmtools/jdec/NestedByteArrayInputStream.java src/org/openjdk/asmtools/jdec/i18n.properties src/org/openjdk/asmtools/jdis/AnnotElem.java src/org/openjdk/asmtools/jdis/AnnotationData.java src/org/openjdk/asmtools/jdis/AttrData.java src/org/openjdk/asmtools/jdis/BootstrapMethodData.java src/org/openjdk/asmtools/jdis/ClassData.java src/org/openjdk/asmtools/jdis/CodeData.java src/org/openjdk/asmtools/jdis/ConstantPool.java src/org/openjdk/asmtools/jdis/FieldData.java src/org/openjdk/asmtools/jdis/InnerClassData.java src/org/openjdk/asmtools/jdis/Main.java src/org/openjdk/asmtools/jdis/MemberData.java src/org/openjdk/asmtools/jdis/MethodData.java src/org/openjdk/asmtools/jdis/Options.java src/org/openjdk/asmtools/jdis/ParameterAnnotationData.java src/org/openjdk/asmtools/jdis/StackMapData.java src/org/openjdk/asmtools/jdis/TextLines.java src/org/openjdk/asmtools/jdis/TraceUtils.java src/org/openjdk/asmtools/jdis/TrapData.java src/org/openjdk/asmtools/jdis/TypeAnnotationData.java src/org/openjdk/asmtools/jdis/Utils.java src/org/openjdk/asmtools/jdis/i18n.properties src/org/openjdk/asmtools/jdis/iAtt.java src/org/openjdk/asmtools/jdis/uEscWriter.java src/org/openjdk/asmtools/util/I18NResourceBundle.java src/org/openjdk/asmtools/util/ProductInfo.java src/org/openjdk/asmtools/util/productinfo.properties
diffstat 81 files changed, 24126 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/Main.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools;
+
+import org.openjdk.asmtools.util.I18NResourceBundle;
+import org.openjdk.asmtools.util.ProductInfo;
+
+/**
+ * Wrapper class that reads the first command line argument and invokes a corresponding
+ * tool.
+ */
+public class Main {
+
+    public static final I18NResourceBundle i18n
+            = I18NResourceBundle.getBundleForClass(Main.class);
+
+    /**
+     * Parses the first argument and deligates execution to an appropriate tool
+     *
+     * @param args - command line arguments
+     */
+    public static void main(String args[]) {
+        if (args.length == 0) {
+            usage(i18n.getString("main.error.no_arguments"), 1);
+        }
+        String cmd = args[0];
+        if (cmd.equals("-?") || cmd.equals("-h") || cmd.equals("-help")) {
+            usage(null, 0);
+        } else if (cmd.equals("-version")) {
+            printVersion();
+        } else {
+            String[] newArgs = new String[args.length - 1];
+            System.arraycopy(args, 1, newArgs, 0, args.length - 1);
+            if (cmd.equals("jasm")) {
+                jasm(newArgs);
+            } else if (cmd.equals("jdis")) {
+                jdis(newArgs);
+            } else if (cmd.equals("jcoder")) {
+                jcoder(newArgs);
+            } else if (cmd.equals("jdec")) {
+                jdec(newArgs);
+            } else if (cmd.equals("jcdec")) {
+                jcdec(newArgs);
+            } else {
+                usage(i18n.getString("main.error.unknown_tool", cmd), 1);
+            }
+        }
+    }
+
+    /**
+     * Prints usage info and error message, afterwards invokes System.exit()
+     *
+     * @param msg - error message to print, or null if no errors occurred
+     * @param exitCode - exit code to be returned by System.exit()
+     */
+    public static void usage(String msg, int exitCode) {
+        System.err.println(i18n.getString("main.usage", "asmtools.jar"));
+        if (msg != null) {
+            System.err.println(msg);
+        }
+        System.exit(exitCode);
+    }
+
+    /**
+     * Prints the tools version and calls System.exit(0)
+     */
+    public static void printVersion() {
+        System.err.println(ProductInfo.FULL_VERSION);
+        System.exit(0);
+    }
+
+    /**
+     * Invokes jasm main class with passed arguments
+     */
+    public static void jasm(String[] args) {
+        org.openjdk.asmtools.jasm.Main.main(args);
+    }
+
+    /**
+     * Invokes jcdec main class with passed arguments
+     */
+    public static void jcdec(String[] args) {
+        org.openjdk.asmtools.jcdec.Main.main(args);
+    }
+
+    /**
+     * Invokes jcoder main class with passed arguments
+     */
+    public static void jcoder(String[] args) {
+        org.openjdk.asmtools.jcoder.Main.main(args);
+    }
+
+    /**
+     * Invokes jdec main class with passed arguments
+     */
+    public static void jdec(String[] args) {
+        org.openjdk.asmtools.jdec.Main.main(args);
+    }
+
+    /**
+     * Invokes jdis main class with passed arguments
+     */
+    public static void jdis(String[] args) {
+        org.openjdk.asmtools.jdis.Main.main(args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/asmutils/HexUtils.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.openjdk.asmtools.asmutils;
+
+/**
+ *
+ */
+public class HexUtils {
+    /*======================================================== Hex */
+
+    private static final String hexString = "0123456789ABCDEF";
+    private static final char hexTable[] = hexString.toCharArray();
+
+    public static String toHex(long val, int width) {
+        StringBuffer s = new StringBuffer();
+        for (int i = width - 1; i >= 0; i--) {
+            s.append(hexTable[((int) (val >> (4 * i))) & 0xF]);
+        }
+        return "0x" + s.toString();
+    }
+
+    public static String toHex(long val) {
+        int width;
+        for (width = 16; width > 0; width--) {
+            if ((val >> (width - 1) * 4) != 0) {
+                break;
+            }
+        }
+        return toHex(val, width);
+    }
+
+    public static String toHex(int val) {
+        int width;
+        for (width = 8; width > 0; width--) {
+            if ((val >> (width - 1) * 4) != 0) {
+                break;
+            }
+        }
+        return toHex(val, width);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/i18n.properties	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,33 @@
+# Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+
+main.usage=\
+Usage: \n\
+to run an assembly tool: \n\
+\   $ java -jar {0} toolName [args...] \n\
+\   where toolName one of: jasm, jdis, jcoder, jdec, jcdec \n\
+to get the version: \n\
+\   $ java -jar {0} -version \n\
+to get this message \n\
+\   $ java -jar {0} -?|-h|-help\n
+
+main.error.no_arguments=No arguments provided!  See options above.
+main.error.unknown_tool=Tool name ''{0}'' unrecognized.  See usage above for possible tool choices.
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/AnnotationData.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * See JVMS3, section 4.8.16.
+ */
+class AnnotationData implements Data {
+
+    boolean invisible;
+    Argument typeCPX;
+    ArrayList<ElemValuePair> elemValuePairs;
+    int annotationLength = 0;
+
+    /**
+     * AnnotationElemValue
+     *
+     * Used to store Annotation Data
+     */
+    static public class ElemValuePair implements Data {
+
+        ConstantPool.ConstCell name;
+        Data value;
+
+        public ElemValuePair(ConstantPool.ConstCell name, Data value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            name.write(out);
+            value.write(out);
+        }
+
+        @Override
+        public int getLength() {
+            return 2 + value.getLength();
+        }
+    }
+
+    public AnnotationData(Argument typeCPX, boolean invisible) {
+        this.typeCPX = typeCPX;
+        this.elemValuePairs = new ArrayList<>();
+        this.invisible = invisible;
+    }
+
+    public void add(ElemValuePair elemValuePair) {
+        elemValuePairs.add(elemValuePair);
+        annotationLength += elemValuePair.getLength();
+    }
+
+    @Override
+    public void write(CheckedDataOutputStream out) throws IOException {
+        out.writeShort(typeCPX.arg);
+        out.writeShort(elemValuePairs.size());
+
+        for (Data pair : elemValuePairs) {
+            pair.write(out);
+        }
+    }
+
+    @Override
+    public int getLength() {
+        return 4 + annotationLength;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/Argument.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+/**
+ *
+ */
+class Argument {
+
+    static final int NotSet = -1;
+    int arg;
+
+    Argument() {
+        arg = NotSet;
+    }
+
+    Argument(int arg) {
+        this.arg = arg;
+    }
+
+    public int hashCode() {
+        return arg;
+    }
+
+    /**
+     * Compares this object to the specified object.
+     *
+     * @param obj the object to compare with
+     * @return true if the objects are the same; false otherwise.
+     */
+    public boolean equals(Object obj) {
+        throw new Parser.CompilerError("ConstCell.equals");
+    }
+
+    boolean isSet() {
+        return arg != NotSet;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/AttrData.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+
+/**
+ * AttrData
+ *
+ * AttrData is the base class for many attributes (or parts of attributes), and it is
+ * instantiated directly for simple attributes (like Synthetic or Deprecated).
+ */
+class AttrData implements Data {
+
+    private final ClassData clsData;
+    private final Argument attrNameCPX;
+
+    AttrData(ClassData cdata, String name) {
+        clsData = cdata;
+        attrNameCPX = cdata.pool.FindCellAsciz(name);
+    }
+
+    // full length of the attribute
+    // declared in Data
+    public int getLength() {
+        return 6 + attrLength();
+    }
+
+    // subclasses must redefine this
+    public int attrLength() {
+        return 0;
+    }
+
+    public void write(CheckedDataOutputStream out) throws IOException {
+        out.writeShort(attrNameCPX.arg);
+        out.writeInt(attrLength()); // attr len
+    }
+} // end class AttrData
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/BootstrapMethodData.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ *
+ */
+class BootstrapMethodData extends Argument implements Data {
+
+    ConstantPool.ConstCell bootstrapMethodHandle;
+    ArrayList<ConstantPool.ConstCell> arguments;
+    public int placeholder_index = -1;
+
+    public BootstrapMethodData(ConstantPool.ConstCell bsmHandle, ArrayList<ConstantPool.ConstCell> arguments) {
+        super();
+        this.bootstrapMethodHandle = bsmHandle;
+        this.arguments = arguments;
+    }
+
+    public BootstrapMethodData(int placeholder) {
+        super();
+        this.bootstrapMethodHandle = null;
+        this.arguments = null;
+        this.placeholder_index = placeholder;
+    }
+
+    public int getLength() {
+        return 4 + arguments.size() * 2;
+    }
+
+    public boolean isPlaceholder() {
+        return placeholder_index > -1;
+    }
+
+    public void write(CheckedDataOutputStream out) throws IOException {
+        out.writeShort(bootstrapMethodHandle.arg);
+        out.writeShort(arguments.size());
+
+        for (ConstantPool.ConstCell argument : arguments) {
+            out.writeShort(argument.arg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/CPXAttr.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+
+/**
+ * Constant Pool Index Attribute
+ */
+class CPXAttr extends AttrData {
+
+    Argument cell;
+
+    public CPXAttr(ClassData cls, String attrName, Argument cell) {
+        super(cls, attrName);
+        this.cell = cell;
+    }
+
+    public int attrLength() {
+        return 2;
+    }
+
+    public void write(CheckedDataOutputStream out) throws IOException {
+        super.write(out);  // attr name, attr len
+        out.writeShort(cell.arg);
+    }
+} // end class CPXAttr
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/CheckedDataOutputStream.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ *
+ */
+public interface CheckedDataOutputStream {
+
+    public void write(int b) throws IOException;
+
+    public void write(byte b[], int off, int len) throws IOException;
+
+    public void writeBoolean(boolean v) throws IOException;
+
+    public void writeByte(int v) throws IOException;
+
+    public void writeShort(int v) throws IOException;
+
+    public void writeChar(int v) throws IOException;
+
+    public void writeInt(int v) throws IOException;
+
+    public void writeLong(long v) throws IOException;
+
+    public void writeFloat(float v) throws IOException;
+
+    public void writeDouble(double v) throws IOException;
+
+    public void writeBytes(String s) throws IOException;
+
+    public void writeChars(String s) throws IOException;
+
+    public void writeUTF(String s) throws IOException;
+
+//       public int writeUTF(String str, DataOutput out) throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/ClassData.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,577 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MAJOR_VERSION;
+import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MINOR_VERSION;
+import static org.openjdk.asmtools.jasm.Tables.*;
+import java.io.*;
+import java.util.ArrayList;
+
+/**
+ * ClassData
+ *
+ * This is the main data structure for representing parsed class data. This structure
+ * renders directly to a class file.
+ *
+ */
+class ClassData extends MemberData {
+
+    /*-------------------------------------------------------- */
+    /* ClassData inner classes */
+
+    /*-------------------------------------------------------- */
+    /* ClassData Fields */
+    short major_version = DEFAULT_MAJOR_VERSION;
+    short minor_version = DEFAULT_MINOR_VERSION;
+    ConstantPool.ConstCell me, father;
+    String myClassName;
+    AttrData sourceFileNameAttr;
+    ArrayList<Argument> interfaces;
+    ArrayList<FieldData> fields = new ArrayList<>();
+    ArrayList<MethodData> methods = new ArrayList<>();
+    DataVectorAttr<InnerClassData> innerClasses = null;
+    DataVectorAttr<BootstrapMethodData> bootstrapMethodsAttr = null;
+    String mdl = null;
+    Environment env;
+    protected ConstantPool pool;
+
+    private static final String DEFAULT_EXTENSION = ".class";
+    String fileExtension = DEFAULT_EXTENSION;
+    public CDOutputStream cdos;
+
+    /*-------------------------------------------------------- */
+    /**
+     * init
+     *
+     * Initializes the ClassData.
+     *
+     * @param me The constant pool reference to this class
+     * @param father The constant pool reference to the super class
+     * @param interfaces A list of interfaces that this class implements
+     */
+    public final void init(int access, ConstantPool.ConstCell me, ConstantPool.ConstCell father, ArrayList<Argument> interfaces) {
+        this.access = access;
+
+        // normalize the modifiers to access flags
+        if (Modifiers.hasPseudoMod(access)) {
+            createPseudoMod();
+        }
+
+        this.me = me;
+        if (father == null) {
+            father = pool.FindCellClassByName("java/lang/Object");
+        }
+        this.father = father;
+        this.interfaces = interfaces;
+    }
+
+    /**
+     * default constructor
+     *
+     * @param env
+     */
+    public ClassData(Environment env) {
+        super(null, 0);  // for a class, these get inited in the super - later.
+        cls = this;
+
+        this.env = env;
+        pool = new ConstantPool(env);
+        cdos = new CDOutputStream();
+
+    }
+
+    /**
+     * canonical default constructor
+     *
+     * @param env The error reporting environment.
+     * @param major_version The major version that this class file supports.
+     * @param minor_version The minor version that this class file supports
+     */
+    public ClassData(Environment env, short major_version, short minor_version) {
+        this(env);
+        this.major_version = major_version;
+        this.minor_version = minor_version;
+    }
+
+    public ClassData(Environment env, int acc, ConstantPool.ConstCell me, ConstantPool.ConstCell father, ArrayList<Argument> impls) {
+        this(env);
+        init(acc, me, father, impls);
+    }
+
+
+    /* *********************************************** */
+    /**
+     * isInterface
+     *
+     * Predicate that describes if this class has an access flag indicating that it is an
+     * interface.
+     *
+     * @return True if the classes access flag indicates it is an interface.
+     */
+    public final boolean isInterface() {
+        return Modifiers.isInterface(access);
+    }
+
+
+    /*
+     * After a constant pool has been explicitly declared,
+     * this method links the Constant_InvokeDynamic constants
+     * with any bootstrap methods that they index in the
+     * Bootstrap Methods Attribute
+     */
+    protected void relinkBootstrapMethods() {
+        if (bootstrapMethodsAttr == null) {
+            return;
+        }
+
+        env.traceln("relinkBootstrapMethods");
+
+        for (ConstantPool.ConstCell cell : pool) {
+            ConstantPool.ConstValue ref = null;
+            if (cell != null) {
+                ref = cell.ref;
+            }
+            if (ref != null
+                    && ref.tag == ConstType.CONSTANT_INVOKEDYNAMIC) {
+                // Find only the Constant
+                ConstantPool.ConstValue_IndyPair refval = (ConstantPool.ConstValue_IndyPair) ref;
+                if (refval != null) {
+                    BootstrapMethodData bsmdata = refval.bsmData;
+                    // only care about BSM Data that were placeholders
+                    if (bsmdata != null && bsmdata.isPlaceholder()) {
+                        // find the real BSM Data at the index
+                        int bsmindex = bsmdata.placeholder_index;
+                        if (bsmindex < 0 || bsmindex > bootstrapMethodsAttr.size()) {
+                            // bad BSM index --
+                            // give a warning, but place the index in the arg anyway
+                            env.traceln("Warning: (ClassData.relinkBootstrapMethods()): Bad bootstrapMethods index: " + bsmindex);
+                            // env.error("const.bsmindex", bsmindex);
+                            bsmdata.arg = bsmindex;
+                        } else {
+
+                            BootstrapMethodData realbsmdata = bootstrapMethodsAttr.get(bsmindex);
+                            // make the IndyPairs BSM Data point to the one from the attribute
+                            refval.bsmData = realbsmdata;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    protected void numberBootstrapMethods() {
+        env.traceln("Numbering Bootstrap Methods");
+        if (bootstrapMethodsAttr == null) {
+            return;
+        }
+
+        int index = 0;
+        for (BootstrapMethodData data : bootstrapMethodsAttr) {
+            data.arg = index++;
+        }
+    }
+
+    /*-------------------------------------------------------- API */
+    public ConstantPool.ConstValue_Pair mkNape(ConstantPool.ConstCell name, ConstantPool.ConstCell sig) {
+        return new ConstantPool.ConstValue_Pair(ConstType.CONSTANT_NAMEANDTYPE, name, sig);
+    }
+
+    public ConstantPool.ConstValue_Pair mkNape(String name, String sig) {
+        return mkNape(pool.FindCellAsciz(name), pool.FindCellAsciz(sig));
+    }
+
+    public void setSourceFileName(String name) {
+    }
+
+    public FieldData addField(int access, ConstantPool.ConstValue_Pair nape) {
+        env.traceln(" [ClassData.addField]:  #" + nape.left.arg + ":#" + nape.right.arg);
+        FieldData res = new FieldData(this, access, nape);
+        fields.add(res);
+        return res;
+    }
+
+    public FieldData addField(int access, ConstantPool.ConstCell name, ConstantPool.ConstCell sig) {
+        return addField(access, mkNape(name, sig));
+    }
+
+    public FieldData addField(int access, String name, String type) {
+        return addField(access, pool.FindCellAsciz(name), pool.FindCellAsciz(type));
+    }
+
+    public ConstantPool.ConstCell LocalFieldRef(FieldData field) {
+        return pool.FindCell(ConstType.CONSTANT_FIELD, me, pool.FindCell(field.nape));
+    }
+
+    public ConstantPool.ConstCell LocalFieldRef(ConstantPool.ConstValue nape) {
+        return pool.FindCell(ConstType.CONSTANT_FIELD, me, pool.FindCell(nape));
+    }
+
+    public ConstantPool.ConstCell LocalFieldRef(ConstantPool.ConstCell name, ConstantPool.ConstCell sig) {
+        return LocalFieldRef(mkNape(name, sig));
+    }
+
+    public ConstantPool.ConstCell LocalFieldRef(String name, String sig) {
+        return LocalFieldRef(pool.FindCellAsciz(name), pool.FindCellAsciz(sig));
+    }
+
+    MethodData curMethod;
+
+    public MethodData StartMethod(int access, ConstantPool.ConstCell name, ConstantPool.ConstCell sig, ArrayList exc_table) {
+        EndMethod();
+        env.traceln(" [ClassData.StartMethod]:  #" + name.arg + ":#" + sig.arg);
+        curMethod = new MethodData(this, access, name, sig, exc_table);
+        methods.add(curMethod);
+        return curMethod;
+    }
+
+    public void EndMethod() {
+        curMethod = null;
+    }
+
+    public ConstantPool.ConstCell LocalMethodRef(ConstantPool.ConstValue nape) {
+        return pool.FindCell(ConstType.CONSTANT_METHOD, me, pool.FindCell(nape));
+    }
+
+    public ConstantPool.ConstCell LocalMethodRef(ConstantPool.ConstCell name, ConstantPool.ConstCell sig) {
+        return LocalMethodRef(mkNape(name, sig));
+    }
+
+    void addLocVarData(int opc, Argument arg) {
+    }
+
+    public void addInnerClass(int access, ConstantPool.ConstCell name, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass) {
+        env.traceln("addInnerClass (with indexes: Name (" + name.toString() + "), Inner (" + innerClass.toString() + "), Outer (" + outerClass.toString() + ").");
+        if (innerClasses == null) {
+            innerClasses = new DataVectorAttr<>(this, AttrTag.ATT_InnerClasses.parsekey());
+        }
+        innerClasses.add(new InnerClassData(access, name, innerClass, outerClass));
+    }
+
+    public void addBootstrapMethod(BootstrapMethodData bsmData) {
+        env.traceln("addBootstrapMethod");
+        if (bootstrapMethodsAttr == null) {
+            bootstrapMethodsAttr = new DataVectorAttr<>(this, AttrTag.ATT_BootstrapMethods.parsekey());
+        }
+        bootstrapMethodsAttr.add(bsmData);
+    }
+
+    public void endClass() {
+        sourceFileNameAttr = new CPXAttr(this,
+                AttrTag.ATT_SourceFile.parsekey(),
+                pool.FindCellAsciz(env.getSourceName()));
+        pool.NumberizePool();
+        pool.CheckGlobals();
+        numberBootstrapMethods();
+        try {
+            me = pool.uncheckedGetCell(me.arg);
+            env.traceln("me=" + me);
+            ConstantPool.ConstValue_Cell me_value = (ConstantPool.ConstValue_Cell) me.ref;
+            ConstantPool.ConstCell ascicell = me_value.cell;
+            env.traceln("ascicell=" + ascicell);
+            ConstantPool.ConstValue_String me_str = (ConstantPool.ConstValue_String) ascicell.ref;
+            myClassName = me_str.value;
+            env.traceln("--------------------------------------------");
+            env.traceln("-- Constant Pool --");
+            env.traceln("-------------------");
+            pool.printPool();
+            env.traceln("--------------------------------------------");
+            env.traceln(" ");
+            env.traceln(" ");
+            env.traceln("--------------------------------------------");
+            env.traceln("-- Inner Classes --");
+            env.traceln("-------------------");
+            printInnerClasses();
+
+        } catch (Throwable e) {
+            env.traceln("check name:" + e);
+            env.error("no.classname");
+            e.printStackTrace();
+        }
+    }
+
+    private void printInnerClasses() {
+        if (innerClasses != null) {
+            int i = 1;
+            for (InnerClassData entry : innerClasses) {
+                env.trace(" InnerClass[" + i + "]: (" + Modifiers.toString(entry.access, CF_Context.CTX_INNERCLASS) + "]), ");
+                env.trace("Name:  " + entry.name.toString() + " ");
+                env.trace("IC_info:  " + entry.innerClass.toString() + " ");
+                env.trace("OC_info:  " + entry.outerClass.toString() + " ");
+                env.traceln(" ");
+                i += 1;
+            }
+        } else {
+            env.traceln("<< NO INNER CLASSES >>");
+        }
+
+    }
+
+    /*====================================================== write */
+    public void write(CheckedDataOutputStream out) throws IOException {
+
+        // Write the header
+        out.writeInt(JAVA_MAGIC);
+        out.writeShort(minor_version);
+        out.writeShort(major_version);
+
+        pool.write(out);
+        out.writeShort(access); // & MM_CLASS; // Q
+        out.writeShort(me.arg);
+        out.writeShort(father.arg);
+
+        // Write the interface names
+        if (interfaces != null) {
+            out.writeShort(interfaces.size());
+            for (Argument intf : interfaces) {
+                out.writeShort(intf.arg);
+            }
+        } else {
+            out.writeShort(0);
+        }
+
+        // Write the fields
+        if (fields != null) {
+            out.writeShort(fields.size());
+            for (FieldData field : fields) {
+                field.write(out);
+            }
+        } else {
+            out.writeShort(0);
+        }
+
+        // Write the methods
+        if (methods != null) {
+            out.writeShort(methods.size());
+            for (MethodData method : methods) {
+                method.write(out);
+            }
+        } else {
+            out.writeShort(0);
+        }
+
+        // Write the attributes
+        DataVector attrs = new DataVector();
+        attrs.add(sourceFileNameAttr);
+        if (innerClasses != null) {
+            attrs.add(innerClasses);
+        }
+        if (syntheticAttr != null) {
+            attrs.add(syntheticAttr);
+        }
+        if (deprecatedAttr != null) {
+            attrs.add(deprecatedAttr);
+        }
+        if (annotAttrVis != null) {
+            attrs.add(annotAttrVis);
+        }
+        if (annotAttrInv != null) {
+            attrs.add(annotAttrInv);
+        }
+        if (type_annotAttrVis != null) {
+            attrs.add(type_annotAttrVis);
+        }
+        if (type_annotAttrInv != null) {
+            attrs.add(type_annotAttrInv);
+        }
+        if (bootstrapMethodsAttr != null) {
+            attrs.add(bootstrapMethodsAttr);
+        }
+        attrs.write(out);
+    } // end ClassData.write()
+
+    static char fileSeparator; //=System.getProperty("file.separator");
+
+    /**
+     * write to the directory passed with -d option
+     */
+    public void write(File destdir) throws IOException {
+        File outfile;
+        if (destdir == null) {
+            int startofname = myClassName.lastIndexOf("/");
+            if (startofname != -1) {
+                myClassName = myClassName.substring(startofname + 1);
+            }
+            outfile = new File(myClassName + fileExtension);
+        } else {
+            env.traceln("writing -d " + destdir.getPath());
+            if (fileSeparator == 0) {
+                fileSeparator = System.getProperty("file.separator").charAt(0);
+            }
+            if (fileSeparator != '/') {
+                myClassName = myClassName.replace('/', fileSeparator);
+            }
+            outfile = new File(destdir, myClassName + fileExtension);
+            File outdir = new File(outfile.getParent());
+            if (!outdir.exists() && !outdir.mkdirs()) {
+                env.error("cannot.write", outdir.getPath());
+                return;
+            }
+        }
+
+        DataOutputStream dos = new DataOutputStream(
+                new BufferedOutputStream(new FileOutputStream(outfile)));
+        cdos.setDataOutputStream(dos);
+        try {
+            write(cdos);
+        } finally {
+            dos.close();
+        }
+    }  // end write()
+
+    public void setByteLimit(int bytelimit) {
+        cdos.enable();
+        cdos.setLimit(bytelimit);
+    }
+
+    /**
+     * CDOutputStream
+     *
+     * This is a wrapper for DataOutputStream, used for debugging purposes. it allows
+     * writing the byte-stream of a class up to a given byte number.
+     */
+    static private class CDOutputStream implements CheckedDataOutputStream {
+
+        private int bytelimit;
+        private DataOutputStream dos;
+        public boolean enabled = false;
+
+        public CDOutputStream() {
+            dos = null;
+        }
+
+        public CDOutputStream(OutputStream out) {
+            setOutputStream(out);
+        }
+
+        public final void setOutputStream(OutputStream out) {
+            dos = new DataOutputStream(out);
+        }
+
+        public void setDataOutputStream(DataOutputStream dos) {
+            this.dos = dos;
+        }
+
+        public void setLimit(int lim) {
+            bytelimit = lim;
+        }
+
+        public void enable() {
+            enabled = true;
+        }
+
+        private synchronized void check(String loc) throws IOException {
+            if (enabled && dos.size() >= bytelimit) {
+                throw new IOException(loc);
+            }
+        }
+
+        @Override
+        public synchronized void write(int b) throws IOException {
+            dos.write(b);
+            check("Writing byte: " + b);
+        }
+
+        @Override
+        public synchronized void write(byte b[], int off, int len) throws IOException {
+            dos.write(b, off, len);
+            check("Writing byte-array: " + b);
+        }
+
+        @Override
+        public final void writeBoolean(boolean v) throws IOException {
+            dos.writeBoolean(v);
+            check("Writing writeBoolean: " + (v ? "true" : "false"));
+        }
+
+        @Override
+        public final void writeByte(int v) throws IOException {
+            dos.writeByte(v);
+            check("Writing writeByte: " + v);
+        }
+
+        @Override
+        public void writeShort(int v) throws IOException {
+            dos.writeShort(v);
+            check("Writing writeShort: " + v);
+        }
+
+        @Override
+        public void writeChar(int v) throws IOException {
+            dos.writeChar(v);
+            check("Writing writeChar: " + v);
+        }
+
+        @Override
+        public void writeInt(int v) throws IOException {
+            dos.writeInt(v);
+            check("Writing writeInt: " + v);
+        }
+
+        @Override
+        public void writeLong(long v) throws IOException {
+            dos.writeLong(v);
+            check("Writing writeLong: " + v);
+        }
+
+        @Override
+        public void writeFloat(float v) throws IOException {
+            dos.writeFloat(v);
+            check("Writing writeFloat: " + v);
+        }
+
+        @Override
+        public void writeDouble(double v) throws IOException {
+            dos.writeDouble(v);
+            check("Writing writeDouble: " + v);
+        }
+
+        @Override
+        public void writeBytes(String s) throws IOException {
+            dos.writeBytes(s);
+            check("Writing writeBytes: " + s);
+        }
+
+        @Override
+        public void writeChars(String s) throws IOException {
+            dos.writeChars(s);
+            check("Writing writeChars: " + s);
+        }
+
+        @Override
+        public void writeUTF(String s) throws IOException {
+            dos.writeUTF(s);
+            check("Writing writeUTF: " + s);
+        }
+        /*
+         public int writeUTF(String str, DataOutput out) throws IOException{
+         int ret = dos.writeUTF(str, out);
+         check("Writing writeUTF: " + str);
+         return ret;
+         }
+         * */
+
+    }
+
+}// end class ClassData
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/CodeAttr.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import org.openjdk.asmtools.jasm.OpcodeTables.Opcode;
+import static org.openjdk.asmtools.jasm.RuntimeConstants.SPLIT_VERIFIER_CFV;
+import org.openjdk.asmtools.jasm.Tables.AttrTag;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+class CodeAttr extends AttrData {
+
+    /*-------------------------------------------------------- */
+    /* CodeAttr inner classes */
+    static public class Local extends Argument {
+
+        String name;
+        boolean defd = false, refd = false;
+
+        public Local(String name) {
+            this.name = name;
+        }
+    }
+
+    /**
+     *
+     */
+    static public class Label extends Local {
+
+        public Label(String name) {
+            super(name);
+        }
+    }
+
+    /**
+     *
+     */
+    class LocVarData extends Local implements Data {
+
+        // arg means slot
+
+        short start_pc, length;
+        ConstantPool.ConstCell name_cpx, sig_cpx;
+
+        public LocVarData(String name) {
+            super(name);
+        }
+
+        @Override
+        public int getLength() {
+            return 10;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeShort(start_pc);
+            out.writeShort(length);
+            out.writeShort(name_cpx.arg);
+            out.writeShort(sig_cpx.arg);
+            out.writeShort(arg);
+        }
+    }
+
+    /**
+     *
+     */
+    class LineNumData implements Data {
+
+        int start_pc, line_number;
+
+        public LineNumData(int start_pc, int line_number) {
+            this.start_pc = start_pc;
+            this.line_number = line_number;
+        }
+
+        @Override
+        public int getLength() {
+            return 4;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeShort(start_pc);
+            out.writeShort(line_number);
+        }
+    }
+
+    /**
+     *
+     */
+    class Trap extends Local {
+
+        int start_pc = Argument.NotSet, end_pc = Argument.NotSet;
+        int pos;
+
+        Trap(int pos, String name) {
+            super(name);
+            this.pos = pos;
+        }
+    }
+
+    /**
+     *
+     */
+    class TrapData implements Data {
+
+        int pos;
+        Trap trap;
+        int handler_pc;
+        Argument catchType;
+
+        public TrapData(int pos, Trap trap, int handler_pc, Argument catchType) {
+            this.pos = pos;
+            this.trap = trap;
+            this.handler_pc = handler_pc;
+            this.catchType = catchType;
+        }
+
+        @Override
+        public int getLength() {
+            return 8; // add the length of number of elements
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeShort(trap.start_pc);
+            out.writeShort(trap.end_pc);
+            out.writeShort(handler_pc);
+            if (catchType.isSet()) {
+                out.writeShort(catchType.arg);
+            } else {
+                out.writeShort(0);
+            }
+        }
+    }  // end TrapData
+
+
+    /*-------------------------------------------------------- */
+    /* CodeAttr Fields */
+    protected MethodData mtd;
+    protected ClassData cls;
+    protected Environment env;
+    protected Argument max_stack, max_locals;
+    protected Instr zeroInstr, lastInstr;
+    protected int cur_pc = 0;
+    protected DataVector<TrapData> trap_table
+            = new DataVector<>(0); // TrapData
+    protected DataVectorAttr<LineNumData> lin_num_tb; // LineNumData
+    protected int lastln = 0;
+    protected DataVectorAttr<LocVarData> loc_var_tb;  // LocVarData
+    protected DataVector<DataVectorAttr<? extends Data>> attrs;
+    //   protected iVector                         slots;
+    protected ArrayList<Integer> slots;
+    protected HashMap<String, LocVarData> locvarsHash;
+    protected HashMap<String, Label> labelsHash;
+    protected HashMap<String, Trap> trapsHash;
+    protected StackMapData curMapEntry = null;
+    protected DataVectorAttr<StackMapData> stackMap;
+    /*-------------------------------------------------------- */
+
+    public CodeAttr(MethodData mtd, int pos, int paramcnt, Argument max_stack, Argument max_locals) {
+        super(mtd.cls, AttrTag.ATT_Code.parsekey());
+        this.mtd = mtd;
+        this.cls = mtd.cls;
+        this.env = cls.env;
+        this.max_stack = max_stack;
+        this.max_locals = max_locals;
+        lastInstr = zeroInstr = new Instr();
+        trap_table = new DataVector<>(0); // TrapData
+        attrs = new DataVector<>();
+        if (env.debugInfoFlag) {
+            lin_num_tb = new DataVectorAttr<>(cls, AttrTag.ATT_LineNumberTable.parsekey());
+            attrs.add(lin_num_tb);
+        }
+//        slots = new iVector(paramcnt);
+        slots = new ArrayList<>(paramcnt);
+        for (int k = 0; k < paramcnt; k++) {
+//            slots.setElement(1, k);
+            slots.add(k, 1);
+        }
+    }
+
+    void endCode() {
+        checkTraps();
+        checkLocVars();
+        checkLabels();
+    }
+
+    /* -------------------------------------- Traps */
+    Trap trapDecl(int pos, String name) {
+        Trap local;
+        if (trapsHash == null) {
+            trapsHash = new HashMap<>(10);
+            local = null;
+        } else {
+            local = trapsHash.get(name);
+        }
+        if (local == null) {
+            local = new Trap(pos, name);
+            trapsHash.put(name, local);
+        }
+        return local;
+    }
+
+    void beginTrap(int pos, String name) {
+        Trap trap = trapDecl(pos, name);
+        if (trap.start_pc != Argument.NotSet) {
+            env.error("trap.tryredecl", name);
+            return;
+        }
+        trap.start_pc = cur_pc;
+    }
+
+    void endTrap(int pos, String name) {
+        Trap trap = trapDecl(pos, name);
+        if (trap.end_pc != Argument.NotSet) {
+            env.error("trap.endtryredecl", name);
+            return;
+        }
+        trap.end_pc = cur_pc;
+    }
+
+    void trapHandler(int pos, String name, Argument type) {
+        Trap trap = trapDecl(pos, name);
+        trap.refd = true;
+        TrapData trapData = new TrapData(pos, trap, cur_pc, type);
+        trap_table.addElement(trapData);
+    }
+
+    void checkTraps() {
+        if (trapsHash == null) {
+            return;
+        }
+        for (Trap trap : trapsHash.values()) {
+            if (!trap.refd) {
+                env.error(trap.pos, "warn.trap.notref", trap.name);
+            }
+        }
+
+        for (TrapData trapData : trap_table) {
+            Trap trapLabel = trapData.trap;
+            if (trapLabel.start_pc == Argument.NotSet) {
+                env.error(trapData.pos, "trap.notry", trapLabel.name);
+            }
+            if (trapLabel.end_pc == Argument.NotSet) {
+                env.error(trapData.pos, "trap.noendtry", trapLabel.name);
+            }
+        }
+    }
+
+    /* -------------------------------------- Labels */
+    Label labelDecl(String name) {
+        Label local;
+        if (labelsHash == null) {
+            labelsHash = new HashMap<>(10);
+            local = null;
+        } else {
+            local = labelsHash.get(name);
+        }
+        if (local == null) {
+            local = new Label(name);
+            labelsHash.put(name, local);
+        }
+        return local;
+    }
+
+    public Label LabelDef(int pos, String name) {
+        Label label = labelDecl(name);
+        if (label.defd) {
+            env.error(pos, "label.redecl", name);
+            return null;
+        }
+        label.defd = true;
+        label.arg = cur_pc;
+        return label;
+    }
+
+    public Label LabelRef(String name) {
+        Label label = labelDecl(name);
+        label.refd = true;
+        return label;
+    }
+
+    void checkLabels() {
+        if (labelsHash == null) {
+            return;
+        }
+
+        for (Label local : labelsHash.values()) {
+            // check that every label is defined
+            if (!local.defd) {
+                env.error("label.undecl", local.name);
+            }
+        }
+    }
+
+    /* -------------------------------------- Variables */
+    LocVarData locvarDecl(String name) {
+        LocVarData local;
+        if (locvarsHash == null) {
+            locvarsHash = new HashMap<>(10);
+            local = null;
+        } else {
+            local = locvarsHash.get(name);
+        }
+        if (local == null) {
+            local = new LocVarData(name);
+            locvarsHash.put(name, local);
+        }
+        return local;
+    }
+
+    public void LocVarDataDef(int slot) {
+//        slots.setElement(1, slot);
+        slots.set(slot, 1);
+        if ((max_locals != null) && (max_locals.arg < slots.size())) {
+
+//        if ((max_locals != null) && (max_locals.arg < slots.length)) {
+            env.error("warn.illslot", new Integer(slot).toString());
+        }
+    }
+
+    public void LocVarDataDef(String name, ConstantPool.ConstCell type) {
+        LocVarData locvar = locvarDecl(name);
+        if (locvar.defd) {
+            env.error("locvar.redecl", name);
+            return;
+        }
+        locvar.defd = true;
+        locvar.start_pc = (short) cur_pc;
+        locvar.name_cpx = cls.pool.FindCellAsciz(name);
+        locvar.sig_cpx = type;
+        int k;
+        findSlot:
+        {
+            /*
+             for (k = 0; k < slots.length; k++) {
+             if (slots.data[k] == 0) {
+             break findSlot;
+             }
+             }
+             k = slots.length;
+             *
+             */
+
+            for (k = 0; k < slots.size(); k++) {
+                if (slots.get(k) == 0) {
+                    break findSlot;
+                }
+            }
+            k = slots.size();
+        }
+        LocVarDataDef(k);
+        locvar.arg = k;
+        if (loc_var_tb == null) {
+            loc_var_tb = new DataVectorAttr<>(cls, AttrTag.ATT_LocalVariableTable.parsekey());
+            attrs.add(loc_var_tb);
+        }
+        loc_var_tb.add(locvar);
+    }
+
+    public Argument LocVarDataRef(String name) {
+        LocVarData locvar = locvarDecl(name);
+        if (!locvar.defd) {
+            env.error("locvar.undecl", name);
+            locvar.defd = true; // to avoid multiple error messages
+        }
+        locvar.refd = true;
+        return locvar;
+    }
+
+    public void LocVarDataEnd(int slot) {
+//        slots.data[slot] = 0;
+        slots.set(slot, 0);
+    }
+
+    public void LocVarDataEnd(String name) {
+        LocVarData locvar = locvarsHash.get(name);
+        if (locvar == null) {
+            env.error("locvar.undecl", name);
+            return;
+        } else if (!locvar.defd) {
+            env.error("locvar.undecl", name);
+            return;
+        }
+        locvar.length = (short) (cur_pc - locvar.start_pc);
+//        slots.data[locvar.arg] = 0;
+
+        slots.set(locvar.arg, 0);
+//      locvarsHash.put(name, null); unfortunately, prohibited
+        locvarsHash.put(name, new LocVarData(name));
+    }
+
+    void checkLocVars() {
+        if (locvarsHash == null) {
+            return;
+        }
+        for (LocVarData locvar : locvarsHash.values()) {
+            if (!locvar.defd) {
+                continue;
+            } // this is false locvar
+            // set end of scope, if not set
+            if (slots.get(locvar.arg) == 1) {
+//            if (slots.data[locvar.arg] == 1) {
+                locvar.length = (short) (cur_pc - locvar.start_pc);
+//                slots.data[locvar.arg] = 0;
+                slots.set(locvar.arg, 0);
+            }
+        }
+    }
+
+    /* -------------------------------------- StackMap */
+    public StackMapData getStackMap() {
+        if (curMapEntry == null) {
+            curMapEntry = new StackMapData(env);
+            if (cls.major_version >= SPLIT_VERIFIER_CFV) {
+                curMapEntry.setIsStackMapTable(true);
+            }
+        }
+        return curMapEntry;
+    }
+
+    /*====================================================== Instr */
+    void addInstr(int mnenoc_pos, Opcode opcode, Argument arg, Object arg2) {
+        Instr newInstr = new Instr(cur_pc, cls.env.pos, opcode, arg, arg2);
+        lastInstr.next = newInstr;
+        lastInstr = newInstr;
+        int len = opcode.length();
+        switch (opcode) {
+            case opc_tableswitch:
+                len = ((SwitchTable) arg2).recalcTableSwitch(cur_pc);
+                break;
+            case opc_lookupswitch:
+                len = ((SwitchTable) arg2).calcLookupSwitch(cur_pc);
+                break;
+            case opc_ldc:
+                ((ConstantPool.ConstCell) arg).setRank(0);
+                break;
+            default:
+                if (arg instanceof ConstantPool.ConstCell) {
+                    ((ConstantPool.ConstCell) arg).setRank(1);
+                }
+        }
+        if (env.debugInfoFlag) {
+            int ln = env.lineNumber(mnenoc_pos);
+            if (ln != lastln) { // only one entry in lin_num_tb per line
+                lin_num_tb.add(new LineNumData(cur_pc, ln));
+                lastln = ln;
+            }
+        }
+        if (curMapEntry != null) {
+            curMapEntry.pc = cur_pc;
+            StackMapData prevStackFrame = null;
+            if (stackMap == null) {
+                if (cls.major_version >= SPLIT_VERIFIER_CFV) {
+                    stackMap = new DataVectorAttr<>(cls, AttrTag.ATT_StackMapTable.parsekey());
+                } else {
+                    stackMap = new DataVectorAttr<>(cls, AttrTag.ATT_StackMap.parsekey());
+                }
+                attrs.add(stackMap);
+            } else if (stackMap.size() > 0) {
+                prevStackFrame = stackMap.get(stackMap.size() - 1);
+            }
+            curMapEntry.setOffset(prevStackFrame);
+            stackMap.add(curMapEntry);
+            curMapEntry = null;
+        }
+
+        cur_pc += len;
+    }
+
+    /*====================================================== Attr interface */
+    // subclasses must redefine this
+    @Override
+    public int attrLength() {
+        return 2 + 2 + 4 // for max_stack, max_locals, and cur_pc
+                + cur_pc //      + 2+trap_table.size()*8
+                + trap_table.getLength() + attrs.getLength();
+
+    }
+
+    @Override
+    public void write(CheckedDataOutputStream out)
+            throws IOException, Parser.CompilerError {
+        int mxstck = (max_stack != null) ? max_stack.arg : 0;
+//        int mxloc = (max_locals != null) ? max_locals.arg : slots.length;
+        int mxloc = (max_locals != null) ? max_locals.arg : slots.size();
+        super.write(out);  // attr name, attr len
+        out.writeShort(mxstck);
+        out.writeShort(mxloc);
+        out.writeInt(cur_pc);
+        for (Instr instr = zeroInstr.next; instr != null; instr = instr.next) {
+            instr.write(out, env);
+        }
+
+        trap_table.write(out);
+
+        attrs.write(out);
+    }
+} // end CodeAttr
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/ConstantPool.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,1198 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import org.openjdk.asmtools.jasm.Tables.ConstType;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * ConstantPool
+ *
+ * ConstantPool is the class responsible for maintaining constants for a given class file.
+ *
+ */
+public class ConstantPool implements Iterable<ConstantPool.ConstCell> {
+
+
+    /*-------------------------------------------------------- */
+    /* ConstantPool Inner Classes */
+    /**
+     * ConstValue
+     *
+     * A (typed) tagged value in the constant pool.
+     */
+    static public class ConstValue {
+
+        protected ConstType tag;
+        protected boolean isSet = false;
+        private boolean vizited = false;
+
+        public ConstValue(ConstType tag) {
+            this.tag = tag;
+        }
+
+        public int size() {
+            return 1;
+        }
+
+        public boolean hasValue() {
+            return isSet;
+        }
+
+        /**
+         * Compute the hash-code, based on the value of the native (_hashCode()) hashcode.
+         */
+        @Override
+        public int hashCode() {
+            if (vizited) {
+                throw new Parser.CompilerError("CV hash:" + this);
+            }
+            vizited = true;
+            int res = _hashCode() + tag.value() * 1023;
+            vizited = false;
+            return res;
+        }
+
+        // sub-classes override this.
+        // this is the default for getting a hash code.
+        protected int _hashCode() {
+            return 37;
+        }
+
+        /**
+         * Compares this object to the specified object.
+         *
+         * Sub-classes must override this
+         *
+         * @param obj the object to compare with
+         * @return true if the objects are the same; false otherwise.
+         */
+        @Override
+        public boolean equals(Object obj) {
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            String tagstr = tag.printval();
+            String retval = "";
+            if (tagstr == null) {
+                return "BOGUS_TAG:" + tag;
+            }
+
+            String valueStr = _toString();
+            if (valueStr != null) {
+                retval = "<" + tagstr + " " + valueStr + ">";
+            } else {
+                retval = "<" + tagstr + ">";
+            }
+            return retval;
+        }
+
+        protected String _toString() {
+            return "";
+        }
+
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeByte(tag.value());
+        }
+    } // end ConstValue
+
+    /**
+     * ConstValue
+     *
+     * A (typed) tagged value in the constant pool.
+     */
+    static public class ConstValue_Zero extends ConstValue {
+
+        public ConstValue_Zero() {
+            super(ConstType.CONSTANT_ZERO);
+            isSet = false;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            throw new Parser.CompilerError("Trying to write Constant 0.");
+        }
+    }
+
+    /**
+     * ConstValue
+     *
+     * A (typed) tagged value in the constant pool.
+     */
+    static public class ConstValue_String extends ConstValue {
+
+        String value;
+
+        public ConstValue_String(String value) {
+            super(ConstType.CONSTANT_UTF8);
+            this.value = value;
+            isSet = (value != null);
+        }
+
+        @Override
+        protected String _toString() {
+            return value;
+        }
+
+        @Override
+        protected int _hashCode() {
+            return value.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if ((obj == null) || !(obj instanceof ConstValue_String)) {
+                return false;
+            }
+            ConstValue_String dobj = (ConstValue_String) obj;
+            if (tag != dobj.tag) {
+                return false;
+            }
+            return value.equals(dobj.value);
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            super.write(out);
+            out.writeUTF(value);
+        }
+    }
+
+    /**
+     * ConstValue
+     *
+     * A (typed) tagged value in the constant pool.
+     */
+    static public class ConstValue_Integer extends ConstValue {
+
+        Integer value;
+
+        public ConstValue_Integer(ConstType tag, Integer value) {
+            super(tag);
+            this.value = value;
+            isSet = (value != null);
+        }
+
+        @Override
+        protected String _toString() {
+            return value.toString();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if ((obj == null) || !(obj instanceof ConstValue_Integer)) {
+                return false;
+            }
+            ConstValue_Integer dobj = (ConstValue_Integer) obj;
+            if (tag != dobj.tag) {
+                return false;
+            }
+            return value.equals(dobj.value);
+        }
+
+        @Override
+        protected int _hashCode() {
+            return value.hashCode();
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            super.write(out);
+            out.writeInt(value.intValue());
+        }
+    }
+
+    /**
+     * ConstValue
+     *
+     * A (typed) tagged value in the constant pool.
+     */
+    static public class ConstValue_Long extends ConstValue {
+
+        Long value;
+
+        public ConstValue_Long(ConstType tag, Long value) {
+            super(tag);
+            this.value = value;
+            isSet = (value != null);
+        }
+
+        @Override
+        public int size() {
+            return 2;
+        }
+
+        @Override
+        protected String _toString() {
+            return value.toString();
+        }
+
+//        @Override
+//        public Object value() { return value; }
+        @Override
+        public boolean equals(Object obj) {
+            if ((obj == null) || !(obj instanceof ConstValue_Long)) {
+                return false;
+            }
+            ConstValue_Long dobj = (ConstValue_Long) obj;
+            if (tag != dobj.tag) {
+                return false;
+            }
+            return value.equals(dobj.value);
+        }
+
+        @Override
+        protected int _hashCode() {
+            return value.hashCode();
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            super.write(out);
+            out.writeLong(value.longValue());
+        }
+    }
+
+    /**
+     * ConstValue
+     *
+     * A (typed) tagged value in the constant pool.
+     */
+    static public class ConstValue_Cell extends ConstValue {
+
+        ConstCell cell;
+
+        public ConstValue_Cell(ConstType tag, ConstCell cell) {
+            super(tag);
+            this.cell = cell;
+            isSet = (cell != null);
+        }
+
+        @Override
+        protected String _toString() {
+            return cell.toString();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if ((obj == null) || !(obj instanceof ConstValue_Cell)) {
+                return false;
+            }
+            ConstValue_Cell dobj = (ConstValue_Cell) obj;
+            if (tag != dobj.tag) {
+                return false;
+            }
+            return cell.equals(dobj.cell);
+        }
+
+        @Override
+        protected int _hashCode() {
+            return cell.hashCode();
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            super.write(out);
+            cell.write(out);
+        }
+    }
+
+    /**
+     * ConstValue
+     *
+     * A (typed) tagged value in the constant pool.
+     */
+    static public class ConstValue_Pair extends ConstValue {
+
+        ConstCell left, right;
+
+        public ConstValue_Pair(ConstType tag, ConstCell left, ConstCell right) {
+            super(tag);
+            this.left = left;
+            this.right = right;
+            isSet = (left != null && right != null);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if ((obj == null) || !(obj instanceof ConstValue_Pair)) {
+                return false;
+            }
+            ConstValue_Pair dobj = (ConstValue_Pair) obj;
+            if (tag != dobj.tag) {
+                return false;
+            }
+            return (dobj.left == left) && (dobj.right == right);
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + "{" + left + "," + right + "}";
+        }
+
+        @Override
+        protected int _hashCode() {
+            return left.hashCode() * right.hashCode();
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            super.write(out);
+            if (tag == ConstType.CONSTANT_METHODHANDLE) {
+                out.writeByte(left.arg); // write subtag value
+            } else {
+                out.writeShort(left.arg);
+            }
+            out.writeShort(right.arg);
+        }
+    }
+
+    /**
+     * ConstValue
+     *
+     * A (typed) tagged value in the constant pool.
+     */
+    static public class ConstValue_IndyPair extends ConstValue {
+
+        BootstrapMethodData bsmData;
+        ConstantPool.ConstCell napeCell;
+
+        public ConstValue_IndyPair(BootstrapMethodData bsmdata, ConstCell napeCell) {
+            super(ConstType.CONSTANT_INVOKEDYNAMIC);
+            this.bsmData = bsmdata;
+            this.napeCell = napeCell;
+            isSet = (bsmdata != null && napeCell != null);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if ((obj == null) || !(obj instanceof ConstValue_IndyPair)) {
+                return false;
+            }
+
+            ConstValue_IndyPair iobj = (ConstValue_IndyPair) obj;
+            return (iobj.bsmData == bsmData) && (iobj.napeCell == napeCell);
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + "{" + bsmData + "," + napeCell + "}";
+        }
+
+        @Override
+        protected int _hashCode() {
+            if (bsmData.isPlaceholder()) {
+                return napeCell.hashCode();
+            }
+            return bsmData.hashCode() * napeCell.hashCode();
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            super.write(out);
+            out.writeShort(bsmData.arg);
+            out.writeShort(napeCell.arg);
+        }
+    }
+
+    /*-------------------------------------------------------- */
+    /* ConstantPool Inner Classes */
+    /**
+     * ConstantCell
+     *
+     * ConstantCell is a type of data that can be in a constant pool.
+     */
+    static public class ConstCell extends Argument implements Data {
+
+        ConstValue ref;
+        int rank = 2; // 0 - highest - ref from ldc, 1 - any ref, 2 - no ref
+
+        ConstCell(int arg, ConstValue ref) {
+            this.arg = arg;
+            this.ref = ref;
+        }
+
+        ConstCell(ConstValue ref) {
+            this(NotSet, ref);
+        }
+
+        ConstCell(int arg) {
+            this(arg, null);
+        }
+
+        @Override
+        public int getLength() {
+            return 2;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeShort(arg);
+        }
+
+        public void setRank(int rank) {
+            this.rank = rank;
+        }
+
+        @Override
+        public int hashCode() {
+            if (arg == NotSet) {
+                if (ref != null) {
+                    return ref.hashCode();
+                } else {
+                    throw new Parser.CompilerError("Can't generate Hash Code, Null ConstCell Reference.");
+                }
+            }
+            return arg;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            return obj == this;
+        }
+
+        public boolean isUnset() {
+            return (arg == NotSet) && (ref == null);
+        }
+
+        @Override
+        public String toString() {
+            return "#" + arg + "=" + ref;
+        }
+    }
+
+    /**
+     * CPVisitor
+     *
+     * CPVisitor base class defining a visitor for decoding constants.
+     */
+    public static class CPTagVisitor<R> implements Constants {
+
+        public CPTagVisitor() {
+        }
+
+        public final R visit(ConstType tag) {
+            R retVal = null;
+            switch (tag) {
+                case CONSTANT_UTF8:
+                    retVal = visitUTF8(tag);
+                    break;
+                case CONSTANT_INTEGER:
+                    retVal = visitInteger(tag);
+                    break;
+                case CONSTANT_FLOAT:
+                    retVal = visitFloat(tag);
+                    break;
+                case CONSTANT_DOUBLE:
+                    retVal = visitDouble(tag);
+                    break;
+                case CONSTANT_LONG:
+                    retVal = visitLong(tag);
+                    break;
+                case CONSTANT_METHODTYPE:
+                    retVal = visitMethodtype(tag);
+                    break;
+                case CONSTANT_STRING:
+                    retVal = visitString(tag);
+                    break;
+                case CONSTANT_CLASS:
+                    retVal = visitClass(tag);
+                    break;
+                case CONSTANT_METHOD:
+                    retVal = visitMethod(tag);
+                    break;
+                case CONSTANT_FIELD:
+                    retVal = visitField(tag);
+                    break;
+                case CONSTANT_INTERFACEMETHOD:
+                    retVal = visitInterfacemethod(tag);
+                    break;
+                case CONSTANT_NAMEANDTYPE:
+                    retVal = visitNameandtype(tag);
+                    break;
+                case CONSTANT_METHODHANDLE:
+                    retVal = visitMethodhandle(tag);
+                    break;
+                case CONSTANT_INVOKEDYNAMIC:
+                    retVal = visitInvokedynamic(tag);
+                    break;
+//                case CONSTANT_INVOKEDYNAMIC_TRANS:
+//                    retVal = visitInvokedynamicTrans(tag);
+//                    break;
+                default:
+                    visitDefault(tag);
+            }
+            return retVal;
+        }
+
+        public R visitUTF8(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitInteger(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitFloat(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitDouble(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitLong(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitMethodtype(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitString(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitClass(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitMethod(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitField(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitInterfacemethod(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitNameandtype(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitMethodhandle(ConstType tag) {
+            return null;
+        }
+
+        ;
+        public R visitInvokedynamic(ConstType tag) {
+            return null;
+        }
+
+        ;
+//        public R visitInvokedynamicTrans() { return null; };
+        public void visitDefault(ConstType tag) {
+        }
+    ;
+
+    }
+
+    /**
+    * CPVisitor
+    *
+    * CPVisitor base class defining a visitor for decoding constants.
+    */
+   public static class CPVisitor<R> implements Constants {
+
+        public CPVisitor() {
+        }
+
+        public final R visit(ConstValue val) {
+            R retVal = null;
+            ConstType tag = val.tag;
+            switch (tag) {
+                case CONSTANT_UTF8:
+                    retVal = visitUTF8((ConstValue_String) val);
+                    break;
+                case CONSTANT_INTEGER:
+                    retVal = visitInteger((ConstValue_Integer) val);
+                    break;
+                case CONSTANT_FLOAT:
+                    retVal = visitFloat((ConstValue_Integer) val);
+                    break;
+                case CONSTANT_DOUBLE:
+                    retVal = visitDouble((ConstValue_Long) val);
+                    break;
+                case CONSTANT_LONG:
+                    retVal = visitLong((ConstValue_Long) val);
+                    break;
+                case CONSTANT_METHODTYPE:
+                    retVal = visitMethodtype((ConstValue_Cell) val);
+                    break;
+                case CONSTANT_STRING:
+                    retVal = visitString((ConstValue_Cell) val);
+                    break;
+                case CONSTANT_CLASS:
+                    retVal = visitClass((ConstValue_Cell) val);
+                    break;
+                case CONSTANT_METHOD:
+                    retVal = visitMethod((ConstValue_Pair) val);
+                    break;
+                case CONSTANT_FIELD:
+                    retVal = visitField((ConstValue_Pair) val);
+                    break;
+                case CONSTANT_INTERFACEMETHOD:
+                    retVal = visitInterfacemethod((ConstValue_Pair) val);
+                    break;
+                case CONSTANT_NAMEANDTYPE:
+                    retVal = visitNameandtype((ConstValue_Pair) val);
+                    break;
+                case CONSTANT_METHODHANDLE:
+                    retVal = visitMethodhandle((ConstValue_Pair) val);
+                    break;
+                case CONSTANT_INVOKEDYNAMIC:
+                    retVal = visitInvokedynamic((ConstValue_IndyPair) val);
+                    break;
+//                case CONSTANT_INVOKEDYNAMIC_TRANS:
+//                    retVal = visitInvokedynamicTrans((ConstValue_Pair) val);
+//                    break;
+                default:
+                    visitDefault(tag);
+            }
+            return retVal;
+        }
+
+        public R visitUTF8(ConstValue_String p) {
+            return null;
+        }
+
+        ;
+        public R visitInteger(ConstValue_Integer p) {
+            return null;
+        }
+
+        ;
+        public R visitFloat(ConstValue_Integer p) {
+            return null;
+        }
+
+        ;
+        public R visitDouble(ConstValue_Long p) {
+            return null;
+        }
+
+        ;
+        public R visitLong(ConstValue_Long p) {
+            return null;
+        }
+
+        ;
+        public R visitMethodtype(ConstValue_Cell p) {
+            return null;
+        }
+
+        ;
+        public R visitString(ConstValue_Cell p) {
+            return null;
+        }
+
+        ;
+        public R visitClass(ConstValue_Cell p) {
+            return null;
+        }
+
+        ;
+        public R visitMethod(ConstValue_Pair p) {
+            return null;
+        }
+
+        ;
+        public R visitField(ConstValue_Pair p) {
+            return null;
+        }
+
+        ;
+        public R visitInterfacemethod(ConstValue_Pair p) {
+            return null;
+        }
+
+        ;
+        public R visitNameandtype(ConstValue_Pair p) {
+            return null;
+        }
+
+        ;
+        public R visitMethodhandle(ConstValue_Pair p) {
+            return null;
+        }
+
+        ;
+        public R visitInvokedynamic(ConstValue_IndyPair p) {
+            return null;
+        }
+
+        ;
+//        public R visitInvokedynamicTrans(ConstValue_Pair p) { return null; };
+        public void visitDefault(ConstType tag) {
+        }
+    ;
+
+    }
+
+
+
+  /*-------------------------------------------------------- */
+  /* Constant Pool Fields */
+
+    private ArrayList<ConstCell> pool = new ArrayList<>(20);
+
+    private final ConstValue ConstValue0
+            = new ConstValue_String("");
+//    private final ConstValue ConstValue0 =
+//            new ConstValue(CONSTANT_UTF8, "");
+    private final ConstCell nullConst
+            = new ConstCell(null);
+    private final ConstCell constant_0
+            = new ConstCell(new ConstValue_Zero());
+//    private final ConstCell constant_0 =
+//            new ConstCell(new ConstValue(CONSTANT_ZERO, null));
+
+    // For hashing by value
+    Hashtable<ConstValue, ConstCell> cpoolHashByValue
+            = new Hashtable<>(40);
+
+    public Environment env;
+
+    private static boolean debugCP = false;
+
+    /*-------------------------------------------------------- */
+    /**
+     * main constructor
+     *
+     * @param env The error reporting environment
+     */
+    public ConstantPool(Environment env) {
+        this.env = env;
+        pool.add(constant_0);
+
+    }
+
+    public void debugStr(String s) {
+        if (debugCP) {
+            env.traceln(s);
+        }
+    }
+
+    @Override
+    public Iterator<ConstCell> iterator() {
+        return pool.iterator();
+    }
+
+
+    /*
+     * Fix Refs in constant pool.
+     *
+     * This is used when scanning JASM files produced from JDis with the verbose
+     * option (eg. where the constant pool is declared in the jasm itself).  In
+     * this scenario, we need two passes - the first pass to scan the entries
+     * (which creates constant references with indexes, but no reference values);
+     * and the second pass, which links references to existing constants.
+     *
+     */
+    public void fixRefsInPool() {
+        // used to fix CP refs when a constant pool is constructed by refs alone.
+        env.traceln("Fixing CP for explicit Constant Entries.");
+        int i = 0;
+        // simply iterate through the pool.
+        for (ConstCell item : pool) {
+            i += 1;
+            // first item is always null
+            if (item == null) {
+                continue;
+            }
+
+            checkAndFixCPRef(i, item);
+        }
+    }
+
+    protected void CheckGlobals() {
+        env.traceln("Checking Globals");
+        //
+        // This fn will put empty UTF8 string entries on any unset
+        // CP entries - before the last CP entry.
+        //
+        for (int cpx = 1; cpx < pool.size(); cpx++) {
+            ConstCell cell = pool.get(cpx);
+            if (cell == nullConst) { // gap
+                cell = new ConstCell(cpx, ConstValue0);
+                pool.set(cpx, cell);
+            }
+            ConstValue cval = cell.ref;
+            if ((cval == null) || !cval.hasValue()) {
+                String name = (new Integer(cpx)).toString();
+                env.error("const.undecl", name);
+            }
+        }
+    }
+
+    /*
+     *  Helper function for "fixRefsInPool"
+     *
+     *  Does recursive checking of references,
+     * using a locally-defined visitor.
+     */
+    private void checkAndFixCPRef(int i, ConstCell item) {
+        ConstValue cv = item.ref;
+        if (cv != null) {
+            fixCPVstr.visit(cv);
+        }
+    }
+
+    private CPVisitor<Void> fixCPVstr = new CPVisitor<Void>() {
+        @Override
+        public Void visitUTF8(ConstValue_String p) {
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitInteger(ConstValue_Integer p) {
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitFloat(ConstValue_Integer p) {
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitDouble(ConstValue_Long p) {
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitLong(ConstValue_Long p) {
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitMethodtype(ConstValue_Cell p) {
+            handleClassRef(p);
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitString(ConstValue_Cell p) {
+            handleClassRef(p);
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitClass(ConstValue_Cell p) {
+            handleClassRef(p);
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitMethod(ConstValue_Pair p) {
+            handleMemberRef(p);
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitField(ConstValue_Pair p) {
+            handleMemberRef(p);
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitInterfacemethod(ConstValue_Pair p) {
+            handleMemberRef(p);
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitNameandtype(ConstValue_Pair p) {
+            handleMemberRef(p);
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitMethodhandle(ConstValue_Pair p) {
+            handleMemberRef(p);
+            return null;
+        }
+
+        ;
+        @Override
+        public Void visitInvokedynamic(ConstValue_IndyPair p) {
+            return null;
+        }
+
+        ;
+
+        public void handleClassRef(ConstValue_Cell cv) {
+            ConstCell clref = cv.cell;
+            if (clref.ref == null) {
+                ConstCell refval = cpool_get(clref.arg);
+                if (refval != null) {
+                    checkAndFixCPRef(clref.arg, refval);
+                    clref.ref = refval.ref;
+                } else {
+                    clref.ref = null;
+                }
+                // env.traceln("FIXED ConstPool[" + i + "](" + cv.TagString(cv.tag) + ") = " + cv.value);
+            }
+        }
+
+        public void handleMemberRef(ConstValue_Pair cv) {
+            // env.traceln("ConstPool[" + i + "](" + cv.TagString(cv.tag) + ") = " + cv.value);
+            ConstCell clref = cv.left;
+            ConstCell typref = cv.right;
+            if (clref.ref == null) {
+                ConstCell refval = cpool_get(clref.arg);
+                if (refval != null) {
+                    checkAndFixCPRef(clref.arg, refval);
+                    clref.ref = refval.ref;
+                } else {
+                    clref.ref = null;
+                }
+                // env.traceln("FIXED ConstPool[" + i + "](" + cv.TagString(cv.tag) + ") = " + cv.value);
+            }
+            if (typref.ref == null) {
+                ConstCell refval = cpool_get(typref.arg);
+                if (refval != null) {
+                    checkAndFixCPRef(typref.arg, refval);
+                    typref.ref = refval.ref;
+                } else {
+                    typref.ref = null;
+                }
+                // env.traceln("FIXED ConstPool[" + i + "](" + cv.TagString(cv.tag) + ") = " + cv.value);
+            }
+        }
+
+    };
+
+    /*
+     * Help debug Constant Pools
+     */
+    public void printPool() {
+        int i = 0;
+        for (ConstCell item : pool) {
+            env.traceln("^^^^^^^^^^^^^  const #" + i + ": " + item);
+            i += 1;
+        }
+    }
+
+    private ConstCell cpool_get(int cpx) {
+        if (cpx >= pool.size()) {
+            return null;
+        }
+        return pool.get(cpx);
+    }
+
+    private void cpool_set(int cpx, ConstCell cell, int sz) {
+        debugStr("cpool_set1: " + cpx + " " + cell);
+        debugStr("param_size: " + sz);
+        debugStr("pool_size: " + pool.size());
+        cell.arg = cpx;
+        if (cpx + sz >= pool.size()) {
+            debugStr("calling ensureCapacity( " + (cpx + sz + 1) + ")");
+            int low = pool.size();
+            int high = cpx + sz;
+            for (int i = 0; i < high - low; i++) {
+                pool.add(nullConst);
+            }
+        }
+        pool.set(cpx, cell);
+        if (sz == 2) {
+            pool.set(cpx + 1, new ConstCell(cpx + 1, ConstValue0));
+        }
+        debugStr(" cpool_set2: " + cpx + " " + cell);
+    }
+
+    protected ConstCell uncheckedGetCell(int cpx) { // by index
+        return pool.get(cpx);
+    }
+
+    public ConstCell getCell(int cpx) { // by index
+        ConstCell cell = cpool_get(cpx);
+        if (cell != null) {
+            return cell;
+        }
+        cell = new ConstCell(cpx, null);
+        return cell;
+    }
+
+    public void setCell(int cpx, ConstCell cell) {
+        ConstValue value = cell.ref;
+        if (value == null) {
+            throw new Parser.CompilerError(env.errorStr("comperr.constcell.nullvalset"));
+        }
+        int sz = value.size();
+
+        if (cpx == 0) {
+            // It is correct to warn about redeclaring constant zero,
+            // since this value is never written out to a class file.
+            env.error("warn.const0.redecl");
+        } else {
+            if ((cpool_get(cpx) != null) || ((sz == 2) && (cpool_get(cpx + 1) != null))) {
+                String name = "#" + cpx;
+                env.error("const.redecl", name);
+                return;
+            }
+            if (cell.isSet() && (cell.arg != cpx)) {
+                env.traceln("setCell: new ConstCell");
+                cell = new ConstCell(value);
+            }
+        }
+        cpool_set(cpx, cell, sz);
+    }
+
+    protected void NumberizePool() {
+        env.traceln("NumberizePool");
+        Enumeration e;
+        for (int rank = 0; rank < 3; rank++) {
+            for (ConstCell cell : cpoolHashByValue.values()) {
+                if (cell.rank != rank) {
+                    continue;
+                }
+                if (cell.isSet()) {
+                    continue;
+                }
+                ConstValue value = cell.ref;
+                if (value == null) {
+                    throw new Parser.CompilerError(env.errorStr("comperr.constcell.nullvalhash"));
+                }
+                int sz = value.size(), cpx;
+find:
+                for (cpx = 1; cpx < pool.size(); cpx++) {
+                    if ((pool.get(cpx) == nullConst) && ((sz == 1) || (pool.get(cpx + 1) == nullConst))) {
+                        break find;
+                    }
+                }
+                cpool_set(cpx, cell, sz);
+            }
+        }
+
+        ConstCell firstCell = cpool_get(0);
+        firstCell.arg = 0;
+    }
+
+    public ConstCell FindCell(ConstValue ref) {
+        if (ref == null) {
+            throw new Parser.CompilerError(env.errorStr("comperr.constcell.nullval"));
+        }
+        ConstCell pconst = null;
+        try {
+            pconst = cpoolHashByValue.get(ref);
+        } catch (Parser.CompilerError e) {
+            throw new Parser.CompilerError(env.errorStr("comperr.constcell.nullvalhash"));
+        }
+        // If we fund a cached ConstValue
+        if (pconst != null) {
+            ConstValue value = pconst.ref;
+            if (!value.equals(ref)) {
+                throw new Parser.CompilerError(env.errorStr("comperr.val.noteq"));
+            }
+            return pconst;
+        }
+        // If we didn't find a cached ConstValue
+        //      Add it to the cache
+        pconst = new ConstCell(ref);
+        cpoolHashByValue.put(ref, pconst);
+        return pconst;
+    }
+
+    public ConstCell FindCell(ConstType tag, String value) {
+        return FindCell(new ConstValue_String(value));
+    }
+
+    public ConstCell FindCell(ConstType tag, Integer value) {
+        return FindCell(new ConstValue_Integer(tag, value));
+    }
+
+    public ConstCell FindCell(ConstType tag, Long value) {
+        return FindCell(new ConstValue_Long(tag, value));
+    }
+
+    public ConstCell FindCell(ConstType tag, ConstCell value) {
+        return FindCell(new ConstValue_Cell(tag, value));
+    }
+
+    public ConstCell FindCell(ConstType tag, ConstCell left, ConstCell right) {
+        return FindCell(new ConstValue_Pair(tag, left, right));
+    }
+
+    public ConstCell FindCellAsciz(String str) {
+        return FindCell(ConstType.CONSTANT_UTF8, str);
+    }
+
+    public ConstCell FindCellClassByName(String name) {
+        return FindCell(ConstType.CONSTANT_CLASS, FindCellAsciz(name));
+    }
+
+    public void write(CheckedDataOutputStream out) throws IOException {
+        // Write the constant pool
+        int length = pool.size();
+        out.writeShort(length);
+        int i;
+        env.traceln("wr.pool:size=" + length);
+        for (i = 1; i < length;) {
+            ConstCell cell = pool.get(i);
+            ConstValue value = cell.ref;
+            if (cell.arg != i) {
+                throw new Parser.CompilerError(env.errorStr("comperr.constcell.invarg", Integer.toString(i), cell.arg));
+            }
+// System.out.print("         WRITE CONST[" + i + "]:");
+            value.write(out);
+            i += value.size();
+        }
+    }
+
+    public static void setEnableDebug(boolean newState) {
+        debugCP = newState;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/Constants.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+/**
+ * This interface defines constant that are used throughout the compiler. It inherits from
+ * RuntimeConstants, which is an autogenerated class that contains constants defined in
+ * the interpreter.
+ */
+public interface Constants extends RuntimeConstants {
+
+    /**
+     * Default version of class file
+     */
+    public static final short DEFAULT_MAJOR_VERSION = 45;
+    public static final short DEFAULT_MINOR_VERSION = 3;
+
+    /**
+     * End of input
+     */
+    public static final int EOF        = -1;
+
+    /*
+     * Flags
+     */
+    public static final int F_VERBOSE        = 1 << 0;
+    public static final int F_DUMP           = 1 << 1;
+    public static final int F_WARNINGS       = 1 << 2;
+    public static final int F_DEBUG          = 1 << 3;
+    public static final int F_OPTIMIZE       = 1 << 4;
+    public static final int F_DEPENDENCIES   = 1 << 5;
+
+    /*
+     * Type codes
+     */
+    public static final int TC_BOOLEAN   = 0;
+    public static final int TC_BYTE      = 1;
+    public static final int TC_CHAR      = 2;
+    public static final int TC_SHORT     = 3;
+    public static final int TC_INT       = 4;
+    public static final int TC_LONG      = 5;
+    public static final int TC_FLOAT     = 6;
+    public static final int TC_DOUBLE    = 7;
+    public static final int TC_NULL      = 8;
+    public static final int TC_ARRAY     = 9;
+    public static final int TC_CLASS     = 10;
+    public static final int TC_VOID      = 11;
+    public static final int TC_METHOD    = 12;
+    public static final int TC_ERROR     = 13;
+
+    /*
+     * Type Masks
+     */
+    public static final int TM_NULL      = 1 << TC_NULL;
+    public static final int TM_VOID      = 1 << TC_VOID;
+    public static final int TM_BOOLEAN   = 1 << TC_BOOLEAN;
+    public static final int TM_BYTE      = 1 << TC_BYTE;
+    public static final int TM_CHAR      = 1 << TC_CHAR;
+    public static final int TM_SHORT     = 1 << TC_SHORT;
+    public static final int TM_INT       = 1 << TC_INT;
+    public static final int TM_LONG      = 1 << TC_LONG;
+    public static final int TM_FLOAT     = 1 << TC_FLOAT;
+    public static final int TM_DOUBLE    = 1 << TC_DOUBLE;
+    public static final int TM_ARRAY     = 1 << TC_ARRAY;
+    public static final int TM_CLASS     = 1 << TC_CLASS;
+    public static final int TM_METHOD    = 1 << TC_METHOD;
+    public static final int TM_ERROR     = 1 << TC_ERROR;
+
+    public static final int TM_INT32     = TM_BYTE | TM_SHORT | TM_CHAR | TM_INT;
+    public static final int TM_NUM32     = TM_INT32 | TM_FLOAT;
+    public static final int TM_NUM64     = TM_LONG | TM_DOUBLE;
+    public static final int TM_INTEGER   = TM_INT32 | TM_LONG;
+    public static final int TM_REAL      = TM_FLOAT | TM_DOUBLE;
+    public static final int TM_NUMBER    = TM_INTEGER | TM_REAL;
+    public static final int TM_REFERENCE = TM_ARRAY | TM_CLASS | TM_NULL;
+
+    /*
+     * Class status
+     */
+    public static final int CS_UNDEFINED        = 0;
+    public static final int CS_UNDECIDED        = 1;
+    public static final int CS_BINARY           = 2;
+    public static final int CS_SOURCE           = 3;
+    public static final int CS_PARSED           = 4;
+    public static final int CS_COMPILED         = 5;
+    public static final int CS_NOTFOUND         = 6;
+
+    /*
+     * Attributes
+     */
+    public static final int ATT_ALL             = -1;
+    public static final int ATT_CODE            = 1;
+
+    /*
+     * Number of bits used in file offsets
+     */
+    public static final int OFFSETBITS          = 19;
+    public static final int MAXFILESIZE         = (1 << OFFSETBITS) - 1;
+    public static final int MAXLINENUMBER       = (1 << (32 - OFFSETBITS)) - 1;
+
+    /*
+     * Operator precedence
+     */
+    /* Who uses this????
+    public static final int opPrecedence[] = {
+        10,  11,  11,  11,  11,  11,  11,  11,  11,  11,
+        11,  11,  11,  12,  13,  14,  15,  16,  17,  18,
+        18,  19,  19,  19,  19,  19,  20,  20,  20,  21,
+        21,  22,  22,  22,  23,  24,  24,  24,  24,  24,
+        24,  25,  25,  26,  26,  26,  26,  26,  26
+    };
+    * */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/Data.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+
+/**
+ *
+ */
+interface Data {
+
+    public void write(CheckedDataOutputStream out) throws IOException;
+
+    public int getLength();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/DataVector.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ *
+ */
+public class DataVector<T extends Data> implements Iterable<T> {
+
+    ArrayList<T> elements;
+
+    public DataVector(int initSize) {
+        elements = new ArrayList<>(initSize);
+    }
+
+    public DataVector() {
+        this(12);
+    }
+
+    public Iterator<T> iterator() {
+        return elements.iterator();
+    }
+
+    public void add(T element) {
+        elements.add(element);
+    }
+
+    // full length of the attribute
+    // declared in Data
+    public int getLength() {
+        int length = 0;
+        // calculate overall size here rather than in add()
+        // because it may not be available at the time of invoking of add()
+        for (T element : elements) {
+            length += element.getLength();
+        }
+
+        return 2 + length; // add the length of number of elements
+    }
+
+    public void write(CheckedDataOutputStream out)
+            throws IOException {
+        out.writeShort(elements.size());
+        writeElements(out);
+    }
+
+    public void writeElements(CheckedDataOutputStream out)
+            throws IOException {
+        for (Data element : elements) {
+            element.write(out);
+        }
+    }
+
+    /* for compatibility with Vector */
+    public void addElement(T element) {
+        elements.add(element);
+    }
+
+    public int size() {
+        return elements.size();
+    }
+
+    public Data elementAt(int k) {
+        return elements.get(k);
+    }
+}// end class DataVector
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/DataVectorAttr.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ *
+ */
+// public class DataVectorAttr extends AttrData implements Constants {
+// }
+class DataVectorAttr<T extends Data> extends AttrData implements Iterable<T> {
+
+    private ArrayList<T> elements;
+    private boolean byteIndex;
+
+    public DataVectorAttr(ClassData cls, String name, boolean byteIndex, ArrayList<T> initialData) {
+        super(cls, name);
+        this.elements = initialData;
+        this.byteIndex = byteIndex;
+    }
+
+    public DataVectorAttr(ClassData cls, String name, ArrayList<T> initialData) {
+        this(cls, name, false, initialData);
+    }
+
+    public DataVectorAttr(ClassData cls, String name) {
+        this(cls, name, false, new ArrayList<T>());
+
+    }
+
+    public DataVectorAttr(ClassData cls, String name, boolean byteIndex) {
+        this(cls, name, byteIndex, new ArrayList<T>());
+
+    }
+
+    public T get(int index) {
+        return elements.get(index);
+    }
+
+    public void add(T element) {
+        elements.add(element);
+    }
+
+    public void add(int i, T element) {
+        elements.add(i, element);
+    }
+
+    public int size() {
+        return elements.size();
+    }
+
+    @Override
+    public Iterator<T> iterator() {
+        return elements.iterator();
+    }
+
+    @Override
+    public int attrLength() {
+        int length = 0;
+        // calculate overall size here rather than in add()
+        // because it may not be available at the time of invoking of add()
+        for (T elem : elements) {
+            length += elem.getLength();
+        }
+
+        // add the length of number of elements
+        if (byteIndex) {
+            length += 1;
+        } else {
+            length += 2;
+        }
+
+        return length;
+    }
+
+    @Override
+    public void write(CheckedDataOutputStream out) throws IOException {
+        super.write(out);  // attr name, attr len
+        if (byteIndex) {
+            out.writeByte(elements.size());
+        } else {
+            out.writeShort(elements.size());
+        } // number of elements
+        for (T elem : elements) {
+            elem.write(out);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/DefaultAnnotationAttr.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+
+/**
+ * DefaultAnnotationAttr
+ *
+ * Used to represent Default Annotation Attributes
+ *
+ */
+public class DefaultAnnotationAttr extends AttrData {
+
+    Data element; // Data
+
+    public DefaultAnnotationAttr(ClassData cls, String name, Data element) {
+        super(cls, name);
+        this.element = element;
+    }
+
+    public DefaultAnnotationAttr(ClassData cls, String name) {
+        super(cls, name);
+        this.element = null;
+    }
+
+    public void add(Data element) {
+        this.element = element;
+    }
+
+    @Override
+    public int attrLength() {
+        return element.getLength(); // add the length of number of elements
+    }
+
+    @Override
+    public void write(CheckedDataOutputStream out) throws IOException {
+        super.write(out);  // attr name, attr len
+        element.write(out);
+    }
+}// end class DataVectorAttr
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/Environment.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import static org.openjdk.asmtools.jasm.Constants.EOF;
+import static org.openjdk.asmtools.jasm.Constants.OFFSETBITS;
+import org.openjdk.asmtools.util.I18NResourceBundle;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.text.MessageFormat;
+
+/**
+ * An input stream for java programs. The stream treats either "\n", "\r" or "\r\n" as the
+ * end of a line, it always returns \n. It also parses UNICODE characters expressed as
+ * \uffff. However, if it sees "\\", the second slash cannot begin a unicode sequence. It
+ * keeps track of the current position in the input stream.
+ *
+ * An position consists of: ((linenr &lt;&lt; OFFSETBITS) | offset) this means that both
+ * the line number and the exact offset into the file are encoded in each position
+ * value.<p>
+ */
+public class Environment {
+
+    /*-------------------------------------------------------- */
+    /* Environment Inner Classes */
+    /**
+     * A sorted list of error messages
+     */
+    final class ErrorMessage {
+
+        int where;
+        String message;
+        ErrorMessage next;
+
+        /**
+         * Constructor
+         */
+        ErrorMessage(int where, String message) {
+            this.where = where;
+            this.message = message;
+        }
+    }
+
+    /*-------------------------------------------------------- */
+    /* Environment Fields */
+    static boolean traceFlag = false;
+    boolean debugInfoFlag = false;
+
+    private File source;
+    public PrintStream out;
+    boolean nowarn;
+    private byte data[];
+    private int bytepos;
+    private int linepos;
+    public int pos;
+    /*-------------------------------------------------------- */
+
+    public Environment(File source, PrintStream out, boolean nowarn) throws IOException {
+        this.out = out;
+        errorFileName = source.getPath();
+        this.source = source;
+        this.nowarn = nowarn;
+        // Read the file
+        FileInputStream in = new FileInputStream(source);
+        data = new byte[in.available()];
+        in.read(data);
+        in.close();
+        bytepos = 0;
+        linepos = 1;
+    }
+
+    public String getErrorFile() {
+        return errorFileName;
+    }
+
+    public String getSourceName() {
+        return source.getName();
+    }
+
+    public int lookForward() {
+        try {
+            return data[bytepos];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            return EOF;
+        }
+    }
+
+    public int convertUnicode() {
+        int c;
+        try {
+            while ((c = data[bytepos]) == 'u') {
+                bytepos++;
+            }
+            int d = 0;
+            for (int i = 0; i < 4; i++) {
+                switch (c) {
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                        d = (d << 4) + c - '0';
+                        break;
+                    case 'a':
+                    case 'b':
+                    case 'c':
+                    case 'd':
+                    case 'e':
+                    case 'f':
+                        d = (d << 4) + 10 + c - 'a';
+                        break;
+                    case 'A':
+                    case 'B':
+                    case 'C':
+                    case 'D':
+                    case 'E':
+                    case 'F':
+                        d = (d << 4) + 10 + c - 'A';
+                        break;
+                    default:
+                        error(pos, "invalid.escape.char");
+                        return d;
+                }
+                ++bytepos;
+                c = data[bytepos];
+            }
+            return d;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            error(pos, "invalid.escape.char");
+            return EOF;
+        }
+    }
+
+    public int read() {
+        int c;
+        pos = (linepos << OFFSETBITS) | bytepos;
+        try {
+            c = data[bytepos];
+        } catch (ArrayIndexOutOfBoundsException e) {
+            return EOF;
+        }
+        bytepos++;
+
+        // parse special characters
+        switch (c) {
+            /*            case '\\':
+             if (lookForward() != 'u') {
+             return '\\';
+             }
+             // we have a unicode sequence
+             return convertUnicode();*/
+            case '\n':
+                linepos++;
+                return '\n';
+
+            case '\r':
+                if (lookForward() == '\n') {
+                    bytepos++;
+                }
+                linepos++;
+                return '\n';
+
+            default:
+                return c;
+        }
+    }
+
+    public int lineNumber(int lcpos) {
+        return lcpos >>> OFFSETBITS;
+    }
+
+    public int lineNumber() {
+        return lineNumber(pos);
+    }
+
+    public int lineOffset(int lcpos) {
+        return lcpos & ((1 << OFFSETBITS) - 1);
+    }
+
+    public int lineOffset() {
+        return lineOffset(pos);
+    }
+
+    /*==============================================================  Environment */
+    /**
+     * The number of errors and warnings
+     */
+    public int nerrors;
+    public int nwarnings;
+    public static final I18NResourceBundle i18n
+            = I18NResourceBundle.getBundleForClass(Main.class);
+
+    /**
+     * Error String
+     */
+    String errorString(String err, Object arg1, Object arg2, Object arg3) {
+        String str = null;
+
+        //str = getProperty(err);
+        str = i18n.getString(err);
+        if (str == null) {
+            return "error message '" + err + "' not found";
+        }
+
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            if ((c == '%') && (i + 1 < str.length())) {
+                switch (str.charAt(++i)) {
+                    case 's':
+                        String arg = arg1.toString();
+                        for (int j = 0; j < arg.length(); j++) {
+                            switch (c = arg.charAt(j)) {
+                                case ' ':
+                                case '\t':
+                                case '\n':
+                                case '\r':
+                                    buf.append((char) c);
+                                    break;
+
+                                default:
+                                    if ((c > ' ') && (c <= 255)) {
+                                        buf.append((char) c);
+                                    } else {
+                                        buf.append('\\');
+                                        buf.append('u');
+                                        buf.append(Integer.toString(c, 16));
+                                    }
+                            }
+                        }
+                        arg1 = arg2;
+                        arg2 = arg3;
+                        break;
+
+                    case '%':
+                        buf.append('%');
+                        break;
+
+                    default:
+                        buf.append('?');
+                        break;
+                }
+            } else {
+                buf.append((char) c);
+            }
+        }
+        // KTL
+        // Need to do message format to substitute args
+        String msg = buf.toString();
+        MessageFormat form = new MessageFormat(msg);
+        Object args[] = {arg1, arg2, arg3};
+        msg = form.format(args);
+
+        return msg;
+
+    }
+
+    /**
+     * The filename where the last errors have occurred
+     */
+    String errorFileName;
+
+    /**
+     * List of outstanding error messages
+     */
+    ErrorMessage errors;
+
+    /**
+     * Insert an error message in the list of outstanding error messages. The list is
+     * sorted on input position.
+     */
+    void insertError(int where, String message) {
+        //output("ERR = " + message);
+        ErrorMessage msg = new ErrorMessage(where, message);
+        if (errors == null) {
+            errors = msg;
+        } else if (errors.where > where) {
+            msg.next = errors;
+            errors = msg;
+        } else {
+            ErrorMessage m = errors;
+            for (; (m.next != null) && (m.next.where <= where); m = m.next);
+            msg.next = m.next;
+            m.next = msg;
+        }
+    }
+
+    /**
+     * Flush outstanding errors
+     */
+    public void flushErrors() {
+        if (errors == null) {
+            traceln("flushErrors: errors == null");
+            return;
+        }
+
+        // Report the errors
+        for (ErrorMessage msg = errors; msg != null; msg = msg.next) {
+            int ln = lineNumber(msg.where);
+            int off = lineOffset(msg.where);
+
+            int i, j;
+            for (i = off; (i > 0) && (data[i - 1] != '\n') && (data[i - 1] != '\r'); i--);
+            for (j = off; (j < data.length) && (data[j] != '\n') && (data[j] != '\r'); j++);
+
+            String prefix = errorFileName + ":" + ln + ":";
+            outputln(prefix + " " + msg.message);
+            outputln(new String(data, i, j - i));
+
+            char strdata[] = new char[(off - i) + 1];
+            for (j = i; j < off; j++) {
+                strdata[j - i] = (data[j] == '\t') ? '\t' : ' ';
+            }
+            strdata[off - i] = '^';
+            outputln(new String(strdata));
+        }
+        errors = null;
+    }
+
+    /**
+     * Output a string. This can either be an error message or something for debugging.
+     * This should be used instead of print.
+     */
+    public void output(String msg) {
+//        try {
+        int len = msg.length();
+        for (int i = 0; i < len; i++) {
+            out.write(msg.charAt(i));
+        }
+//        } catch (IOException e) {
+//        }
+    }
+
+    /**
+     * Output a string. This can either be an error message or something for debugging.
+     * This should be used instead of println.
+     */
+    public void outputln(String msg) {
+        output(msg);
+        out.write('\n');
+    }
+
+    /**
+     * Issue an error. source - the input source, usually a file name string offset - the
+     * offset in the source of the error err - the error number (as defined in this
+     * interface) arg1 - an optional argument to the error (null if not applicable) arg2 -
+     * a second optional argument to the error (null if not applicable) arg3 - a third
+     * optional argument to the error (null if not applicable)
+     */
+    /**
+     * Issue an error
+     */
+    public void error(int where, String err, Object arg1, Object arg2, Object arg3) {
+        String msg;
+        if (err.startsWith("warn.")) {
+            if (nowarn) {
+                return;
+            }
+            nwarnings++;
+            msg = "Warning: ";
+        } else {
+            err = "err." + err;
+            nerrors++;
+            msg = "Error: ";
+        }
+        msg = msg + errorString(err, arg1, arg2, arg3);
+        traceln("error(" + lineNumber(where) + ":" + lineOffset(where) + "):" + msg);
+        insertError(where, msg);
+    }
+
+    public final void error(int where, String err, Object arg1, Object arg2) {
+        error(where, err, arg1, arg2, null);
+    }
+
+    public final void error(int where, String err, Object arg1) {
+        error(where, err, arg1, null, null);
+    }
+
+    public final void error(int where, String err) {
+        error(where, err, null, null, null);
+    }
+
+    public final void error(String err, Object arg1, Object arg2, Object arg3) {
+        error(pos, err, arg1, arg2, arg3);
+    }
+
+    public final void error(String err, Object arg1, Object arg2) {
+        error(pos, err, arg1, arg2, null);
+    }
+
+    public final void error(String err, Object arg1) {
+        error(pos, err, arg1, null, null);
+    }
+
+    public final void error(String err) {
+        error(pos, err, null, null, null);
+    }
+
+    public final String errorStr(String err, Object arg1, Object arg2, Object arg3) {
+        return errorString(err, arg1, arg2, arg3);
+    }
+
+    public final String errorStr(String err, Object arg1, Object arg2) {
+        return errorStr(err, arg1, arg2, null);
+    }
+
+    public final String errorStr(String err, Object arg1) {
+        return errorStr(err, arg1, null, null);
+    }
+
+    public final String errorStr(String err) {
+        return errorStr(err, null, null, null);
+    }
+
+    /*==============================================================  trace */
+    public boolean isTraceEnabled() {
+        return traceFlag;
+    }
+
+    public boolean isDebugEnabled() {
+        return debugInfoFlag;
+    }
+
+    void trace(String message) {
+        if (traceFlag) {
+            output(message);
+        }
+    }
+
+    void traceln(String message) {
+        if (traceFlag) {
+            outputln(message);
+        }
+    }
+
+} // end Environment
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/FieldData.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import org.openjdk.asmtools.jasm.Tables.AttrTag;
+import java.io.IOException;
+
+/**
+ *
+ */
+class FieldData extends MemberData {
+
+    /*-------------------------------------------------------- */
+    /* FieldData Fields */
+    protected ConstantPool.ConstValue_Pair nape;
+    private AttrData initValue;
+    /*-------------------------------------------------------- */
+
+    public FieldData(ClassData cls, int acc, ConstantPool.ConstValue_Pair nape) {
+        super(cls, acc);
+        this.nape = nape;
+        if (Modifiers.hasPseudoMod(acc)) {
+            createPseudoMod();
+        }
+    }
+
+    public void SetValue(Argument value_cpx) {
+        initValue = new CPXAttr(cls, AttrTag.ATT_ConstantValue.parsekey(),
+                value_cpx);
+    }
+
+    public void write(CheckedDataOutputStream out) throws IOException, Parser.CompilerError {
+        out.writeShort(access);
+        out.writeShort(nape.left.arg);
+        out.writeShort(nape.right.arg);
+
+        DataVector attrs = new DataVector();
+        if (initValue != null) {
+            attrs.add(initValue);
+        }
+        if (syntheticAttr != null) {
+            attrs.add(syntheticAttr);
+        }
+        if (deprecatedAttr != null) {
+            attrs.add(deprecatedAttr);
+        }
+        if (annotAttrVis != null) {
+            attrs.add(annotAttrVis);
+        }
+        if (annotAttrInv != null) {
+            attrs.add(annotAttrInv);
+        }
+        if (type_annotAttrVis != null) {
+            attrs.add(type_annotAttrVis);
+        }
+        if (type_annotAttrInv != null) {
+            attrs.add(type_annotAttrInv);
+        }
+        attrs.write(out);
+    }
+} // end FieldData
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/InnerClassData.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+
+/**
+ *
+ */
+class InnerClassData implements Data {
+
+    int access;
+    ConstantPool.ConstCell name, innerClass, outerClass;
+
+    public InnerClassData(int access, ConstantPool.ConstCell name, ConstantPool.ConstCell innerClass, ConstantPool.ConstCell outerClass) {
+        this.access = access;
+        this.name = name;
+        this.innerClass = innerClass;
+        this.outerClass = outerClass;
+    }
+
+    @Override
+    public int getLength() {
+        return 8;
+    }
+
+    @Override
+    public void write(CheckedDataOutputStream out) throws IOException {
+        out.writeShort(innerClass.arg);
+        if (outerClass.isSet()) {
+            out.writeShort(outerClass.arg);
+        } else {
+            out.writeShort(0);
+        }
+        if (name.isSet()) {
+            out.writeShort(name.arg);
+        } else {
+            out.writeShort(0);
+        }
+        out.writeShort(access);
+    }
+}// end class InnerClassData
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/Instr.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+
+import static org.openjdk.asmtools.jasm.OpcodeTables.*;
+
+/**
+ *
+ */
+class Instr {
+
+    Instr next = null;
+    int pc;
+    int pos;
+    Opcode opc;
+    Argument arg;
+    Object arg2; // second or unusual argument
+
+    public Instr(int pc, int pos, Opcode opc, Argument arg, Object arg2) {
+        this.pc = pc;
+        this.pos = pos;
+        this.opc = opc;
+        this.arg = arg;
+        this.arg2 = arg2;
+    }
+
+    public Instr() {
+    }
+
+    public void write(CheckedDataOutputStream out, Environment env) throws IOException {
+        OpcodeType type = opc.type();
+        switch (type) {
+            case NORMAL: {
+                if (opc == Opcode.opc_bytecode) {
+                    out.writeByte(arg.arg);
+                    return;
+                }
+                out.writeByte(opc.value());
+                int opcLen = opc.length();
+                if (opcLen == 1) {
+                    return;
+                }
+
+                switch (opc) {
+                    case opc_tableswitch:
+                        ((SwitchTable) arg2).writeTableSwitch(out);
+                        return;
+                    case opc_lookupswitch:
+                        ((SwitchTable) arg2).writeLookupSwitch(out);
+                        return;
+                }
+
+                int iarg;
+                try {
+                    iarg = arg.arg;
+                } catch (NullPointerException e) {
+                    throw new Parser.CompilerError(env.errorStr("comperr.instr.nullarg", opc.parsekey()));
+                }
+//env.traceln("instr:"+opcNamesTab[opc]+" len="+opcLen+" arg:"+iarg);
+                switch (opc) {
+                    case opc_jsr:
+                    case opc_goto:
+                    case opc_ifeq:
+                    case opc_ifge:
+                    case opc_ifgt:
+                    case opc_ifle:
+                    case opc_iflt:
+                    case opc_ifne:
+                    case opc_if_icmpeq:
+                    case opc_if_icmpne:
+                    case opc_if_icmpge:
+                    case opc_if_icmpgt:
+                    case opc_if_icmple:
+                    case opc_if_icmplt:
+                    case opc_if_acmpeq:
+                    case opc_if_acmpne:
+                    case opc_ifnull:
+                    case opc_ifnonnull:
+                    case opc_jsr_w:
+                    case opc_goto_w:
+                        iarg = iarg - pc;
+                        break;
+                    case opc_iinc:
+                        iarg = (iarg << 8) | (((Argument) arg2).arg & 0xFF);
+                        break;
+                    case opc_invokeinterface:
+                        iarg = ((iarg << 8) | (((Argument) arg2).arg & 0xFF)) << 8;
+                        break;
+                    case opc_invokedynamic: // JSR-292
+                        iarg = (iarg << 16);
+                        break;
+                    case opc_ldc:
+                        if ((iarg & 0xFFFFFF00) != 0) {
+                            throw new Parser.CompilerError(
+                                    env.errorStr("comperr.instr.arglong", opc.parsekey(), iarg));
+                        }
+                        break;
+                }
+                switch (opcLen) {
+                    case 1:
+                        return;
+                    case 2:
+                        out.writeByte(iarg);
+                        return;
+                    case 3:
+                        out.writeShort(iarg);
+                        return;
+                    case 4: // opc_multianewarray only
+                        out.writeShort(iarg);
+                        iarg = ((Argument) arg2).arg;
+                        out.writeByte(iarg);
+                        return;
+                    case 5:
+                        out.writeInt(iarg);
+                        return;
+                    default:
+                        throw new Parser.CompilerError(
+                                env.errorStr("comperr.instr.opclen", opc.parsekey()));
+                }
+            }
+            case WIDE:
+                out.writeByte(Opcode.opc_wide.value());
+                out.writeByte(opc.value() & 0xFF);
+                out.writeShort(arg.arg);
+                if (opc == Opcode.opc_iinc_w) {
+                    out.writeShort(((Argument) arg2).arg);
+                }
+                return;
+            case PRIVELEGED:
+            case NONPRIVELEGED:
+                out.writeByte(opc.value() >> 8);
+                out.writeByte(opc.value() & 0xFF);
+                return;
+            default:
+                throw new Parser.CompilerError(
+                        env.errorStr("comperr.instr.opclen", opc.parsekey()));
+        } // end writeSpecCode
+
+    }
+} // end Instr
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/JasmTokens.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.util.HashMap;
+
+/**
+ *
+ * JasmTokens
+ *
+ * This class contains tokens specific to parsing JASM syntax.
+ *
+ * The classes in JasmTokens are following a Singleton Pattern. These classes are Enums,
+ * and they are contained in private hash maps (lookup tables and reverse lookup tables).
+ * These hash maps all have public accessors, which clients use to look-up enums.
+ *
+ * Tokens in this table carry no external state, and are typically treated as constants.
+ * They do not need to be reset.
+ */
+public class JasmTokens {
+
+    /*-------------------------------------------------------- */
+    /* Marker: describes the type of Keyword */
+    static public enum KeywordType {
+        TOKEN            (0, "TOKEN"),
+        VALUE            (1, "VALUE"),
+        JASMIDENTIFIER   (2, "JASM"),
+        KEYWORD          (3, "KEYWORD");
+
+        private final Integer value;
+        private final String printval;
+
+        KeywordType(Integer val, String print) {
+            value = val;
+            printval = print;
+        }
+
+        public String printval() {
+            return printval;
+        }
+    }
+
+
+    /*-------------------------------------------------------- */
+    /* Marker - describes the type of token */
+    /*    this is rather cosmetic, no function currently. */
+    static public enum TokenType {
+        MODIFIER            (0, "Modifier"),
+        OPERATOR            (1, "Operator"),
+        VALUE               (2, "Value"),
+        TYPE                (3, "Type"),
+        EXPRESSION          (4, "Expression"),
+        STATEMENT           (5, "Statement"),
+        DECLARATION         (6, "Declaration"),
+        PUNCTUATION         (7, "Punctuation"),
+        SPECIAL             (8, "Special"),
+        JASM                (9, "Jasm"),
+        MISC                (10, "Misc");
+
+        private final Integer value;
+        private final String printval;
+
+        TokenType(Integer val, String print) {
+            value = val;
+            printval = print;
+        }
+
+        public String printval() {
+            return printval;
+        }
+    }
+
+    /*-------------------------------------------------------- */
+    /**
+     * Scanner Tokens (Definitive List)
+     */
+    static public enum Token {
+        EOF                 (-1, "EOF",         "EOF",  TokenType.MISC),
+        COMMA               (0, "COMMA",        ",",    TokenType.OPERATOR),
+        ASSIGN              (1, "ASSIGN",       "=",    TokenType.OPERATOR),
+
+        ASGMUL              (2, "ASGMUL",       "*=",   TokenType.OPERATOR),
+        ASGDIV              (3, "ASGDIV",       "/=",   TokenType.OPERATOR),
+        ASGREM              (4, "ASGREM",       "%=",   TokenType.OPERATOR),
+        ASGADD              (5, "ASGADD",       "+=",   TokenType.OPERATOR),
+        ASGSUB              (6, "ASGSUB",       "-=",   TokenType.OPERATOR),
+        ASGLSHIFT           (7, "ASGLSHIFT",    "<<=",  TokenType.OPERATOR),
+        ASGRSHIFT           (8, "ASGRSHIFT",    ">>=",  TokenType.OPERATOR),
+        ASGURSHIFT          (9, "ASGURSHIFT",   "<<<=", TokenType.OPERATOR),
+        ASGBITAND           (10, "ASGBITAND",   "&=",   TokenType.OPERATOR),
+        ASGBITOR            (11, "ASGBITOR",    "|=",   TokenType.OPERATOR),
+        ASGBITXOR           (12, "ASGBITXOR",   "^=",   TokenType.OPERATOR),
+
+        COND                (13, "COND",        "?:",   TokenType.OPERATOR),
+        OR                  (14, "OR",          "||",   TokenType.OPERATOR),
+        AND                 (15, "AND",         "&&",   TokenType.OPERATOR),
+        BITOR               (16, "BITOR",       "|",    TokenType.OPERATOR),
+        BITXOR              (17, "BITXOR",      "^",    TokenType.OPERATOR),
+        BITAND              (18, "BITAND",      "&",    TokenType.OPERATOR),
+        NE                  (19, "NE",          "!=",   TokenType.OPERATOR),
+        EQ                  (20, "EQ",          "==",   TokenType.OPERATOR),
+        GE                  (21, "GE",          ">=",   TokenType.OPERATOR),
+        GT                  (22, "GT",          ">",    TokenType.OPERATOR),
+        LE                  (23, "LE",          "<=",   TokenType.OPERATOR),
+        LT                  (24, "LT",          "<",    TokenType.OPERATOR),
+        INSTANCEOF          (25, "INSTANCEOF",  "instanceof",  TokenType.OPERATOR),
+        LSHIFT              (26, "LSHIFT",      "<<",   TokenType.OPERATOR),
+        RSHIFT              (27, "RSHIFT",      ">>",   TokenType.OPERATOR),
+        URSHIFT             (28, "URSHIFT",     "<<<",  TokenType.OPERATOR),
+        ADD                 (29, "ADD",         "+",    TokenType.OPERATOR),
+        SUB                 (30, "SUB",         "-",    TokenType.OPERATOR),
+        DIV                 (31, "DIV",         "/",    TokenType.OPERATOR),
+        REM                 (32, "REM",         "%",    TokenType.OPERATOR),
+        MUL                 (33, "MUL",         "*",    TokenType.OPERATOR),
+        CAST                (34, "CAST",        "cast", TokenType.OPERATOR),
+        POS                 (35, "POS",         "+",    TokenType.OPERATOR),
+        NEG                 (36, "NEG",         "-",    TokenType.OPERATOR),
+        NOT                 (37, "NOT",         "!",    TokenType.OPERATOR),
+        BITNOT              (38, "BITNOT",      "~",    TokenType.OPERATOR),
+        PREINC              (39, "PREINC",      "++",   TokenType.OPERATOR),
+        PREDEC              (40, "PREDEC",      "--",   TokenType.OPERATOR),
+        NEWARRAY            (41, "NEWARRAY",    "new",  TokenType.OPERATOR),
+        NEWINSTANCE         (42, "NEWINSTANCE", "new",  TokenType.OPERATOR),
+        NEWFROMNAME         (43, "NEWFROMNAME", "new",  TokenType.OPERATOR),
+        POSTINC             (44, "POSTINC",     "++",   TokenType.OPERATOR),
+        POSTDEC             (45, "POSTDEC",     "--",   TokenType.OPERATOR),
+        FIELD               (46, "FIELD",       "field", TokenType.OPERATOR),
+        METHOD              (47, "METHOD",      "method",  TokenType.OPERATOR),
+        ARRAYACCESS         (48, "ARRAYACCESS", "[]",   TokenType.OPERATOR),
+        NEW                 (49, "NEW",         "new",  TokenType.OPERATOR),
+        INC                 (50, "INC",         "++",   TokenType.OPERATOR),
+        DEC                 (51, "DEC",         "--",   TokenType.OPERATOR),
+
+        CONVERT             (55, "CONVERT",     "convert", TokenType.OPERATOR),
+        EXPR                (56, "EXPR",        "expr", TokenType.OPERATOR),
+        ARRAY               (57, "ARRAY",       "array", TokenType.OPERATOR),
+        GOTO                (58, "GOTO",        "goto", TokenType.OPERATOR),
+
+
+
+    /*
+     * Value tokens
+     */
+        IDENT               (60, "IDENT",       "Identifier", TokenType.VALUE, KeywordType.VALUE, true),
+        BOOLEANVAL          (61, "BOOLEANVAL",  "Boolean",  TokenType.VALUE, KeywordType.VALUE),
+        BYTEVAL             (62, "BYTEVAL",     "Byte",     TokenType.VALUE),
+        CHARVAL             (63, "CHARVAL",     "Char",     TokenType.VALUE),
+        SHORTVAL            (64, "SHORTVAL",    "Short",    TokenType.VALUE),
+        INTVAL              (65, "INTVAL",      "Integer",  TokenType.VALUE, KeywordType.VALUE),
+        LONGVAL             (66, "LONGVAL",     "Long",     TokenType.VALUE, KeywordType.VALUE),
+        FLOATVAL            (67, "FLOATVAL",    "Float",    TokenType.VALUE, KeywordType.VALUE),
+        DOUBLEVAL           (68, "DOUBLEVAL",   "Double",   TokenType.VALUE, KeywordType.VALUE),
+        STRINGVAL           (69, "STRINGVAL",   "String",   TokenType.VALUE, KeywordType.VALUE),
+
+    /*
+     * Type keywords
+     */
+        BYTE                (70, "BYTE",        "byte",     TokenType.TYPE),
+        CHAR                (71, "CHAR",        "char",     TokenType.TYPE),
+        SHORT               (72, "SHORT",       "short",    TokenType.TYPE),
+        INT                 (73, "INT",         "int",      TokenType.TYPE),
+        LONG                (74, "LONG",        "long",     TokenType.TYPE),
+        FLOAT               (75, "FLOAT",       "float",    TokenType.TYPE),
+        DOUBLE              (76, "DOUBLE",      "double",   TokenType.TYPE),
+        VOID                (77, "VOID",        "void",     TokenType.TYPE),
+        BOOLEAN             (78, "BOOLEAN",     "boolean",  TokenType.TYPE),
+
+    /*
+     * Expression keywords
+     */
+        TRUE                (80, "TRUE",        "true",     TokenType.EXPRESSION),
+        FALSE               (81, "FALSE",       "false",    TokenType.EXPRESSION),
+        THIS                (82, "THIS",        "this",     TokenType.EXPRESSION),
+        SUPER               (83, "SUPER",       "super",     TokenType.MODIFIER, KeywordType.KEYWORD),
+        NULL                (84, "NULL",        "null",     TokenType.EXPRESSION),
+
+    /*
+     * Statement keywords
+     */
+        IF                  (90, "IF",          "if",       TokenType.STATEMENT),
+        ELSE                (91, "ELSE",        "else",     TokenType.STATEMENT),
+        FOR                 (92, "FOR",         "for",      TokenType.STATEMENT),
+        WHILE               (93, "WHILE",       "while",    TokenType.STATEMENT),
+        DO                  (94, "DO",          "do",       TokenType.STATEMENT),
+        SWITCH              (95, "SWITCH",      "switch",   TokenType.STATEMENT),
+        CASE                (96, "CASE",        "case",     TokenType.STATEMENT),
+        DEFAULT             (97,  "DEFAULT",    "default",  TokenType.STATEMENT, KeywordType.KEYWORD),
+        BREAK               (98, "BREAK",       "break",    TokenType.STATEMENT),
+        CONTINUE            (99, "CONTINUE",    "continue", TokenType.STATEMENT),
+        RETURN              (100, "RETURN",     "return",   TokenType.STATEMENT),
+        TRY                 (101, "TRY",        "try",      TokenType.STATEMENT),
+        CATCH               (102, "CATCH",      "catch",    TokenType.STATEMENT),
+        FINALLY             (103, "FINALLY",    "finally",  TokenType.STATEMENT),
+        THROW               (104, "THROW",      "throw",    TokenType.STATEMENT),
+        STAT                (105, "STAT",       "stat",     TokenType.STATEMENT),
+        EXPRESSION          (106, "EXPRESSION", "expression",  TokenType.STATEMENT),
+        DECLARATION         (107, "DECLARATION", "declaration",   TokenType.STATEMENT),
+        VARDECLARATION      (108, "VARDECLARATION", "vdeclaration", TokenType.STATEMENT),
+
+    /*
+     * Declaration keywords
+     */
+        IMPORT              (110, "IMPORT",     "import",   TokenType.DECLARATION),
+        CLASS               (111, "CLASS",      "class",    TokenType.DECLARATION, KeywordType.KEYWORD),
+        EXTENDS             (112, "EXTENDS",    "extends",  TokenType.DECLARATION, KeywordType.KEYWORD),
+        IMPLEMENTS          (113, "IMPLEMENTS", "implements", TokenType.DECLARATION, KeywordType.KEYWORD),
+        INTERFACE           (114, "INTERFACE",  "interface", TokenType.DECLARATION, KeywordType.KEYWORD),
+        PACKAGE             (115, "PACKAGE",    "package",  TokenType.DECLARATION, KeywordType.KEYWORD),
+        ENUM                (116, "ENUM",       "enum",     TokenType.DECLARATION, KeywordType.KEYWORD),
+        MANDATED            (117, "MANDATED",   "mandated", TokenType.DECLARATION, KeywordType.KEYWORD),
+     /*
+     * Modifier keywords
+     */
+        PRIVATE             (120, "PRIVATE",    "private",  TokenType.MODIFIER, KeywordType.KEYWORD),
+        PUBLIC              (121, "PUBLIC",     "public",   TokenType.MODIFIER, KeywordType.KEYWORD),
+        PROTECTED           (122, "PROTECTED",  "protected", TokenType.MODIFIER, KeywordType.KEYWORD),
+        CONST               (123, "CONST",      "const",    TokenType.DECLARATION, KeywordType.KEYWORD),
+        STATIC              (124, "STATIC",     "static",   TokenType.MODIFIER, KeywordType.KEYWORD),
+        TRANSIENT           (125, "TRANSIENT",  "transient", TokenType.MODIFIER, KeywordType.KEYWORD),
+        SYNCHRONIZED        (126, "SYNCHRONIZED", "synchronized", TokenType.MODIFIER, KeywordType.KEYWORD),
+        NATIVE              (127, "NATIVE",     "native",   TokenType.MODIFIER, KeywordType.KEYWORD),
+        FINAL               (128, "FINAL",      "final",    TokenType.MODIFIER, KeywordType.KEYWORD),
+        VOLATILE            (129, "VOLATILE",   "volatile", TokenType.MODIFIER, KeywordType.KEYWORD),
+        ABSTRACT            (130, "ABSTRACT",   "abstract", TokenType.MODIFIER, KeywordType.KEYWORD),
+
+    /*
+     * Punctuation
+     */
+        SEMICOLON           (135, "SEMICOLON",  ";",    TokenType.PUNCTUATION, KeywordType.VALUE),
+        COLON               (136, "COLON",      ":",    TokenType.PUNCTUATION, KeywordType.VALUE),
+        QUESTIONMARK        (137, "QUESTIONMARK", "?",  TokenType.PUNCTUATION),
+        LBRACE              (138, "LBRACE",     "{",    TokenType.PUNCTUATION, KeywordType.VALUE),
+        RBRACE              (139, "RBRACE",     "}",    TokenType.PUNCTUATION, KeywordType.VALUE),
+        LPAREN              (140, "LPAREN",     "(",    TokenType.PUNCTUATION),
+        RPAREN              (141, "RPAREN",     ")",    TokenType.PUNCTUATION),
+        LSQBRACKET          (142, "LSQBRACKET", "[",    TokenType.PUNCTUATION),
+        RSQBRACKET          (143, "RSQBRACKET", "]",    TokenType.PUNCTUATION),
+        THROWS              (144, "THROWS",     "throws",  TokenType.DECLARATION, KeywordType.KEYWORD),
+    /*
+     * Special tokens
+     */
+        ERROR               (145, "ERROR",      "error",    TokenType.MODIFIER),
+        COMMENT             (146, "COMMENT",    "comment",   TokenType.MODIFIER),
+        TYPE                (147, "TYPE",       "type",     TokenType.MODIFIER),
+        LENGTH              (148, "LENGTH",     "length",   TokenType.DECLARATION),
+        INLINERETURN        (149, "INLINERETURN", "inline-return", TokenType.MODIFIER),
+        INLINEMETHOD        (150, "INLINEMETHOD", "inline-method", TokenType.MODIFIER),
+        INLINENEWINSTANCE   (151, "INLINENEWINSTANCE", "inline-new", TokenType.MODIFIER),
+
+    /*
+     * Added for jasm
+     */
+        METHODREF           (152, "METHODREF",  "Method",   TokenType.DECLARATION, KeywordType.KEYWORD, true),
+        FIELDREF            (153, "FIELD",      "Field",    TokenType.DECLARATION, KeywordType.KEYWORD, true),
+        STACK               (154, "STACK",      "stack",    TokenType.DECLARATION, KeywordType.KEYWORD, true),
+        LOCAL               (155, "LOCAL",      "locals",   TokenType.DECLARATION, KeywordType.KEYWORD, true),
+        CPINDEX             (156, "CPINDEX",    "CPINDEX",  TokenType.DECLARATION, true),
+        CPNAME              (157, "CPNAME",     "CPName",   TokenType.DECLARATION, true),
+        SIGN                (158, "SIGN",       "SIGN",     TokenType.DECLARATION, true),
+        BITS                (159, "BITS",       "bits",     TokenType.MISC, KeywordType.KEYWORD, true),
+        INF                 (160, "INF",        "Inf", "Infinity", TokenType.MISC, KeywordType.KEYWORD),
+        NAN                 (161, "NAN",        "NaN",      TokenType.MISC, KeywordType.KEYWORD, true),
+        INNERCLASS          (162, "INNERCLASS", "InnerClass", TokenType.DECLARATION, KeywordType.KEYWORD, true),
+        OF                  (163, "OF",         "of",       TokenType.DECLARATION, KeywordType.KEYWORD, true),
+        SYNTHETIC           (164, "SYNTHETIC",  "synthetic", TokenType.MODIFIER, KeywordType.KEYWORD, true),
+        STRICT              (165, "STRICT",     "strict",   TokenType.MODIFIER, KeywordType.KEYWORD, true),
+        DEPRECATED          (166, "DEPRECATED", "deprecated", TokenType.MODIFIER, KeywordType.KEYWORD, true),
+        VERSION             (167, "VERSION",    "version",  TokenType.DECLARATION, KeywordType.KEYWORD, true),
+        MODULE              (168, "MODULE",     "module",   TokenType.DECLARATION, KeywordType.KEYWORD),
+        ANNOTATION          (169, "ANNOTATION", "@",        TokenType.MISC),
+        PARAM_NAME          (173, "PARAM_NAME", "#",        TokenType.MISC),
+
+        VARARGS             (170, "VARARGS",    "varargs",  TokenType.MODIFIER, KeywordType.KEYWORD),
+        BRIDGE              (171, "BRIDGE",     "bridge",   TokenType.MODIFIER, KeywordType.KEYWORD),
+
+        // Declaration keywords
+        BOOTSTRAPMETHOD     (172, "BOOTSTRAPMETHOD", "BootstrapMethod", TokenType.DECLARATION, KeywordType.KEYWORD, true);
+
+        // Misc Keywords
+        private Integer value;
+        private String printval;
+        private String alias;
+        private TokenType tok_type;
+        private KeywordType key_type;
+        private String parsekey;
+        private boolean possible_jasm_identifier;
+
+        // By default, if a KeywordType is not specified, it has the value 'TOKEN'
+        Token(Integer val, String print, String op, TokenType ttype) {
+            init(val, print, op, null, ttype, KeywordType.TOKEN, false);
+        }
+
+        Token(Integer val, String print, String op, TokenType ttype, boolean ident) {
+            init(val, print, op, null, ttype, KeywordType.TOKEN, ident);
+        }
+
+        Token(Integer val, String print, String op, String als, TokenType ttype) {
+            init(val, print, op, als, ttype, KeywordType.TOKEN, false);
+        }
+
+        Token(Integer val, String print, String op, TokenType ttype, KeywordType ktype) {
+            init(val, print, op, null, ttype, ktype, false);
+        }
+
+        Token(Integer val, String print, String op, TokenType ttype, KeywordType ktype, boolean ident) {
+            init(val, print, op, null, ttype, ktype, ident);
+        }
+
+        Token(Integer val, String print, String op, String als, TokenType ttype, KeywordType ktype) {
+            init(val, print, op, als, ttype, ktype, false);
+        }
+
+        private void init(Integer val, String print, String op, String als, TokenType ttype, KeywordType ktype, boolean ident) {
+            value = val;
+            printval = print;
+            parsekey = op;
+            tok_type = ttype;
+            key_type = ktype;
+            alias = als;
+            possible_jasm_identifier = ident;
+        }
+
+        public String printval() {
+            return printval;
+        }
+
+        public String parsekey() {
+            return parsekey;
+        }
+
+        public int value() {
+            return value;
+        }
+
+        public boolean possibleJasmIdentifier() {
+            return possible_jasm_identifier;
+        }
+
+        @Override
+        public String toString() {
+            return "<" + printval + "> [" + value + "]";
+        }
+
+    }
+
+    /**
+     * Initialized keyword and token Hash Maps (and Reverse Tables)
+     */
+    static protected final int MaxTokens = 172;
+    private static HashMap<Integer, Token> TagToTokens = new HashMap<>(MaxTokens);
+    private static HashMap<String, Token> SymbolToTokens = new HashMap<>(MaxTokens);
+    private static HashMap<String, Token> ParsekeyToTokens = new HashMap<>(MaxTokens);
+
+    static protected final int MaxValTokens = 12;
+    private static HashMap<Integer, Token> TagToValTokens = new HashMap<>(MaxValTokens);
+    private static HashMap<String, Token> SymbolToValTokens = new HashMap<>(MaxValTokens);
+    private static HashMap<String, Token> ParsekeyToValTokens = new HashMap<>(MaxValTokens);
+
+    private static HashMap<Integer, Token> PossibleJasmIdentifiers = new HashMap<>(MaxValTokens);
+
+    static protected final int MaxKeywords = 40;
+    private static HashMap<Integer, Token> TagToKeywords = new HashMap<>(MaxKeywords);
+    private static HashMap<String, Token> SymbolToKeywords = new HashMap<>(MaxKeywords);
+    private static HashMap<String, Token> ParsekeyToKeywords = new HashMap<>(MaxKeywords);
+
+    static {
+
+        // register all of the tokens
+        for (Token tk : Token.values()) {
+            registerToken(tk);
+        }
+    }
+
+    private static void registerToken(Token tk) {
+        // Tag is a keyword
+        if (tk.key_type == KeywordType.KEYWORD) {
+            TagToKeywords.put(tk.value, tk);
+            if (tk.alias != null) {
+                ParsekeyToKeywords.put(tk.alias, tk);
+            }
+            SymbolToKeywords.put(tk.printval, tk);
+            if (tk.parsekey != null) {
+                ParsekeyToKeywords.put(tk.parsekey, tk);
+            }
+        }
+
+        // Values (and Keywords) go on the Val tokens list
+        if (tk.key_type == KeywordType.KEYWORD
+                || tk.key_type == KeywordType.VALUE) {
+            TagToValTokens.put(tk.value, tk);
+            SymbolToValTokens.put(tk.printval, tk);
+            if (tk.alias != null) {
+                SymbolToValTokens.put(tk.alias, tk);
+            }
+            if (tk.parsekey != null) {
+                ParsekeyToValTokens.put(tk.parsekey, tk);
+            }
+        }
+
+        // make the list of 'possible jasm identifiers'
+        if (tk.possible_jasm_identifier) {
+            PossibleJasmIdentifiers.put(tk.value(), tk);
+        }
+
+        // Finally, register all tokens
+        TagToTokens.put(tk.value, tk);
+        SymbolToTokens.put(tk.printval, tk);
+        ParsekeyToTokens.put(tk.printval, tk);
+    }
+
+    /* Token accessors */
+    public static Token token(int tk) {
+        return TagToTokens.get(tk);
+    }
+
+    public static Token val_token(int tk) {
+        return TagToValTokens.get(tk);
+    }
+
+    public static Token keyword_token(int tk) {
+        return TagToKeywords.get(tk);
+    }
+
+    public static Token possibleJasmIdentifiers(int token) {
+        return PossibleJasmIdentifiers.get(token);
+    }
+
+    /* Reverse lookup accessors */
+    public static Token token(String parsekey) {
+        return ParsekeyToTokens.get(parsekey);
+    }
+
+    public static Token val_token(String parsekey) {
+        return ParsekeyToValTokens.get(parsekey);
+    }
+
+    public static Token keyword_token(String parsekey) {
+        return ParsekeyToKeywords.get(parsekey);
+    }
+
+    /* Reverse lookup by ID accessors */
+    public static Token token_ID(String ID) {
+        return ParsekeyToTokens.get(ID);
+    }
+
+    public static Token val_token_ID(String ID) {
+        return ParsekeyToValTokens.get(ID);
+    }
+
+    public static Token keyword_token_ID(String ID) {
+        return ParsekeyToKeywords.get(ID);
+    }
+
+    public static String keywordName(int token) {
+        String retval = null;
+        Token tk = keyword_token(token);
+        if (tk != null) {
+            retval = tk.parsekey;
+        }
+        return retval;
+    }
+
+    public static int val_token_int(String idValue) {
+        Token kwd = val_token(idValue);
+        int retval = Token.IDENT.value;
+
+        if (kwd != null) {
+            retval = kwd.value;
+        }
+        return retval;
+    }
+
+    public static Token keyword_token_ident(String idValue) {
+        Token kwd = keyword_token(idValue);
+
+        if (kwd == null) {
+            kwd = Token.IDENT;
+        }
+        return kwd;
+    }
+
+    public static int keyword_token_int(String idValue) {
+        return keyword_token_ident(idValue).value();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/Main.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MAJOR_VERSION;
+import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MINOR_VERSION;
+import org.openjdk.asmtools.util.I18NResourceBundle;
+import org.openjdk.asmtools.util.ProductInfo;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+
+/**
+ *
+ *
+ */
+public class Main {
+
+    /**
+     * Name of the program.
+     */
+    String program;
+    /**
+     * The stream where error message are printed.
+     */
+    PrintStream out;
+    int nerrors = 0;
+
+    public static final I18NResourceBundle i18n
+            = I18NResourceBundle.getBundleForClass(Main.class);
+
+    private File destDir = null;
+    private boolean traceFlag = false;
+    private boolean debugInfoFlag = false;
+    private long tm = System.currentTimeMillis();
+    private ArrayList<String> v = new ArrayList<>();
+    private boolean nowrite = false;
+    private boolean nowarn = false;
+    private boolean strict = false;
+    private String props = null;
+    private int nwarnings = 0;
+    private short major_version = DEFAULT_MAJOR_VERSION;
+    private short minor_version = DEFAULT_MINOR_VERSION;
+    private int bytelimit = 0;
+    private boolean debugScanner = false;
+    private boolean debugMembers = false;
+    private boolean debugCP = false;
+    private boolean debugAnnot = false;
+    private boolean debugInstr = false;
+
+    /**
+     * Constructor.
+     */
+    public Main(PrintStream out, String program) {
+        this.out = out;
+        this.program = program;
+    }
+
+    /**
+     * Top level error message
+     */
+    public void error(String msg) {
+        nerrors++;
+        out.println(program + ": " + msg);
+    }
+
+    /**
+     * Usage
+     */
+    public void usage() {
+        out.println(i18n.getString("jasm.usage"));
+        out.println(i18n.getString("jasm.opt.d"));
+        out.println(i18n.getString("jasm.opt.g"));
+        out.println(i18n.getString("jasm.opt.v"));
+        out.println(i18n.getString("jasm.opt.nowrite"));
+        out.println(i18n.getString("jasm.opt.nowarn"));
+        out.println(i18n.getString("jasm.opt.strict"));
+        out.println(i18n.getString("jasm.opt.cv", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION));
+        out.println(i18n.getString("jasm.opt.version"));
+    }
+
+    /**
+     * Run the compiler
+     */
+    private synchronized boolean parseArgs(String argv[]) {
+        // Parse arguments
+        for (int i = 0; i < argv.length; i++) {
+            String arg = argv[i];
+            switch (arg) {
+                case "-v":
+                    traceFlag = true;
+                    break;
+                case "-g":
+                    debugInfoFlag = true;
+                    break;
+                case "-nowrite":
+                    nowrite = true;
+                    break;
+                case "-strict":
+                    strict = true;
+                    break;
+                case "-nowarn":
+                    nowarn = true;
+                    break;
+                case "-version":
+                    out.println(ProductInfo.FULL_VERSION);
+                    break;
+                case "-d":
+                    if ((i + 1) >= argv.length) {
+                        error(i18n.getString("jasm.error.d_requires_argument"));
+                        usage();
+                        return false;
+                    }
+                    destDir = new File(argv[++i]);
+                    if (!destDir.exists()) {
+                        error(i18n.getString("jasm.error.does_not_exist", destDir.getPath()));
+                        return false;
+                    }
+                    break;
+                // non-public options
+                case "-XdScanner":
+                    debugScanner = true;
+                    break;
+                case "-XdMember":
+                    debugMembers = true;
+                    break;
+                case "-XdCP":
+                    debugCP = true;
+                    break;
+                case "-XdInstr":
+                    debugInstr = true;
+                    break;
+                case "-XdAnnot":
+                    debugAnnot = true;
+                    break;
+                case "-XdAll":
+                    debugScanner = true;
+                    debugMembers = true;
+                    debugCP = true;
+                    debugInstr = true;
+                    debugAnnot = true;
+                    break;
+                case "-Xdlimit":
+                    // parses file until the specified byte number
+                    if (i + 1 > argv.length) {
+                        out.println(" Error: Unspecified byte-limit");
+                        return false;
+                    } else {
+                        i++;
+                        String bytelimstr = argv[i];
+                        bytelimit = 0;
+                        try {
+                            bytelimit = Integer.parseInt(bytelimstr);
+                        } catch (NumberFormatException e) {
+                            out.println(" Error: Unspecified byte-limit");
+                            return false;
+                        }
+                    }
+                    break;
+                case "-cv":
+                    if ((i + 1) >= argv.length) {
+                        error(i18n.getString("jasm.error.cv_requires_arg"));
+                        usage();
+                        return false;
+                    }
+                    String[] versions = {"", ""};                      // workaround for String.split()
+                    int index = argv[++i].indexOf(".");                //
+                    if (index != -1) {                                 //
+                        versions[0] = argv[i].substring(0, index);     //
+                        versions[1] = argv[i].substring(index + 1);    //
+                    }                                                  //
+                    if (versions.length != 2) {
+                        error(i18n.getString("jasm.error.invalid_major_minor_param"));
+                        usage();
+                        return false;
+                    }
+                    try {
+                        major_version = Short.parseShort(versions[0]);
+                        minor_version = Short.parseShort(versions[1]);
+                    } catch (NumberFormatException e) {
+                        error(i18n.getString("jasm.error.invalid_major_minor_param"));
+                        usage();
+                        return false;
+                    }
+                    break;
+                default:
+                    if (arg.startsWith("-")) {
+                        error(i18n.getString("jasm.error.invalid_option", arg));
+                        usage();
+                        return false;
+                    } else {
+                        v.add(argv[i]);
+                    }
+                    break;
+            }
+        }
+        if (v.size() == 0) {
+            usage();
+            return false;
+        }
+        if (strict) {
+            nowarn = false;
+        }
+        return true;
+    }
+
+    private void reset() {
+        destDir = null;
+        traceFlag = false;
+        debugInfoFlag = false;
+        System.currentTimeMillis();
+        v = new ArrayList<>();
+        nowrite = false;
+        nowarn = false;
+        strict = false;
+        props = null;
+        nwarnings = 0;
+        major_version = DEFAULT_MAJOR_VERSION;
+        minor_version = DEFAULT_MINOR_VERSION;
+        bytelimit = 0;
+    }
+
+    /**
+     * Run the compiler
+     */
+    public synchronized boolean compile(String argv[]) {
+        // Reset the state of all objs
+        reset();
+
+        boolean validArgs = parseArgs(argv);
+        if (!validArgs) {
+            return false;
+        }
+        // compile all input files
+        Environment sf = null;
+        try {
+            for (String inpname : v) {
+                Parser p;
+                try {
+                    sf = new Environment(new File(inpname), out, nowarn);
+                    sf.traceFlag = traceFlag;
+                    sf.debugInfoFlag = debugInfoFlag;
+                    p = new Parser(sf, major_version, minor_version);
+                    p.setDebugFlags(debugScanner, debugMembers, debugCP, debugAnnot, debugInstr);
+                    p.parseFile();
+                } catch (FileNotFoundException ex) {
+                    error(i18n.getString("jasm.error.cannot_read", inpname));
+                    continue;
+                }
+                nerrors += sf.nerrors;
+                nwarnings += sf.nwarnings;
+                if (nowrite || (nerrors > 0)) {
+                    sf.flushErrors();
+                    continue;
+                }
+                try {
+                    ClassData[] clsData = p.getClassesData();
+                    for (int i = 0; i < clsData.length; i++) {
+                        ClassData cd = clsData[i];
+                        if (bytelimit > 0) {
+                            cd.setByteLimit(bytelimit);
+                        }
+                        cd.write(destDir);
+                    }
+                } catch (IOException ex) {
+                    if (bytelimit > 0) {
+                        // IO Error thrown from user-specified byte ount
+                        ex.printStackTrace();
+                        error("UserSpecified byte-limit at byte[" + bytelimit + "]: " + ex.getMessage() + "\n" + sf.getErrorFile() + ": [" + sf.lineNumber() + ", " + sf.lineOffset() + "]");
+                    } else {
+                        String er = i18n.getString("jasm.error.cannot_write", ex.getMessage());
+                        error(er + "\n" + sf.getErrorFile() + ": [" + sf.lineNumber() + ", " + sf.lineOffset() + "]");
+                    }
+                }
+                sf.flushErrors(); // possible errors from write()
+            }
+        } catch (Error ee) {
+            if (debugInfoFlag) {
+                ee.printStackTrace();
+            }
+            String er = ee.getMessage() + "\n" + i18n.getString("jasm.error.fatal_error");
+            error(er + "\n" + sf.getErrorFile() + ": [" + sf.lineNumber() + ", " + sf.lineOffset() + "]");
+        } catch (Exception ee) {
+            if (debugInfoFlag) {
+                ee.printStackTrace();
+            }
+            String er = ee.getMessage() + "\n" + ee.getMessage() + "\n" + i18n.getString("jasm.error.fatal_exception");
+            error(er + "\n" + sf.getErrorFile() + ": [" + sf.lineNumber() + ", " + sf.lineOffset() + "]");
+        }
+
+        boolean errs = nerrors > 0;
+        boolean warns = (nwarnings > 0) && (!nowarn);
+        boolean errsOrWarns = errs || warns;
+        if (!errsOrWarns) {
+            return true;
+        }
+        if (errs) {
+            out.print(nerrors > 1 ? (nerrors + " errors") : "1 error");
+        }
+        if (errs && warns) {
+            out.print(", ");
+        }
+        if (warns) {
+            out.print(nwarnings > 1 ? (nwarnings + " warnings") : "1 warning");
+        }
+        out.println();
+        if (strict) {
+            return !errsOrWarns;
+        } else {
+            return !errs;
+        }
+    }
+
+    /**
+     * main program
+     */
+    public static void main(String argv[]) {
+        Main compiler = new Main(System.out, "jasm");
+        System.exit(compiler.compile(argv) ? 0 : 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/MemberData.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import static org.openjdk.asmtools.jasm.RuntimeConstants.DEPRECATED_ATTRIBUTE;
+import static org.openjdk.asmtools.jasm.RuntimeConstants.SYNTHETIC_ATTRIBUTE;
+import org.openjdk.asmtools.jasm.Tables.AttrTag;
+import java.util.ArrayList;
+
+/**
+ *
+ *
+ */
+public class MemberData {
+
+    protected int access;
+    protected AttrData syntheticAttr,
+            deprecatedAttr;
+    protected DataVectorAttr<AnnotationData> annotAttrVis = null;
+    protected DataVectorAttr<AnnotationData> annotAttrInv = null;
+    protected DataVectorAttr<TypeAnnotationData> type_annotAttrVis = null;
+    protected DataVectorAttr<TypeAnnotationData> type_annotAttrInv = null;
+    protected ClassData cls;
+
+    public MemberData(ClassData cls, int access) {
+        this.cls = cls;
+        init(access);
+    }
+
+    public void init(int access) {
+        this.access = access;
+    }
+
+    public void createPseudoMod() {
+        // If a member has a Pseudo-modifier
+
+        // create the appropriate marker attributes,
+        // and clear the PseudoModifiers from the access flags.
+        if (Modifiers.isSyntheticPseudoMod(access)) {
+            syntheticAttr = new AttrData(cls,
+                    AttrTag.ATT_Synthetic.parsekey());
+
+            access &= ~SYNTHETIC_ATTRIBUTE;
+        }
+        if (Modifiers.isDeprecatedPseudoMod(access)) {
+            deprecatedAttr = new AttrData(cls,
+                    AttrTag.ATT_Deprecated.parsekey());
+            access &= ~DEPRECATED_ATTRIBUTE;
+        }
+    }
+
+    public void addAnnotations(ArrayList<AnnotationData> annttns) {
+        for (AnnotationData annot : annttns) {
+            boolean invisible = annot.invisible;
+            if (annot instanceof TypeAnnotationData) {
+                // Type Annotations
+                TypeAnnotationData tannot = (TypeAnnotationData) annot;
+                if (invisible) {
+                    if (type_annotAttrInv == null) {
+                        type_annotAttrInv = new DataVectorAttr(cls,
+                                AttrTag.ATT_RuntimeInvisibleTypeAnnotations.parsekey());
+
+                    }
+                    type_annotAttrInv.add(tannot);
+                } else {
+                    if (type_annotAttrVis == null) {
+                        type_annotAttrVis = new DataVectorAttr(cls,
+                                AttrTag.ATT_RuntimeVisibleTypeAnnotations.parsekey());
+                    }
+                    type_annotAttrVis.add(tannot);
+                }
+            } else {
+                // Regular Annotations
+                if (invisible) {
+                    if (annotAttrInv == null) {
+                        annotAttrInv = new DataVectorAttr(cls,
+                                AttrTag.ATT_RuntimeInvisibleAnnotations.parsekey());
+
+                    }
+                    annotAttrInv.add(annot);
+                } else {
+                    if (annotAttrVis == null) {
+                        annotAttrVis = new DataVectorAttr(cls,
+                                AttrTag.ATT_RuntimeVisibleAnnotations.parsekey());
+
+                    }
+                    annotAttrVis.add(annot);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/MethodData.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import org.openjdk.asmtools.jasm.Tables.AttrTag;
+import org.openjdk.asmtools.jasm.ConstantPool.ConstCell;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.TreeMap;
+
+/**
+ *
+ */
+class MethodData extends MemberData {
+
+    /**
+     * MethodParamData
+     */
+    class ParamNameData implements Data {
+
+        int access;
+        ConstCell name;
+
+        public ParamNameData(int access, ConstCell name) {
+            this.access = access;
+            this.name = name;
+        }
+
+        @Override
+        public int getLength() {
+            return 4;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            int nm = 0;
+            int ac = 0;
+            if (name != null) {
+                nm = name.arg;
+                ac = access;
+            }
+
+// short acc = (short) ac;
+// env.traceln("ParamNameData.write() (name[" + nm + "], Flags: (" + access + ").  [TESTING: short_access=" + acc + "]");
+            out.writeShort(nm);
+            out.writeShort(ac);
+        }
+    }// end class MethodParamData
+  /*-------------------------------------------------------- */
+    /* MethodParamData Inner Classes */
+
+    /**
+     * DataPArrayAttr
+     *
+     * Used to store Parameter Arrays (as attributes)
+     */
+    static public class DataPArrayAttr<T extends Data> extends AttrData implements Constants {
+
+        TreeMap<Integer, ArrayList<T>> elements; // Data
+        int paramsTotal;
+
+        public DataPArrayAttr(ClassData cls, String name, int paramsTotal, TreeMap<Integer, ArrayList<T>> elements) {
+            super(cls, name);
+            this.paramsTotal = paramsTotal;
+            this.elements = elements;
+        }
+
+        public DataPArrayAttr(ClassData cls, String name, int paramsTotal) {
+            this(cls, name, paramsTotal, new TreeMap<Integer, ArrayList<T>>());
+        }
+
+        public void put(int paramNum, T element) {
+            ArrayList<T> v = get(paramNum);
+            if (v == null) {
+                v = new ArrayList<>();
+                elements.put(paramNum, v);
+            }
+
+            v.add(element);
+        }
+
+        public ArrayList<T> get(int paramNum) {
+            return elements.get(paramNum);
+        }
+
+        @Override
+        public int attrLength() {
+            int length = 1;  // One byte for the paramater count
+
+            // calculate overall size here rather than in add()
+            // because it may not be available at the time of invoking of add()
+            for (int i = 0; i < paramsTotal; i++) {
+                ArrayList<T> attrarray = get(i);
+                if (attrarray != null) {
+                    for (Data item : attrarray) {
+                        length += item.getLength();
+                    }
+                }
+                length += 2; // 2 bytes for the annotation count for each parameter
+            }
+
+            return length;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            super.write(out);  // attr name, attr len
+            out.writeByte(paramsTotal); // number of parameters total (in byte)
+
+            for (int i = 0; i < paramsTotal; i++) {
+                ArrayList<T> attrarray = get(i);
+                if (attrarray != null) {
+                    // write out the number of annotations for the current param
+                    out.writeShort(attrarray.size());
+                    for (T item : attrarray) {
+                        item.write(out); // write the current annotation
+                    }
+                } else {
+                    out.writeShort(0);
+                    // No annotations to write out
+                }
+            }
+        }
+    }// end class DataPArrayAttr
+
+
+    /*-------------------------------------------------------- */
+    /* Method Data Fields */
+    protected Environment env;
+    protected ConstCell nameCell, sigCell;
+    protected CodeAttr code;
+    protected DataVectorAttr<ConstCell> exceptions = null;
+    protected DataVectorAttr<ParamNameData> paramNames = null;
+    protected DataPArrayAttr<AnnotationData> pannotAttrVis = null;
+    protected DataPArrayAttr<AnnotationData> pannotAttrInv = null;
+    protected DefaultAnnotationAttr defaultAnnot = null;
+    protected DataVector attrs = new DataVector();
+    /*-------------------------------------------------------- */
+
+    public MethodData(ClassData cls, int acc,
+            ConstCell name, ConstCell sig, ArrayList<ConstCell> exc_table) {
+        super(cls, acc);
+        this.env = cls.env;
+        nameCell = name;
+        sigCell = sig;
+        if ((exc_table != null) && (!exc_table.isEmpty())) {
+            exceptions = new DataVectorAttr<>(cls,
+                    AttrTag.ATT_Exceptions.parsekey(),
+                    exc_table);
+        }
+        // Normalize the modifiers to access flags
+        if (Modifiers.hasPseudoMod(acc)) {
+            createPseudoMod();
+        }
+    }
+
+    public void addMethodParameter(int totalParams, int paramNum, ConstCell name, int access) {
+        env.traceln("addMethodParameter Param[" + paramNum + "] (name: " + name.toString() + ", Flags (" + access + ").");
+        if (paramNames == null) {
+            paramNames = new DataVectorAttr<>(cls, AttrTag.ATT_MethodParameters.parsekey(), true);
+            for (int i = 0; i < totalParams; i++) {
+                // initialize the paramName array (in case the name is not given in Jasm syntax)
+                paramNames.add(new ParamNameData(0, null));
+            }
+        }
+        paramNames.add(paramNum, new ParamNameData(access, name));
+    }
+
+    public CodeAttr startCode(int pos, int paramcnt, Argument max_stack, Argument max_locals) {
+        code = new CodeAttr(this, pos, paramcnt, max_stack, max_locals);
+        return code;
+    }
+
+    public void addDefaultAnnotation(DefaultAnnotationAttr data) {
+        defaultAnnot = data;
+    }
+
+    public void addParamAnnotation(int totalParams, int paramNum, AnnotationData data) {
+        if (!data.invisible) {
+            if (pannotAttrVis == null) {
+                pannotAttrVis = new DataPArrayAttr<>(cls,
+                        AttrTag.ATT_RuntimeVisibleParameterAnnotations.parsekey(),
+                        totalParams);
+            }
+            pannotAttrVis.put(paramNum, data);
+
+        } else {
+            if (pannotAttrInv == null) {
+                pannotAttrInv = new DataPArrayAttr<>(cls,
+                        AttrTag.ATT_RuntimeInvisibleParameterAnnotations.parsekey(),
+                        totalParams);
+            }
+            pannotAttrInv.put(paramNum, data);
+        }
+    }
+
+
+    /*====================================================== Write */
+    public void write(CheckedDataOutputStream out) throws IOException, Parser.CompilerError {
+        out.writeShort(access);
+        out.writeShort(nameCell.arg);
+        out.writeShort(sigCell.arg);
+        if (exceptions != null) {
+            attrs.add(exceptions);
+        }
+        if (syntheticAttr != null) {
+            attrs.add(syntheticAttr);
+        }
+        if (deprecatedAttr != null) {
+            attrs.add(deprecatedAttr);
+        }
+        if (paramNames != null) {
+            attrs.add(paramNames);
+        }
+        if (code != null) {
+            attrs.add(code);
+        }
+        if (defaultAnnot != null) {
+            attrs.add(defaultAnnot);
+        }
+        if (annotAttrVis != null) {
+            attrs.add(annotAttrVis);
+        }
+        if (annotAttrInv != null) {
+            attrs.add(annotAttrInv);
+        }
+        if (type_annotAttrVis != null) {
+            attrs.add(type_annotAttrVis);
+        }
+        if (type_annotAttrInv != null) {
+            attrs.add(type_annotAttrInv);
+        }
+        if (pannotAttrVis != null) {
+            attrs.add(pannotAttrVis);
+        }
+        if (pannotAttrInv != null) {
+            attrs.add(pannotAttrInv);
+        }
+
+        attrs.write(out);
+    }
+} // end MethodData
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/Modifiers.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
+import static org.openjdk.asmtools.jasm.JasmTokens.*;
+import static org.openjdk.asmtools.jasm.Tables.CF_Context;
+
+/**
+ *
+ *
+ */
+public class Modifiers {
+
+    private static Modifiers ref;
+
+    /*
+     * Modifier masks
+     */
+    public static final int MM_ATTR        = SYNTHETIC_ATTRIBUTE | DEPRECATED_ATTRIBUTE;
+
+    public static final int MM_INTRF       = ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE | MM_ATTR ; // | ACC_MODULE  ;
+    public static final int MM_CLASS       = ACC_PUBLIC | ACC_FINAL|  ACC_SUPER | ACC_ABSTRACT | ACC_SYNTHETIC  | ACC_ANNOTATION | ACC_ENUM | MM_ATTR ; // |  ACC_MODULE ;
+    public static final int MM_ACCESS      = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED; // | ACC_MODULE;
+    public static final int MM_FIELD       = MM_ACCESS | ACC_STATIC | ACC_FINAL |  ACC_VOLATILE | ACC_TRANSIENT |  ACC_SYNTHETIC | ACC_ENUM | MM_ATTR ; // |  ACC_MODULE ;
+    public static final int MM_I_METHOD    = ACC_ABSTRACT | ACC_PUBLIC | ACC_VARARGS | ACC_BRIDGE | ACC_SYNTHETIC ; // interface method
+    public static final int MM_A_METHOD    = MM_ACCESS | ACC_ABSTRACT | MM_ATTR;
+    public static final int MM_N_METHOD    = MM_ACCESS | ACC_STRICT | ACC_VARARGS | ACC_SYNTHETIC | MM_ATTR;  // <init>
+    public static final int MM_METHOD      = MM_ACCESS | ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |  ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE | ACC_ABSTRACT |  ACC_STRICT | ACC_SYNTHETIC | MM_ATTR ; // |  ACC_MODULE ;
+    public static final int MM_INNERCLASS  = MM_ACCESS | ACC_STATIC | ACC_FINAL | ACC_SUPER | ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM | MM_ATTR ; // |  ACC_MODULE ;
+
+    private Modifiers() {
+    }
+
+    public static Modifiers ModifiersObject() {
+        if (ref == null) {
+            ref = new Modifiers();
+        }
+        return ref;
+    }
+
+    public static boolean validClass(int mod) {
+        return (mod & ~MM_CLASS) == 0;
+    }
+
+    public static boolean validInnerClass(int mod) {
+        return (mod & ~MM_INNERCLASS) == 0;
+    }
+
+    public static boolean validField(int mod) {
+        return (mod & ~MM_FIELD) == 0;
+    }
+
+    public static boolean validMethod(int mod) {
+        return (mod & ~MM_METHOD) == 0;
+    }
+
+    public static boolean validInterface(int mod) {
+        return (mod & ~MM_INTRF) == 0;
+    }
+
+    public static boolean validAbstractMethod(int mod) {
+        return (mod & ~MM_A_METHOD) == 0;
+    }
+
+    public static boolean validInitMethod(int mod) {
+        return (mod & ~MM_N_METHOD) == 0;
+    }
+
+    public static boolean validInterfaceMethod(int mod) {
+//        return (mod & ~MM_ATTR) == MM_I_METHOD;
+        return ((mod & ~MM_I_METHOD) == 0) && isPublic(mod) && isAbstract(mod);
+    }
+
+    public static boolean validInterfaceField(int mod) {
+        return mod == (ACC_STATIC | ACC_PUBLIC | ACC_FINAL);
+    }
+
+    public static boolean isPublic(int mod) {
+        return (mod & ACC_PUBLIC) != 0;
+    }
+
+    public static boolean isPrivate(int mod) {
+        return (mod & ACC_PRIVATE) != 0;
+    }
+
+    public static boolean isProtected(int mod) {
+        return (mod & ACC_PROTECTED) != 0;
+    }
+
+    public static boolean isInterface(int mod) {
+        return (mod & ACC_INTERFACE) != 0;
+    }
+
+    public static boolean isAbstract(int mod) {
+        return (mod & ACC_ABSTRACT) != 0;
+    }
+
+    public static boolean isFinal(int mod) {
+        return (mod & ACC_FINAL) != 0;
+    }
+
+    public static boolean isStatic(int mod) {
+        return (mod & ACC_STATIC) != 0;
+    }
+
+    public static boolean isSynthetic(int mod) {
+        return (mod & ACC_SYNTHETIC) != 0;
+    }
+
+    public static boolean isDeprecated(int mod) {
+        return (mod & DEPRECATED_ATTRIBUTE) != 0;
+    }
+
+    public static boolean isTransient(int mod) {
+        return (mod & ACC_TRANSIENT) != 0;
+    }
+
+    public static boolean isAnnotation(int mod) {
+        return (mod & ACC_ANNOTATION) != 0;
+    }
+
+    public static boolean isNative(int mod) {
+        return (mod & ACC_NATIVE) != 0;
+    }
+
+    public static boolean isStrict(int mod) {
+        return (mod & ACC_STRICT) != 0;
+    }
+
+    public static boolean isEnum(int mod) {
+        return (mod & ACC_ENUM) != 0;
+    }
+
+    public static boolean isSuper(int mod) {
+        return (mod & ACC_SUPER) != 0;
+    }
+    /*
+     public static boolean isModule(int mod) {
+     return (mod & ACC_MODULE)!=0;
+     }
+     * */
+
+    public static boolean isMandated(int mod) {
+        return (mod & ACC_MANDATED) != 0;
+    }
+
+    public static boolean isSynchronized(int mod) {
+        return (mod & ACC_SYNCHRONIZED) != 0;
+    }
+
+    public static boolean isBridge(int mod) {
+        return (mod & ACC_BRIDGE) != 0;
+    }
+
+    public static boolean isVolatile(int mod) {
+        return (mod & ACC_VOLATILE) != 0;
+    }
+
+    public static boolean isVarArgs(int mod) {
+        return (mod & ACC_VARARGS) != 0;
+    }
+
+    public static boolean isSyntheticPseudoMod(int mod) {
+        return (mod & SYNTHETIC_ATTRIBUTE) != 0;
+    }
+
+    public static boolean isDeprecatedPseudoMod(int mod) {
+        return (mod & DEPRECATED_ATTRIBUTE) != 0;
+    }
+
+    public static boolean hasPseudoMod(int mod) {
+        return isSyntheticPseudoMod(mod) || isDeprecatedPseudoMod(mod);
+    }
+
+    /*
+     * Checks that only one (or none) of the Access flags are set.
+     */
+    public static boolean validAccess(int mod) {
+        boolean retval = true;
+        switch (mod & MM_ACCESS) {
+            case 0:
+            //        case ACC_MODULE:
+            case ACC_PUBLIC:
+            case ACC_PRIVATE:
+            case ACC_PROTECTED:
+                break;
+            default:
+                retval = false;
+        }
+
+        return retval;
+
+    }
+
+    /*
+     * Are both flags set
+     *
+     */
+    public static boolean both(int mod, int flagA, int flagB) {
+        return (mod & (flagA | flagB)) == (flagA | flagB);
+    }
+
+    /**
+     * Check the modifier flags for the class
+     *
+     * @param env The error reporting environment.
+     * @param mod The modifier flags being checked
+     * @param pos the position of the parser in the file
+     */
+    public static void checkClassModifiers(Environment env, int mod, int pos) {
+        if (isInterface(mod)) {
+            if (!validInterface(mod)) {
+                env.error(pos, "warn.invalid.modifier.int");
+            }
+            if (!isAbstract(mod)) {
+                env.error(pos, "warn.invalid.modifier.int.abs");
+            }
+        } else {
+            if (!validClass(mod)) {
+                env.error(pos, "warn.invalid.modifier.class");
+            }
+            if (isAbstract(mod) && Modifiers.isFinal(mod)) {
+                env.error(pos, "warn.invalid.modifier.class.finabs");
+            }
+        }
+    }
+
+    /**
+     * Check the modifier flags for the field
+     *
+     * @param cd The ClassData for the current class
+     * @param mod The modifier flags being checked
+     * @param pos the position of the parser in the file
+     */
+    public static void checkFieldModifiers(ClassData cd, int mod, int pos) {
+        Environment env = cd.env;
+        if (cd.isInterface()) {
+            // For interfaces
+            if (!validInterfaceField(mod)) {
+                env.error(pos, "warn.invalid.modifier.intfield");
+            }
+        } else {
+            // For non-interfaces
+            if (!validField(mod)) {
+                env.error(pos, "warn.invalid.modifier.field");
+            }
+            if (both(mod, ACC_FINAL, ACC_VOLATILE)) {
+                env.error(pos, "warn.invalid.modifier.fiva");
+            }
+            if (!validAccess(mod)) {
+                env.error(pos, "warn.invalid.modifier.acc");
+            }
+        }
+
+    }
+
+    /**
+     * Check the modifier flags for the method
+     *
+     * @param cd The ClassData for the current class
+     * @param mod The modifier flags being checked
+     * @param pos the position of the parser in the file
+     */
+    public static void checkMethodModifiers(ClassData cd, int mod, int pos, boolean is_init, boolean is_clinit) {
+        Environment env = cd.env;
+        if (!is_clinit) {
+            if (cd.isInterface()) {
+                if (is_init) {
+                    env.error(pos, "warn.init.in_int");
+                } else if (!validInterfaceMethod(mod)) {
+                    int badflags = (mod & ~MM_I_METHOD);
+                    env.error(pos, "warn.invalid.modifier.intmth", toString(badflags, CF_Context.CTX_METHOD)
+                            + "   *****" + toString(mod, CF_Context.CTX_METHOD) + "*****");
+                }
+            } else {
+                if (is_init && !validInitMethod(mod)) {
+                    int badflags = (mod & ~MM_N_METHOD);
+                    env.error(pos, "warn.invalid.modifier.init", toString(badflags, CF_Context.CTX_METHOD)
+                            + "   *****" + toString(mod, CF_Context.CTX_METHOD) + "*****");
+                } else if (isAbstract(mod)) {
+                    if (!validAbstractMethod(mod)) {
+                        int badflags = (mod & ~MM_A_METHOD);
+                        env.error(pos, "warn.invalid.modifier.abst", toString(badflags, CF_Context.CTX_METHOD)
+                                + "   *****" + toString(mod, CF_Context.CTX_METHOD) + "*****");
+                    }
+                } else {
+                    if (!validMethod(mod)) {
+                        env.error(pos, "warn.invalid.modifier.mth");
+                    }
+                }
+                if (!validAccess(mod)) {
+                    env.error(pos, "warn.invalid.modifier.acc");
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Check the modifier flags for the inner-class
+     *
+     * @param cd The ClassData for the current class
+     * @param mod The modifier flags being checked
+     * @param pos the position of the parser in the file
+     */
+    public static void checkInnerClassModifiers(ClassData cd, int mod, int pos) {
+        Environment env = cd.env;
+
+        if (!validInnerClass(mod)) {
+            int badflags = (mod & ~MM_INNERCLASS);
+            env.error(pos, "warn.invalid.modifier.innerclass",
+                    toString(badflags, CF_Context.CTX_INNERCLASS)
+                    + "   *****" + toString(mod, CF_Context.CTX_INNERCLASS) + "*****");
+        }
+
+    }
+
+    private static StringBuffer _accessString(int mod, CF_Context context) {
+        StringBuffer sb = new StringBuffer();
+ //       if (isModule(mod))
+        //           sb.append(Tables.keywordName(Tables.Module) + " ");
+        if (isPublic(mod)) {
+            sb.append(Token.PUBLIC.parsekey() + " ");
+        }
+        if (isPrivate(mod)) {
+            sb.append(Token.PRIVATE.parsekey() + " ");
+        }
+        if (isProtected(mod)) {
+            sb.append(Token.PROTECTED.parsekey() + " ");
+        }
+        if (isStatic(mod)) {
+            sb.append(Token.STATIC.parsekey() + " ");
+        }
+        if (context == CF_Context.CTX_METHOD && isFinal(mod)) {
+            sb.append(Token.FINAL.parsekey() + " ");
+        }
+        if (context == CF_Context.CTX_FIELD && isTransient(mod)) {
+            sb.append(Token.TRANSIENT.parsekey() + " ");
+        }
+        if (context == CF_Context.CTX_CLASS && isSuper(mod)) {
+            sb.append(Token.SUPER.parsekey() + " ");
+        }
+        if (context == CF_Context.CTX_METHOD && isSynchronized(mod)) {
+            sb.append(Token.SYNCHRONIZED.parsekey() + " ");
+        }
+        if (context == CF_Context.CTX_METHOD) {
+            if (isBridge(mod)) {
+                sb.append(Token.BRIDGE.parsekey() + " ");
+            }
+            if (isVarArgs(mod)) {
+                sb.append(Token.VARARGS.parsekey() + " ");
+            }
+            if (isNative(mod)) {
+                sb.append(Token.NATIVE.parsekey() + " ");
+            }
+        }
+        if (isAbstract(mod)) {
+            if ((context != CF_Context.CTX_CLASS) || !isInterface(mod)) {
+                sb.append(Token.ABSTRACT.parsekey() + " ");
+            }
+        }
+        if ((context == CF_Context.CTX_CLASS || context == CF_Context.CTX_INNERCLASS || context == CF_Context.CTX_FIELD) && isFinal(mod)) {
+            sb.append(Token.FINAL.parsekey() + " ");
+        }
+        if ((context == CF_Context.CTX_CLASS || context == CF_Context.CTX_INNERCLASS) && isInterface(mod)) {
+            sb.append(Token.INTERFACE.parsekey() + " ");
+        }
+        if (isStrict(mod)) {
+            sb.append(Token.STRICT.parsekey() + " ");
+        }
+        if (isSynthetic(mod)) {
+            sb.append(Token.SYNTHETIC.parsekey() + " ");
+        }
+        if (context == CF_Context.CTX_FIELD && isVolatile(mod)) {
+            sb.append(Token.VOLATILE.parsekey() + " ");
+        }
+        if (isEnum(mod)) {
+            sb.append(Token.ENUM.parsekey() + " ");
+        }
+        if (isMandated(mod)) {
+            sb.append(Token.MANDATED.parsekey() + " ");
+        }
+//      We don't have print identifiers for annotation flags
+//      if (isAnnotation(mod))
+//          sb.append(Tables.keywordName(Tables.ANNOTATION) + " ");
+
+        return sb;
+    }
+
+    public static String toString(int mod, CF_Context context) {
+        StringBuffer sb = _accessString(mod, context);
+
+        if (isSyntheticPseudoMod(mod)) {
+            sb.append("Synthetic(Pseudo) ");
+        }
+        if (isDeprecatedPseudoMod(mod)) {
+            sb.append("Deprecated(Pseudo) ");
+        }
+
+        return sb.toString();
+    }
+
+    public static String accessString(int mod, CF_Context context) {
+        StringBuffer sb = _accessString(mod, context);
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/OpcodeTables.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.util.HashMap;
+
+/**
+ *
+ * OpcodeTables
+ *
+ * The OpcodeTables class follows a Singleton Pattern. This class contains Enums, that are
+ * contained in private hash maps (lookup tables and reverse lookup tables). These hash
+ * maps all have public accessors, which clients use to look-up opcodes.
+ *
+ * Tokens in this table carry no external state, and are typically treated as constants.
+ * They do not need to be reset.
+ *
+ */
+public class OpcodeTables {
+
+    /**
+     * Initialized keyword and token Hash Maps (and Reverse Tables)
+     */
+    static private final int MaxOpcodes = 301;
+    static private HashMap<Integer, Opcode> IntToNormalOpcodes = new HashMap<>(MaxOpcodes);
+    static private HashMap<Integer, Opcode> IntToAllOpcodes = new HashMap<>(MaxOpcodes);
+    static private HashMap<String, Opcode> mnemocodes = new HashMap<>(MaxOpcodes);
+
+    static private HashMap<Integer, Opcode> IntToPrivOpcode = new HashMap<>(MaxOpcodes);
+    static private HashMap<String, Opcode> PrivMnemocodes = new HashMap<>(MaxOpcodes);
+
+    static private HashMap<Integer, Opcode> IntToNonPrivOpcode = new HashMap<>(MaxOpcodes);
+    static private HashMap<String, Opcode> NonPrivMnemocodes = new HashMap<>(MaxOpcodes);
+
+    static {
+        // register all of the tokens
+        for (Opcode opc : Opcode.values()) {
+            registerOpcode(opc);
+        }
+
+    }
+
+    private static void registerOpcode(Opcode opc) {
+        IntToAllOpcodes.put(opc.value, opc);
+        mnemocodes.put(opc.parsekey, opc);
+        if (opc.alias != null) {
+            mnemocodes.put(opc.alias, opc);
+        }
+
+        if (opc.type == OpcodeType.PRIVELEGED) {
+            PrivMnemocodes.put(opc.parsekey, opc);
+            IntToPrivOpcode.put(opc.baseVal, opc);
+        } else if (opc.type == OpcodeType.NONPRIVELEGED) {
+            NonPrivMnemocodes.put(opc.parsekey, opc);
+            IntToNonPrivOpcode.put(opc.baseVal, opc);
+        }
+
+    }
+
+    public static Opcode opcode(String mnemonic) {
+        return mnemocodes.get(mnemonic);
+    }
+
+    public static Opcode opcode(Integer mnem_code) {
+        return IntToAllOpcodes.get(mnem_code);
+    }
+
+    /*-------------------------------------------------------- */
+    /**
+     * Marker: describes the type of Opcode.
+     *
+     * certain types of Opcodes will be added to specific lookup tables.
+     */
+    static public enum OpcodeType {
+        NORMAL            (0, "Normal"),
+        NONPRIVELEGED     (1, "NonPriv"),
+        PRIVELEGED        (2, "Priv"),
+        WIDE              (3, "Wide");
+
+        private final Integer value;
+        private final String printval;
+
+        OpcodeType(Integer val, String print) {
+            value = val;
+            printval = print;
+        }
+
+        public String printval() {
+            return printval;
+        }
+
+    }
+
+    /*-------------------------------------------------------- */
+    /* Opcode Enums */
+    static public enum Opcode {
+     /* Opcodes */
+    opc_dead                (-2, " opc_dead", 0),
+    opc_label               (-1, "opc_label", 0),
+    opc_nop                 (0, "nop", 1),
+    opc_aconst_null         (1, "aconst_null", 1),
+    opc_iconst_m1           (2, "iconst_m1", 1),
+    opc_iconst_0            (3, "iconst_0", 1),
+    opc_iconst_1            (4, "iconst_1", 1),
+    opc_iconst_2            (5, "iconst_2", 1),
+    opc_iconst_3            (6, "iconst_3", 1),
+    opc_iconst_4            (7, "iconst_4", 1),
+    opc_iconst_5            (8, "iconst_5", 1),
+    opc_lconst_0            (9, "lconst_0", 1),
+    opc_lconst_1            (10, "lconst_1", 1),
+    opc_fconst_0            (11, "fconst_0", 1),
+    opc_fconst_1            (12, "fconst_1", 1),
+    opc_fconst_2            (13, "fconst_2", 1),
+    opc_dconst_0            (14, "dconst_0", 1),
+    opc_dconst_1            (15, "dconst_1", 1),
+    opc_bipush              (16, "bipush", 2),
+    opc_sipush              (17, "sipush", 3),
+    opc_ldc                 (18, "ldc", 2),
+    opc_ldc_w               (19, "ldc_w", 3),
+    opc_ldc2_w              (20, "ldc2_w", 3),
+    opc_iload               (21, "iload", 2),
+    opc_lload               (22, "lload", 2),
+    opc_fload               (23, "fload", 2),
+    opc_dload               (24, "dload", 2),
+    opc_aload               (25, "aload", 2),
+    opc_iload_0            (26, "iload_0", 1),
+    opc_iload_1            (27, "iload_1", 1),
+    opc_iload_2            (28, "iload_2", 1),
+    opc_iload_3            (29, "iload_3", 1),
+    opc_lload_0            (30, "lload_0", 1),
+    opc_lload_1            (31, "lload_1", 1),
+    opc_lload_2            (32, "lload_2", 1),
+    opc_lload_3            (33, "lload_3", 1),
+    opc_fload_0            (34, "fload_0", 1),
+    opc_fload_1            (35, "fload_1", 1),
+    opc_fload_2            (36, "fload_2", 1),
+    opc_fload_3            (37, "fload_3", 1),
+    opc_dload_0            (38, "dload_0", 1),
+    opc_dload_1            (39, "dload_1", 1),
+    opc_dload_2            (40, "dload_2", 1),
+    opc_dload_3            (41, "dload_3", 1),
+    opc_aload_0            (42, "aload_0", 1),
+    opc_aload_1            (43, "aload_1", 1),
+    opc_aload_2            (44, "aload_2", 1),
+    opc_aload_3            (45, "aload_3", 1),
+    opc_iaload            (46, "iaload", 1),
+    opc_laload            (47, "laload", 1),
+    opc_faload            (48, "faload", 1),
+    opc_daload            (49, "daload", 1),
+    opc_aaload            (50, "aaload", 1),
+    opc_baload            (51, "baload", 1),
+    opc_caload            (52, "caload", 1),
+    opc_saload            (53, "saload", 1),
+    opc_istore            (54, "istore", 2),
+    opc_lstore            (55, "lstore", 2),
+    opc_fstore            (56, "fstore", 2),
+    opc_dstore            (57, "dstore", 2),
+    opc_astore            (58, "astore", 2),
+    opc_istore_0            (59, "istore_0", 1),
+    opc_istore_1            (60, "istore_1", 1),
+    opc_istore_2            (61, "istore_2", 1),
+    opc_istore_3            (62, "istore_3", 1),
+    opc_lstore_0            (63, "lstore_0", 1),
+    opc_lstore_1            (64, "lstore_1", 1),
+    opc_lstore_2            (65, "lstore_2", 1),
+    opc_lstore_3            (66, "lstore_3", 1),
+    opc_fstore_0            (67, "fstore_0", 1),
+    opc_fstore_1            (68, "fstore_1", 1),
+    opc_fstore_2            (69, "fstore_2", 1),
+    opc_fstore_3            (70, "fstore_3", 1),
+    opc_dstore_0            (71, "dstore_0", 1),
+    opc_dstore_1            (72, "dstore_1", 1),
+    opc_dstore_2            (73, "dstore_2", 1),
+    opc_dstore_3            (74, "dstore_3", 1),
+    opc_astore_0            (75, "astore_0", 1),
+    opc_astore_1            (76, "astore_1", 1),
+    opc_astore_2            (77, "astore_2", 1),
+    opc_astore_3            (78, "astore_3", 1),
+    opc_iastore             (79, "iastore", 1),
+    opc_lastore             (80, "lastore", 1),
+    opc_fastore             (81, "fastore", 1),
+    opc_dastore             (82, "dastore", 1),
+    opc_aastore             (83, "aastore", 1),
+    opc_bastore             (84, "bastore", 1),
+    opc_castore             (85, "castore", 1),
+    opc_sastore             (86, "sastore", 1),
+    opc_pop                 (87, "pop", 1),
+    opc_pop2                (88, "pop2", 1),
+    opc_dup                 (89, "dup", 1),
+    opc_dup_x1              (90, "dup_x1", 1),
+    opc_dup_x2              (91, "dup_x2", 1),
+    opc_dup2                (92, "dup2", 1),
+    opc_dup2_x1             (93, "dup2_x1", 1),
+    opc_dup2_x2             (94, "dup2_x2", 1),
+    opc_swap                (95, "swap", 1),
+    opc_iadd                (96, "iadd", 1),
+    opc_ladd                (97, "ladd", 1),
+    opc_fadd                (98, "fadd", 1),
+    opc_dadd                (99, "dadd", 1),
+    opc_isub                (100, "isub", 1),
+    opc_lsub                (101, "lsub", 1),
+    opc_fsub                (102, "fsub", 1),
+    opc_dsub                (103, "dsub", 1),
+    opc_imul                (104, "imul", 1),
+    opc_lmul                (105, "lmul", 1),
+    opc_fmul                (106, "fmul", 1),
+    opc_dmul                (107, "dmul", 1),
+    opc_idiv                (108, "idiv", 1),
+    opc_ldiv                (109, "ldiv", 1),
+    opc_fdiv                (110, "fdiv", 1),
+    opc_ddiv                (111, "ddiv", 1),
+    opc_irem                (112, "irem", 1),
+    opc_lrem                (113, "lrem", 1),
+    opc_frem                (114, "frem", 1),
+    opc_drem                (115, "drem", 1),
+    opc_ineg                (116, "ineg", 1),
+    opc_lneg                (117, "lneg", 1),
+    opc_fneg                (118, "fneg", 1),
+    opc_dneg                (119, "dneg", 1),
+    opc_ishl                (120, "ishl", 1),
+    opc_lshl                (121, "lshl", 1),
+    opc_ishr                (122, "ishr", 1),
+    opc_lshr                (123, "lshr", 1),
+    opc_iushr               (124, "iushr", 1),
+    opc_lushr               (125, "lushr", 1),
+    opc_iand                (126, "iand", 1),
+    opc_land                (127, "land", 1),
+    opc_ior                 (128, "ior", 1),
+    opc_lor                 (129, "lor", 1),
+    opc_ixor                (130, "ixor", 1),
+    opc_lxor                (131, "lxor", 1),
+    opc_iinc                (132, "iinc", 3),
+    opc_i2l                 (133, "i2l", 1),
+    opc_i2f                 (134, "i2f", 1),
+    opc_i2d                 (135, "i2d", 1),
+    opc_l2i                 (136, "l2i", 1),
+    opc_l2f                 (137, "l2f", 1),
+    opc_l2d                 (138, "l2d", 1),
+    opc_f2i                 (139, "f2i", 1),
+    opc_f2l                 (140, "f2l", 1),
+    opc_f2d                 (141, "f2d", 1),
+    opc_d2i                 (142, "d2i", 1),
+    opc_d2l                 (143, "d2l", 1),
+    opc_d2f                 (144, "d2f", 1),
+    opc_i2b                 (145, "i2b", 1),
+    opc_i2c                 (146, "i2c", 1),
+    opc_i2s                 (147, "i2s", 1),
+    opc_lcmp                (148, "lcmp", 1),
+    opc_fcmpl               (149, "fcmpl", 1),
+    opc_fcmpg               (150, "fcmpg", 1),
+    opc_dcmpl               (151, "dcmpl", 1),
+    opc_dcmpg               (152, "dcmpg", 1),
+    opc_ifeq                (153, "ifeq", 3),
+    opc_ifne                (154, "ifne", 3),
+    opc_iflt                (155, "iflt", 3),
+    opc_ifge                (156, "ifge", 3),
+    opc_ifgt                (157, "ifgt", 3),
+    opc_ifle                (158, "ifle", 3),
+    opc_if_icmpeq           (159, "if_icmpeq", 3),
+    opc_if_icmpne           (160, "if_icmpne", 3),
+    opc_if_icmplt           (161, "if_icmplt", 3),
+    opc_if_icmpge           (162, "if_icmpge", 3),
+    opc_if_icmpgt           (163, "if_icmpgt", 3),
+    opc_if_icmple           (164, "if_icmple", 3),
+    opc_if_acmpeq           (165, "if_acmpeq", 3),
+    opc_if_acmpne           (166, "if_acmpne", 3),
+    opc_goto                (167, "goto", 3),
+    opc_jsr                 (168, "jsr", 3),
+    opc_ret                 (169, "ret", 2),
+    opc_tableswitch         (170, "tableswitch", 99),
+    opc_lookupswitch        (171, "lookupswitch", 99),
+    opc_ireturn             (172, "ireturn", 1),
+    opc_lreturn             (173, "lreturn", 1),
+    opc_freturn             (174, "freturn", 1),
+    opc_dreturn             (175, "dreturn", 1),
+    opc_areturn             (176, "areturn", 1),
+    opc_return              (177, "return", 1),
+    opc_getstatic           (178, "getstatic", 3),
+    opc_putstatic           (179, "putstatic", 3),
+    opc_getfield            (180, "getfield", 3),
+    opc_putfield            (181, "putfield", 3),
+    opc_invokevirtual       (182, "invokevirtual", 3),
+    opc_invokespecial       (183, "invokespecial", "invokenonvirtual", 3),
+    opc_invokestatic        (184, "invokestatic", 3),
+    opc_invokeinterface     (185, "invokeinterface", 5),
+    opc_invokedynamic       (186, "invokedynamic", 5),
+    opc_new                 (187, "new", 3),
+    opc_newarray            (188, "newarray", 2),
+    opc_anewarray           (189, "anewarray", 3),
+    opc_arraylength         (190, "arraylength", 1),
+    opc_athrow              (191, "athrow", 1),
+    opc_checkcast           (192, "checkcast", 3),
+    opc_instanceof          (193, "instanceof", 3),
+    opc_monitorenter        (194, "monitorenter", 1),
+    opc_monitorexit         (195, "monitorexit", 1),
+
+        // Wide Marker (not really an opcode)
+        opc_wide            (196, null, 0),
+    opc_multianewarray      (197, "multianewarray", 4),
+    opc_ifnull              (198, "ifnull", 3),
+    opc_ifnonnull           (199, "ifnonnull", 3),
+    opc_goto_w              (200, "goto_w", 5),
+    opc_jsr_w               (201, "jsr_w", 5),
+//    opc_bytecode 202            (202, "bytecode 202", 1),
+        /* Pseudo-instructions */
+    opc_bytecode            (203, "bytecode", 1),
+    opc_try                 (204, "try", 0),
+    opc_endtry              (205, "endtry", 0),
+    opc_catch               (206, "catch", 0),
+    opc_var                 (207, "var", 0),
+    opc_endvar              (208, "endvar", 0),
+    opc_locals_map          (209, "locals_map", 0),
+    opc_stack_map           (210, "stack_map", 0),
+    opc_stack_frame_type    (211, "stack_frame_type", 0),
+
+
+        // Priv/NonPriv Marker (not really an opcode)
+        opc_nonpriv         (254, "priv", 0),
+        opc_priv            (255, "nonpriv", 0),
+
+
+        /* Wide instructions */
+        opc_iload_w                     (opc_iload.value, "iload_w", 4, OpcodeType.WIDE),
+        opc_lload_w                     (opc_lload.value, "lload_w", 4, OpcodeType.WIDE),
+        opc_fload_w                     (opc_fload.value, "fload_w", 4, OpcodeType.WIDE),
+        opc_dload_w                     (opc_dload.value, "dload_w", 4, OpcodeType.WIDE),
+        opc_aload_w                     (opc_aload.value, "aload_w", 4, OpcodeType.WIDE),
+        opc_istore_w                    (opc_istore.value, "istore_w", 4, OpcodeType.WIDE),
+        opc_lstore_w                    (opc_lstore.value, "lstore_w", 4, OpcodeType.WIDE),
+        opc_fstore_w                    (opc_fstore.value, "fstore_w", 4, OpcodeType.WIDE),
+        opc_dstore_w                    (opc_dstore.value, "dstore_w", 4, OpcodeType.WIDE),
+        opc_astore_w                    (opc_astore.value, "astore_w", 4, OpcodeType.WIDE),
+        opc_ret_w                       (opc_ret.value, "ret_w", 4, OpcodeType.WIDE),
+        opc_iinc_w                      (opc_iinc.value, "iinc_w", 6, OpcodeType.WIDE),
+
+
+        /* Priveleged instructions */
+    opc_load_ubyte                  (0, "load_ubyte", OpcodeType.NONPRIVELEGED),
+    opc_priv_load_ubyte        (0, "priv_load_ubyte", OpcodeType.PRIVELEGED),
+    opc_load_byte            (1, "load_byte", OpcodeType.NONPRIVELEGED),
+    opc_priv_load_byte        (1, "priv_load_byte", OpcodeType.PRIVELEGED),
+    opc_load_char            (2, "load_char", OpcodeType.NONPRIVELEGED),
+    opc_priv_load_char        (2, "priv_load_char", OpcodeType.PRIVELEGED),
+    opc_load_short            (3, "load_short", OpcodeType.NONPRIVELEGED),
+    opc_priv_load_short        (3, "priv_load_short", OpcodeType.PRIVELEGED),
+    opc_load_word            (4, "load_word", OpcodeType.NONPRIVELEGED),
+    opc_priv_load_word        (4, "priv_load_word", OpcodeType.PRIVELEGED),
+    opc_load_char_oe            (10, "load_char_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_load_char_oe        (10, "priv_load_char_oe", OpcodeType.PRIVELEGED),
+    opc_load_short_oe        (11, "load_short_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_load_short_oe        (11, "priv_load_short_oe", OpcodeType.PRIVELEGED),
+    opc_load_word_oe            (12, "load_word_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_load_word_oe        (12, "priv_load_word_oe", OpcodeType.PRIVELEGED),
+    opc_ncload_ubyte            (16, "ncload_ubyte", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncload_ubyte        (16, "priv_ncload_ubyte", OpcodeType.PRIVELEGED),
+    opc_ncload_byte            (17, "ncload_byte", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncload_byte        (17, "priv_ncload_byte", OpcodeType.PRIVELEGED),
+    opc_ncload_char            (18, "ncload_char", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncload_char        (18, "priv_ncload_char", OpcodeType.PRIVELEGED),
+    opc_ncload_short            (19, "ncload_short", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncload_short        (19, "priv_ncload_short", OpcodeType.PRIVELEGED),
+    opc_ncload_word            (20, "ncload_word", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncload_word        (20, "priv_ncload_word", OpcodeType.PRIVELEGED),
+    opc_ncload_char_oe        (26, "ncload_char_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncload_char_oe        (26, "priv_ncload_char_oe", OpcodeType.PRIVELEGED),
+    opc_ncload_short_oe        (27, "ncload_short_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncload_short_oe        (27, "priv_ncload_short_oe", OpcodeType.PRIVELEGED),
+    opc_ncload_word_oe        (28, "ncload_word_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncload_word_oe        (28, "priv_ncload_word_oe", OpcodeType.PRIVELEGED),
+    opc_cache_flush            (30, "cache_flush", OpcodeType.NONPRIVELEGED),
+    opc_priv_cache_flush        (30, "priv_cache_flush", OpcodeType.PRIVELEGED),
+    opc_store_byte            (32, "store_byte", OpcodeType.NONPRIVELEGED),
+    opc_priv_store_byte        (32, "priv_store_byte", OpcodeType.PRIVELEGED),
+    opc_store_short            (34, "store_short", OpcodeType.NONPRIVELEGED),
+    opc_priv_store_short        (34, "priv_store_short", OpcodeType.PRIVELEGED),
+    opc_store_word            (36, "store_word", OpcodeType.NONPRIVELEGED),
+    opc_priv_store_word        (36, "priv_store_word", OpcodeType.PRIVELEGED),
+    opc_store_short_oe        (42, "store_short_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_store_short_oe        (42, "priv_store_short_oe", OpcodeType.PRIVELEGED),
+    opc_store_word_oe        (44, "store_word_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_store_word_oe        (44, "priv_store_word_oe", OpcodeType.PRIVELEGED),
+    opc_ncstore_byte            (48, "ncstore_byte", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncstore_byte        (48, "priv_ncstore_byte", OpcodeType.PRIVELEGED),
+    opc_ncstore_short        (50, "ncstore_short", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncstore_short        (50, "priv_ncstore_short", OpcodeType.PRIVELEGED),
+    opc_ncstore_word        (52, "ncstore_word", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncstore_word        (52, "priv_ncstore_word", OpcodeType.PRIVELEGED),
+    opc_ncstore_short_oe        (58, "ncstore_short_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncstore_short_oe    (58, "priv_ncstore_short_oe", OpcodeType.PRIVELEGED),
+    opc_ncstore_word_oe        (60, "ncstore_word_oe", OpcodeType.NONPRIVELEGED),
+    opc_priv_ncstore_word_oe        (60, "priv_ncstore_word_oe", OpcodeType.PRIVELEGED),
+    opc_zero_line            (62, "zero_line", OpcodeType.NONPRIVELEGED),
+    opc_priv_zero_line        (62, "priv_zero_line", OpcodeType.PRIVELEGED),
+    opc_ret_from_sub            (5, "ret_from_sub", OpcodeType.NONPRIVELEGED),
+    opc_enter_sync_method        (63, "enter_sync_method", OpcodeType.NONPRIVELEGED),
+    opc_priv_ret_from_trap        (5, "priv_ret_from_trap", OpcodeType.PRIVELEGED),
+    opc_priv_read_dcache_tag    (6, "priv_read_dcache_tag", OpcodeType.PRIVELEGED),
+    opc_priv_read_dcache_data    (7, "priv_read_dcache_data", OpcodeType.PRIVELEGED),
+    opc_priv_read_icache_tag    (14, "priv_read_icache_tag", OpcodeType.PRIVELEGED),
+    opc_priv_read_icache_data    (15, "priv_read_icache_data", OpcodeType.PRIVELEGED),
+    opc_priv_powerdown        (22, "priv_powerdown", OpcodeType.PRIVELEGED),
+    opc_priv_read_scache_data    (23, "priv_read_scache_data", OpcodeType.PRIVELEGED),
+    opc_priv_cache_index_flush    (31, "priv_cache_index_flush", OpcodeType.PRIVELEGED),
+    opc_priv_write_dcache_tag    (38, "priv_write_dcache_tag", OpcodeType.PRIVELEGED),
+    opc_priv_write_dcache_data    (39, "priv_write_dcache_data", OpcodeType.PRIVELEGED),
+    opc_priv_write_icache_tag    (46, "priv_write_icache_tag", OpcodeType.PRIVELEGED),
+    opc_priv_write_icache_data    (47, "priv_write_icache_data", OpcodeType.PRIVELEGED),
+    opc_priv_reset            (54, "priv_reset", OpcodeType.PRIVELEGED),
+    opc_priv_write_scache_data    (55, "priv_write_scache_data", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_0        (64, "priv_read_reg_0", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_1        (65, "priv_read_reg_1", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_2        (66, "priv_read_reg_2", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_3        (67, "priv_read_reg_3", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_4        (68, "priv_read_reg_4", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_5        (69, "priv_read_reg_5", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_6        (70, "priv_read_reg_6", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_7        (71, "priv_read_reg_7", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_8        (72, "priv_read_reg_8", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_9        (73, "priv_read_reg_9", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_10        (74, "priv_read_reg_10", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_11        (75, "priv_read_reg_11", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_12        (76, "priv_read_reg_12", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_13        (77, "priv_read_reg_13", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_14        (78, "priv_read_reg_14", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_15        (79, "priv_read_reg_15", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_16        (80, "priv_read_reg_16", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_17        (81, "priv_read_reg_17", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_18        (82, "priv_read_reg_18", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_19        (83, "priv_read_reg_19", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_20        (84, "priv_read_reg_20", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_21        (85, "priv_read_reg_21", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_22        (86, "priv_read_reg_22", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_23        (87, "priv_read_reg_23", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_24        (88, "priv_read_reg_24", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_25        (89, "priv_read_reg_25", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_26        (90, "priv_read_reg_26", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_27        (91, "priv_read_reg_27", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_28        (92, "priv_read_reg_28", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_29        (93, "priv_read_reg_29", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_30        (94, "priv_read_reg_30", OpcodeType.PRIVELEGED),
+    opc_priv_read_reg_31        (95, "priv_read_reg_31", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_0        (96, "priv_write_reg_0", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_1        (97, "priv_write_reg_1", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_2        (98, "priv_write_reg_2", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_3        (99, "priv_write_reg_3", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_4        (100, "priv_write_reg_4", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_5        (101, "priv_write_reg_5", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_6        (102, "priv_write_reg_6", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_7        (103, "priv_write_reg_7", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_8        (104, "priv_write_reg_8", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_9        (105, "priv_write_reg_9", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_10        (106, "priv_write_reg_10", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_11        (107, "priv_write_reg_11", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_12        (108, "priv_write_reg_12", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_13        (109, "priv_write_reg_13", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_14        (110, "priv_write_reg_14", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_15        (111, "priv_write_reg_15", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_16        (112, "priv_write_reg_16", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_17        (113, "priv_write_reg_17", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_18        (114, "priv_write_reg_18", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_19        (115, "priv_write_reg_19", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_20        (116, "priv_write_reg_20", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_21        (117, "priv_write_reg_21", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_22        (118, "priv_write_reg_22", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_23        (119, "priv_write_reg_23", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_24        (120, "priv_write_reg_24", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_25        (121, "priv_write_reg_25", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_26        (122, "priv_write_reg_26", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_27        (123, "priv_write_reg_27", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_28        (124, "priv_write_reg_28", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_29        (125, "priv_write_reg_29", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_30        (126, "priv_write_reg_30", OpcodeType.PRIVELEGED),
+    opc_priv_write_reg_31        (127, "priv_write_reg_31", OpcodeType.PRIVELEGED);
+
+        private Integer value;
+        private String parsekey;
+        private String alias;
+        private Integer length;
+        private Integer baseVal;
+        private OpcodeType type;
+
+        Opcode(Integer val, String parse, OpcodeType tp) {
+            init(val, parse, null, 2, tp);
+        }
+
+        Opcode(Integer val, String parse, int len, OpcodeType tp) {
+            init(val, parse, null, len, tp);
+        }
+
+        Opcode(Integer val, String parse) {
+            init(val, parse, null, 2, OpcodeType.NORMAL);
+        }
+
+        Opcode(Integer val, String parse, int len) {
+            init(val, parse, null, len, OpcodeType.NORMAL);
+        }
+
+        Opcode(Integer val, String parse, String als, int len) {
+            init(val, parse, als, len, OpcodeType.NORMAL);
+        }
+
+        Opcode(Integer val, String parse, String als, int len, OpcodeType tp) {
+            init(val, parse, als, len, tp);
+        }
+
+        private void init(Integer val, String parse, String als, int len, OpcodeType tp) {
+            type = tp;
+            baseVal = null;
+            switch (tp) {
+                case NORMAL:
+                    value = val;
+                    break;
+                case WIDE:
+                    value = (opc_wide.value << 8) | val;
+                    break;
+                case PRIVELEGED:
+                    value = (opc_priv.value * 0xFF) + val;
+                    baseVal = val;
+                    break;
+                case NONPRIVELEGED:
+                    value = (opc_nonpriv.value * 0xFF) + val;
+                    baseVal = val;
+                    break;
+            }
+            parsekey = parse;
+            alias = als;
+            length = len;
+        }
+
+        public Integer value() {
+            return value;
+        }
+
+        public int length() {
+            return length;
+        }
+
+        public String parsekey() {
+            return parsekey;
+        }
+
+        public OpcodeType type() {
+            return type;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/ParseBase.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+/**
+ *
+ */
+public class ParseBase {
+
+    protected boolean debugFlag;
+    protected Scanner scanner;
+    protected Parser parser;
+    protected Environment env;
+
+    public ParseBase() {
+        init(null, null, null);
+    }
+
+    public void init(Scanner scnr, Parser prsr, Environment envr) {
+        debugFlag = false;
+        scanner = scnr;
+        parser = prsr;
+        env = envr;
+    }
+
+    public void enableDebug(boolean debState) {
+        debugFlag = debState;
+    }
+
+    protected void debugStr(String str) {
+        if (debugFlag) {
+            env.traceln(str);
+        }
+    }
+
+    protected void debugScan(String str) {
+        if (debugFlag) {
+            scanner.debugScan(str);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/Parser.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,1457 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.asmtools.jasm;
+
+import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MAJOR_VERSION;
+import static org.openjdk.asmtools.jasm.Constants.DEFAULT_MINOR_VERSION;
+import static org.openjdk.asmtools.jasm.ConstantPool.*;
+import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
+import static org.openjdk.asmtools.jasm.Tables.*;
+import static org.openjdk.asmtools.jasm.JasmTokens.*;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * This class is used to parse Jasm statements and expressions.
+ * The result is a parse tree.<p>
+ *
+ * This class implements an operator precedence parser. Errors are
+ * reported to the Environment object, if the error can't be
+ * resolved immediately, a SyntaxError exception is thrown.<p>
+ *
+ * Error recovery is implemented by catching Scanner.SyntaxError exceptions
+ * and discarding input scanner.tokens until an input token is reached that
+ * is possibly a legal continuation.<p>
+ *
+ * The parse tree that is constructed represents the input
+ * exactly (no rewrites to simpler forms). This is important
+ * if the resulting tree is to be used for code formatting in
+ * a programming environment. Currently only documentation comments
+ * are retained.<p>
+ *
+ * A parser owns several components (scanner, constant-parser,
+ * instruction-parser, annotations-parser) to which it delegates certain
+ * parsing responsibilities.  This parser contains functions to parse the
+ * overall form of a class, and any members (fields, methods, inner-classes).
+ * <p>
+ *
+ * Syntax errors, should always be caught inside the
+ * parser for error recovery.
+ */
+class Parser extends ParseBase {
+
+  /*-------------------------------------------------------- */
+  /* Annotation Inner Classes */
+    /**
+     * The main compile error for the parser
+     */
+    public static class CompilerError extends Error {
+
+        CompilerError(String message) {
+            super(message);
+        }
+    }
+  /*-------------------------------------------------------- */
+  /* Parser Fields */
+
+    private ArrayList                   clsDataList = new ArrayList<>();
+    protected ClassData                 cd = null;
+    protected ConstantPool              pool = null;
+    private MethodData                  curMethod;
+    protected CodeAttr                  curCode;
+    private String                      pkg = null;
+    private String                      pkgPrefix = "";
+    private ArrayList<AnnotationData>   pkgAnnttns = null;
+    /* RemoveModules
+    private String mdl = null;
+    private ArrayList<AnnotationData> mdlAnnttns = null;
+     */
+    private ArrayList<AnnotationData>   clsAnnttns = null;
+    private ArrayList<AnnotationData>   memberAnnttns = null;
+    private short                       major_version = DEFAULT_MAJOR_VERSION;
+    private short                       minor_version = DEFAULT_MINOR_VERSION;
+    private boolean                     explicitcp = false;
+
+    /** other parser components */
+    private ParserAnnotation            annotParser = null;     // For parsing Annotations
+    private ParserCP                    cpParser    = null;     // for parsing Constants
+    private ParserInstr                 instrParser = null;     // for parsing Instructions
+
+
+   /*-------------------------------------------------------- */
+
+
+    /**
+     * Create a parser
+     */
+    /*
+    protected Parser(Environment sf) throws IOException {
+        this.scanner = new Scanner(sf);
+    }
+    * */
+
+    protected Parser(Environment sf, short major_version, short minor_version) throws IOException {
+        super.init(new Scanner(sf), this, sf);
+        this.major_version = major_version;
+        this.minor_version = minor_version;
+        this.annotParser = new ParserAnnotation(scanner, this, env);
+        this.cpParser = new ParserCP(scanner, this, env);
+        this.instrParser = new ParserInstr(scanner, this, cpParser, env);
+    }
+
+
+    protected void setDebugFlags(boolean debugScanner, boolean debugMembers,
+            boolean debugCP, boolean debugAnnot, boolean debugInstr) {
+
+        enableDebug(debugMembers);
+        scanner.enableDebug(debugScanner);
+        cpParser.enableDebug(debugCP);
+        annotParser.enableDebug(debugAnnot);
+        instrParser.enableDebug(debugInstr);
+    }
+
+
+
+
+    /*---------------------------------------------*/
+
+    protected String encodeClassString(String classname) {
+        return "L" + classname + ";";
+    }
+
+    /**
+     * Parses version in package statements
+     */
+
+    protected final void parseVersionPkg() throws IOException  {
+        if (scanner.token == Token.SEMICOLON) {
+            return;
+        }
+        parse_ver: {
+            if (scanner.token != Token.VERSION) {
+                break parse_ver;
+            }
+            scanner.scan();
+            if (scanner.token != Token.INTVAL) {
+                break parse_ver;
+            }
+            major_version = (short)scanner.intValue;
+            scanner.scan();
+            if (scanner.token != Token.COLON) {
+                break parse_ver;
+            }
+            scanner.scan();
+            if (scanner.token != Token.INTVAL) {
+                break parse_ver;
+            }
+            minor_version = (short)scanner.intValue;
+            scanner.scan();
+            debugScan("     [Parser.parseVersionPkg]: " + major_version + ":" + minor_version);
+            return;
+        }
+        env.error(scanner.pos, "version.expected");
+        throw new Scanner.SyntaxError();
+    }
+
+    protected final void parseVersion() throws IOException  {
+        if (scanner.token == Token.LBRACE) {
+            return;
+        }
+        parse_ver: {
+            if (scanner.token != Token.VERSION) {
+                break parse_ver;
+            }
+            scanner.scan();
+            if (scanner.token != Token.INTVAL) {
+                break parse_ver;
+            }
+            cd.major_version = (short)scanner.intValue;
+            scanner.scan();
+            if (scanner.token != Token.COLON) {
+                break parse_ver;
+            }
+            scanner.scan();
+            if (scanner.token != Token.INTVAL) {
+                break parse_ver;
+            }
+            cd.minor_version = (short)scanner.intValue;
+            scanner.scan();
+            debugStr("parseVersion: " + cd.major_version + ":" + cd.minor_version);
+            return;
+        }
+        env.error(scanner.pos, "version.expected");
+        throw new Scanner.SyntaxError();
+    }
+
+    /**
+     * Parse an internal name: identifier.
+     */
+    protected String parseIdent() throws Scanner.SyntaxError, IOException {
+        String v = scanner.idValue;
+        scanner.expect(Token.IDENT);
+        return v;
+    }
+
+    /**
+     * Parse a local variable
+     */
+    protected void parseLocVarDef() throws Scanner.SyntaxError, IOException {
+        if (scanner.token == Token.INTVAL) {
+            int v = scanner.intValue;
+            scanner.scan();
+            curCode.LocVarDataDef(v);
+        } else {
+            String name = scanner.stringValue, type;
+            scanner.expect(Token.IDENT);
+            if (scanner.token == Token.COLON) {
+                scanner.scan();
+                type = parseIdent();
+            } else {
+                type = "I";                  // TBD
+            }
+            curCode.LocVarDataDef(name, pool.FindCellAsciz(type));
+        }
+    }
+
+    protected Argument parseLocVarRef() throws Scanner.SyntaxError, IOException {
+        if (scanner.token == Token.INTVAL) {
+            int v = scanner.intValue;
+            scanner.scan();
+            return new Argument(v);
+        } else {
+            String name = scanner.stringValue;
+            scanner.expect(Token.IDENT);
+            return curCode.LocVarDataRef(name);
+        }
+    }
+
+    protected void parseLocVarEnd() throws Scanner.SyntaxError, IOException {
+        if (scanner.token == Token.INTVAL) {
+            int v = scanner.intValue;
+            scanner.scan();
+            curCode.LocVarDataEnd(v);
+        } else {
+            String name = scanner.stringValue;
+            scanner.expect(Token.IDENT);
+            curCode.LocVarDataEnd(name);
+        }
+    }
+
+    protected void parseMapItem(DataVector map) throws Scanner.SyntaxError, IOException {
+        StackMapType itemType = stackMapType(scanner.intValue);
+        ConstType tag = null;
+        Argument arg = null;
+        Token ptoken = scanner.token;
+        int iValue = scanner.intValue;
+        String sValue = scanner.stringValue;
+        scanner.scan();
+        resolve: {
+            switch (ptoken) {
+                case INTVAL:
+                    break resolve;
+                case CLASS:
+                    itemType = StackMapType.ITEM_Object;
+                    tag = ConstType.CONSTANT_CLASS;
+                    break resolve;
+                case CPINDEX:
+                    itemType = StackMapType.ITEM_Object;
+                    arg = pool.getCell(iValue);
+                    break resolve;
+                case IDENT:
+                    itemType = stackMapType(sValue);
+                    ConstType tg = Tables.tag(sValue);
+//                    tag = (tg == null) ? 0 : tg.value;
+                    tag = tg;
+                    if (itemType != null) { // itemType OK
+                        if ((tag != null) // ambiguity: "int," or "int 77,"?
+                                && (scanner.token != Token.SEMICOLON)
+                                && (scanner.token != Token.COMMA)) {
+                            itemType=StackMapType.ITEM_Object;
+                        }
+                        break resolve;
+                    } else if (tag != null) { // tag OK
+                        itemType=StackMapType.ITEM_Object;
+                        break resolve;
+                    }
+            }
+            // resolution failed:
+            itemType = StackMapType.ITEM_Bogus;
+            env.error("itemtype.expected", "<" + ptoken.printval() + ">");
+        }
+        switch (itemType) {
+            case ITEM_Object:  // followed by CP index
+                if (arg == null) {
+                    arg = pool.FindCell(cpParser.parseConstValue(tag));
+                }
+                map.addElement(new StackMapData.StackMapItem2(itemType, arg));
+                break;
+            case ITEM_NewObject:  // followed by label
+                arg = instrParser.parseLabelRef();
+                map.addElement(new StackMapData.StackMapItem2(itemType, arg));
+                break;
+            default:
+                map.addElement(new StackMapData.StackMapItem1(itemType));
+        }
+    }
+
+
+    /**
+     * Parse an external name: CPINDEX, string, or identifier.
+     */
+    protected ConstCell parseName() throws Scanner.SyntaxError, IOException {
+        debugScan("------- [Parser.parseName]: ");
+        String v;
+        switch (scanner.token) {
+            case CPINDEX: {
+                int cpx = scanner.intValue;
+                scanner.scan();
+                return pool.getCell(cpx);
+            }
+            case STRINGVAL:
+                v = scanner.stringValue;
+                scanner.scan();
+                return pool.FindCellAsciz(v);
+
+                // In many cases, Identifiers can correctly have the same
+                // names as keywords.  We need to allow these.
+            case SYNTHETIC:
+            case DEPRECATED:
+            case VERSION:
+            case BITS:
+            case STACK:
+            case LOCAL:
+            case OF:
+            case NAN:
+            case INNERCLASS:
+            case STRICT:
+            case FIELDREF:
+            case METHODREF:
+            case IDENT:
+            case BRIDGE:
+                v = scanner.idValue;
+                scanner.scan();
+                return pool.FindCellAsciz(v);
+            default:
+                env.error(scanner.pos, "name.expected", scanner.token);
+                throw new Scanner.SyntaxError();
+        }
+    }
+
+    /**
+     * Parses a field or method reference for method handle.
+     */
+    protected ConstCell parseMethodHandle(SubTag subtag) throws Scanner.SyntaxError, IOException {
+        ConstCell refCell;
+        switch (subtag) {
+            case REF_GETFIELD: case REF_GETSTATIC:
+            case REF_PUTFIELD: case REF_PUTSTATIC:
+                refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_FIELD));
+                break;
+            case REF_INVOKEVIRTUAL: case REF_INVOKESTATIC:
+            case REF_INVOKESPECIAL: case REF_NEWINVOKESPECIAL:
+                refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_METHOD));
+                break;
+            case REF_INVOKEINTERFACE:
+                refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_INTERFACEMETHOD));
+                break;
+            default:
+                // should not reach
+                throw new Scanner.SyntaxError();
+        }
+        return refCell;
+    }
+
+    /**
+     * Parses a sub-tag value in method handle.
+     */
+    protected SubTag parseSubtag() throws Scanner.SyntaxError, IOException {
+        SubTag subtag = null;
+        switch (scanner.token) {
+            case IDENT:
+                subtag = subtag(scanner.stringValue);
+                break;
+            case INTVAL:
+                subtag  = subtag(scanner.intValue);
+                break;
+        }
+        if (subtag == null) {
+            env.error("subtag.expected");
+            throw new Scanner.SyntaxError();
+        }
+        scanner.scan();
+        return subtag;
+    }
+
+    protected ConstCell parseClassName(boolean uncond) throws Scanner.SyntaxError, IOException {
+        String v;
+        switch (scanner.token) {
+            case CPINDEX: {
+                int cpx = scanner.intValue;
+                scanner.scan();
+                return pool.getCell(cpx);
+            }
+            case STRINGVAL:
+                v = scanner.stringValue;
+                scanner.scan();
+                return pool.FindCellAsciz(v);
+                // Some identifiers might coincide with token names.
+                // these should be OK to use as identifier names.
+            case SYNTHETIC:
+            case DEPRECATED:
+            case VERSION:
+            case BITS:
+            case STACK:
+            case LOCAL:
+            case OF:
+            case NAN:
+            case INNERCLASS:
+            case STRICT:
+            case FIELDREF:
+            case METHODREF:
+            case BRIDGE:
+            case IDENT:
+                v = scanner.idValue;
+                scanner.scan();
+                if (uncond || (scanner.token == Token.FIELD)) {  //?????????????????????????????????????
+                    if ((v.indexOf("/") == -1)           // class identifier doesn't contain "/"
+                            && (v.indexOf("[")==-1)){    // class identifier doesn't contain "["
+                        v = pkgPrefix + v; // add package
+                    }
+                }
+                return pool.FindCellAsciz(v);
+            default:
+                ConstType key = Tables.tag(scanner.token.value());
+                env.traceln("%%%%% Unrecognized token [" + scanner.token + "]: '" + (key == null? "null":key.parseKey()) + "'.");
+                env.error(scanner.prevPos, "name.expected");
+                throw new Scanner.SyntaxError();
+        }
+    }
+
+
+    /**
+     * Parse a signed integer of size bytes long.
+     *  size = 1 or 2
+     */
+    protected Argument parseInt(int size) throws Scanner.SyntaxError, IOException {
+        if (scanner.token == Token.BITS) {
+            scanner.scan();
+        }
+        if (scanner.token != Token.INTVAL) {
+            env.error(scanner.pos, "int.expected");
+            throw new Scanner.SyntaxError();
+        }
+        int arg = scanner.intValue * scanner.sign;
+        switch (size) {
+            case 1:
+//                if ((arg>127)||(arg<-128)) { // 0xFF not allowed
+                if ((arg > 255) || (arg < -128)) { // to allow 0xFF
+                    env.error(scanner.pos, "value.large", "1 byte");
+                    throw new Scanner.SyntaxError();
+                }
+                break;
+            case 2:
+//                if ((arg > 32767) || (arg < -32768)) { //this seems
+// natural but is not backward compatible. Some tests contain
+// expressions like:
+//                sipush    0x8765;
+
+                if ((arg > 65535) || (arg < -32768)) {
+                    env.error(scanner.pos, "value.large", "2 bytes");
+                    throw new Scanner.SyntaxError();
+                }
+                break;
+            default:
+                throw new InternalError("parseInt("+size+")");
+        }
+        scanner.scan();
+        return new Argument(arg);
+    }
+
+    /**
+     * Parse an unsigned integer of size bytes long.
+     *  size = 1 or 2
+     */
+    protected Argument parseUInt(int size) throws Scanner.SyntaxError, IOException {
+        if (scanner.token != Token.INTVAL) {
+            env.error(scanner.pos, "int.expected");
+            throw new Scanner.SyntaxError();
+        }
+        if (scanner.sign == -1) {
+            env.error(scanner.pos, "neg.forbidden");
+            throw new Scanner.SyntaxError();
+        }
+        int arg = scanner.intValue;
+        switch (size) {
+            case 1:
+                if (arg > 255) {
+                    env.error(scanner.pos, "value.large", "1 byte");
+                    throw new Scanner.SyntaxError();
+                }
+                break;
+            case 2:
+                if (arg > 65535) {
+                    env.error(scanner.pos, "value.large", "2 bytes");
+                    throw new Scanner.SyntaxError();
+                }
+                break;
+            default:
+                throw new InternalError("parseUInt("+size+")");
+        }
+        scanner.scan();
+        return new Argument(arg);
+    }
+
+    /**
+     * Parse constant declaration
+     */
+    protected void parseConstDef() throws IOException {
+        for (;;) {
+            if (scanner.token == Token.CPINDEX) {
+                int cpx = scanner.intValue;
+                scanner.scan();
+                scanner.expect(Token.ASSIGN);
+                env.traceln("parseConstDef:"+cpx);
+                pool.setCell(cpx, cpParser.parseConstRef(null));
+            } else {
+                env.error("const.def.expected");
+                throw new Scanner.SyntaxError();
+            }
+            if (scanner.token != Token.COMMA) {
+                scanner.expect(Token.SEMICOLON);
+                return;
+            }
+            scanner.scan(); // COMMA
+        }
+    }
+
+    /**
+     * Parse the modifiers
+     */
+    private int scanModifier(int mod) throws IOException {
+        int nextmod, prevpos;
+
+        while (true) {
+            nextmod = 0;
+            switch (scanner.token) {
+                case PUBLIC:       nextmod = ACC_PUBLIC;       break;
+                case PRIVATE:      nextmod = ACC_PRIVATE;      break;
+                case PROTECTED:    nextmod = ACC_PROTECTED;    break;
+                case STATIC:       nextmod = ACC_STATIC;       break;
+                case FINAL:        nextmod = ACC_FINAL;        break;
+                case SYNCHRONIZED: nextmod = ACC_SYNCHRONIZED; break;
+                case SUPER:        nextmod = ACC_SUPER;        break;
+                case VOLATILE:     nextmod = ACC_VOLATILE;     break;
+                case BRIDGE:       nextmod = ACC_BRIDGE;       break;
+                case TRANSIENT:    nextmod = ACC_TRANSIENT;    break;
+                case VARARGS:      nextmod = ACC_VARARGS;      break;
+                case NATIVE:       nextmod = ACC_NATIVE;       break;
+                case INTERFACE:    nextmod = ACC_INTERFACE;    break;
+                case ABSTRACT:     nextmod = ACC_ABSTRACT;     break;
+                case STRICT:       nextmod = ACC_STRICT;       break;
+                case ENUM:         nextmod = ACC_ENUM;         break;
+                case SYNTHETIC:    nextmod = ACC_SYNTHETIC;    break;
+ //               case SYNTHETIC:    nextmod = SYNTHETIC_ATTRIBUTE;    break;
+
+                case DEPRECATED:   nextmod = DEPRECATED_ATTRIBUTE;   break;
+                case MANDATED:       nextmod = ACC_MANDATED;       break;
+                default:
+//                    env.traceln(" is not a mod");
+                    return nextmod;
+            }
+            prevpos = scanner.pos;
+            scanner.scan();
+            if ((mod & nextmod) == 0) {
+                return nextmod;
+            }
+            env.error(prevpos, "warn.repeated.modifier");
+        }
+    }
+
+    protected int scanModifiers() throws IOException {
+        int mod = 0, nextmod;
+
+        while (true) {
+            nextmod = scanModifier(mod);
+            if (nextmod == 0) {
+                return mod;
+            }
+            mod = mod | nextmod;
+        }
+    }
+
+    /**
+     * Parse a field.
+     */
+    protected void parseField(int mod) throws Scanner.SyntaxError, IOException {
+        debugStr("  [Parser.parseField]: <<<Begin>>>");
+        // check access modifiers:
+        Modifiers.checkFieldModifiers(cd, mod, scanner.pos);
+
+        while (true) {
+            ConstCell nameCell = parseName();
+            scanner.expect(Token.COLON);
+            ConstCell typeCell = parseName();
+
+            // Define the variable
+            FieldData fld = cd.addField(mod, nameCell, typeCell);
+
+            if (memberAnnttns != null) {
+                fld.addAnnotations(memberAnnttns);
+            }
+
+            // Parse the optional initializer
+            if (scanner.token == Token.ASSIGN) {
+                scanner.scan();
+                fld.SetValue(cpParser.parseConstRef(null));
+            }
+
+            // If the next scanner.token is a comma, then there is more
+            debugScan("  [Parser.parseField]: Field: " + fld + " ");
+
+            if (scanner.token != Token.COMMA) {
+                scanner.expect(Token.SEMICOLON);
+                return;
+            }
+            scanner.scan();
+        }  // end while
+    }  // end parseField
+
+    /**
+     * Scan method's signature to determine size of parameters.
+     */
+    protected int countParams(int pos, ConstCell sigCell) throws Scanner.SyntaxError, IOException {
+        String sig;
+        try {
+            ConstValue_String strConst = (ConstValue_String) sigCell.ref;
+            sig = strConst.value;
+        } catch (NullPointerException | ClassCastException e) {
+            return 0; // ??? TBD
+        }
+        int siglen = sig.length(), k = 0, loccnt = 0, errparam = 0;
+        boolean arraytype = false;
+        scan: {
+            if (k >= siglen) {
+                break scan;
+            }
+            if (sig.charAt(k) != '(') {
+                errparam = 1;
+                break scan;
+            }
+            for (k = 1; k < siglen; k++) {
+                switch (sig.charAt(k)) {
+                    case ')':
+                        if (arraytype) {
+                            errparam = 2;
+                            break scan;
+                        }
+                        return loccnt;
+                    case '[':
+                        arraytype = true;
+                        break;
+                    case 'B':
+                    case 'C':
+                    case 'F':
+                    case 'I':
+                    case 'S':
+                    case 'Z':
+                        loccnt++;
+                        arraytype = false;
+                        break;
+                    case 'D':
+                    case 'J':
+                        loccnt++;
+                        if (arraytype) {
+                            arraytype = false;
+                        }
+                        else {
+                            loccnt++;
+                        }
+                        break;
+                    case 'L':
+                        for (;;k++) {
+                            if (k >= siglen) {
+                                errparam = 3;
+                                break scan;
+                            }
+                            if (sig.charAt(k) == ';') {
+                                break;
+                            }
+                        }
+                        loccnt++;
+                        arraytype = false;
+                        break;
+                    default:
+                        errparam = 4;
+                        break scan;
+                }
+            }
+        }
+        env.error(scanner.pos, "msig.malformed", new Integer(k).toString(),
+                new Integer(errparam).toString());
+        return loccnt;
+    }
+
+    /**
+     * Parse a method.
+     */
+    protected void parseMethod(int mod) throws Scanner.SyntaxError, IOException {
+
+        // The start of the method
+        int posa = scanner.pos;
+        debugStr("  [Parser.parseMethod]: <<<Begin>>>");
+
+        ConstCell nameCell = parseName();
+        ConstValue_String strConst = (ConstValue_String) nameCell.ref;
+        String name = strConst.value;
+        boolean is_clinit = name.equals("<clinit>");
+        boolean is_init = name.equals("<init>");
+        DefaultAnnotationAttr defAnnot = null;
+
+        // check access modifiers:
+        Modifiers.checkMethodModifiers(cd, mod, posa, is_init, is_clinit);
+
+        scanner.expect(Token.COLON);
+        ConstCell typeCell = parseName();
+        int paramcnt = countParams(scanner.pos, typeCell);
+        if ((! Modifiers.isStatic(mod)) && ! is_clinit) {
+            paramcnt++;
+        }
+        if (paramcnt > 255) {
+            env.error(scanner.pos, "warn.msig.more255", new Integer(paramcnt).toString());
+        }
+        // Parse throws clause
+        ArrayList<ConstCell> exc_table = null;
+        if (scanner.token == Token.THROWS) {
+            scanner.scan();
+            exc_table = new  ArrayList<>();
+            for (;;) {
+                posa = scanner.pos;
+                ConstCell exc = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
+                if (exc_table.contains(exc)) {
+                    env.error(posa, "warn.exc.repeated");
+                } else {
+                    exc_table.add(exc);
+                    env.traceln("THROWS:"+exc.arg);
+                }
+                if (scanner.token != Token.COMMA) {
+                    break;
+                }
+                scanner.scan();
+            }
+        }
+        if (scanner.token == Token.DEFAULT) {
+            // need to scan the annotation value
+            defAnnot = annotParser.parseDefaultAnnotation();
+        }
+
+        curMethod = cd.StartMethod(mod, nameCell, typeCell, exc_table);
+        Argument max_stack = null, max_locals = null;
+
+        if (scanner.token == Token.STACK) {
+            scanner.scan();
+            max_stack = parseUInt(2);
+        }
+        if (scanner.token == Token.LOCAL) {
+            scanner.scan();
+            max_locals = parseUInt(2);
+        }
+        if (scanner.token == Token.INTVAL) {
+            annotParser.parseParamAnnots(paramcnt, curMethod);
+        }
+
+        if (scanner.token == Token.SEMICOLON) {
+            if ((max_stack != null) || (max_locals != null)) {
+                env.error("token.expected", "{");
+            }
+            scanner.scan();
+        }  else {
+            scanner.expect(Token.LBRACE);
+            curCode = curMethod.startCode(posa, paramcnt, max_stack, max_locals);
+            while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
+                instrParser.parseInstr();
+                if (scanner.token == Token.RBRACE) {
+                    break;
+                }
+                scanner.expect(Token.SEMICOLON);
+            }
+
+            curCode.endCode();
+            scanner.expect(Token.RBRACE);
+        }
+
+        if (defAnnot != null) {
+            curMethod.addDefaultAnnotation(defAnnot);
+        }
+        if (memberAnnttns != null) {
+            curMethod.addAnnotations(memberAnnttns);
+        }
+        cd.EndMethod();
+        debugStr("  [Parser.parseMethod]: Method: " + curMethod );
+
+    }  // end parseMethod
+
+
+    /**
+     * Parse a (CPX based) BootstrapMethod entry.
+     */
+    protected void parseCPXBootstrapMethod(int mod) throws Scanner.SyntaxError, IOException {
+        // Parses in the form:
+        // BOOTSTRAPMETHOD CPX_MethodHandle (CPX_Arg)* ;
+        if (scanner.token == Token.CPINDEX) {
+            // CPX can be a CPX to an MethodHandle constant,
+            int cpx = scanner.intValue;
+            ConstCell MHCell = pool.getCell(cpx);
+            scanner.scan();
+            ArrayList<ConstCell> bsm_args = new ArrayList<>(256);
+
+            while (scanner.token != Token.SEMICOLON) {
+                if (scanner.token == Token.CPINDEX) {
+                    bsm_args.add(pool.getCell(scanner.intValue));
+
+                } else {
+                    // throw error, bootstrap method is not recognizable
+                    env.error(scanner.pos, "invalid.bootstrapmethod");
+                    throw new Scanner.SyntaxError();
+                }
+                scanner.scan();
+            }
+            BootstrapMethodData bsmData = new BootstrapMethodData(MHCell, bsm_args);
+            cd.addBootstrapMethod(bsmData);
+        } else {
+            // throw error, bootstrap method is not recognizable
+            env.error(scanner.pos, "invalid.bootstrapmethod");
+            throw new Scanner.SyntaxError();
+        }
+     }
+
+
+
+    /**
+     * Parse an inner class.
+     */
+    protected void parseInnerClass(int mod) throws Scanner.SyntaxError, IOException {
+        // Parses in the form:
+        // MODIFIERS (INNERCLASSNAME =)? (INNERCLASS) (OF OUTERCLASS)? ;
+        //
+        // where
+        //    INNERCLASSNAME = (IDENT | CPX_IN-CL-NM)
+        //    INNERCLASS = (CLASS IDENT | CPX_IN-CL) (S2)
+        //    OUTERCLASS = (CLASS IDENT | CPX_OT-CL) (S3)
+        //
+        // Note:
+        //    If a class reference cannot be identified using IDENT, CPX indexes must be used.
+
+        // check access modifiers:
+        debugScan("[Parser.parseInnerClass]:  Begin ");
+        Modifiers.checkInnerClassModifiers(cd, mod, scanner.pos);
+
+        ConstCell nameCell;
+        ConstCell innerClass = null;
+        ConstCell outerClass = null;
+
+
+        if (scanner.token == Token.CLASS) {
+            nameCell = pool.getCell(0);  // no NameIndex
+            parseInnerClass_s2(mod, nameCell, innerClass, outerClass);
+        } else {
+            if ((scanner.token == Token.IDENT) || scanner.checkTokenIdent()) {
+                // Got a Class Name
+                nameCell = parseName();
+                parseInnerClass_s1(mod, nameCell, innerClass, outerClass);
+            } else if (scanner.token == Token.CPINDEX) {
+                // CPX can be either a CPX to an InnerClassName,
+                // or a CPX to an InnerClassInfo
+                int cpx = scanner.intValue;
+                nameCell = pool.getCell(cpx);
+                ConstValue nameCellValue = nameCell.ref;
+
+                if (nameCellValue instanceof ConstValue_String) {
+                    // got a name cell
+                   scanner.scan();
+                   parseInnerClass_s1(mod, nameCell, innerClass, outerClass);
+                } else {
+                    // got a CPRef cell
+                    nameCell = pool.getCell(0);  // no NameIndex
+                    parseInnerClass_s2(mod, nameCell, innerClass, outerClass);
+                }
+            } else {
+                pic_error();
+            }
+
+        }
+    }
+
+    private void parseInnerClass_s1(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) throws IOException {
+        // next scanner.token must be '='
+        if (scanner.token == Token.ASSIGN) {
+            scanner.scan();
+            parseInnerClass_s2(mod, nameCell, innerClass, outerClass);
+        } else {
+            pic_error();
+        }
+
+    }
+
+
+    private void parseInnerClass_s2(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) throws IOException {
+        // scanner.token is either "CLASS IDENT" or "CPX_Class"
+        if ((scanner.token == Token.CPINDEX) || (scanner.token == Token.CLASS)) {
+            if (scanner.token == Token.CPINDEX) {
+                int cpx = scanner.intValue;
+                innerClass = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
+            }
+
+            if (scanner.token == Token.CLASS) {
+                // next symbol needs to be InnerClass
+                scanner.scan();
+                innerClass = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
+            }
+
+            // See if declaration is terminated
+            if (scanner.token == Token.SEMICOLON) {
+                // InnerClass is complete, no OUTERINFO;
+                outerClass = pool.getCell(0);
+                pic_tracecreate(mod, nameCell, innerClass, outerClass);
+                cd.addInnerClass(mod, nameCell, innerClass, outerClass);
+            } else if (scanner.token == Token.OF) {
+                // got an outer class reference
+                parseInnerClass_s3(mod, nameCell, innerClass, outerClass);
+            } else {
+                pic_error();
+            }
+
+        } else {
+            pic_error();
+        }
+
+    }
+
+
+    private void parseInnerClass_s3(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) throws IOException {
+        scanner.scan();
+        if ((scanner.token == Token.CLASS) || (scanner.token == Token.CPINDEX)) {
+            if (scanner.token == Token.CLASS) {
+                // next symbol needs to be InnerClass
+               scanner.scan();
+               outerClass = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
+            }
+            if (scanner.token == Token.CPINDEX) {
+                int cpx = scanner.intValue;
+                outerClass = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
+            }
+
+            if (scanner.token == Token.SEMICOLON) {
+               pic_tracecreate(mod, nameCell, innerClass, outerClass);
+               cd.addInnerClass(mod, nameCell, innerClass, outerClass);
+            } else {
+                pic_error();
+            }
+        } else {
+            pic_error();
+        }
+    }
+
+    private void pic_tracecreate(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) {
+            // throw error, IC is not recognizable
+            env.trace(" Creating InnerClass: [" + Modifiers.toString(mod, CF_Context.CTX_INNERCLASS) + "], ");
+
+            if (nameCell != pool.getCell(0)) {
+                ConstValue value = nameCell.ref;
+                if (value != null) {
+                    env.trace(value.toString() + " = ");
+                }
+            }
+
+            ConstValue_Cell ici_val = (ConstValue_Cell) innerClass.ref;
+            ConstCell ici_ascii = (ConstCell) ici_val.cell;
+            // Constant pool may not be numberized yet.
+            //
+            // check values before dereference on a trace.
+            if (ici_ascii.ref == null) {
+                env.trace("<#cpx-unresolved> ");
+            } else {
+                ConstValue_String cval = ( ConstValue_String) ici_ascii.ref;
+                if (cval.value == null){
+                    env.trace("<#cpx-0> ");
+                } else {
+                    env.trace(cval.value + " ");
+                }
+            }
+
+            if (outerClass != pool.getCell(0)) {
+                if (outerClass.arg != 0) {
+                    ConstValue_Cell oci_val = (ConstValue_Cell) outerClass.ref;
+                    ConstCell  oci_ascii = (ConstCell) oci_val.cell;
+                    if (oci_ascii.ref == null) {
+                        env.trace(" of <#cpx-unresolved>  ");
+                    } else {
+                        ConstValue_String cval = ( ConstValue_String) oci_ascii.ref;
+                        if (cval.value == null) {
+                            env.trace(" of <#cpx-0>  ");
+                        } else {
+                            env.trace(" of " + cval.value);
+                        }
+                    }
+                }
+            }
+
+            env.traceln("");
+    }
+
+    private void pic_error() {
+            // throw error, IC is not recognizable
+            env.error(scanner.pos, "invalid.innerclass");
+            throw new Scanner.SyntaxError();
+    }
+
+    /**
+     * The match() method is used to quickly match opening
+     * brackets (ie: '(', '{', or '[') with their closing
+     * counter part. This is useful during error recovery.<p>
+     *
+     * Scan to a matching '}', ']' or ')'. The current scanner.token must be
+     * a '{', '[' or '(';
+     */
+    protected void match(Token open, Token close) throws IOException {
+        int depth = 1;
+
+        while (true) {
+            scanner.scan();
+            if (scanner.token == open) {
+                depth++;
+            } else if (scanner.token == close) {
+                if (--depth == 0) {
+                    return;
+                }
+            } else if (scanner.token == Token.EOF) {
+                env.error(scanner.pos, "unbalanced.paren");
+                return;
+            }
+        }
+    }
+
+    /**
+     * Recover after a syntax error in a field. This involves
+     * discarding scanner.tokens until an EOF or a possible legal
+     * continuation is encountered.
+     */
+    protected void recoverField() throws Scanner.SyntaxError, IOException {
+        while (true) {
+            switch (scanner.token) {
+                case EOF:
+                case STATIC:
+                case FINAL:
+                case PUBLIC:
+                case PRIVATE:
+                case SYNCHRONIZED:
+                case TRANSIENT:
+                case PROTECTED:
+                case VOLATILE:
+                case NATIVE:
+//                case INTERFACE: see below
+                case ABSTRACT:
+
+                // possible begin of a field, continue
+                return;
+
+                case LBRACE:
+                    match(Token.LBRACE, Token.RBRACE);
+                    scanner.scan();
+                    break;
+
+                case LPAREN:
+                    match(Token.LPAREN, Token.RPAREN);
+                    scanner.scan();
+                    break;
+
+                case LSQBRACKET:
+                    match(Token.LSQBRACKET, Token.RSQBRACKET);
+                    scanner.scan();
+                    break;
+
+                case RBRACE:
+                case INTERFACE:
+                case CLASS:
+                case IMPORT:
+                case PACKAGE:
+                    // begin of something outside a class, panic more
+                    endClass(scanner.pos);
+                    scanner.debugStr("    [Parser.recoverField]: pos: [" + scanner.pos + "]: ");
+                    throw new Scanner.SyntaxError();
+
+                default:
+                    // don't know what to do, skip
+                    scanner.scan();
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Parse a class or interface declaration.
+     */
+    protected void parseClass(int mod) throws IOException {
+        int posa = scanner.pos;
+        debugStr("   [Parser.parseClass]:  Begin ");
+        // check access modifiers:
+        Modifiers.checkClassModifiers(env, mod, posa);
+
+        if (cd == null) {
+            cd = new ClassData(env, major_version, minor_version);
+            pool = cd.pool;
+        }
+
+        if (clsAnnttns != null) {
+            cd.addAnnotations(clsAnnttns);
+        }
+
+        // move the tokenizer to the identifier:
+        if (scanner.token == Token.CLASS) {
+            scanner.scan();
+        }
+
+        // Parse the class name
+        ConstCell nm = cpParser.parseConstRef(ConstType.CONSTANT_CLASS, null, true);
+
+        if (scanner.token == Token.FIELD) { // DOT
+            String fileExtension;
+            scanner.scan();
+            switch (scanner.token) {
+                case STRINGVAL:
+                    fileExtension = scanner.stringValue;
+                    break;
+                case IDENT:
+                    fileExtension = scanner.idValue;
+                    break;
+                default:
+                    env.error(scanner.pos, "name.expected");
+                    throw new Scanner.SyntaxError();
+            }
+            scanner.scan();
+            cd.fileExtension="."+fileExtension;
+        } else if (scanner.token == Token.SEMICOLON) {
+            // drop the semi-colon following a name
+            scanner.scan();
+        }
+
+        // Parse extends clause
+        ConstCell sup = null;
+        if (scanner.token == Token.EXTENDS) {
+            scanner.scan();
+            sup = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
+            while (scanner.token == Token.COMMA) {
+                scanner.scan();
+                env.error(posa, "multiple.inherit");
+                cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
+            }
+        }
+
+        // Parse implements clause
+        ArrayList<Argument> impl = new ArrayList<>();
+        if (scanner.token == Token.IMPLEMENTS) {
+            do {
+                scanner.scan();
+                Argument intf = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
+                if (impl.contains(intf)) {
+                    env.error(posa, "warn.intf.repeated", intf);
+                } else {
+                    impl.add(intf);
+                }
+            } while (scanner.token == Token.COMMA);
+        }
+        parseVersion();
+        scanner.expect(Token.LBRACE);
+
+        // Begin a new class
+        cd.init(mod, nm, sup, impl);
+
+       // Parse constant declarations
+
+        // Parse class members
+        while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
+            switch (scanner.token) {
+                case SEMICOLON:
+                    // Empty fields are allowed
+                    scanner.scan();
+                    break;
+
+                case CONST:
+                    scanner.scan();
+                    parseConstDef();
+                    explicitcp = true;
+                    break;
+
+
+                default:   // scanner.token is some member.
+                    parseClassMembers();
+            }  // end switch
+        } // while
+
+        scanner.expect(Token.RBRACE);
+
+        // End the class
+        endClass(scanner.prevPos);
+    } // end parseClass
+
+    private void parseClassMembers() throws IOException {
+        debugScan("[Parser.parseClassMembers]:  Begin ");
+        // Parse annotations
+        if (scanner.token == Token.ANNOTATION) {
+            memberAnnttns = annotParser.scanAnnotations();
+        }
+
+        // Parse modifiers
+        int mod = scanModifiers();
+        try {
+            switch (scanner.token) {
+                case FIELDREF:
+                    scanner.scan();
+                    parseField(mod);
+                    break;
+                case METHODREF:
+                    scanner.scan();
+                    parseMethod(mod);
+                    break;
+                case INNERCLASS:
+                    scanner.scan();
+                    parseInnerClass(mod);
+                    break;
+                case BOOTSTRAPMETHOD:
+                    scanner.scan();
+                    parseCPXBootstrapMethod(mod);
+                    break;
+                default:
+                    env.error(scanner.pos, "field.expected");
+                    throw new Scanner.SyntaxError();
+            }  // end switch
+        } catch (Scanner.SyntaxError e) {
+            recoverField();
+        }
+        memberAnnttns = null;
+    }
+
+    /**
+     * Recover after a syntax error in the file.
+     * This involves discarding scanner.tokens until an EOF
+     * or a possible legal continuation is encountered.
+     */
+    protected void recoverFile() throws IOException {
+        while (true) {
+            env.traceln("recoverFile: scanner.token=" + scanner.token);
+            switch (scanner.token) {
+                case CLASS:
+                case INTERFACE:
+                    // Start of a new source file statement, continue
+                    return;
+
+                case LBRACE:
+                    match(Token.LBRACE, Token.RBRACE);
+                    scanner.scan();
+                    break;
+
+                case LPAREN:
+                    match(Token.LPAREN, Token.RPAREN);
+                    scanner.scan();
+                    break;
+
+                case LSQBRACKET:
+                    match(Token.LSQBRACKET, Token.RSQBRACKET);
+                    scanner.scan();
+                    break;
+
+                case EOF:
+                    return;
+
+                default:
+                    // Don't know what to do, skip
+                    scanner.scan();
+                    break;
+            }
+        }
+    }
+
+    /**
+     * End class
+     */
+    protected void endClass(int where) {
+        if (explicitcp) {
+            // Fix references in the constant pool (for explicitly coded CPs)
+            pool.fixRefsInPool();
+            // Fix any bootstrap Method references too
+            cd.relinkBootstrapMethods();
+        }
+
+        cd.endClass();
+        clsDataList.add(cd);
+        cd = null;
+    }
+
+    public final ClassData[] getClassesData() {
+        return ((ClassData[]) clsDataList.toArray(new ClassData[0]));
+    }
+
+    /**
+     * Determines whether the JASM file is for a package-info class
+     * or a module-info class.
+     *
+     * creates the correct kind of ClassData accordingly.
+     *
+     * @throws IOException
+     */
+    private void parseJasmPackages() throws IOException {
+        try {
+            // starting annotations could either be
+            // a package annotation, or a class annotation
+            if (scanner.token == Token.ANNOTATION) {
+                if (cd == null) {
+                    cd = new ClassData(env, major_version, minor_version);
+                    pool = cd.pool;
+                }
+                pkgAnnttns = annotParser.scanAnnotations();
+            }
+            if (scanner.token == Token.PACKAGE) {
+                // Package statement
+                scanner.scan();
+                int where = scanner.pos;
+                String id = parseIdent();
+                parseVersionPkg();
+                scanner.expect(Token.SEMICOLON);
+
+                if (pkg == null) {
+                    pkg = id;
+                    pkgPrefix = id + "/";
+                } else {
+                    env.error(where, "package.repeated");
+                }
+                debugScan("[Parser.parseJasmPackages] {PARSED} package-prefix: " + pkgPrefix + " ");
+            }
+        } catch (Scanner.SyntaxError e) {
+            recoverFile();
+        }
+        // skip bogus semi colons
+        while (scanner.token == Token.SEMICOLON) {
+            scanner.scan();
+        }
+
+        // checks that we compile module or package compilation unit
+        if (scanner.token == Token.EOF) {
+            env.traceln("Scanner:  EOF");
+            String sourceName = env.getSourceName();
+            int mod = ACC_INTERFACE | ACC_ABSTRACT;
+
+            // package-info
+            if (sourceName.endsWith("package-info.jasm")) {
+                env.traceln("Creating \"package-info.jasm\": package: " + pkg + " " + major_version + ":" + minor_version);
+
+                if (cd == null) {
+                    cd = new ClassData(env, major_version, minor_version);
+                    pool = cd.pool;
+                } else {
+                    cd.major_version = major_version;
+                    cd.minor_version = minor_version;
+                }
+                ConstCell me = pool.FindCellClassByName(pkgPrefix + "package-info");
+
+                if (major_version > 49) {
+                    mod |= SYNTHETIC_ATTRIBUTE;
+                }
+                cd.init(mod, me, new ConstCell(0), null);
+
+                if (pkgAnnttns != null) {
+                    cd.addAnnotations(pkgAnnttns);
+                }
+
+                endClass(scanner.prevPos);
+            }
+            return;
+        }
+
+        if (pkg == null && pkgAnnttns != null) { // RemoveModules
+            clsAnnttns = pkgAnnttns;
+            pkgAnnttns = null;
+        }
+    }
+
+    /**
+     * Parse an Jasm file.
+     */
+    public void parseFile() {
+        try{
+            // First, parse any package identifiers (and associated package annotations)
+            parseJasmPackages();
+
+            while (scanner.token != Token.EOF) {
+                // Second, parse any class identifiers (and associated class annotations)
+                try {
+                    // Parse annotations
+                    if (scanner.token == Token.ANNOTATION) {
+                        if (cd == null) {
+                            cd = new ClassData(env, major_version, minor_version);
+                            pool = cd.pool;
+                        }
+                        clsAnnttns = annotParser.scanAnnotations();
+                    }
+
+                    // Parse class modifiers
+                    int mod = scanModifiers();
+                    if (mod == 0) {
+                        switch (scanner.token) {
+                        case CLASS:
+                        case CPINDEX:
+                        case STRINGVAL:
+                        case IDENT:
+                          // this is a class declaration anyway
+                          break;
+                        case SEMICOLON:
+                          // Bogus semi colon
+                          scanner.scan();
+                          continue;
+                        default:
+                          // no class declaration found
+                          debugScan(" [Parser.parseFile]: ");
+                          env.error(scanner.pos, "toplevel.expected");
+                          throw new Scanner.SyntaxError();
+                        }
+                    } else if (Modifiers.isInterface(mod) && (scanner.token != Token.CLASS)) {
+                        // rare syntactic sugar:
+                        // interface <ident> == abstract interface class <ident>
+                        mod |= ACC_ABSTRACT;
+                    }
+                    parseClass(mod);
+                    clsAnnttns = null;
+                } catch (Scanner.SyntaxError e) {
+                    // KTL
+                    env.traceln("^^^^^^^ Syntax Error ^^^^^^^^^^^^");
+                    if (scanner.debugFlag)
+                        e.printStackTrace();
+                    recoverFile();
+                }
+            }
+        } catch (IOException e) {
+            env.error(scanner.pos, "io.exception", env.getSourceName());
+        } catch (Error er) {
+            er.printStackTrace();
+        }
+    } //end parseFile
+}  //end Parser
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/ParserAnnotation.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,1142 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import static org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
+import static org.openjdk.asmtools.jasm.JasmTokens.*;
+import static org.openjdk.asmtools.jasm.ConstantPool.*;
+import static org.openjdk.asmtools.jasm.Tables.*;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.TreeMap;
+
+/**
+ * ParserAnnotation
+ *
+ * ParserAnnotation is a parser class owned by Parser.java. It is primarily responsible
+ * for parsing Annotations (for classes, methods or fields).
+ *
+ * ParserAnnotation can parse the different types of Annotation Attributes:
+ * Runtime(In)Visible Annotations (JDK 6+) Default Annotations (JDK 6+)
+ * Runtime(In)VisibleParameter Annotations (JDK 7+) Runtime(In)VisibleType Annotations
+ * (JSR308, JDK8+)
+ */
+public class ParserAnnotation extends ParseBase {
+
+    /*-------------------------------------------------------- */
+    /* Annotation Inner Classes */
+    /**
+     * AnnotationElemValue
+     *
+     * Used to store Annotation values
+     */
+    class AnnotationElemValue implements Data {
+
+        AnnotationData annotation;
+
+        public AnnotationElemValue(AnnotationData annotation) {
+            this.annotation = annotation;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeByte('@');
+            annotation.write(out);
+        }
+
+        @Override
+        public int getLength() {
+            return 1 + annotation.getLength();
+        }
+    }
+
+    /**
+     * ClassElemValue
+     *
+     * Annotation Element value referring to a class
+     */
+    class ClassElemValue implements Data {
+
+        ConstCell indx;
+
+        public ClassElemValue(ConstCell indx) {
+            this.indx = indx;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeByte('c');
+            indx.write(out);
+        }
+
+        @Override
+        public int getLength() {
+            return 3;
+        }
+    }
+
+    /**
+     * ArrayElemValue
+     *
+     * Annotation Element value referring to an Array
+     */
+    class ArrayElemValue implements Data {
+
+        ArrayList<Data> elemValues;
+        int arrayLength = 0;
+
+        public ArrayElemValue() {
+            this.elemValues = new ArrayList<>();
+        }
+
+        void add(Data elemValue) {
+            elemValues.add(elemValue);
+            arrayLength += elemValue.getLength();
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeByte('[');
+            out.writeShort(elemValues.size());
+
+            for (Data eval : elemValues) {
+                eval.write(out);
+            }
+        }
+
+        @Override
+        public int getLength() {
+            return 3 + arrayLength;
+        }
+    }
+
+    /**
+     * ConstElemValue
+     *
+     * Annotation Element value referring to a Constant
+     */
+    class ConstElemValue implements Data {
+
+        char tag;
+        ConstCell indx;
+
+        public ConstElemValue(char tag, ConstCell indx) {
+            this.tag = tag;
+            this.indx = indx;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeByte(tag);
+            indx.write(out);
+        }
+
+        @Override
+        public int getLength() {
+            return 3;
+        }
+    }
+
+    /**
+     * EnumElemValue
+     *
+     * Element Value for Enums
+     */
+    class EnumElemValue implements Data {
+
+        ConstCell type;
+        ConstCell value;
+
+        public EnumElemValue(ConstCell type, ConstCell value) {
+            this.type = type;
+            this.value = value;
+        }
+
+        @Override
+        public void write(CheckedDataOutputStream out) throws IOException {
+            out.writeByte('e');
+            type.write(out);
+            value.write(out);
+        }
+
+        @Override
+        public int getLength() {
+            return 5;
+        }
+    }
+
+    /*-------------------------------------------------------- */
+    /* Annotation Parser Fields */
+    /**
+     * local handles on the scanner, main parser, and the error reporting env
+     */
+    private static TTVis ttVisitor;
+    /*-------------------------------------------------------- */
+
+    /**
+     * main constructor
+     *
+     * @param scanner
+     * @param parser
+     * @param env
+     */
+    protected ParserAnnotation(Scanner scanner, Parser parser, Environment env) {
+        super.init(scanner, parser, env);
+        ttVisitor = new TTVis();
+        ttVisitor.init(env, scanner);
+    }
+
+    protected void scanParamName(int totalParams, int paramNum, MethodData curMethod) throws IOException {
+        debugScan(" - - - > [ParserAnnotation.scanParamName]: Begin ");
+        scanner.scan();
+        scanner.expect(Token.LBRACE);
+        // First scan the Name (String, or CPX to name)
+        ConstCell nameCell = null;
+        if ((scanner.token == Token.IDENT) || scanner.checkTokenIdent()) {
+            // Got a Class Name
+            nameCell = parser.parseName();
+        } else if (scanner.token == Token.CPINDEX) {
+            int cpx = scanner.intValue;
+            nameCell = parser.pool.getCell(cpx);
+            // check the constant
+            ConstValue nameCellValue = nameCell.ref;
+            if (!(nameCellValue instanceof ConstValue_String)) {
+                // throw an error
+                env.error(scanner.pos, "paramname.constnum.invaltype", cpx);
+                throw new Scanner.SyntaxError();
+            }
+
+        } else {
+            // throw scan error - unexpected token
+            env.error(scanner.pos, "paramname.token.unexpected", scanner.stringValue);
+            throw new Scanner.SyntaxError();
+        }
+
+        // Got the name cell. Next, scan the access flags
+        int mod = parser.scanModifiers();
+
+        scanner.expect(Token.RBRACE);
+
+        curMethod.addMethodParameter(totalParams, paramNum, nameCell, mod);
+
+        debugScan(" - - - > [ParserAnnotation.scanParamName]: End ");
+    }
+
+    /**
+     * scanAnnotations
+     *
+     * The main entry for parsing an annotation list.
+     *
+     * @return An ArrayList of parsed annotations
+     * @throws IOException
+     */
+    protected ArrayList<AnnotationData> scanAnnotations() throws IOException {
+        ArrayList<AnnotationData> annttns = new ArrayList<>();
+
+        while (scanner.token == Token.ANNOTATION) {
+            if (isAnnotationToken(scanner.stringValue)) {
+                annttns.add(parseAnnotation());
+            } else if (isTypeAnnotationToken(scanner.stringValue)) {
+                annttns.add(parseTypeAnnotation());
+            }
+        }
+
+        if (annttns.size() > 0) {
+            return annttns;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * isAnnotation
+     *
+     * examines the beginning of a string to see if it starts with an annotation character
+     *
+     * @param str
+     * @return True if the string starts with an annotation char.
+     */
+    protected boolean isAnnotation(String str) {
+        return (str.startsWith("@"));
+    }
+
+    /**
+     * isAnnotationToken
+     *
+     * examines the beginning of a string to see if it starts with an annotation
+     * characters ('@+' = visible annotation, '@-' = invisible).
+     *
+     * @param str
+     * @return True if the string starts with an annotation char.
+     */
+    protected boolean isAnnotationToken(String str) {
+        return (str.startsWith("@+") || str.startsWith("@-"));
+    }
+
+    /**
+     * isTypeAnnotationToken
+     *
+     * examines the beginning of a string to see if it starts with type annotation
+     * characters ('@T+' = visible type annotation, '@T-' = invisible).
+     *
+     * @param str
+     * @return True if the string starts with an annotation char.
+     */
+    protected boolean isTypeAnnotationToken(String str) {
+        return (str.startsWith("@T+") || str.startsWith("@T-"));
+    }
+
+    /**
+     * isInvisibleAnnotToken
+     *
+     * examines the end of an annotation token to determine visibility ('+' = visible
+     * annotation, '-' = invisible).
+     *
+     * @param str
+     * @return True if the token implies invisible annotation.
+     */
+    protected boolean isInvisibleAnnotToken(String str) {
+        return (str.endsWith("-"));
+    }
+
+    /**
+     * parseDefaultAnnotation
+     *
+     * parses a default Annotation attribute
+     *
+     * @return the parsed Annotation Attribute
+     * @throws org.openjdk.asmtools.jasm.Scanner.SyntaxError
+     * @throws IOException
+     */
+    protected DefaultAnnotationAttr parseDefaultAnnotation() throws Scanner.SyntaxError, IOException {
+        scanner.scan();
+        DefaultAnnotationAttr attr = null;
+        Data value = null;
+        scanner.expect(Token.LBRACE);
+
+        if ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
+            value = scanAnnotationData("default");
+        }
+        scanner.expect(Token.RBRACE);
+        attr = new DefaultAnnotationAttr(parser.cd,
+                AttrTag.ATT_AnnotationDefault.parsekey(),
+                value);
+        return attr;
+    }
+
+    /**
+     * parseParamAnnots
+     *
+     * Parses Parameter Annotations attributes.
+     *
+     * @param _totalParams
+     * @param curMethod
+     * @throws org.openjdk.asmtools.jasm.Scanner.SyntaxError
+     * @throws IOException
+     */
+    protected void parseParamAnnots(int _totalParams, MethodData curMethod) throws Scanner.SyntaxError, IOException {
+        debugScan(" - - - > [ParserAnnotation.parseParamAnnots]: Begin, totalParams =  " + _totalParams + " ");
+        // _The method thinks there are N+1 params in the signature
+        // (N = total params in the call list) + 1 (return value)
+        int totalParams = _totalParams - 1;
+        TreeMap<Integer, ArrayList<AnnotationData>> pAnnots = new TreeMap<>();
+
+        while (scanner.token == Token.INTVAL) {
+            // Create the Parameter Array for  Param Annotations
+
+            // Do something with Parameter annotations
+            // --------------------
+            // First - validate that the parameter number (integer)
+            // (eg >= 0, < numParams, and param num is not previously set)
+            int paramNum = scanner.intValue;
+            Integer iParamNum = new Integer(paramNum);
+            if (paramNum < 0 || paramNum >= totalParams) {
+                //invalid Parameter number.  Throw an error.
+                env.error(scanner.pos, "invalid.paramnum", paramNum);
+            }
+            if (pAnnots.get(iParamNum) != null) {
+                // paramter is already populated with annotations/pnames, Throw an error.
+                env.error(scanner.pos, "duplicate.paramnum", paramNum);
+            }
+            // 2nd - Parse the COLON (invalid if not present)
+            scanner.scan();
+            scanner.expect(Token.COLON);
+
+            // 3rd - parse either an optional ParamName, or a list of annotations
+            if (scanner.token == Token.PARAM_NAME) {
+                //parse the ParamName
+                scanParamName(_totalParams, iParamNum, curMethod);
+            }
+
+            // 4th - parse each Annotation (followed by comma, followed by annotation
+            //       assign array of annotations to param array
+            if (scanner.token == Token.ANNOTATION) {
+                ArrayList<AnnotationData> pAnnot = scanAnnotations();
+                pAnnots.put(iParamNum, pAnnot);
+
+                for (AnnotationData data : pAnnot) {
+                    curMethod.addParamAnnotation(totalParams, paramNum, data);
+                }
+            }
+
+        }
+    }
+
+    /* ************************* Private Members  *************************** */
+    /**
+     * parseTypeAnnotation
+     *
+     * parses an individual annotation.
+     *
+     * @return a parsed annotation.
+     * @throws IOException
+     */
+    private AnnotationData parseTypeAnnotation() throws Scanner.SyntaxError, IOException {
+        boolean invisible = isInvisibleAnnotToken(scanner.stringValue);
+        scanner.scan();
+        debugScan("     [ParserAnnotation.parseTypeAnnotation]: id = " + scanner.stringValue + " ");
+        String annoName = "L" + scanner.stringValue + ";";
+        TypeAnnotationData anno = new TypeAnnotationData(parser.pool.FindCellAsciz(annoName), invisible);
+        scanner.scan();
+        debugScan("     [ParserAnnotation.parseTypeAnnotation]:new type annotation: " + annoName + " ");
+
+        scanner.expect(Token.LBRACE);
+
+        // Scan the usual annotation data
+        _scanAnnotation(anno);
+
+        // scan the Target
+        _scanTypeTarget(anno);
+
+        // scan the Location
+        _scanTargetPath(anno);
+
+        scanner.expect(Token.RBRACE);
+        return anno;
+    }
+
+    /**
+     * scanAnnotation
+     *
+     * parses an individual annotation.
+     *
+     * @return a parsed annotation.
+     * @throws IOException
+     */
+    private AnnotationData parseAnnotation() throws Scanner.SyntaxError, IOException {
+        debugScan(" - - - > [ParserAnnotation.parseAnnotation]: Begin ");
+        boolean invisible = isInvisibleAnnotToken(scanner.stringValue);
+        scanner.scan();
+        String annoName = "L" + scanner.stringValue + ";";
+
+        AnnotationData anno = new AnnotationData(parser.pool.FindCellAsciz(annoName), invisible);
+        scanner.scan();
+        debugScan("[ParserAnnotation.parseAnnotation]: new annotation: " + annoName);
+        _scanAnnotation(anno);
+
+        return anno;
+    }
+
+    /**
+     * _scanAnnotation
+     *
+     * parses an individual annotation-data.
+     *
+     * @return a parsed annotation.
+     * @throws IOException
+     */
+    private void _scanAnnotation(AnnotationData annotData) throws Scanner.SyntaxError, IOException {
+        debugScan(" - - - > [ParserAnnotation._scanAnnotation]: Begin");
+        scanner.expect(Token.LBRACE);
+
+        while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
+            ConstCell nameCell = parser.parseName();
+            scanner.expect(Token.ASSIGN);
+
+            ConstValue cellref = nameCell.ref;
+            if (cellref.tag != ConstType.CONSTANT_UTF8) {
+                throw new Scanner.SyntaxError();
+            }
+            String name = ((ConstValue_String) cellref)._toString();
+            debugScan(" - - - > [ParserAnnotation._scanAnnotation]: Annot - Field Name: " + name);
+            Data data = scanAnnotationData(name);
+            annotData.add(new AnnotationData.ElemValuePair(nameCell, data));
+
+            // consume tokens inbetween annotation fields
+            if (scanner.token == Token.COMMA) {
+                scanner.scan();
+            }
+        }
+        scanner.expect(Token.RBRACE);
+    }
+
+    /**
+     * _scanAnnotation
+     *
+     * parses an individual annotation-data.
+     *
+     * @return a parsed annotation.
+     * @throws IOException
+     */
+    private void _scanTypeTarget(TypeAnnotationData annotData) throws Scanner.SyntaxError, IOException {
+        debugScan("     [ParserAnnotation._scanTypeTarget]: Begin ");
+        scanner.expect(Token.LBRACE);
+
+        //Scan the target_type and the target_info
+        scanner.expect(Token.IDENT);
+        debugScan("     [ParserAnnotation._scanTypeTarget]: TargetType: " + scanner.idValue);
+        TypeAnnotationUtils.TargetType tt = TypeAnnotationUtils.getTargetType(scanner.idValue);
+        if (tt == null) {
+            env.error(scanner.pos, "incorrect.typeannot.target", scanner.idValue);
+            throw new Scanner.SyntaxError();
+        }
+
+        debugScan("     [ParserAnnotation._scanTypeTarget]: Got TargetType: " + tt);
+
+        if (ttVisitor.scanner == null) {
+            ttVisitor.scanner = scanner;
+        }
+        ttVisitor.visitExcept(tt);
+
+        annotData.targetInfo = ttVisitor.getTargetInfo();
+        annotData.targetType = tt;
+        debugScan("     [ParserAnnotation._scanTypeTarget]: Got TargetInfo: " + annotData.targetInfo);
+
+        scanner.expect(Token.RBRACE);
+    }
+
+    /**
+     * TTVis
+     *
+     * Target Type visitor, used for constructing the target-info within a type
+     * annotation. visitExcept() is the entry point. ti is the constructed target info.
+     */
+    private static class TTVis extends TypeAnnotationUtils.TypeAnnotationTargetVisitor {
+
+        private TypeAnnotationUtils.TargetInfo ti;
+        private IOException IOProb;
+        private Scanner.SyntaxError SyProb;
+        private Scanner scanner;
+        private Environment env;
+
+        public TTVis() {
+            super();
+            reset();
+        }
+
+        public void init(Environment en, Scanner scn) {
+            if (scanner == null) {
+                scanner = scn;
+            }
+            if (env == null) {
+                env = en;
+            }
+        }
+
+        public final void reset() {
+            ti = null;
+            IOProb = null;
+            SyProb = null;
+        }
+
+        //This is the entry point for a visitor that tunnels exceptions
+        public void visitExcept(TypeAnnotationUtils.TargetType tt) throws IOException, Scanner.SyntaxError {
+            IOProb = null;
+            SyProb = null;
+            ti = null;
+
+            visit(tt);
+
+            if (IOProb != null) {
+                throw IOProb;
+            }
+
+            if (SyProb != null) {
+                throw SyProb;
+            }
+        }
+
+        public TypeAnnotationUtils.TargetInfo getTargetInfo() {
+            return ti;
+        }
+
+        // this fn gathers intvals, and tunnels any exceptions thrown by
+        // the scanner
+        private int scanIntVal(TypeAnnotationUtils.TargetType tt) {
+            int ret = -1;
+            if (scanner.token == Token.INTVAL) {
+                ret = scanner.intValue;
+                try {
+                    scanner.scan();
+                } catch (IOException e) {
+                    IOProb = e;
+                } catch (Scanner.SyntaxError e) {
+                    SyProb = e;
+                }
+            } else {
+                env.error(scanner.pos, "incorrect.typeannot.targtype.int", tt.parseKey(), scanner.token);
+                SyProb = new Scanner.SyntaxError();
+            }
+            return ret;
+        }
+
+        // this fn gathers intvals, and tunnels any exceptions thrown by
+        // the scanner
+        private String scanStringVal(TypeAnnotationUtils.TargetType tt) {
+            String ret = "";
+            if (scanner.token == Token.STRINGVAL) {
+                ret = scanner.stringValue;
+                try {
+                    scanner.scan();
+                } catch (IOException e) {
+                    IOProb = e;
+                } catch (Scanner.SyntaxError e) {
+                    SyProb = e;
+                }
+            } else {
+                env.error(scanner.pos, "incorrect.typeannot.targtype.string", tt.parseKey(), scanner.token);
+                SyProb = new Scanner.SyntaxError();
+            }
+            return ret;
+        }
+
+        // this fn gathers intvals, and tunnels any exceptions thrown by
+        // the scanner
+        private void scanBrace(boolean left) {
+            try {
+                scanner.expect(left ? Token.LBRACE : Token.RBRACE);
+            } catch (IOException e) {
+                IOProb = e;
+            } catch (Scanner.SyntaxError e) {
+                SyProb = e;
+            }
+        }
+
+        private boolean error() {
+            return IOProb != null || SyProb != null;
+        }
+
+        @Override
+        public void visit_type_param_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("Type Param Target: ");
+            int byteval = scanIntVal(tt); // param index
+            if (!error()) {
+                ti = new TypeAnnotationUtils.typeparam_target(tt, byteval);
+            }
+        }
+
+        @Override
+        public void visit_supertype_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("SuperType Target: ");
+            int shortval = scanIntVal(tt); // type index
+            if (!error()) {
+                ti = new TypeAnnotationUtils.supertype_target(tt, shortval);
+            }
+        }
+
+        @Override
+        public void visit_typeparam_bound_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("TypeParam Bound Target: ");
+            int byteval1 = scanIntVal(tt); // param index
+            if (error()) {
+                return;
+            }
+            int byteval2 = scanIntVal(tt); // bound index
+            if (error()) {
+                return;
+            }
+            ti = new TypeAnnotationUtils.typeparam_bound_target(tt, byteval1, byteval2);
+        }
+
+        @Override
+        public void visit_empty_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("Empty Target: ");
+            if (!error()) {
+                ti = new TypeAnnotationUtils.empty_target(tt);
+            }
+        }
+
+        @Override
+        public void visit_methodformalparam_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("MethodParam Target: ");
+            int byteval = scanIntVal(tt); // param index
+            if (!error()) {
+                ti = new TypeAnnotationUtils.methodformalparam_target(tt, byteval);
+            }
+        }
+
+        @Override
+        public void visit_throws_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("Throws Target: ");
+            int shortval = scanIntVal(tt); // exception index
+            if (!error()) {
+                ti = new TypeAnnotationUtils.throws_target(tt, shortval);
+            }
+        }
+
+        @Override
+        public void visit_localvar_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("LocalVar Target: ");
+            TypeAnnotationUtils.localvar_target locvartab = new TypeAnnotationUtils.localvar_target(tt, 0);
+            ti = locvartab;
+
+            while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
+                // consume the left brace
+                scanBrace(true);
+                if (error()) {
+                    return;
+                }
+                // scan the local var triple
+                int shortval1 = scanIntVal(tt); // startPC
+                if (error()) {
+                    return;
+                }
+                int shortval2 = scanIntVal(tt); // length
+                if (error()) {
+                    return;
+                }
+                int shortval3 = scanIntVal(tt); // CPX
+                locvartab.addEntry(shortval1, shortval2, shortval3);
+                scanBrace(false);
+                if (error()) {
+                    return;
+                }
+            }
+        }
+
+        @Override
+        public void visit_catch_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("Catch Target: ");
+            int shortval = scanIntVal(tt); // catch index
+
+            ti = new TypeAnnotationUtils.catch_target(tt, shortval);
+        }
+
+        @Override
+        public void visit_offset_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("Offset Target: ");
+            int shortval = scanIntVal(tt); // offset index
+            if (!error()) {
+                ti = new TypeAnnotationUtils.offset_target(tt, shortval);
+            }
+        }
+
+        @Override
+        public void visit_typearg_target(TypeAnnotationUtils.TargetType tt) {
+            env.traceln("TypeArg Target: ");
+            int shortval = scanIntVal(tt); // offset
+            if (error()) {
+                return;
+            }
+            int byteval = scanIntVal(tt); // type index
+            if (error()) {
+                return;
+            }
+            ti = new TypeAnnotationUtils.typearg_target(tt, shortval, byteval);
+        }
+
+    }
+
+    /**
+     * _scanTypeLocation
+     *
+     * parses an individual annotation-data.
+     *
+     * @return a parsed annotation.
+     * @throws IOException
+     */
+    private void _scanTargetPath(TypeAnnotationData annotData) throws Scanner.SyntaxError, IOException {
+
+        ArrayList<TypePathEntry> targPath = new ArrayList<>();
+        // parse the location info
+        scanner.expect(Token.LBRACE);
+
+        while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
+            TypePathEntry tpe = _scanTypePathEntry();
+
+            scanner.scan();
+            // throw away comma
+            if (scanner.token == Token.COMMA) {
+                scanner.scan();
+            }
+        }
+        scanner.expect(Token.RBRACE);
+        annotData.targetPath = targPath;
+    }
+
+    /**
+     * _scanTypeLocation
+     *
+     * parses an individual annotation-data.
+     *
+     * @return a parsed annotation.
+     * @throws IOException
+     */
+    private TypePathEntry _scanTypePathEntry() throws Scanner.SyntaxError, IOException {
+        TypePathEntry tpe;
+
+        if ((scanner.token != Token.EOF) && (scanner.token == Token.STRINGVAL)) {
+            String pathEntryKey = scanner.stringValue;
+            PathKind pk = pathKind(pathEntryKey);
+            if (pk == null) {
+                // unexpected Type Path
+                env.error(scanner.pos, "incorrect.typeannot.pathentry", scanner.stringValue);
+                throw new Scanner.SyntaxError();
+            }
+            if (pk == PathKind.ITHARG_PARAMETERTYPE) {
+                //
+                // need to scan the index
+                // Take the form:  INNER_TYPE(#)
+                scanner.expect(Token.LPAREN);
+                int index = 0;
+                if ((scanner.token != Token.EOF) && (scanner.token == Token.INTVAL)) {
+                    index = scanner.intValue;
+                } else {
+                    // incorrect Arg index
+                    env.error(scanner.pos, "incorrect.typeannot.pathentry.argindex", scanner.token);
+                    throw new Scanner.SyntaxError();
+                }
+
+                scanner.expect(Token.RPAREN);
+                tpe = new TypePathEntry(pk.key(), (char) index);
+            } else {
+                tpe = new TypePathEntry(pk.key(), (char) 0);
+            }
+        } else {
+            // unexpected Type Path
+            env.error(scanner.pos, "incorrect.typeannot.pathentry", scanner.token);
+            throw new Scanner.SyntaxError();
+        }
+
+        return tpe;
+    }
+
+    /**
+     * scanAnnotationArray
+     *
+     * Scans an Array of annotations.
+     *
+     * @param name Name of the annotation
+     * @return Array Element
+     * @throws IOException if scanning errors exist
+     */
+    private ArrayElemValue scanAnnotationArray(String name) throws IOException {
+        scanner.scan();
+        ArrayElemValue arrayElem = new ArrayElemValue();
+
+        while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
+            Data data = scanAnnotationData(name + " {}");
+            arrayElem.add(data);
+
+            // consume tokens inbetween annotation fields
+            if (scanner.token == Token.COMMA) {
+                scanner.scan();
+            }
+        }
+
+        scanner.expect(Token.RBRACE);
+        return arrayElem;
+    }
+
+    /**
+     * scanAnnotationEnum
+     *
+     * Scans an annotation enum val.
+     *
+     * @param name Annotation Name
+     * @return Constant element value for the Class Annotation.
+     * @throws IOException
+     */
+    private Data scanAnnotationClass(String name) throws IOException {
+        Data constVal = null;
+        // scan the next identifier.
+        // if it is an Ident, consume it as the class name.
+        scanner.scan();
+        switch (scanner.token) {
+            case IDENT:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Constant Class Field: " + name + " = " + scanner.stringValue);
+                //need to encode the stringval as an (internal) descriptor.
+                String desc = parser.encodeClassString(scanner.stringValue);
+
+                // note: for annotations, a class field points to a string with the class descriptor.
+                constVal = new ConstElemValue('c', parser.pool.FindCellAsciz(desc));
+                scanner.scan();
+                break;
+            case CPINDEX:
+                // could be a reference to a class name
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Constant Class Field: " + name + " = " + scanner.stringValue);
+                Integer ConstNmCPX = new Integer(scanner.stringValue);
+                constVal = new ClassElemValue(parser.pool.getCell(ConstNmCPX));
+                scanner.scan();
+                break;
+            default:
+                env.error(scanner.pos, "incorrect.annot.class", scanner.stringValue);
+                throw new Scanner.SyntaxError();
+        }
+
+        return constVal;
+    }
+
+    /**
+     * scanAnnotationEnum
+     *
+     * Scans an annotation enum val.
+     *
+     * @param name Annotation Name
+     * @return Enumeration Element Value
+     * @throws IOException for scanning errors.
+     */
+    private EnumElemValue scanAnnotationEnum(String name) throws IOException {
+        scanner.scan();
+        EnumElemValue enumval = null;
+        switch (scanner.token) {
+            case IDENT:
+                // could be a string identifying enum class and name
+                String enumClassName = scanner.stringValue;
+                scanner.scan();
+                // could be a string identifying enum class and name
+                switch (scanner.token) {
+                    case IDENT:
+                        // could be a string identifying enum class and name
+                        String enumTypeName = scanner.stringValue;
+                        env.traceln("[AnnotationParser.scanAnnotationEnum]:: Constant Enum Field: " + name + " = " + enumClassName + " " + enumTypeName);
+                        String encodedClass = parser.encodeClassString(enumClassName);
+                        ConstElemValue classConst = new ConstElemValue('s', parser.pool.FindCellAsciz(encodedClass));
+                        ConstElemValue typeConst = new ConstElemValue('s', parser.pool.FindCellAsciz(enumTypeName));
+                        enumval = new EnumElemValue(classConst.indx, typeConst.indx);
+                        scanner.scan();
+                        break;
+
+                    default:
+                        env.error(scanner.pos, "incorrect.annot.enum", scanner.stringValue);
+                        throw new Scanner.SyntaxError();
+                }
+                break;
+            case CPINDEX:
+                Integer typeNmCPX = new Integer(scanner.stringValue);
+                scanner.scan();
+                //need two indexes to form a proper enum
+                switch (scanner.token) {
+                    case CPINDEX:
+                        Integer ConstNmCPX = new Integer(scanner.stringValue);
+                        env.traceln("[AnnotationParser.scanAnnotationEnum]:: Enumeration Field: " + name + " = #" + typeNmCPX + " #" + ConstNmCPX);
+                        enumval = new EnumElemValue(parser.pool.getCell(typeNmCPX), parser.pool.getCell(ConstNmCPX));
+                        scanner.scan();
+                        break;
+                    default:
+                        env.error(scanner.pos, "incorrect.annot.enum.cpx");
+                        throw new Scanner.SyntaxError();
+                }
+                break;
+        }
+
+        return enumval;
+    }
+
+    /**
+     * scanAnnotationData
+     *
+     * parses the internals of an annotation.
+     *
+     * @param name Annotation Name
+     * @return a Data data structure containing the annotation data.
+     * @throws IOException for scanning errors.
+     */
+    private Data scanAnnotationData(String name) throws IOException {
+        Data data = null;
+        switch (scanner.token) {
+            // This handles the Annotation types (as normalized in the constant pool)
+            // Some primitive types (Boolean, char, short, byte) are identified by a keyword.
+            case INTVAL:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Integer Field: " + name + " = " + scanner.intValue);
+                data = new ConstElemValue('I', parser.pool.FindCell(ConstType.CONSTANT_INTEGER, new Integer(scanner.intValue)));
+                scanner.scan();
+                break;
+            case DOUBLEVAL:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Double Field: " + name + " = " + scanner.doubleValue);
+                double dval = new Double(scanner.doubleValue);
+                long ivdal = Double.doubleToLongBits(dval);
+                Long val = new Long(ivdal);
+                data = new ConstElemValue('D', parser.pool.FindCell(ConstType.CONSTANT_DOUBLE, val));
+                scanner.scan();
+                break;
+            case FLOATVAL:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Float Field: " + name + " = " + scanner.floatValue);
+                float fval = new Float(scanner.floatValue);
+                int ifval = Float.floatToIntBits(fval);
+                Integer val1 = new Integer(ifval);
+                data = new ConstElemValue('F', parser.pool.FindCell(ConstType.CONSTANT_FLOAT, val1));
+                scanner.scan();
+                break;
+            case LONGVAL:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Long Field: " + name + " = " + scanner.longValue);
+                data = new ConstElemValue('J', parser.pool.FindCell(ConstType.CONSTANT_LONG, new Long(scanner.longValue)));
+                scanner.scan();
+                break;
+            case STRINGVAL:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: String Field: " + name + " = " + scanner.stringValue);
+                data = new ConstElemValue('s', parser.pool.FindCellAsciz(scanner.stringValue));
+                scanner.scan();
+                break;
+            case CLASS:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Class) keyword: " + scanner.stringValue);
+                data = scanAnnotationClass(name);
+                break;
+            case ENUM:
+                // scan the next two identifiers (eg ident.ident), or 2 CPRefs.
+                // if it is an Ident, use consume it as the class name.
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Enum) keyword: " + scanner.stringValue);
+                data = scanAnnotationEnum(name);
+                break;
+            case IDENT:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: JASM Keyword: (annotation field name: " + name + ") keyword: " + scanner.stringValue);
+                data = scanAnnotationIdent(scanner.stringValue, name);
+                break;
+            case ANNOTATION:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Annotation Field: " + name + " = " + scanner.stringValue);
+                data = new AnnotationElemValue(parseAnnotation());
+                break;
+            case LBRACE:
+                env.traceln("[AnnotationParser.scanAnnotationData]:: Annotation Array Field: " + name);
+                data = scanAnnotationArray(name);
+                break;
+            default:
+                env.error(scanner.pos, "incorrect.annot.token", scanner.token);
+                throw new Scanner.SyntaxError();
+        }
+
+        return data;
+    }
+
+    /**
+     * scanAnnotationIdent
+     *
+     * parses the identifier of an annotation.
+     *
+     * @param ident Basic Type identifier
+     * @param name Annotation Name
+     * @return Basic Type Annotation data
+     * @throws IOException if scanning errors occur
+     */
+    private Data scanAnnotationIdent(String ident, String name) throws IOException {
+        // Handle JASM annotation Keyword Identifiers
+        Data data = null;
+        BasicType type = basictype(ident);
+        switch (type) {
+
+            case T_BOOLEAN:
+                // consume the keyword, get the value
+                scanner.scan();
+                switch (scanner.token) {
+                    case INTVAL:
+                        // Handle Boolean value in integer form
+                        env.traceln("Boolean Field: " + name + " = " + scanner.intValue);
+                        Integer val = new Integer(scanner.intValue);
+                        if (val > 1 || val < 0) {
+                            env.traceln("Warning: Boolean Field: " + name + " value is not 0 or 1, value = " + scanner.intValue);
+                        }
+                        data = new ConstElemValue('Z', parser.pool.FindCell(ConstType.CONSTANT_INTEGER, val));
+                        scanner.scan();
+                        break;
+                    case IDENT:
+                        // handle boolean value with true/false keywords
+                        int val1 = 0;
+                        switch (scanner.stringValue) {
+                            case "true":
+                                val1 = 1;
+                                break;
+                            case "false":
+                                val1 = 0;
+                                break;
+                            default:
+                                throw new IOException("Incorrect Annotation (boolean), expected true/false), got \"" + scanner.stringValue + "\".");
+                        }
+                        env.traceln("Boolean Field: " + name + " = " + scanner.stringValue);
+                        data = new ConstElemValue('Z', parser.pool.FindCell(ConstType.CONSTANT_INTEGER, new Integer(val1)));
+                        scanner.scan();
+                        break;
+                    default:
+                        env.error(scanner.pos, "incorrect.annot.bool", scanner.stringValue);
+                        throw new Scanner.SyntaxError();
+                }
+                break;
+            case T_BYTE:
+                // consume the keyword, get the value
+                scanner.scan();
+                switch (scanner.token) {
+                    case INTVAL:
+                        env.traceln("Byte Field: " + name + " = " + scanner.intValue);
+                        Integer val = new Integer(scanner.intValue);
+                        if (val > 0xFF) {
+                            env.traceln("Warning: Byte Field: " + name + " value is greater than 0xFF, value = " + scanner.intValue);
+                        }
+                        data = new ConstElemValue('B', parser.pool.FindCell(ConstType.CONSTANT_INTEGER, val));
+                        scanner.scan();
+                        break;
+                    default:
+                        env.error(scanner.pos, "incorrect.annot.byte", scanner.stringValue);
+                        throw new Scanner.SyntaxError();
+                }
+                break;
+            case T_CHAR:
+                // consume the keyword, get the value
+                scanner.scan();
+                switch (scanner.token) {
+                    case INTVAL:
+                        env.traceln("Char Field: " + name + " = " + scanner.intValue);
+                        Integer val = new Integer(scanner.intValue);
+                        // Bounds check?
+                        data = new ConstElemValue('C', parser.pool.FindCell(ConstType.CONSTANT_INTEGER, val));
+                        scanner.scan();
+                        break;
+                    default:
+                        env.error(scanner.pos, "incorrect.annot.char", scanner.stringValue);
+                        throw new Scanner.SyntaxError();
+                }
+                break;
+            case T_SHORT:
+                // consume the keyword, get the value
+                scanner.scan();
+                switch (scanner.token) {
+                    case INTVAL:
+                        env.traceln("Short Field: " + name + " = " + scanner.intValue);
+                        Integer val = new Integer(scanner.intValue);
+                        if (val > 0xFFFF) {
+                            env.traceln("Warning: Short Field: " + name + " value is greater than 0xFFFF, value = " + scanner.intValue);
+                        }
+                        data = new ConstElemValue('S', parser.pool.FindCell(ConstType.CONSTANT_INTEGER, val));
+                        scanner.scan();
+                        break;
+                    default:
+                        env.error(scanner.pos, "incorrect.annot.short", scanner.stringValue);
+                        throw new Scanner.SyntaxError();
+                }
+                break;
+            default:
+                env.error(scanner.pos, "incorrect.annot.keyword", ident);
+                throw new Scanner.SyntaxError();
+        }
+
+        return data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/ParserCP.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,587 @@
+/*
+ * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import static org.openjdk.asmtools.jasm.JasmTokens.*;
+import static org.openjdk.asmtools.jasm.Tables.*;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * ParserCP
+ *
+ * ParseCP is a parser class owned by Parser.java. It is primarily responsible for parsing
+ * the constant pool and constant declarations.
+ */
+public class ParserCP extends ParseBase {
+
+    /**
+     * local handles on the scanner, main parser, and the error reporting env
+     */
+    /**
+     * Visitor object
+     */
+    private ParserCPVisitor pConstVstr;
+
+    /**
+     * main constructor
+     *
+     * @param scanner
+     * @param parser
+     * @param env
+     */
+    protected ParserCP(Scanner scanner, Parser parser, Environment env) {
+        super.init(scanner, parser, env);
+        pConstVstr = new ParserCPVisitor();
+    }
+
+    /**
+     * ParserCPVisitor
+     *
+     * This inner class overrides a constant pool visitor to provide specific parsing
+     * instructions (per method) for each type of Constant.
+     *
+     * Note: since the generic visitor throws no exceptions, this derived class tunnels
+     * the exceptions, rethrown in the visitEcept method.
+     */
+    class ParserCPVisitor extends ConstantPool.CPTagVisitor<ConstantPool.ConstValue> {
+
+        private IOException IOProb;
+        private Scanner.SyntaxError SyProb;
+
+        public ParserCPVisitor() {
+            IOProb = null;
+            SyProb = null;
+        }
+
+        //This is the entry point for a visitor that tunnels exceptions
+        public ConstantPool.ConstValue visitExcept(ConstType tag) throws IOException, Scanner.SyntaxError {
+            IOProb = null;
+            SyProb = null;
+            debugStr("------- [ParserCPVisitor.visitExcept]: ");
+            ConstantPool.ConstValue ret = visit(tag);
+
+            if (IOProb != null) {
+                throw IOProb;
+            }
+
+            if (SyProb != null) {
+                throw SyProb;
+            }
+
+            return ret;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitUTF8(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitUTF8]: ");
+            try {
+                scanner.expect(Token.STRINGVAL);
+            } catch (IOException e) {
+                IOProb = e;
+            }
+            ConstantPool.ConstValue_String obj
+                    = new ConstantPool.ConstValue_String(scanner.stringValue);
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitInteger(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitInteger]: ");
+            ConstantPool.ConstValue_Integer obj;
+            int v = 0;
+            try {
+                if (scanner.token == Token.BITS) {
+                    scanner.scan();
+                    scanner.inBits = true;
+                }
+                v = scanner.intValue * scanner.sign;
+                scanner.expect(Token.INTVAL);
+            } catch (IOException e) {
+                IOProb = e;
+            }
+            obj = new ConstantPool.ConstValue_Integer(tag, new Integer(v));
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitLong(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitLong]: ");
+            ConstantPool.ConstValue_Long obj = null;
+            try {
+                long v;
+                if (scanner.token == Token.BITS) {
+                    scanner.scan();
+                    scanner.inBits = true;
+                }
+                switch (scanner.token) {
+                    case INTVAL:
+                        v = scanner.intValue;
+                        break;
+                    case LONGVAL:
+                        v = scanner.longValue;
+                        break;
+                    default:
+                        env.error(scanner.prevPos, "token.expected", "Integer");
+                        throw new Scanner.SyntaxError();
+                }
+                obj = new ConstantPool.ConstValue_Long(tag, new Long(v * scanner.sign));
+                scanner.scan();
+            } catch (IOException e) {
+                IOProb = e;
+            } catch (Scanner.SyntaxError e) {
+                SyProb = e;
+            }
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitFloat(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitFloat]: ");
+            ConstantPool.ConstValue_Integer obj = null;
+            try {
+                int v;
+                float f;
+                scanner.inBits = false;  // this needs to be initialized for each float!
+                if (scanner.token == Token.BITS) {
+                    scanner.scan();
+                    scanner.inBits = true;
+                }
+i2f:            {
+                    switch (scanner.token) {
+                        case INTVAL:
+                            if (scanner.inBits) {
+                                v = scanner.intValue;
+                                break i2f;
+                            } else {
+                                f = (float) scanner.intValue;
+                                break;
+                            }
+                        case FLOATVAL:
+                            f = scanner.floatValue;
+                            break;
+                        case DOUBLEVAL:
+                            f = (float) scanner.doubleValue; // to be excluded?
+                            break;
+                        case INF:
+                            f = Float.POSITIVE_INFINITY;
+                            break;
+                        case NAN:
+                            f = Float.NaN;
+                            break;
+                        default:
+                            env.traceln("token=" + scanner.token);
+                            env.error(scanner.pos, "token.expected", "<Float>");
+                            throw new Scanner.SyntaxError();
+                    }
+                    v = Float.floatToIntBits(f);
+                }
+                if (scanner.sign == -1) {
+                    v = v ^ 0x80000000;
+                }
+                obj = new ConstantPool.ConstValue_Integer(tag, new Integer(v));
+                scanner.scan();
+            } catch (IOException e) {
+                IOProb = e;
+            } catch (Scanner.SyntaxError e) {
+                SyProb = e;
+            }
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitDouble(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitDouble]: ");
+            ConstantPool.ConstValue_Long obj = null;
+            try {
+                long v;
+                double d;
+                if (scanner.token == Token.BITS) {
+                    scanner.scan();
+                    scanner.inBits = true;
+                }
+d2l:            {
+                    switch (scanner.token) {
+                        case INTVAL:
+                            if (scanner.inBits) {
+                                v = scanner.intValue;
+                                break d2l;
+                            } else {
+                                d = (double) scanner.intValue;
+                                break;
+                            }
+                        case LONGVAL:
+                            if (scanner.inBits) {
+                                v = scanner.longValue;
+                                break d2l;
+                            } else {
+                                d = (double) scanner.longValue;
+                                break;
+                            }
+                        case FLOATVAL:
+                            d = scanner.floatValue;
+                            break;
+                        case DOUBLEVAL:
+                            d = scanner.doubleValue;
+                            break;
+                        case INF:
+                            d = Double.POSITIVE_INFINITY;
+                            break;
+                        case NAN:
+                            d = Double.NaN;
+                            break;
+                        default:
+                            env.error(scanner.pos, "token.expected", "Double");
+                            throw new Scanner.SyntaxError();
+                    }
+                    v = Double.doubleToLongBits(d);
+                }
+                if (scanner.sign == -1) {
+                    v = v ^ 0x8000000000000000L;
+                }
+                obj = new ConstantPool.ConstValue_Long(tag, new Long(v));
+                scanner.scan();
+            } catch (IOException e) {
+                IOProb = e;
+            } catch (Scanner.SyntaxError e) {
+                SyProb = e;
+            }
+            return obj;
+        }
+
+        private ConstantPool.ConstCell visitName(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitName]: ");
+            ConstantPool.ConstCell obj = null;
+            try {
+                obj = parser.parseName();
+            } catch (IOException e) {
+                IOProb = e;
+            }
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitMethodtype(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitMethodtype]: ");
+            ConstantPool.ConstValue_Cell obj = null;
+            ConstantPool.ConstCell cell = visitName(tag);
+            if (IOProb == null) {
+                obj = new ConstantPool.ConstValue_Cell(tag, cell);
+            }
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitString(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitString]: ");
+            ConstantPool.ConstValue_Cell obj = null;
+            ConstantPool.ConstCell cell = visitName(tag);
+            if (IOProb == null) {
+                obj = new ConstantPool.ConstValue_Cell(tag, cell);
+            }
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitClass(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitClass]: ");
+            ConstantPool.ConstValue_Cell obj = null;
+            try {
+                ConstantPool.ConstCell cell = parser.parseClassName(true);
+                obj = new ConstantPool.ConstValue_Cell(tag, cell);
+            } catch (IOException e) {
+                IOProb = e;
+            }
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitMethodhandle(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitMethodHandle]: ");
+            ConstantPool.ConstValue_Pair obj = null;
+            try {
+                ConstantPool.ConstCell refCell;
+                ConstantPool.ConstCell subtagCell;
+                SubTag subtag;
+                if (scanner.token == Token.INTVAL) {
+                    // Handle explicit constant pool form
+                    subtag = subtag(scanner.intValue);
+                    subtagCell = new ConstantPool.ConstCell(subtag.value());
+                    scanner.scan();
+                    scanner.expect(Token.COLON);
+                    if (scanner.token != Token.CPINDEX) {
+                        env.traceln("token=" + scanner.token);
+                        env.error(scanner.pos, "token.expected", "<CPINDEX>");
+                        throw new Scanner.SyntaxError();
+                    }
+                    int cpx = scanner.intValue;
+                    refCell = parser.pool.getCell(cpx);
+                    scanner.scan();
+
+                } else {
+                    // normal JASM
+                    subtag = parser.parseSubtag();
+                    subtagCell = new ConstantPool.ConstCell(subtag.value());
+                    scanner.expect(Token.COLON);
+                    refCell = parser.parseMethodHandle(subtag);
+                }
+                obj = new ConstantPool.ConstValue_Pair(tag, subtagCell, refCell);
+            } catch (IOException e) {
+                IOProb = e;
+            }
+            return obj;
+        }
+
+        private ConstantPool.ConstValue_Pair visitMember(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitMember]: ");
+            ConstantPool.ConstValue_Pair obj = null;
+            try {
+                Token prevtoken = scanner.token;
+                ConstantPool.ConstCell firstName, ClassCell, NameCell, NapeCell;
+                firstName = parser.parseClassName(false);
+                if (scanner.token == Token.FIELD) { // DOT
+                    scanner.scan();
+                    if (prevtoken == Token.CPINDEX) {
+                        ClassCell = firstName;
+                    } else {
+                        ClassCell = parser.pool.FindCell(ConstType.CONSTANT_CLASS, firstName);
+                    }
+                    NameCell = parser.parseName();
+                } else {
+                    // no class provided - assume current class
+                    ClassCell = parser.cd.me;
+                    NameCell = firstName;
+                }
+                if (scanner.token == Token.COLON) {
+                    // name and type separately
+                    scanner.scan();
+                    NapeCell = parser.pool.FindCell(ConstType.CONSTANT_NAMEANDTYPE, NameCell, parser.parseName());
+                } else {
+                    // name and type as single name
+                    NapeCell = NameCell;
+                }
+                obj = new ConstantPool.ConstValue_Pair(tag, ClassCell, NapeCell);
+            } catch (IOException e) {
+                IOProb = e;
+            }
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitField(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitField]: ");
+            return visitMember(tag);
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitMethod(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitMethod]: ");
+            return visitMember(tag);
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitInterfacemethod(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitInterfacemethod]: ");
+            return visitMember(tag);
+        }
+
+        @Override
+        public ConstantPool.ConstValue visitNameandtype(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitNameandtype]: ");
+            ConstantPool.ConstValue_Pair obj = null;
+            try {
+                ConstantPool.ConstCell NameCell = parser.parseName(), TypeCell;
+                scanner.expect(Token.COLON);
+                TypeCell = parser.parseName();
+                obj = new ConstantPool.ConstValue_Pair(tag, NameCell, TypeCell);
+            } catch (IOException e) {
+                IOProb = e;
+            }
+            return obj;
+        }
+
+        @Override
+        public ConstantPool.ConstValue_IndyPair visitInvokedynamic(ConstType tag) {
+            debugStr("------- [ParserCPVisitor.visitInvokeDynamic]: ");
+            ConstantPool.ConstValue_IndyPair obj = null;
+            try {
+                if (scanner.token == Token.INTVAL) {
+                    // Handle explicit constant pool form
+                    int bsmIndex = scanner.intValue;
+                    scanner.scan();
+                    scanner.expect(Token.COLON);
+                    if (scanner.token != Token.CPINDEX) {
+                        env.traceln("token=" + scanner.token);
+                        env.error(scanner.pos, "token.expected", "<CPINDEX>");
+                        throw new Scanner.SyntaxError();
+                    }
+                    int cpx = scanner.intValue;
+                    scanner.scan();
+                    // Put a placeholder in place of BSM.
+                    // resolve placeholder after the attributes are scanned.
+                    BootstrapMethodData bsmData = new BootstrapMethodData(bsmIndex);
+                    obj = new ConstantPool.ConstValue_IndyPair(bsmData, parser.pool.getCell(cpx));
+
+                } else {
+                    // Handle full form
+                    ConstantPool.ConstCell MHCell = parser.pool.FindCell(parseConstValue(ConstType.CONSTANT_METHODHANDLE));
+                    scanner.expect(Token.COLON);
+                    ConstantPool.ConstCell NapeCell = parser.pool.FindCell(parseConstValue(ConstType.CONSTANT_NAMEANDTYPE));
+
+                    ArrayList<ConstantPool.ConstCell> bsm_args = new ArrayList<>(256);
+                    while (scanner.token != Token.SEMICOLON) {
+                        if (scanner.token == Token.COMMA) {
+                            scanner.scan();
+                        }
+                        bsm_args.add(parseConstRef(null));
+                    }
+                    BootstrapMethodData bsmData = new BootstrapMethodData(MHCell, bsm_args);
+                    parser.cd.addBootstrapMethod(bsmData);
+                    obj = new ConstantPool.ConstValue_IndyPair(bsmData, NapeCell);
+                }
+            } catch (IOException e) {
+                IOProb = e;
+            }
+            return obj;
+        }
+
+    } // End Visitor
+
+    /**
+     * Parse CONSTVALUE
+     */
+    protected ConstantPool.ConstValue parseConstValue(ConstType tag) throws IOException, Scanner.SyntaxError {
+        return pConstVstr.visitExcept(tag);
+    }
+
+    /**
+     * Parse [TAG] CONSTVALUE
+     */
+    protected ConstantPool.ConstValue parseTagConstValue(ConstType defaultTag) throws Scanner.SyntaxError, IOException {
+        return parseTagConstValue(defaultTag, null, false);
+    }
+
+    private ConstType scanConstByID(boolean ignoreKeywords) {
+        ConstType tag = null;
+        if (!ignoreKeywords) {
+            ConstType tg = Tables.tag(scanner.idValue);
+            if (tg != null) {
+                tag = tg;
+            }
+            debugStr(" *^*^*^*^ [ParserCP.scanConst]: {TAG = " + (tg == null ? "null" : tg.toString()) + " ");
+        }
+        return tag;
+    }
+
+    private ConstType scanConstPrimVal() throws Scanner.SyntaxError, IOException {
+        ConstType tag = null;
+        switch (scanner.token) {
+            case INTVAL:
+                tag = ConstType.CONSTANT_INTEGER;
+                break;
+            case LONGVAL:
+                tag = ConstType.CONSTANT_LONG;
+                break;
+            case FLOATVAL:
+                tag = ConstType.CONSTANT_FLOAT;
+                break;
+            case DOUBLEVAL:
+                tag = ConstType.CONSTANT_DOUBLE;
+                break;
+            case STRINGVAL:
+            case BITS:
+            case IDENT:
+                tag = ConstType.CONSTANT_STRING;
+                break;
+            default:
+                // problem - no constant value
+                System.err.println("NEAR: " + scanner.token.printval());
+                env.error(scanner.pos, "value.expected");
+                throw new Scanner.SyntaxError();
+        }
+        return tag;
+    }
+
+    private void checkWrongTag(ConstType tag, ConstType defaultTag, ConstType default2Tag) throws Scanner.SyntaxError, IOException {
+        if (defaultTag != null) {
+            if (tag != defaultTag) {
+                if (default2Tag == null) {
+                    env.error("warn.wrong.tag", defaultTag.parseKey());
+                } else if (tag != default2Tag) {
+                    env.error("warn.wrong.tag2", defaultTag.parseKey(), default2Tag.parseKey());
+                }
+            }
+        }
+    }
+
+    protected ConstantPool.ConstValue parseTagConstValue(ConstType defaultTag, ConstType default2Tag, boolean ignoreKeywords) throws Scanner.SyntaxError, IOException {
+        debugScan(" *^*^*^*^ [ParserCP.parseTagConstValue]: Begin default_tag:  ignoreKeywords: " + (ignoreKeywords ? "true" : "false"));
+        // Lookup the Tag from the scanner
+        ConstType tag = scanConstByID(ignoreKeywords);
+        debugStr(" *^*^*^*^ [ParserCP.parseTagConstValue]: {tag = " + tag + ", defaulttag = " + defaultTag + "} ");
+
+        // If the scanned tag is null
+        if (tag == null) {
+            // and, if the expected tag is null
+            if (defaultTag == null) {
+                // return some other type of constant as the tag
+                tag = scanConstPrimVal();
+            } else {
+                // otherwise, make the scanned-tag the same constant-type
+                // as the expected tag.
+                tag = defaultTag;
+            }
+        } else {
+            // If the scanned tag is some constant type
+            // and the scanned type does not equal the expected type
+            checkWrongTag(tag, defaultTag, default2Tag);
+            scanner.scan();
+        }
+        return parseConstValue(tag);
+    } // end parseTagConstValue
+
+    protected ConstantPool.ConstCell parseConstRef(ConstType defaultTag) throws Scanner.SyntaxError, IOException {
+        return parseConstRef(defaultTag, null, false);
+    }
+
+    protected ConstantPool.ConstCell parseConstRef(ConstType defaultTag, ConstType default2Tag) throws Scanner.SyntaxError, IOException {
+        return parseConstRef(defaultTag, default2Tag, false);
+    }
+
+    /**
+     * Parse an instruction argument, one of: * #NUMBER, #NAME, [TAG] CONSTVALUE
+     */
+    protected ConstantPool.ConstCell parseConstRef(ConstType defaultTag,
+            ConstType default2Tag,
+            boolean ignoreKeywords) throws Scanner.SyntaxError, IOException {
+        if (scanner.token == Token.CPINDEX) {
+            int cpx = scanner.intValue;
+            scanner.scan();
+            return parser.pool.getCell(cpx);
+        } else {
+            ConstantPool.ConstValue ref = null;
+            ref = parseTagConstValue(defaultTag, default2Tag, ignoreKeywords);
+            return parser.pool.FindCell(ref);
+        }
+    } // end parseConstRef
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openjdk/asmtools/jasm/ParserInstr.java	Thu Dec 18 14:56:02 2014 -0700
@@ -0,0 +1,405 @@