/*
 * Copyright (c) 2010, 2011, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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 indify;

import java.util.*;
import java.io.*;
import java.lang.reflect.Modifier;
import java.util.regex.*;

/**
 * Transform one or more class files to incorporate JSR 292 features,
 * such as {@code invokedynamic}.
 * <p>
 * This is a standalone program in a single source file.
 * In this form, it may be useful for test harnesses, small experiments, and javadoc examples.
 * Copies of this file may show up in multiple locations for standalone usage.
 * The primary maintained location of this file is as follows:
 * <a href="http://kenai.com/projects/ninja/sources/indify-repo/content/src/indify/Indify.java">
 * http://kenai.com/projects/ninja/sources/indify-repo/content/src/indify/Indify.java</a>
 * <p>
 * Static private methods named MH_x and MT_x (where x is arbitrary)
 * must be stereotyped generators of MethodHandle and MethodType
 * constants.  All calls to them are transformed to {@code CONSTANT_MethodHandle}
 * and {@code CONSTANT_MethodType} "ldc" instructions.
 * The stereotyped code must create method types by calls to {@code methodType} or
 * {@code fromMethodDescriptorString}.  The "lookup" argument must be created
 * by calls to {@code java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
 * The class and string arguments must be constant.
 * The following methods of {@code java.lang.invoke.MethodHandle.Lookup Lookup} are
 * allowed for method handle creation: {@code findStatic}, {@code findVirtual},
 * {@code findConstructor}, {@code findSpecial},
 * {@code findGetter}, {@code findSetter},
 * {@code findStaticGetter}, or {@code findStaticSetter}.
 * The call to one of these methods must be followed immediately
 * by an {@code areturn} instruction.
 * The net result of the call to the MH_x or MT_x method must be
 * the creation of a constant method handle.  Thus, replacing calls
 * to MH_x or MT_x methods by {@code ldc} instructions should leave
 * the meaning of the program unchanged.
 * <p>
 * Static private methods named INDY_x must be stereotyped generators
 * of {@code invokedynamic} call sites.
 * All calls to them must be immediately followed by
 * {@code invokeExact} calls.
 * All such pairs of calls are transformed to {@code invokedynamic}
 * instructions.  Each INDY_x method must begin with a call to a
 * MH_x method, which is taken to be its bootstrap method.
 * The method must be immediately invoked (via {@code invokeGeneric}
 * on constant lookup, name, and type arguments.  An object array of
 * constants may also be appended to the {@code invokeGeneric call}.
 * This call must be cast to {@code CallSite}, and the result must be
 * immediately followed by a call to {@code dynamicInvoker}, with the
 * resulting method handle returned.
 * <p>
 * The net result of all of these actions is equivalent to the JVM's
 * execution of an {@code invokedynamic} instruction in the unlinked state.
 * Running this code once should produce the same results as running
 * the corresponding {@code invokedynamic} instruction.
 * In order to model the caching behavior, the code of an INDY_x
 * method is allowed to begin with getstatic, aaload, and if_acmpne
 * instructions which load a static method handle value and return it
 * if the value is non-null.
 * <p>
 * Example usage:
 * <blockquote><pre>
$ JAVA_HOME=(some recent OpenJDK 7 build)
$ ant
$ $JAVA_HOME/bin/java -cp build/classes indify.Indify --overwrite --dest build/testout build/classes/indify/Example.class
$ $JAVA_HOME/bin/java -cp build/classes indify.Example
MT = (java.lang.Object)java.lang.Object
MH = adder(int,int)java.lang.Integer
adder(1,2) = 3
calling indy:  42
$ $JAVA_HOME/bin/java -cp build/testout indify.Example
(same output as above)
 * </pre></blockquote>
 * <p>
 * A version of this transformation built on top of <a href="http://asm.ow2.org/">http://asm.ow2.org/</a> would be welcome.
 * @author John Rose
 */
public class Indify {
    public static void main(String... av) throws IOException {
        new Indify().run(av);
    }

    public File dest;
    public String[] classpath = {"."};
    public boolean keepgoing = false;
    public boolean expandProperties = false;
    public boolean overwrite = false;
    public boolean quiet = false;
    public boolean verbose = false;
    public boolean all = false;
    public int verifySpecifierCount = -1;

    public void run(String... av) throws IOException {
        List<String> avl = new ArrayList<>(Arrays.asList(av));
        parseOptions(avl);
        if (avl.isEmpty())
            throw new IllegalArgumentException("Usage: indify [--dest dir] [option...] file...");
        if ("--java".equals(avl.get(0))) {
            avl.remove(0);
            try {
                runApplication(avl.toArray(new String[0]));
            } catch (Exception ex) {
                if (ex instanceof RuntimeException)  throw (RuntimeException) ex;
                throw new RuntimeException(ex);
            }
            return;
        }
        Exception err = null;
        for (String a : avl) {
            try {
                indify(a);
            } catch (Exception ex) {
                if (err == null)  err = ex;
                System.err.println("failure on "+a);
                if (!keepgoing)  break;
            }
        }
        if (err != null) {
            if (err instanceof IOException)  throw (IOException) err;
            throw (RuntimeException) err;
        }
    }

    /** Execute the given application under a class loader which indifies all application classes. */
    public void runApplication(String... av) throws Exception {
        List<String> avl = new ArrayList<>(Arrays.asList(av));
        String mainClassName = avl.remove(0);
        av = avl.toArray(new String[0]);
        Class<?> mainClass = Class.forName(mainClassName, true, makeClassLoader());
        java.lang.reflect.Method main = mainClass.getMethod("main", String[].class);
        try { main.setAccessible(true); } catch (SecurityException ex) { }
        main.invoke(null, (Object) av);
    }

    public void parseOptions(List<String> av) throws IOException {
        for (; !av.isEmpty(); av.remove(0)) {
            String a = av.get(0);
            if (a.startsWith("-")) {
                String a2 = null;
                int eq = a.indexOf('=');
                if (eq > 0) {
                    a2 = maybeExpandProperties(a.substring(eq+1));
                    a = a.substring(0, eq+1);
                }
                switch (a) {
                case "--java":
                    return;  // keep this argument
                case "-d": case "--dest": case "-d=": case "--dest=":
                    dest = new File(a2 != null ? a2 : maybeExpandProperties(av.remove(1)));
                    break;
                case "-cp": case "--classpath":
                    classpath = maybeExpandProperties(av.remove(1)).split("["+File.pathSeparatorChar+"]");
                    break;
                case "-k": case "--keepgoing": case "--keepgoing=":
                    keepgoing = booleanOption(a2);  // print errors but keep going
                    break;
                case "--expand-properties": case "--expand-properties=":
                    expandProperties = booleanOption(a2);  // expand property references in subsequent arguments
                    break;
                case "--verify-specifier-count": case "--verify-specifier-count=":
                    verifySpecifierCount = Integer.valueOf(a2);
                    break;
                case "--overwrite": case "--overwrite=":
                    overwrite = booleanOption(a2);  // overwrite output files
                    break;
                case "--all": case "--all=":
                    all = booleanOption(a2);  // copy all classes, even if no patterns
                    break;
                case "-q": case "--quiet": case "--quiet=":
                    quiet = booleanOption(a2);  // less output
                    break;
                case "-v": case "--verbose": case "--verbose=":
                    verbose = booleanOption(a2);  // more output
                    break;
                default:
                    throw new IllegalArgumentException("unrecognized flag: "+a);
                }
                continue;
            } else {
                break;
            }
        }
        if (dest == null && !overwrite)
            throw new RuntimeException("no output specified; need --dest d or --overwrite");
        if (expandProperties) {
            for (int i = 0; i < av.size(); i++)
                av.set(i, maybeExpandProperties(av.get(i)));
        }
    }

    private boolean booleanOption(String s) {
        if (s == null)  return true;
        switch (s) {
        case "true":  case "yes": case "on":  case "1": return true;
        case "false": case "no":  case "off": case "0": return false;
        }
        throw new IllegalArgumentException("unrecognized boolean flag="+s);
    }

    private String maybeExpandProperties(String s) {
        if (!expandProperties)  return s;
        Set<String> propsDone = new HashSet<>();
        while (s.contains("${")) {
            int lbrk = s.indexOf("${");
            int rbrk = s.indexOf('}', lbrk);
            if (rbrk < 0)  break;
            String prop = s.substring(lbrk+2, rbrk);
            if (!propsDone.add(prop))  break;
            String value = System.getProperty(prop);
            if (verbose)  System.err.println("expanding ${"+prop+"} => "+value);
            if (value == null)  break;
            s = s.substring(0, lbrk) + value + s.substring(rbrk+1);
        }
        return s;
    }

    public void indify(String a) throws IOException {
        File f = new File(a);
        String fn = f.getName();
        if (fn.endsWith(".class") && f.isFile())
            indifyFile(f, dest);
        else if (fn.endsWith(".jar") && f.isFile())
            indifyJar(f, dest);
        else if (f.isDirectory())
            indifyTree(f, dest);
        else if (!keepgoing)
            throw new RuntimeException("unrecognized file: "+a);
    }

    private void ensureDirectory(File dir) {
        if (dir.mkdirs() && !quiet)
            System.err.println("created "+dir);
    }

    public void indifyFile(File f, File dest) throws IOException {
        if (verbose)  System.err.println("reading "+f);
        ClassFile cf = new ClassFile(f);
        Logic logic = new Logic(cf);
        boolean changed = logic.transform();
        logic.reportPatternMethods(quiet, keepgoing);
        if (changed || all) {
            File outfile;
            if (dest != null) {
                ensureDirectory(dest);
                outfile = classPathFile(dest, cf.nameString());
            } else {
                outfile = f;  // overwrite input file, no matter where it is
            }
            cf.writeTo(outfile);
            if (!quiet)  System.err.println("wrote "+outfile);
        }
    }

    File classPathFile(File pathDir, String className) {
        String qualname = className.replace('.','/')+".class";
        qualname = qualname.replace('/', File.separatorChar);
        return new File(pathDir, qualname);
    }

    public void indifyJar(File f, Object dest) throws IOException {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public void indifyTree(File f, File dest) throws IOException {
        if (verbose)  System.err.println("reading directory: "+f);
        for (File f2 : f.listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    if (name.endsWith(".class"))  return true;
                    if (name.contains("."))  return false;
                    // return true if it might be a package name:
                    return Character.isJavaIdentifierStart(name.charAt(0));
                }})) {
            if (f2.getName().endsWith(".class"))
                indifyFile(f2, dest);
            else if (f2.isDirectory())
                indifyTree(f2, dest);
        }
    }

    public ClassLoader makeClassLoader() {
        return new Loader();
    }
    private class Loader extends ClassLoader {
        Loader() {
            this(Indify.class.getClassLoader());
        }
        Loader(ClassLoader parent) {
            super(parent);
        }
        public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            File f = findClassInPath(name);
            if (f != null) {
                try {
                    Class<?> c = transformAndLoadClass(f);
                    if (c != null) {
                        if (resolve)  resolveClass(c);
                        return c;
                    }
                } catch (ClassNotFoundException ex) {
                    // fall through
                } catch (IOException ex) {
                    // fall through
                } catch (Exception ex) {
                    // pass error from reportPatternMethods, etc.
                    if (ex instanceof RuntimeException)  throw (RuntimeException) ex;
                    throw new RuntimeException(ex);
                }
            }
            return super.loadClass(name, resolve);
        }
        private File findClassInPath(String name) {
            for (String s : classpath) {
                File f = classPathFile(new File(s), name);
                //System.out.println("Checking for "+f);
                if (f.exists() && f.canRead()) {
                    return f;
                }
            }
            return null;
        }
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                File f = findClassInPath(name);
                if (f != null) {
                    Class<?> c = transformAndLoadClass(f);
                    if (c != null)  return c;
                }
            } catch (IOException ex) {
                throw new ClassNotFoundException("IO error", ex);
            }
            throw new ClassNotFoundException();
        }
        private Class<?> transformAndLoadClass(File f) throws ClassNotFoundException, IOException {
            if (verbose)  System.err.println("Loading class from "+f);
            ClassFile cf = new ClassFile(f);
            Logic logic = new Logic(cf);
            boolean changed = logic.transform();
            if (verbose && !changed)  System.err.println("(no change)");
            logic.reportPatternMethods(!verbose, keepgoing);
            byte[] bytes = cf.toByteArray();
            return defineClass(null, bytes, 0, bytes.length);
        }
    }

    private class Logic {
        // Indify logic, per se.
        ClassFile cf;
        final char[] poolMarks;
        final Map<Method,Constant> constants = new HashMap<>();
        final Map<Method,String> indySignatures = new HashMap<>();
        Logic(ClassFile cf) {
            this.cf = cf;
            poolMarks = new char[cf.pool.size()];
        }
        boolean transform() {
            if (!initializeMarks())  return false;
            if (!findPatternMethods())  return false;
            Pool pool = cf.pool;
            //for (Constant c : cp)  System.out.println("  # "+c);
            for (Method m : cf.methods) {
                if (constants.containsKey(m))  continue;  // don't bother
                // Transform references.
                int blab = 0;
                for (Instruction i = m.instructions(); i != null; i = i.next()) {
                    if (i.bc != opc_invokestatic)  continue;
                    int methi = i.u2At(1);
                    if (poolMarks[methi] == 0)  continue;
                    Short[] ref = pool.getMemberRef((short)methi);
                    Method conm = findMember(cf.methods, ref[1], ref[2]);
                    if (conm == null)  continue;
                    Constant con = constants.get(conm);
                    if (con == null)  continue;
                    if (blab++ == 0 && !quiet)
                        System.err.println("patching "+cf.nameString()+"."+m);
                    //if (blab == 1) { for (Instruction j = m.instructions(); j != null; j = j.next()) System.out.println("  |"+j); }
                    if (con.tag == CONSTANT_InvokeDynamic) {
                        // need to patch the following instruction too,
                        // but there are usually intervening argument pushes too
                        Instruction i2 = findPop(i);
                        Short[] ref2 = null;
                        short ref2i = 0;
                        if (i2 != null && i2.bc == opc_invokevirtual &&
                                poolMarks[(char)(ref2i = (short) i2.u2At(1))] == 'D')
                            ref2 = pool.getMemberRef(ref2i);
                        if (ref2 == null || !"invokeExact".equals(pool.getString(ref2[1]))) {
                            System.err.println(m+": failed to create invokedynamic at "+i.pc);
                            continue;
                        }
                        String invType = pool.getString(ref2[2]);
                        String bsmType = indySignatures.get(conm);
                        if (!invType.equals(bsmType)) {
                            System.err.println(m+": warning: "+conm+" call type and local invoke type differ: "
                                    +bsmType+", "+invType);
                        }
                        assert(i.len == 3 || i2.len == 3);
                        if (!quiet)  System.err.println(i+" "+conm+";...; "+i2+" => invokedynamic "+con);
                        int start = i.pc + 3, end = i2.pc;
                        System.arraycopy(i.codeBase, start, i.codeBase, i.pc, end-start);
                        i.forceNext(0);  // force revisit of new instruction
                        i2.u1AtPut(-3, opc_invokedynamic);
                        i2.u2AtPut(-2, con.index);
                        i2.u2AtPut(0, (short)0);
                        i2.u1AtPut(2, opc_nop);
                        //System.out.println(new Instruction(i.codeBase, i2.pc-3));
                    } else {
                        if (!quiet)  System.err.println(i+" "+conm+" => ldc "+con);
                        assert(i.len == 3);
                        i.u1AtPut(0, opc_ldc_w);
                        i.u2AtPut(1, con.index);
                    }
                }
                //if (blab >= 1) { for (Instruction j = m.instructions(); j != null; j = j.next()) System.out.println("    |"+j); }
            }
            cf.methods.removeAll(constants.keySet());
            return true;
        }

        // Scan forward from the instruction to find where the stack p
        // below the current sp at the instruction.
        Instruction findPop(Instruction i) {
            //System.out.println("findPop from "+i);
            Pool pool = cf.pool;
            JVMState jvm = new JVMState();
        decode:
            for (i = i.clone().next(); i != null; i = i.next()) {
                String pops = INSTRUCTION_POPS[i.bc];
                //System.out.println("  "+i+" "+jvm.stack+" : "+pops.replace("$", " => "));
                if (pops == null)  break;
                if (jvm.stackMotion(i.bc))  continue decode;
                if (pops.indexOf('Q') >= 0) {
                    Short[] ref = pool.getMemberRef((short) i.u2At(1));
                    String type = simplifyType(pool.getString(CONSTANT_Utf8, ref[2]));
                    switch (i.bc) {
                    case opc_getstatic:
                    case opc_getfield:
                    case opc_putstatic:
                    case opc_putfield:
                        pops = pops.replace("Q", type);
                        break;
                    default:
                        if (!type.startsWith("("))
                            throw new InternalError(i.toString());
                        pops = pops.replace("Q$Q", type.substring(1).replace(")","$"));
                        break;
                    }
                    //System.out.println("special type: "+type+" => "+pops);
                }
                int npops = pops.indexOf('$');
                if (npops < 0)  throw new InternalError();
                if (npops > jvm.sp())  return i;
                List<Object> args = jvm.args(npops);
                int k = 0;
                for (Object x : args) {
                    char have = (Character) x;
                    char want = pops.charAt(k++);
                    if (have == 'X' || want == 'X')  continue;
                    if (have != want)  break decode;
                }
                if (pops.charAt(k++) != '$')  break decode;
                args.clear();
                while (k < pops.length())
                    args.add(pops.charAt(k++));
            }
            System.err.println("*** bailout on jvm: "+jvm.stack+" "+i);
            return null;
        }

        boolean findPatternMethods() {
            boolean found = false;
            for (char mark : "THI".toCharArray()) {
                for (Method m : cf.methods) {
                    if (!Modifier.isPrivate(m.access))  continue;
                    if (!Modifier.isStatic(m.access))  continue;
                    if (nameAndTypeMark(m.name, m.type) == mark) {
                        Constant con = scanPattern(m, mark);
                        if (con == null)  continue;
                        constants.put(m, con);
                        found = true;
                    }
                }
            }
            return found;
        }

        void reportPatternMethods(boolean quietly, boolean allowMatchFailure) {
            if (!quietly && !constants.keySet().isEmpty())
                System.err.println("pattern methods removed: "+constants.keySet());
            for (Method m : cf.methods) {
                if (nameMark(cf.pool.getString(m.name)) != 0 &&
                    constants.get(m) == null) {
                    String failure = "method has special name but fails to match pattern: "+m;
                    if (!allowMatchFailure)
                        throw new IllegalArgumentException(failure);
                    else if (!quietly)
                        System.err.println("warning: "+failure);
                }
            }
            if (verifySpecifierCount >= 0) {
                List<Object[]> specs = bootstrapMethodSpecifiers(false);
                int specsLen = (specs == null ? 0 : specs.size());
                // Pass by specsLen == 0, to help with associated (inner) classes.
                if (specsLen == 0)  specsLen = verifySpecifierCount;
                if (specsLen != verifySpecifierCount) {
                    throw new IllegalArgumentException("BootstrapMethods length is "+specsLen+" but should be "+verifySpecifierCount);
                }
            }
            if (!quiet)  System.err.flush();
        }

        // mark constant pool entries according to participation in patterns
        boolean initializeMarks() {
            boolean changed = false;
            for (;;) {
                boolean changed1 = false;
                int cpindex = -1;
                for (Constant e : cf.pool) {
                    ++cpindex;
                    if (e == null)  continue;
                    char mark = poolMarks[cpindex];
                    if (mark != 0)  continue;
                    switch (e.tag) {
                    case CONSTANT_Utf8:
                        mark = nameMark(e.itemString()); break;
                    case CONSTANT_NameAndType:
                        mark = nameAndTypeMark(e.itemIndexes()); break;
                    case CONSTANT_Class: {
                        int n1 = e.itemIndex();
                        char nmark = poolMarks[(char)n1];
                        if ("DJ".indexOf(nmark) >= 0)
                            mark = nmark;
                        break;
                    }
                    case CONSTANT_Field:
                    case CONSTANT_Method: {
                        Short[] n12 = e.itemIndexes();
                        short cl = n12[0];
                        short nt = n12[1];
                        char cmark = poolMarks[(char)cl];
                        if (cmark != 0) {
                            mark = cmark;  // it is a java.lang.invoke.* or java.lang.* method
                            break;
                        }
                        String cls = cf.pool.getString(CONSTANT_Class, cl);
                        if (cls.equals(cf.nameString())) {
                            switch (poolMarks[(char)nt]) {
                            // it is a private MH/MT/INDY method
                            case 'T': case 'H': case 'I':
                                mark = poolMarks[(char)nt];
                                break;
                            }
                        }
                        break;
                    }
                    default:  break;
                    }
                    if (mark != 0) {
                        poolMarks[cpindex] = mark;
                        changed1 = true;
                    }
                }
                if (!changed1)
                    break;
                changed = true;
            }
            return changed;
        }
        char nameMark(String s) {
            if (s.startsWith("MT_"))                return 'T';
            else if (s.startsWith("MH_"))           return 'H';
            else if (s.startsWith("INDY_"))         return 'I';
            else if (s.startsWith("java/lang/invoke/"))  return 'D';
            else if (s.startsWith("java/lang/"))    return 'J';
            return 0;
        }
        char nameAndTypeMark(Short[] n12) {
            return nameAndTypeMark(n12[0], n12[1]);
        }
        char nameAndTypeMark(short n1, short n2) {
            char mark = poolMarks[(char)n1];
            if (mark == 0)  return 0;
            String descr = cf.pool.getString(CONSTANT_Utf8, n2);
            String requiredType;
            switch (poolMarks[(char)n1]) {
            case 'H': requiredType = "()Ljava/lang/invoke/MethodHandle;";  break;
            case 'T': requiredType = "()Ljava/lang/invoke/MethodType;";    break;
            case 'I': requiredType = "()Ljava/lang/invoke/MethodHandle;";  break;
            default:  return 0;
            }
            if (matchType(descr, requiredType))  return mark;
            return 0;
        }

        boolean matchType(String descr, String requiredType) {
            if (descr.equals(requiredType))  return true;
            return false;
        }

        private class JVMState {
            final List<Object> stack = new ArrayList<>();
            int sp() { return stack.size(); }
            void push(Object x) { stack.add(x); }
            void push2(Object x) { stack.add(EMPTY_SLOT); stack.add(x); }
            void pushAt(int pos, Object x) { stack.add(stack.size()+pos, x); }
            Object pop() { return stack.remove(sp()-1); }
            Object top() { return stack.get(sp()-1); }
            List<Object> args(boolean hasRecv, String type) {
                return args(argsize(type) + (hasRecv ? 1 : 0));
            }
            List<Object> args(int argsize) {
                return stack.subList(sp()-argsize, sp());
            }
            boolean stackMotion(int bc) {
                switch (bc) {
                case opc_pop:    pop();             break;
                case opc_pop2:   pop(); pop();      break;
                case opc_swap:   pushAt(-1, pop()); break;
                case opc_dup:    push(top());       break;
                case opc_dup_x1: pushAt(-2, top()); break;
                case opc_dup_x2: pushAt(-3, top()); break;
                // ? also: dup2{,_x1,_x2}
                default:  return false;
                }
                return true;
            }
        }
        private final String EMPTY_SLOT = "_";
        private void removeEmptyJVMSlots(List<Object> args) {
            for (;;) {
                int i = args.indexOf(EMPTY_SLOT);
                if (i >= 0 && i+1 < args.size()
                    && (isConstant(args.get(i+1), CONSTANT_Long) ||
                        isConstant(args.get(i+1), CONSTANT_Double)))
                    args.remove(i);
                else  break;
            }
        }

        private Constant scanPattern(Method m, char patternMark) {
            if (verbose)  System.err.println("scan "+m+" for pattern="+patternMark);
            int wantTag;
            switch (patternMark) {
            case 'T': wantTag = CONSTANT_MethodType; break;
            case 'H': wantTag = CONSTANT_MethodHandle; break;
            case 'I': wantTag = CONSTANT_InvokeDynamic; break;
            default: throw new InternalError();
            }
            Instruction i = m.instructions();
            JVMState jvm = new JVMState();
            Pool pool = cf.pool;
            int branchCount = 0;
            Object arg;
            List<Object> args;
            List<Object> bsmArgs = null;  // args to invokeGeneric
        decode:
            for (; i != null; i = i.next()) {
                //System.out.println(jvm.stack+" "+i);
                int bc = i.bc;
                switch (bc) {
                case opc_ldc:           jvm.push(pool.get(i.u1At(1)));   break;
                case opc_ldc_w:         jvm.push(pool.get(i.u2At(1)));   break;
                case opc_ldc2_w:        jvm.push2(pool.get(i.u2At(1)));  break;
                case opc_aconst_null:   jvm.push(null);                  break;
                case opc_bipush:        jvm.push((int)(byte) i.u1At(1)); break;
                case opc_sipush:        jvm.push((int)(short)i.u2At(1)); break;

                // these support creation of a restarg array
                case opc_anewarray:
                    arg = jvm.pop();
                    if (!(arg instanceof Integer))  break decode;
                    arg = Arrays.asList(new Object[(Integer)arg]);
                    jvm.push(arg);
                    break;
                case opc_dup:
                    jvm.push(jvm.top()); break;
                case opc_aastore:
                    args = jvm.args(3);  // array, index, value
                    if (args.get(0) instanceof List &&
                        args.get(1) instanceof Integer) {
                        ((List<Object>)args.get(0)).set( (Integer)args.get(1), args.get(2) );
                    }
                    args.clear();
                    break;

                case opc_new:
                {
                    String type = pool.getString(CONSTANT_Class, (short)i.u2At(1));
                    //System.out.println("new "+type);
                    switch (type) {
                    case "java/lang/StringBuilder":
                        jvm.push("StringBuilder");
                        continue decode;  // go to next instruction
                    }
                    break decode;  // bail out
                }

                case opc_getstatic:
                {
                    // int.class compiles to getstatic Integer.TYPE
                    int fieldi = i.u2At(1);
                    char mark = poolMarks[fieldi];
                    //System.err.println("getstatic "+fieldi+Arrays.asList(pool.getStrings(pool.getMemberRef((short)fieldi)))+mark);
                    if (mark == 'J') {
                        Short[] ref = pool.getMemberRef((short) fieldi);
                        String name = pool.getString(CONSTANT_Utf8, ref[1]);
                        if ("TYPE".equals(name)) {
                            String wrapperName = pool.getString(CONSTANT_Class, ref[0]).replace('/', '.');
                            // a primitive type descriptor
                            Class<?> primClass;
                            try {
                                primClass = (Class<?>) Class.forName(wrapperName).getField(name).get(null);
                            } catch (Exception ex) {
                                throw new InternalError("cannot load "+wrapperName+"."+name);
                            }
                            jvm.push(primClass);
                            break;
                        }
                    }
                    // unknown field; keep going...
                    jvm.push(UNKNOWN_CON);
                    break;
                }
                case opc_putstatic:
                {
                    if (patternMark != 'I')  break decode;
                    jvm.pop();
                    // unknown field; keep going...
                    break;
                }

                case opc_invokestatic:
                case opc_invokevirtual:
                case opc_invokespecial:
                {
                    boolean hasRecv = (bc != opc_invokestatic);
                    int methi = i.u2At(1);
                    char mark = poolMarks[methi];
                    Short[] ref = pool.getMemberRef((short)methi);
                    String type = pool.getString(CONSTANT_Utf8, ref[2]);
                    //System.out.println("invoke "+pool.getString(CONSTANT_Utf8, ref[1])+" "+Arrays.asList(ref)+" : "+type);
                    args = jvm.args(hasRecv, type);
                    String intrinsic = null;
                    Constant con;
                    if (mark == 'D' || mark == 'J') {
                        intrinsic = pool.getString(CONSTANT_Utf8, ref[1]);
                        if (mark == 'J') {
                            String cls = pool.getString(CONSTANT_Class, ref[0]);
                            cls = cls.substring(1+cls.lastIndexOf('/'));
                            intrinsic = cls+"."+intrinsic;
                        }
                        //System.out.println("recognized intrinsic "+intrinsic);
                        byte refKind = -1;
                        switch (intrinsic) {
                        case "findGetter":          refKind = REF_getField;         break;
                        case "findStaticGetter":    refKind = REF_getStatic;        break;
                        case "findSetter":          refKind = REF_putField;         break;
                        case "findStaticSetter":    refKind = REF_putStatic;        break;
                        case "findVirtual":         refKind = REF_invokeVirtual;    break;
                        case "findStatic":          refKind = REF_invokeStatic;     break;
                        case "findSpecial":         refKind = REF_invokeSpecial;    break;
                        case "findConstructor":     refKind = REF_newInvokeSpecial; break;
                        }
                        if (refKind >= 0 && (con = parseMemberLookup(refKind, args)) != null) {
                            args.clear(); args.add(con);
                            continue;
                        }
                    }
                    Method ownMethod = null;
                    if (mark == 'T' || mark == 'H' || mark == 'I') {
                        ownMethod = findMember(cf.methods, ref[1], ref[2]);
                    }
                    //if (intrinsic != null)  System.out.println("intrinsic = "+intrinsic);
                    switch (intrinsic == null ? "" : intrinsic) {
                    case "fromMethodDescriptorString":
                        con = makeMethodTypeCon(args.get(0));
                        args.clear(); args.add(con);
                        continue;
                    case "methodType": {
                        flattenVarargs(args);  // there are several overloadings, some with varargs
                        StringBuilder buf = new StringBuilder();
                        String rtype = null;
                        for (Object typeArg : args) {
                            if (typeArg instanceof Class) {
                                Class<?> argClass = (Class<?>) typeArg;
                                if (argClass.isPrimitive()) {
                                    char tchar;
                                    switch (argClass.getName()) {
                                    case "void":    tchar = 'V'; break;
                                    case "boolean": tchar = 'Z'; break;
                                    case "byte":    tchar = 'B'; break;
                                    case "char":    tchar = 'C'; break;
                                    case "short":   tchar = 'S'; break;
                                    case "int":     tchar = 'I'; break;
                                    case "long":    tchar = 'J'; break;
                                    case "float":   tchar = 'F'; break;
                                    case "double":  tchar = 'D'; break;
                                    default:  throw new InternalError(argClass.toString());
                                    }
                                    buf.append(tchar);
                                } else {
                                    // should not happen, but...
                                    buf.append('L').append(argClass.getName().replace('.','/')).append(';');
                                }
                            } else if (typeArg instanceof Constant) {
                                Constant argCon = (Constant) typeArg;
                                if (argCon.tag == CONSTANT_Class) {
                                    String cn = pool.get(argCon.itemIndex()).itemString();
                                    if (cn.endsWith(";"))
                                        buf.append(cn);
                                    else
                                        buf.append('L').append(cn).append(';');
                                } else {
                                    break decode;
                                }
                            } else {
                                break decode;
                            }
                            if (rtype == null) {
                                // first arg is treated differently
                                rtype = buf.toString();
                                buf.setLength(0);
                                buf.append('(');
                            }
                        }
                        buf.append(')').append(rtype);
                        con = con = makeMethodTypeCon(buf.toString());
                        args.clear(); args.add(con);
                        continue;
                    }
                    case "lookup":
                    case "dynamicInvoker":
                        args.clear(); args.add(intrinsic);
                        continue;
                    case "lookupClass":
                        if (args.equals(Arrays.asList("lookup"))) {
                            // fold lookup().lookupClass() to the enclosing class
                            args.clear(); args.add(pool.get(cf.thisc));
                            continue;
                        }
                        break;
                    case "invoke":
                    case "invokeGeneric":
                    case "invokeWithArguments":
                        if (patternMark != 'I')  break decode;
                        if ("invokeWithArguments".equals(intrinsic))
                            flattenVarargs(args);
                        bsmArgs = new ArrayList(args);
                        args.clear(); args.add("invokeGeneric");
                        continue;
                    case "Integer.valueOf":
                    case "Float.valueOf":
                    case "Long.valueOf":
                    case "Double.valueOf":
                        removeEmptyJVMSlots(args);
                        if (args.size() == 1) {
                            arg = args.remove(0);
                            assert(3456 == (CONSTANT_Integer*1000 + CONSTANT_Float*100 + CONSTANT_Long*10 + CONSTANT_Double));
                            if (isConstant(arg, CONSTANT_Integer + "IFLD".indexOf(intrinsic.charAt(0)))
                                || arg instanceof Number) {
                                args.add(arg); continue;
                            }
                        }
                        break decode;
                    case "StringBuilder.append":
                        // allow calls like ("value = "+x)
                        removeEmptyJVMSlots(args);
                        args.subList(1, args.size()).clear();
                        continue;
                    case "StringBuilder.toString":
                        args.clear();
                        args.add(intrinsic);
                        continue;
                    }
                    if (!hasRecv && ownMethod != null && patternMark != 0) {
                        con = constants.get(ownMethod);
                        if (con == null)  break decode;
                        args.clear(); args.add(con);
                        continue;
                    } else if (type.endsWith(")V")) {
                        // allow calls like println("reached the pattern method")
                        args.clear();
                        continue;
                    }
                    break decode;  // bail out for most calls
                }
                case opc_areturn:
                {
                    ++branchCount;
                    if (bsmArgs != null) {
                        // parse bsmArgs as (MH, lookup, String, MT, [extra])
                        Constant indyCon = makeInvokeDynamicCon(bsmArgs);
                        if (indyCon != null) {
                            Constant typeCon = (Constant) bsmArgs.get(3);
                            indySignatures.put(m, pool.getString(typeCon.itemIndex()));
                            return indyCon;
                        }
                        System.err.println(m+": inscrutable bsm arguments: "+bsmArgs);
                        break decode;  // bail out
                    }
                    arg = jvm.pop();
                    if (branchCount == 2 && UNKNOWN_CON.equals(arg))
                        break;  // merge to next path
                    if (isConstant(arg, wantTag))
                        return (Constant) arg;
                    break decode;  // bail out
                }
                default:
                    if (jvm.stackMotion(i.bc))  break;
                    if (bc >= opc_nconst_MIN && bc <= opc_nconst_MAX)
                        { jvm.push(INSTRUCTION_CONSTANTS[bc - opc_nconst_MIN]); break; }
                    if (patternMark == 'I') {
                        // these support caching paths in INDY_x methods
                        if (bc == opc_aload || bc >= opc_aload_0 && bc <= opc_aload_MAX)
                            { jvm.push(UNKNOWN_CON); break; }
                        if (bc == opc_astore || bc >= opc_astore_0 && bc <= opc_astore_MAX)
                            { jvm.pop(); break; }
                        switch (bc) {
                        case opc_getfield:
                        case opc_aaload:
                            jvm.push(UNKNOWN_CON); break;
                        case opc_ifnull:
                        case opc_ifnonnull:
                            // ignore branch target
                            if (++branchCount != 1)  break decode;
                            jvm.pop();
                            break;
                        case opc_checkcast:
                            arg = jvm.top();
                            if ("invokeWithArguments".equals(arg) ||
                                "invokeGeneric".equals(arg))
                                break;  // assume it is a helpful cast
                            break decode;
                        default:
                            break decode;  // bail out
                        }
                        continue decode; // go to next instruction
                    }
                    break decode;  // bail out
                } //end switch
            }
            System.err.println(m+": bailout on "+i+" jvm stack: "+jvm.stack);
            return null;
        }
        private final String UNKNOWN_CON = "<unknown>";

        private void flattenVarargs(List<Object> args) {
            int size = args.size();
            if (size > 0 && args.get(size-1) instanceof List)
                args.addAll((List<Object>) args.remove(size-1));
        }

        private boolean isConstant(Object x, int tag) {
            return x instanceof Constant && ((Constant)x).tag == tag;
        }
        private Constant makeMethodTypeCon(Object x) {
            short utfIndex;
            if (x instanceof String)
                utfIndex = (short) cf.pool.addConstant(CONSTANT_Utf8, x).index;
            else if (isConstant(x, CONSTANT_String))
                utfIndex = ((Constant)x).itemIndex();
            else  return null;
            return cf.pool.addConstant(CONSTANT_MethodType, utfIndex);
        }
        private Constant parseMemberLookup(byte refKind, List<Object> args) {
            // E.g.: lookup().findStatic(Foo.class, "name", MethodType)
            if (args.size() != 4)  return null;
            int argi = 0;
            if (!"lookup".equals(args.get(argi++)))  return null;
            short refindex, cindex, ntindex, nindex, tindex;
            Object con;
            if (!isConstant(con = args.get(argi++), CONSTANT_Class))  return null;
            cindex = (short)((Constant)con).index;
            if (!isConstant(con = args.get(argi++), CONSTANT_String))  return null;
            nindex = ((Constant)con).itemIndex();
            if (isConstant(con = args.get(argi++), CONSTANT_MethodType) ||
                isConstant(con, CONSTANT_Class)) {
                tindex = ((Constant)con).itemIndex();
            } else return null;
            ntindex = (short) cf.pool.addConstant(CONSTANT_NameAndType,
                    new Short[]{ nindex, tindex }).index;
            byte reftag = CONSTANT_Method;
            if (refKind <= REF_putStatic)
                reftag = CONSTANT_Field;
            else if (refKind == REF_invokeInterface)
                reftag = CONSTANT_InterfaceMethod;
            Constant ref = cf.pool.addConstant(reftag, new Short[]{ cindex, ntindex });
            return cf.pool.addConstant(CONSTANT_MethodHandle, new Object[]{ refKind, (short)ref.index });
        }
        private Constant makeInvokeDynamicCon(List<Object> args) {
            // E.g.: MH_bsm.invokeGeneric(lookup(), "name", MethodType, "extraArg")
            removeEmptyJVMSlots(args);
            if (args.size() < 4)  return null;
            int argi = 0;
            short nindex, tindex, ntindex, bsmindex;
            Object con;
            if (!isConstant(con = args.get(argi++), CONSTANT_MethodHandle))  return null;
            bsmindex = (short) ((Constant)con).index;
            if (!"lookup".equals(args.get(argi++)))  return null;
            if (!isConstant(con = args.get(argi++), CONSTANT_String))  return null;
            nindex = ((Constant)con).itemIndex();
            if (!isConstant(con = args.get(argi++), CONSTANT_MethodType))  return null;
            tindex = ((Constant)con).itemIndex();
            ntindex = (short) cf.pool.addConstant(CONSTANT_NameAndType,
                                                  new Short[]{ nindex, tindex }).index;
            List<Object> extraArgs = new ArrayList<Object>();
            if (argi < args.size()) {
                extraArgs.addAll(args.subList(argi, args.size() - 1));
                Object lastArg = args.get(args.size() - 1);
                if (lastArg instanceof List) {
                    List<Object> lastArgs = (List<Object>) lastArg;
                    removeEmptyJVMSlots(lastArgs);
                    extraArgs.addAll(lastArgs);
                } else {
                    extraArgs.add(lastArg);
                }
            }
            List<Short> extraArgIndexes = new CountedList<>(Short.class);
            for (Object x : extraArgs) {
                if (x instanceof Number) {
                    Object num = null; byte numTag = 0;
                    if (x instanceof Integer) { num = x; numTag = CONSTANT_Integer; }
                    if (x instanceof Float)   { num = Float.floatToRawIntBits((Float)x); numTag = CONSTANT_Float; }
                    if (x instanceof Long)    { num = x; numTag = CONSTANT_Long; }
                    if (x instanceof Double)  { num = Double.doubleToRawLongBits((Double)x); numTag = CONSTANT_Double; }
                    if (num != null)  x = cf.pool.addConstant(numTag, x);
                }
                if (!(x instanceof Constant)) {
                    System.err.println("warning: unrecognized BSM argument "+x);
                    return null;
                }
                extraArgIndexes.add((short) ((Constant)x).index);
            }
            List<Object[]> specs = bootstrapMethodSpecifiers(true);
            int specindex = -1;
            Object[] spec = new Object[]{ bsmindex, extraArgIndexes };
            for (Object[] spec1 : specs) {
                if (Arrays.equals(spec1, spec)) {
                    specindex = specs.indexOf(spec1);
                    if (verbose)  System.err.println("reusing BSM specifier: "+spec1[0]+spec1[1]);
                    break;
                }
            }
            if (specindex == -1) {
                specindex = (short) specs.size();
                specs.add(spec);
                if (verbose)  System.err.println("adding BSM specifier: "+spec[0]+spec[1]);
            }
            return cf.pool.addConstant(CONSTANT_InvokeDynamic,
                        new Short[]{ (short)specindex, ntindex });
        }

        List<Object[]> bootstrapMethodSpecifiers(boolean createIfNotFound) {
            Attr bsms = cf.findAttr("BootstrapMethods");
            if (bsms == null) {
                if (!createIfNotFound)  return null;
                bsms = new Attr(cf, "BootstrapMethods", new byte[]{0,0});
                assert(bsms == cf.findAttr("BootstrapMethods"));
            }
            if (bsms.item instanceof byte[]) {
                // unflatten
                List<Object[]> specs = new CountedList<>(Object[].class);
                DataInputStream in = new DataInputStream(new ByteArrayInputStream((byte[]) bsms.item));
                try {
                    int len = (char) in.readShort();
                    for (int i = 0; i < len; i++) {
                        short bsm = in.readShort();
                        int argc = (char) in.readShort();
                        List<Short> argv = new CountedList<>(Short.class);
                        for (int j = 0; j < argc; j++)
                            argv.add(in.readShort());
                        specs.add(new Object[]{ bsm, argv });
                    }
                } catch (IOException ex) { throw new InternalError(); }
                bsms.item = specs;
            }
            return (List<Object[]>) bsms.item;
        }
    }

    private DataInputStream openInput(File f) throws IOException {
        return new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
    }

    private DataOutputStream openOutput(File f) throws IOException {
        if (!overwrite && f.exists())
            throw new IOException("file already exists: "+f);
        ensureDirectory(f.getParentFile());
        return new DataOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
    }

    static byte[] readRawBytes(DataInputStream in, int size) throws IOException {
        byte[] bytes = new byte[size];
        int nr = in.read(bytes);
        if (nr != size)
            throw new InternalError("wrong size: "+nr);
        return bytes;
    }

    private interface Chunk {
        void readFrom(DataInputStream in) throws IOException;
        void writeTo(DataOutputStream out) throws IOException;
    }

    private static class CountedList<T> extends ArrayList<T> implements Chunk {
        final Class<? extends T> itemClass;
        final int rowlen;
        CountedList(Class<? extends T> itemClass, int rowlen) {
            this.itemClass = itemClass;
            this.rowlen = rowlen;
        }
        CountedList(Class<? extends T> itemClass) { this(itemClass, -1); }
        public void readFrom(DataInputStream in) throws IOException {
            int count = in.readUnsignedShort();
            while (size() < count) {
                if (rowlen < 0) {
                    add(readInput(in, itemClass));
                } else {
                    Class<?> elemClass = itemClass.getComponentType();
                    Object[] row = (Object[]) java.lang.reflect.Array.newInstance(elemClass, rowlen);
                    for (int i = 0; i < rowlen; i++)
                        row[i] = readInput(in, elemClass);
                    add(itemClass.cast(row));
                }
            }
        }
        public void writeTo(DataOutputStream out) throws IOException {
            out.writeShort((short)size());
            for (T item : this) {
                writeOutput(out, item);
            }
        }
    }

    private static <T> T readInput(DataInputStream in, Class<T> dataClass) throws IOException {
        Object data;
        if (dataClass == Integer.class) {
            data = in.readInt();
        } else if (dataClass == Short.class) {
            data = in.readShort();
        } else if (dataClass == Byte.class) {
            data = in.readByte();
        } else if (dataClass == String.class) {
            data = in.readUTF();
        } else if (Chunk.class.isAssignableFrom(dataClass)) {
            T obj;
            try { obj = dataClass.newInstance(); }
                catch (Exception ex) { throw new RuntimeException(ex); }
            ((Chunk)obj).readFrom(in);
            data = obj;
        } else {
            throw new InternalError("bad input datum: "+dataClass);
        }
        return dataClass.cast(data);
    }
    private static <T> T readInput(byte[] bytes, Class<T> dataClass) {
        try {
            return readInput(new DataInputStream(new ByteArrayInputStream(bytes)), dataClass);
        } catch (IOException ex) {
            throw new InternalError();
        }
    }
    private static void readInputs(DataInputStream in, Object... data) throws IOException {
        for (Object x : data)  ((Chunk)x).readFrom(in);
    }

    private static void writeOutput(DataOutputStream out, Object data) throws IOException {
        if (data == null) {
            return;
        } if (data instanceof Integer) {
            out.writeInt((Integer)data);
        } else if (data instanceof Long) {
            out.writeLong((Long)data);
        } else if (data instanceof Short) {
            out.writeShort((Short)data);
        } else if (data instanceof Byte) {
            out.writeByte((Byte)data);
        } else if (data instanceof String) {
            out.writeUTF((String)data);
        } else if (data instanceof byte[]) {
            out.write((byte[])data);
        } else if (data instanceof Object[]) {
            for (Object x : (Object[]) data)
                writeOutput(out, x);
        } else if (data instanceof Chunk) {
            Chunk x = (Chunk) data;
            x.writeTo(out);
        } else if (data instanceof List) {
            for (Object x : (List<?>) data)
                writeOutput(out, x);
        } else {
            throw new InternalError("bad output datum: "+data+" : "+data.getClass().getName());
        }
    }
    private static void writeOutputs(DataOutputStream out, Object... data) throws IOException {
        for (Object x : data)  writeOutput(out, x);
    }

    public static abstract class Outer {
        public abstract List<? extends Inner> inners();
        protected void linkInners() {
            for (Inner i : inners()) {
                i.linkOuter(this);
                if (i instanceof Outer)
                    ((Outer)i).linkInners();
            }
        }
        public <T extends Outer> T outer(Class<T> c) {
            for (Outer walk = this;; walk = ((Inner)walk).outer()) {
                if (c.isInstance(walk))
                    return c.cast(walk);
                //if (!(walk instanceof Inner))  return null;
            }
        }

        public abstract List<Attr> attrs();
        public Attr findAttr(String name) {
            return findAttr(outer(ClassFile.class).pool.stringIndex(name, false));
        }
        public Attr findAttr(int name) {
            if (name == 0)  return null;
            for (Attr a : attrs()) {
                if (a.name == name)  return a;
            }
            return null;
        }
    }
    public interface Inner { Outer outer(); void linkOuter(Outer o); }
    public static abstract class InnerOuter extends Outer implements Inner {
        public Outer outer;
        public Outer outer() { return outer; }
        public void linkOuter(Outer o) { assert(outer == null); outer = o; }
    }
    public static class Constant<T> implements Chunk {
        public final byte tag;
        public final T item;
        public final int index;
        public Constant(int index, byte tag, T item) {
            this.index = index;
            this.tag = tag;
            this.item = item;
        }
        public Constant checkTag(byte tag) {
            if (this.tag != tag)  throw new InternalError(this.toString());
            return this;
        }
        public String itemString() { return (String)item; }
        public Short itemIndex() { return (Short)item; }
        public Short[] itemIndexes() { return (Short[])item; }
        public void readFrom(DataInputStream in) throws IOException {
            throw new InternalError("do not call");
        }
        public void writeTo(DataOutputStream out) throws IOException {
            writeOutputs(out, tag, item);
        }
        public boolean equals(Object x) { return (x instanceof Constant && equals((Constant)x)); }
        public boolean equals(Constant that) {
            return (this.tag == that.tag && this.itemAsComparable().equals(that.itemAsComparable()));
        }
        public int hashCode() { return (tag * 31) + this.itemAsComparable().hashCode(); }
        public Object itemAsComparable() {
            switch (tag) {
            case CONSTANT_Double:   return Double.longBitsToDouble((Long)item);
            case CONSTANT_Float:    return Float.intBitsToFloat((Integer)item);
            }
            return (item instanceof Object[] ? Arrays.asList((Object[])item) : item);
        }
        public String toString() {
            String itstr = String.valueOf(itemAsComparable());
            return (index + ":" + tagName(tag) + (itstr.startsWith("[")?"":"=") + itstr);
        }
        private static String[] TAG_NAMES;
        public static String tagName(byte tag) {  // used for error messages
            if (TAG_NAMES == null)
                TAG_NAMES = ("None Utf8 Unicode Integer Float Long Double Class String"
                             +" Fieldref Methodref InterfaceMethodref NameAndType #13 #14"
                             +" MethodHandle MethodType InvokeDynamic#17 InvokeDynamic").split(" ");
            if ((tag & 0xFF) >= TAG_NAMES.length)  return "#"+(tag & 0xFF);
            return TAG_NAMES[tag & 0xFF];
        }
    }

    public static class Pool extends CountedList<Constant> implements Chunk {
        private Map<String,Short> strings = new TreeMap<>();

        public Pool() {
            super(Constant.class);
        }
        public void readFrom(DataInputStream in) throws IOException {
            int count = in.readUnsignedShort();
            add(null);  // always ignore first item
            while (size() < count) {
                readConstant(in);
            }
        }
        public <T> Constant<T> addConstant(byte tag, T item) {
            Constant<T> con = new Constant<>(size(), tag, item);
            int idx = indexOf(con);
            if (idx >= 0)  return get(idx);
            add(con);
            if (tag == CONSTANT_Utf8)  strings.put((String)item, (short) con.index);
            return con;
        }
        private void readConstant(DataInputStream in) throws IOException {
            byte tag = in.readByte();
            int index = size();
            Object arg;
            switch (tag) {
            case CONSTANT_Utf8:
                arg = in.readUTF();
                strings.put((String) arg, (short) size());
                break;
            case CONSTANT_Integer:
            case CONSTANT_Float:
                arg = in.readInt(); break;
            case CONSTANT_Long:
            case CONSTANT_Double:
                add(new Constant(index, tag, in.readLong()));
                add(null);
                return;
            case CONSTANT_Class:
            case CONSTANT_String:
                arg = in.readShort(); break;
            case CONSTANT_Field:
            case CONSTANT_Method:
            case CONSTANT_InterfaceMethod:
            case CONSTANT_NameAndType:
            case CONSTANT_InvokeDynamic:
                // read an ordered pair
                arg = new Short[] { in.readShort(), in.readShort() };
                break;
            case CONSTANT_MethodHandle:
                // read an ordered pair; first part is a u1 (not u2)
                arg = new Object[] { in.readByte(), in.readShort() };
                break;
            case CONSTANT_MethodType:
                arg = in.readShort(); break;
            default:
                throw new InternalError("bad CP tag "+tag);
            }
            add(new Constant(index, tag, arg));
        }

        // Access:
        public Constant get(int index) {
            // extra 1-bits get into the shorts
            return super.get((char) index);
        }
        String getString(byte tag, short index) {
            get(index).checkTag(tag);
            return getString(index);
        }
        String getString(short index) {
            Object v = get(index).item;
            if (v instanceof Short)
                v = get((Short)v).checkTag(CONSTANT_Utf8).item;
            return (String) v;
        }
        String[] getStrings(Short[] indexes) {
            String[] res = new String[indexes.length];
            for (int i = 0; i < indexes.length; i++)
                res[i] = getString(indexes[i]);
            return res;
        }
        int stringIndex(String name, boolean createIfNotFound) {
            Short x = strings.get(name);
            if (x != null)  return (char)(int) x;
            if (!createIfNotFound)  return 0;
            return addConstant(CONSTANT_Utf8, name).index;
        }
        Short[] getMemberRef(short index) {
            Short[] cls_nnt = get(index).itemIndexes();
            Short[] name_type = get(cls_nnt[1]).itemIndexes();
            return new Short[]{ cls_nnt[0], name_type[0], name_type[1] };
        }
    }

    public class ClassFile extends Outer implements Chunk {
        ClassFile(File f) throws IOException {
            DataInputStream in = openInput(f);
            try {
                readFrom(in);
            } finally {
                if (in != null)  in.close();
            }
        }

        public int                magic, version;  // <min:maj>
        public final Pool         pool       = new Pool();
        public short              access, thisc, superc;
        public final List<Short>  interfaces = new CountedList<>(Short.class);
        public final List<Field>  fields     = new CountedList<>(Field.class);
        public final List<Method> methods    = new CountedList<>(Method.class);
        public final List<Attr>   attrs      = new CountedList<>(Attr.class);

        public final void readFrom(DataInputStream in) throws IOException {
            magic = in.readInt(); version = in.readInt();
            if (magic != 0xCAFEBABE)  throw new IOException("bad magic number");
            pool.readFrom(in);
            Code_index = pool.stringIndex("Code", false);
            access = in.readShort(); thisc = in.readShort(); superc = in.readShort();
            readInputs(in, interfaces, fields, methods, attrs);
            if (in.read() >= 0)  throw new IOException("junk after end of file");
            linkInners();
        }

        void writeTo(File f) throws IOException {
            DataOutputStream out = openOutput(f);
            try {
                writeTo(out);
            } finally {
                out.close();
            }
        }

        public void writeTo(DataOutputStream out) throws IOException {
            writeOutputs(out, magic, version, pool,
                         access, thisc, superc, interfaces,
                         fields, methods, attrs);
        }

        public byte[] toByteArray() {
            try {
                ByteArrayOutputStream buf = new ByteArrayOutputStream();
                writeTo(new DataOutputStream(buf));
                return buf.toByteArray();
            } catch (IOException ex) {
                throw new InternalError();
            }
        }

        public List<Inner> inners() {
            List<Inner> inns = new ArrayList<>();
            inns.addAll(fields); inns.addAll(methods); inns.addAll(attrs);
            return inns;
        }
        public List<Attr> attrs() { return attrs; }

        // derived stuff:
        public String nameString() { return pool.getString(CONSTANT_Class, thisc); }
        int Code_index;
    }

    private static <T extends Member> T findMember(List<T> mems, int name, int type) {
        if (name == 0 || type == 0)  return null;
        for (T m : mems) {
            if (m.name == name && m.type == type)  return m;
        }
        return null;
    }

    public static class Member extends InnerOuter implements Chunk {
        public short access, name, type;
        public final List<Attr> attrs = new CountedList<>(Attr.class);
        public void readFrom(DataInputStream in) throws IOException {
            access = in.readShort(); name = in.readShort(); type = in.readShort();
            readInputs(in, attrs);
        }
        public void writeTo(DataOutputStream out) throws IOException {
            writeOutputs(out, access, name, type, attrs);
        }
        public List<Attr> inners() { return attrs; }
        public List<Attr> attrs() { return attrs; }
        public ClassFile outer() { return (ClassFile) outer; }
        public String nameString() { return outer().pool.getString(CONSTANT_Utf8, name); }
        public String typeString() { return outer().pool.getString(CONSTANT_Utf8, type); }
        public String toString() {
            if (outer == null)  return super.toString();
            return nameString() + (this instanceof Method ? "" : ":")
                    + simplifyType(typeString());
        }
    }
    public static class Field extends Member {
    }
    public static class Method extends Member {
        public Code code() {
            Attr a = findAttr("Code");
            if (a == null)  return null;
            return (Code) a.item;
        }
        public Instruction instructions() {
            Code code = code();
            if (code == null)  return null;
            return code.instructions();
        }
    }

    public static class Attr extends InnerOuter implements Chunk {
        public short name;
        public int size = -1;  // no pre-declared size
        public Object item;

        public Attr() {}
        public Attr(Outer outer, String name, Object item) {
            ClassFile cf = outer.outer(ClassFile.class);
            linkOuter(outer);
            this.name = (short) cf.pool.stringIndex(name, true);
            this.item = item;
            outer.attrs().add(this);
        }
        public void readFrom(DataInputStream in) throws IOException {
            name = in.readShort();
            size = in.readInt();
            item = readRawBytes(in, size);
        }
        public void writeTo(DataOutputStream out) throws IOException {
            out.writeShort(name);
            // write the 4-byte size header and then the contents:
            byte[] bytes;
            int trueSize;
            if (item instanceof byte[]) {
                bytes = (byte[]) item;
                out.writeInt(trueSize = bytes.length);
                out.write(bytes);
            } else {
                trueSize = flatten(out);
                //if (!(item instanceof Code))  System.err.println("wrote complex attr name="+(int)(char)name+" size="+trueSize+" data="+Arrays.toString(flatten()));
            }
            if (trueSize != size && size >= 0)
                System.err.println("warning: attribute size changed "+size+" to "+trueSize);
        }
        public void linkOuter(Outer o) {
            super.linkOuter(o);
            if (item instanceof byte[] &&
                outer instanceof Method &&
                ((Method)outer).outer().Code_index == name) {
                    item = readInput((byte[])item, Code.class);
            }
        }
        public List<Inner> inners() {
            if (item instanceof Inner)
                return Collections.nCopies(1, (Inner)item);
            return Collections.emptyList();
        }
        public List<Attr> attrs() { return null; }  // Code overrides this
        public byte[] flatten() {
            ByteArrayOutputStream buf = new ByteArrayOutputStream(Math.max(20, size));
            flatten(buf);
            return buf.toByteArray();
        }
        public int flatten(DataOutputStream out) throws IOException {
            ByteArrayOutputStream buf = new ByteArrayOutputStream(Math.max(20, size));
            int trueSize = flatten(buf);
            out.writeInt(trueSize);
            buf.writeTo(out);
            return trueSize;
        }
        private int flatten(ByteArrayOutputStream buf) {
            try {
                writeOutput(new DataOutputStream(buf), item);
                return buf.size();
            } catch (IOException ex) {
                throw new InternalError();
            }
        }
        public String nameString() {
            ClassFile cf = outer(ClassFile.class);
            if (cf == null)  return "#"+name;
            return cf.pool.getString(name);
        }
        public String toString() {
            return nameString()+(size < 0 ? "=" : "["+size+"]=")+item;
        }
    }

    public static class Code extends InnerOuter implements Chunk {
        public short stacks, locals;
        public byte[] bytes;
        public final List<Short[]> etable = new CountedList<>(Short[].class, 4);
        public final List<Attr> attrs = new CountedList<>(Attr.class);
        // etable[N] = (N)*{ startpc, endpc, handlerpc, catchtype }
        public void readFrom(DataInputStream in) throws IOException {
            stacks = in.readShort(); locals = in.readShort();
            bytes = readRawBytes(in, in.readInt());
            readInputs(in, etable, attrs);
        }
        public void writeTo(DataOutputStream out) throws IOException {
            writeOutputs(out, stacks, locals, bytes.length, bytes, etable, attrs);
        }
        public List<Attr> inners() { return attrs; }
        public List<Attr> attrs() { return attrs; }
        public Instruction instructions() {
            return new Instruction(bytes, 0);
        }
    }

    // lots of constants
    private static final byte
        CONSTANT_Utf8              = 1,
        CONSTANT_Integer           = 3,
        CONSTANT_Float             = 4,
        CONSTANT_Long              = 5,
        CONSTANT_Double            = 6,
        CONSTANT_Class             = 7,
        CONSTANT_String            = 8,
        CONSTANT_Field             = 9,
        CONSTANT_Method            = 10,
        CONSTANT_InterfaceMethod   = 11,
        CONSTANT_NameAndType       = 12,
        CONSTANT_MethodHandle      = 15,  // JSR 292
        CONSTANT_MethodType        = 16,  // JSR 292
        CONSTANT_InvokeDynamic     = 18;  // JSR 292
    private static final byte
        REF_getField               = 1,
        REF_getStatic              = 2,
        REF_putField               = 3,
        REF_putStatic              = 4,
        REF_invokeVirtual          = 5,
        REF_invokeStatic           = 6,
        REF_invokeSpecial          = 7,
        REF_newInvokeSpecial       = 8,
        REF_invokeInterface        = 9;

    private static final int
        opc_nop                    = 0,
        opc_aconst_null            = 1,
        opc_nconst_MIN             = 2,  // iconst_m1
        opc_nconst_MAX             = 15, // dconst_1
        opc_bipush                 = 16,
        opc_sipush                 = 17,
        opc_ldc                    = 18,
        opc_ldc_w                  = 19,
        opc_ldc2_w                 = 20,
        opc_aload                  = 25,
        opc_aload_0                = 42,
        opc_aload_MAX              = 45,
        opc_aaload                 = 50,
        opc_astore                 = 58,
        opc_astore_0               = 75,
        opc_astore_MAX             = 78,
        opc_aastore                = 83,
        opc_pop                    = 87,
        opc_pop2                   = 88,
        opc_dup                    = 89,
        opc_dup_x1                 = 90,
        opc_dup_x2                 = 91,
        opc_dup2                   = 92,
        opc_dup2_x1                = 93,
        opc_dup2_x2                = 94,
        opc_swap                   = 95,
        opc_tableswitch            = 170,
        opc_lookupswitch           = 171,
        opc_areturn                = 176,
        opc_getstatic              = 178,
        opc_putstatic              = 179,
        opc_getfield               = 180,
        opc_putfield               = 181,
        opc_invokevirtual          = 182,
        opc_invokespecial          = 183,
        opc_invokestatic           = 184,
        opc_invokeinterface        = 185,
        opc_invokedynamic          = 186,
        opc_new                    = 187,
        opc_anewarray              = 189,
        opc_checkcast              = 192,
        opc_ifnull                 = 198,
        opc_ifnonnull              = 199,
        opc_wide                   = 196;

    private static final Object[] INSTRUCTION_CONSTANTS = {
        -1, 0, 1, 2, 3, 4, 5, 0L, 1L, 0.0F, 1.0F, 2.0F, 0.0D, 1.0D
    };

    private static final String INSTRUCTION_FORMATS =
        "nop$ aconst_null$L iconst_m1$I iconst_0$I iconst_1$I "+
        "iconst_2$I iconst_3$I iconst_4$I iconst_5$I lconst_0$J_ "+
        "lconst_1$J_ fconst_0$F fconst_1$F fconst_2$F dconst_0$D_ "+
        "dconst_1$D_ bipush=bx$I sipush=bxx$I ldc=bk$X ldc_w=bkk$X "+
        "ldc2_w=bkk$X_ iload=bl/wbll$I lload=bl/wbll$J_ fload=bl/wbll$F "+
        "dload=bl/wbll$D_ aload=bl/wbll$L iload_0$I iload_1$I "+
        "iload_2$I iload_3$I lload_0$J_ lload_1$J_ lload_2$J_ "+
        "lload_3$J_ fload_0$F fload_1$F fload_2$F fload_3$F dload_0$D_ "+
        "dload_1$D_ dload_2$D_ dload_3$D_ aload_0$L aload_1$L "+
        "aload_2$L aload_3$L iaload$LI$I laload$LI$J_ faload$LI$F "+
        "daload$LI$D_ aaload$LI$L baload$LI$I caload$LI$I saload$LI$I "+
        "istore=bl/wbll$I$ lstore=bl/wbll$J_$ fstore=bl/wbll$F$ "+
        "dstore=bl/wbll$D_$ astore=bl/wbll$L$ istore_0$I$ istore_1$I$ "+
        "istore_2$I$ istore_3$I$ lstore_0$J_$ lstore_1$J_$ "+
        "lstore_2$J_$ lstore_3$J_$ fstore_0$F$ fstore_1$F$ fstore_2$F$ "+
        "fstore_3$F$ dstore_0$D_$ dstore_1$D_$ dstore_2$D_$ "+
        "dstore_3$D_$ astore_0$L$ astore_1$L$ astore_2$L$ astore_3$L$ "+
        "iastore$LII$ lastore$LIJ_$ fastore$LIF$ dastore$LID_$ "+
        "aastore$LIL$ bastore$LII$ castore$LII$ sastore$LII$ pop$X$ "+
        "pop2$XX$ dup$X$XX dup_x1$XX$XXX dup_x2$XXX$XXXX dup2$XX$XXXX "+
        "dup2_x1$XXX$XXXXX dup2_x2$XXXX$XXXXXX swap$XX$XX "+
        "iadd$II$I ladd$J_J_$J_ fadd$FF$F dadd$D_D_$D_ isub$II$I "+
        "lsub$J_J_$J_ fsub$FF$F dsub$D_D_$D_ imul$II$I lmul$J_J_$J_ "+
        "fmul$FF$F dmul$D_D_$D_ idiv$II$I ldiv$J_J_$J_ fdiv$FF$F "+
        "ddiv$D_D_$D_ irem$II$I lrem$J_J_$J_ frem$FF$F drem$D_D_$D_ "+
        "ineg$I$I lneg$J_$J_ fneg$F$F dneg$D_$D_ ishl$II$I lshl$J_I$J_ "+
        "ishr$II$I lshr$J_I$J_ iushr$II$I lushr$J_I$J_ iand$II$I "+
        "land$J_J_$J_ ior$II$I lor$J_J_$J_ ixor$II$I lxor$J_J_$J_ "+
        "iinc=blx/wbllxx$ i2l$I$J_ i2f$I$F i2d$I$D_ l2i$J_$I l2f$J_$F "+
        "l2d$J_$D_ f2i$F$I f2l$F$J_ f2d$F$D_ d2i$D_$I d2l$D_$J_ "+
        "d2f$D_$F i2b$I$I i2c$I$I i2s$I$I lcmp fcmpl fcmpg dcmpl dcmpg "+
        "ifeq=boo ifne=boo iflt=boo ifge=boo ifgt=boo ifle=boo "+
        "if_icmpeq=boo if_icmpne=boo if_icmplt=boo if_icmpge=boo "+
        "if_icmpgt=boo if_icmple=boo if_acmpeq=boo if_acmpne=boo "+
        "goto=boo jsr=boo ret=bl/wbll tableswitch=* lookupswitch=* "+
        "ireturn lreturn freturn dreturn areturn return "+
        "getstatic=bkf$Q putstatic=bkf$Q$ getfield=bkf$L$Q "+
        "putfield=bkf$LQ$ invokevirtual=bkm$LQ$Q "+
        "invokespecial=bkm$LQ$Q invokestatic=bkm$Q$Q "+
        "invokeinterface=bkixx$LQ$Q invokedynamic=bkd__$Q$Q new=bkc$L "+
        "newarray=bx$I$L anewarray=bkc$I$L arraylength$L$I athrow "+
        "checkcast=bkc$L$L instanceof=bkc$L$I monitorenter$L "+
        "monitorexit$L wide=* multianewarray=bkcx ifnull=boo "+
        "ifnonnull=boo goto_w=boooo jsr_w=boooo ";
    private static final String[] INSTRUCTION_NAMES;
    private static final String[] INSTRUCTION_POPS;
    private static final int[] INSTRUCTION_INFO;
    static {
        String[] insns = INSTRUCTION_FORMATS.split(" ");
        assert(insns[opc_lookupswitch].startsWith("lookupswitch"));
        assert(insns[opc_tableswitch].startsWith("tableswitch"));
        assert(insns[opc_wide].startsWith("wide"));
        assert(insns[opc_invokedynamic].startsWith("invokedynamic"));
        int[] info = new int[256];
        String[] names = new String[256];
        String[] pops = new String[256];
        for (int i = 0; i < insns.length; i++) {
            String insn = insns[i];
            int dl = insn.indexOf('$');
            if (dl > 0) {
                String p = insn.substring(dl+1);
                if (p.indexOf('$') < 0)  p = "$" + p;
                pops[i] = p;
                insn = insn.substring(0, dl);
            }
            int eq = insn.indexOf('=');
            if (eq < 0) {
                info[i] = 1;
                names[i] = insn;
                continue;
            }
            names[i] = insn.substring(0, eq);
            String fmt = insn.substring(eq+1);
            if (fmt.equals("*")) {
                info[i] = 0;
                continue;
            }
            int sl = fmt.indexOf('/');
            if (sl < 0) {
                info[i] = (char) fmt.length();
            } else {
                String wfmt = fmt.substring(sl+1);
                fmt = fmt.substring(0, sl);
                info[i] = (char)( fmt.length() + (wfmt.length() * 16) );
            }
        }
        INSTRUCTION_INFO = info;
        INSTRUCTION_NAMES = names;
        INSTRUCTION_POPS = pops;
    }

    public static class Instruction implements Cloneable {
        byte[] codeBase;
        int pc;
        int bc;
        int info;
        int wide;
        int len;
        Instruction(byte[] codeBase, int pc) {
            this.codeBase = codeBase;
            init(pc);
        }
        public Instruction clone() {
            try {
                return (Instruction) super.clone();
            } catch (CloneNotSupportedException ex) {
                throw new InternalError();
            }
        }
        private Instruction init(int pc) {
            this.pc = pc;
            this.bc = codeBase[pc] & 0xFF;
            this.info = INSTRUCTION_INFO[bc];
            this.wide = 0;
            this.len = (info & 0x0F);
            if (len == 0)
                computeLength();
            return this;
        }
        Instruction next() {
            if (len == 0 && bc != 0)  throw new InternalError();
            int npc = pc + len;
            if (npc == codeBase.length)
                return null;
            return init(npc);
        }
        void forceNext(int newLen) {
            bc = opc_nop;
            len = newLen;
        }

        public String toString() {
            StringBuilder buf = new StringBuilder();
            buf.append(pc).append(":").append(INSTRUCTION_NAMES[bc]);
            switch (len) {
            case 3: buf.append(" ").append(u2At(1)); break;
            case 5: buf.append(" ").append(u2At(1)).append(" ").append(u2At(3)); break;
            default:  for (int i = 1; i < len; i++)  buf.append(" ").append(u1At(1));
            }
            return buf.toString();
        }

        // these are the hard parts
        private void computeLength() {
            int cases;
            switch (bc) {
            case opc_wide:
                bc = codeBase[pc + 1];
                info = INSTRUCTION_INFO[bc];
                len = ((info >> 4) & 0x0F);
                if (len == 0)  throw new RuntimeException("misplaced wide bytecode: "+bc);
                return;

            case opc_tableswitch:
                cases = (u4At(alignedIntOffset(2)) - u4At(alignedIntOffset(1)) + 1);
                len = alignedIntOffset(3 + cases*1);
                return;

            case opc_lookupswitch:
                cases = u4At(alignedIntOffset(1));
                len = alignedIntOffset(2 + cases*2);
                return;

            default:
                throw new RuntimeException("unknown bytecode: "+bc);
            }
        }
        // switch code
        // clget the Nth int (where 0 is the first after the opcode itself)
        public int alignedIntOffset(int n) {
            int pos = pc + 1;
            pos += ((-pos) & 0x03);  // align it
            pos += (n * 4);
            return pos - pc;
        }
        public int u1At(int pos) {
            return (codeBase[pc+pos] & 0xFF);
        }
        public int u2At(int pos) {
            return (u1At(pos+0)<<8) + u1At(pos+1);
        }
        public int u4At(int pos) {
            return (u2At(pos+0)<<16) + u2At(pos+2);
        }
        public void u1AtPut(int pos, int x) {
            codeBase[pc+pos] = (byte)x;
        }
        public void u2AtPut(int pos, int x) {
            codeBase[pc+pos+0] = (byte)(x >> 8);
            codeBase[pc+pos+1] = (byte)(x >> 0);
        }
    }

    static String simplifyType(String type) {
        String simpleType = OBJ_SIGNATURE.matcher(type).replaceAll("L");
        assert(simpleType.matches("^\\([A-Z]*\\)[A-Z]$"));
        // change (DD)D to (D_D_)D_
        simpleType = WIDE_SIGNATURE.matcher(simpleType).replaceAll("\\0_");
        return simpleType;
    }
    static int argsize(String type) {
        return simplifyType(type).length()-3;
    }
    private static final Pattern OBJ_SIGNATURE = Pattern.compile("\\[*L[^;]*;|\\[+[A-Z]");
    private static final Pattern WIDE_SIGNATURE = Pattern.compile("[JD]");
}
