/*
 * Copyright (c) 2013, 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.
 */

/*
 * @test
 * @summary verify Lookup.revealDirect on a variety of input handles
 * @compile -XDignore.symbol.file RevealDirectTest.java
 * @run junit/othervm -ea -esa test.java.lang.invoke.RevealDirectTest
 *
 * @test
 * @summary verify Lookup.revealDirect on a variety of input handles, with security manager
 * @run main/othervm/policy=jtreg.security.policy/secure=java.lang.SecurityManager -ea -esa test.java.lang.invoke.RevealDirectTest
 */

/* To run manually:
 * $ $JAVA8X_HOME/bin/javac -cp $JUNIT4_JAR -d ../../../.. -XDignore.symbol.file RevealDirectTest.java
 * $ $JAVA8X_HOME/bin/java  -cp $JUNIT4_JAR:../../../.. -ea -esa org.junit.runner.JUnitCore test.java.lang.invoke.RevealDirectTest
 * $ $JAVA8X_HOME/bin/java  -cp $JUNIT4_JAR:../../../.. -ea -esa    -Djava.security.manager test.java.lang.invoke.RevealDirectTest
 */

package test.java.lang.invoke;

import java.lang.reflect.*;
import java.lang.invoke.*;
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
import static java.lang.invoke.MethodHandleInfo.*;
import java.util.*;
import static org.junit.Assert.*;
import org.junit.*;

public class RevealDirectTest {
    public static void main(String... av) throws Throwable {
        // Run the @Test methods explicitly, in case we don't want to use the JUnitCore driver.
        // This appears to be necessary when running with a security manager.
        Throwable fail = null;
        for (Method test : RevealDirectTest.class.getDeclaredMethods()) {
            if (!test.isAnnotationPresent(Test.class))  continue;
            try {
                test.invoke(new RevealDirectTest());
            } catch (Throwable ex) {
                if (ex instanceof InvocationTargetException)
                    ex = ex.getCause();
                if (fail == null)  fail = ex;
                System.out.println("Testcase: "+test.getName()
                                   +"("+test.getDeclaringClass().getName()
                                   +"):\tCaused an ERROR");
                System.out.println(ex);
                ex.printStackTrace(System.out);
            }
        }
        if (fail != null)  throw fail;
    }

    public interface SimpleSuperInterface {
        public abstract int getInt();
        public static void printAll(String... args) {
            System.out.println(Arrays.toString(args));
        }
        public int NICE_CONSTANT = 42;
    }
    public interface SimpleInterface extends SimpleSuperInterface {
        default float getFloat() { return getInt(); }
        public static void printAll(String[] args) {
            System.out.println(Arrays.toString(args));
        }
    }
    public static class Simple implements SimpleInterface, Cloneable {
        public int intField;
        public final int finalField;
        private static String stringField;
        public int getInt() { return NICE_CONSTANT; }
        private static Number getNum() { return 804; }
        public Simple clone() {
            try {
                return (Simple) super.clone();
            } catch (CloneNotSupportedException ex) {
                throw new RuntimeException(ex);
            }
        }
        Simple() { finalField = -NICE_CONSTANT; }
        private static Lookup localLookup() { return lookup(); }
        private static List<Member> members() { return getMembers(lookup().lookupClass()); };
    }
    static class Nestmate {
        private static Lookup localLookup() { return lookup(); }
    }

    static boolean VERBOSE = false;

    @Test public void testSimple() throws Throwable {
        if (VERBOSE)  System.out.println("@Test testSimple");
        testOnMembers("testSimple", Simple.members(), Simple.localLookup());
    }
    @Test public void testPublicLookup() throws Throwable {
        if (VERBOSE)  System.out.println("@Test testPublicLookup");
        List<Member> mems = publicOnly(Simple.members());
        Lookup pubLookup = publicLookup(), privLookup = Simple.localLookup();
        testOnMembers("testPublicLookup/1", mems, pubLookup);
        // reveal using publicLookup:
        testOnMembers("testPublicLookup/2", mems, privLookup, pubLookup);
        // lookup using publicLookup, but reveal using private:
        testOnMembers("testPublicLookup/3", mems, pubLookup, privLookup);
    }
    @Test public void testPublicLookupNegative() throws Throwable {
        if (VERBOSE)  System.out.println("@Test testPublicLookupNegative");
        List<Member> mems = nonPublicOnly(Simple.members());
        Lookup pubLookup = publicLookup(), privLookup = Simple.localLookup();
        testOnMembersNoLookup("testPublicLookupNegative/1", mems, pubLookup);
        testOnMembersNoReveal("testPublicLookupNegative/2", mems, privLookup, pubLookup);
        testOnMembersNoReflect("testPublicLookupNegative/3", mems, privLookup, pubLookup);
    }
    @Test public void testJavaLangClass() throws Throwable {
        if (VERBOSE)  System.out.println("@Test testJavaLangClass");
        List<Member> mems = callerSensitive(false, publicOnly(getMembers(Class.class)));
        mems = limit(20, mems);
        testOnMembers("testJavaLangClass", mems, Simple.localLookup());
    }
    @Test public void testCallerSensitive() throws Throwable {
        if (VERBOSE)  System.out.println("@Test testCallerSensitive");
        List<Member> mems = union(getMembers(MethodHandles.class, "lookup"),
                                  getMembers(Method.class, "invoke"),
                                  getMembers(Field.class, "get", "set", "getLong"),
                                  getMembers(Class.class));
        mems = callerSensitive(true, publicOnly(mems));
        mems = limit(10, mems);
        testOnMembers("testCallerSensitive", mems, Simple.localLookup());
    }
    @Test public void testCallerSensitiveNegative() throws Throwable {
        if (VERBOSE)  System.out.println("@Test testCallerSensitiveNegative");
        List<Member> mems = union(getMembers(MethodHandles.class, "lookup"),
                                  getMembers(Class.class, "forName"),
                                  getMembers(Method.class, "invoke"));
        mems = callerSensitive(true, publicOnly(mems));
        // CS methods cannot be looked up with publicLookup
        testOnMembersNoLookup("testCallerSensitiveNegative/1", mems, publicLookup());
        // CS methods have to be revealed with a matching lookupClass
        testOnMembersNoReveal("testCallerSensitiveNegative/2", mems, Simple.localLookup(), publicLookup());
        testOnMembersNoReveal("testCallerSensitiveNegative/3", mems, Simple.localLookup(), Nestmate.localLookup());
    }
    @Test public void testMethodHandleNatives() throws Throwable {
        if (VERBOSE)  System.out.println("@Test testMethodHandleNatives");
        List<Member> mems = getMembers(MethodHandle.class, "invoke", "invokeExact");
        testOnMembers("testMethodHandleNatives", mems, Simple.localLookup());
    }
    @Test public void testMethodHandleInvokes() throws Throwable {
        if (VERBOSE)  System.out.println("@Test testMethodHandleInvokes");
        List<MethodType> types = new ArrayList<>();
        Class<?>[] someParamTypes = { void.class, int.class, Object.class, Object[].class };
        for (Class<?> rt : someParamTypes) {
            for (Class<?> p0 : someParamTypes) {
                if (p0 == void.class) { types.add(methodType(rt)); continue; }
                for (Class<?> p1 : someParamTypes) {
                    if (p1 == void.class) { types.add(methodType(rt, p0)); continue; }
                    for (Class<?> p2 : someParamTypes) {
                        if (p2 == void.class) { types.add(methodType(rt, p0, p1)); continue; }
                        types.add(methodType(rt, p0, p1, p2));
                    }
                }
            }
        }
        List<Member> mems = union(getPolyMembers(MethodHandle.class, "invoke", types),
                                  getPolyMembers(MethodHandle.class, "invokeExact", types));
        testOnMembers("testMethodHandleInvokes/1", mems, Simple.localLookup());
        testOnMembers("testMethodHandleInvokes/2", mems, publicLookup());
    }

    static List<Member> getPolyMembers(Class<?> cls, String name, List<MethodType> types) {
        assert(cls == MethodHandle.class);
        ArrayList<Member> mems = new ArrayList<>();
        for (MethodType type : types) {
            mems.add(new SignaturePolymorphicMethod(name, type));
        }
        return mems;
    }
    static List<Member> getMembers(Class<?> cls) {
        return getMembers(cls, (String[]) null);
    }
    static List<Member> getMembers(Class<?> cls, String... onlyNames) {
        List<String> names = (onlyNames == null || onlyNames.length == 0 ? null : Arrays.asList(onlyNames));
        ArrayList<Member> res = new ArrayList<>();
        for (Class<?> sup : getSupers(cls)) {
            res.addAll(getDeclaredMembers(sup, "getDeclaredFields"));
            res.addAll(getDeclaredMembers(sup, "getDeclaredMethods"));
            res.addAll(getDeclaredMembers(sup, "getDeclaredConstructors"));
        }
        res = new ArrayList<>(new LinkedHashSet<>(res));
        for (int i = 0; i < res.size(); i++) {
            Member mem = res.get(i);
            if (!canBeReached(mem, cls) ||
                res.indexOf(mem) != i ||
                mem.isSynthetic() ||
                (names != null && !names.contains(mem.getName()))
                ) {
                res.remove(i--);
            }
        }
        return res;
    }
    static List<Class<?>> getSupers(Class<?> cls) {
        ArrayList<Class<?>> res = new ArrayList<>();
        ArrayList<Class<?>> intfs = new ArrayList<>();
        for (Class<?> sup = cls; sup != null; sup = sup.getSuperclass()) {
            res.add(sup);
            for (Class<?> intf : cls.getInterfaces()) {
                if (!intfs.contains(intf))
                    intfs.add(intf);
            }
        }
        for (int i = 0; i < intfs.size(); i++) {
            for (Class<?> intf : intfs.get(i).getInterfaces()) {
                if (!intfs.contains(intf))
                    intfs.add(intf);
            }
        }
        res.addAll(intfs);
        //System.out.println("getSupers => "+res);
        return res;
    }
    static boolean hasSM() {
        return (System.getSecurityManager() != null);
    }
    static List<Member> getDeclaredMembers(Class<?> cls, String accessor) {
        Member[] mems = {};
        Method getter = getMethod(Class.class, accessor);
        if (hasSM()) {
            try {
                mems = (Member[]) invokeMethod(getter, cls);
            } catch (SecurityException ex) {
                //if (VERBOSE)  ex.printStackTrace();
                accessor = accessor.replace("Declared", "");
                getter = getMethod(Class.class, accessor);
                if (VERBOSE)  System.out.println("replaced accessor: "+getter);
            }
        }
        if (mems.length == 0) {
            try {
                mems = (Member[]) invokeMethod(getter, cls);
            } catch (SecurityException ex) {
                ex.printStackTrace();
            }
        }
        if (VERBOSE)  System.out.println(accessor+" "+cls.getName()+" => "+mems.length+" members");
        return Arrays.asList(mems);
    }
    static Method getMethod(Class<?> cls, String name) {
        try {
            return cls.getMethod(name);
        } catch (ReflectiveOperationException ex) {
            throw new AssertionError(ex);
        }
    }
    static Object invokeMethod(Method m, Object recv, Object... args) {
        try {
            return m.invoke(recv, args);
        } catch (InvocationTargetException ex) {
            Throwable ex2 = ex.getCause();
            if (ex2 instanceof RuntimeException)  throw (RuntimeException) ex2;
            if (ex2 instanceof Error)  throw (Error) ex2;
            throw new AssertionError(ex);
        } catch (ReflectiveOperationException ex) {
            throw new AssertionError(ex);
        }
    }

    static List<Member> limit(int len, List<Member> mems) {
        if (mems.size() <= len)  return mems;
        return mems.subList(0, len);
    }
    @SafeVarargs
    static List<Member> union(List<Member> mems, List<Member>... mem2s) {
        for (List<Member> mem2 : mem2s) {
            for (Member m : mem2) {
                if (!mems.contains(m))
                    mems.add(m);
            }
        }
        return mems;
    }
    static List<Member> callerSensitive(boolean cond, List<Member> members) {
        for (Iterator<Member> i = members.iterator(); i.hasNext(); ) {
            Member mem = i.next();
            if (isCallerSensitive(mem) != cond)
                i.remove();
        }
        if (members.isEmpty())  throw new AssertionError("trivial result");
        return members;
    }
    static boolean isCallerSensitive(Member mem) {
        if (!(mem instanceof AnnotatedElement))  return false;
        AnnotatedElement ae = (AnnotatedElement) mem;
        if (CS_CLASS != null)
            return ae.isAnnotationPresent(sun.reflect.CallerSensitive.class);
        for (java.lang.annotation.Annotation a : ae.getDeclaredAnnotations()) {
            if (a.toString().contains(".CallerSensitive"))
                return true;
        }
        return false;
    }
    static final Class<?> CS_CLASS;
    static {
        Class<?> c = null;
        try {
            c = sun.reflect.CallerSensitive.class;
        } catch (SecurityException | LinkageError ex) {
        }
        CS_CLASS = c;
    }
    static List<Member> publicOnly(List<Member> members) {
        return removeMods(members, Modifier.PUBLIC, 0);
    }
    static List<Member> nonPublicOnly(List<Member> members) {
        return removeMods(members, Modifier.PUBLIC, -1);
    }
    static List<Member> removeMods(List<Member> members, int mask, int bits) {
        int publicMods = (mask & Modifier.PUBLIC);
        members = new ArrayList<>(members);
        for (Iterator<Member> i = members.iterator(); i.hasNext(); ) {
            Member mem = i.next();
            int mods = mem.getModifiers();
            if ((publicMods & mods) != 0 &&
                (publicMods & mem.getDeclaringClass().getModifiers()) == 0)
                mods -= publicMods;
            if ((mods & mask) == (bits & mask))
                i.remove();
        }
        return members;
    }

    void testOnMembers(String tname, List<Member> mems, Lookup lookup, Lookup... lookups) throws Throwable {
        if (VERBOSE)  System.out.println("testOnMembers "+mems);
        Lookup revLookup = (lookups.length > 0) ? lookups[0] : null;
        if (revLookup == null)  revLookup = lookup;
        Lookup refLookup = (lookups.length > 1) ? lookups[1] : null;
        if (refLookup == null)  refLookup = lookup;
        assert(lookups.length <= 2);
        testOnMembersImpl(tname, mems, lookup, revLookup, refLookup, NO_FAIL);
    }
    void testOnMembersNoLookup(String tname, List<Member> mems, Lookup lookup) throws Throwable {
        if (VERBOSE)  System.out.println("testOnMembersNoLookup "+mems);
        testOnMembersImpl(tname, mems, lookup, null, null, FAIL_LOOKUP);
    }
    void testOnMembersNoReveal(String tname, List<Member> mems,
                               Lookup lookup, Lookup negLookup) throws Throwable {
        if (VERBOSE)  System.out.println("testOnMembersNoReveal "+mems);
        testOnMembersImpl(tname, mems, lookup, negLookup, null, FAIL_REVEAL);
    }
    void testOnMembersNoReflect(String tname, List<Member> mems,
                                Lookup lookup, Lookup negLookup) throws Throwable {
        if (VERBOSE)  System.out.println("testOnMembersNoReflect "+mems);
        testOnMembersImpl(tname, mems, lookup, lookup, negLookup, FAIL_REFLECT);
    }
    void testOnMembersImpl(String tname, List<Member> mems,
                           Lookup lookup,
                           Lookup revLookup,
                           Lookup refLookup,
                           int failureMode) throws Throwable {
        Throwable fail = null;
        int failCount = 0;
        failureModeCounts = new int[FAIL_MODE_COUNT];
        long tm0 = System.currentTimeMillis();
        for (Member mem : mems) {
            try {
                testWithMember(mem, lookup, revLookup, refLookup, failureMode);
            } catch (Throwable ex) {
                if (fail == null)  fail = ex;
                if (++failCount > 10) { System.out.println("*** FAIL: too many failures"); break; }
                System.out.println("*** FAIL: "+mem+" => "+ex);
                if (VERBOSE)  ex.printStackTrace(System.out);
            }
        }
        long tm1 = System.currentTimeMillis();
        System.out.printf("@Test %s executed %s tests in %d ms",
                          tname, testKinds(failureModeCounts), (tm1-tm0)).println();
        if (fail != null)  throw fail;
    }
    static String testKinds(int[] modes) {
        int pos = modes[0], neg = -pos;
        for (int n : modes)  neg += n;
        if (neg == 0)  return pos + " positive";
        String negs = "";
        for (int n : modes)  negs += "/"+n;
        negs = negs.replaceFirst("/"+pos+"/", "");
        negs += " negative";
        if (pos == 0)  return negs;
        return pos + " positive, " + negs;
    }
    static class SignaturePolymorphicMethod implements Member {  // non-reflected instance of MH.invoke*
        final String name;
        final MethodType type;
        SignaturePolymorphicMethod(String name, MethodType type) {
            this.name = name;
            this.type = type;
        }
        public String toString() {
            String typeStr = type.toString();
            if (isVarArgs())  typeStr = typeStr.replaceFirst("\\[\\])$", "...)");
            return (Modifier.toString(getModifiers())
                    +typeStr.substring(0, typeStr.indexOf('('))+" "
                    +getDeclaringClass().getTypeName()+"."
                    +getName()+typeStr.substring(typeStr.indexOf('(')));
        }
        public boolean equals(Object x) {
            return (x instanceof SignaturePolymorphicMethod && equals((SignaturePolymorphicMethod)x));
        }
        public boolean equals(SignaturePolymorphicMethod that) {
            return this.name.equals(that.name) && this.type.equals(that.type);
        }
        public int hashCode() {
            return name.hashCode() * 31 + type.hashCode();
        }
        public Class<?> getDeclaringClass() { return MethodHandle.class; }
        public String getName() { return name; }
        public MethodType getMethodType() { return type; }
        public int getModifiers() { return Modifier.PUBLIC | Modifier.FINAL | Modifier.NATIVE | SYNTHETIC; }
        public boolean isVarArgs() { return Modifier.isTransient(getModifiers()); }
        public boolean isSynthetic() { return true; }
        public Class<?> getReturnType() { return type.returnType(); }
        public Class<?>[] getParameterTypes() { return type.parameterArray(); }
        static final int SYNTHETIC = 0x00001000;
    }
    static class UnreflectResult {  // a tuple
        final MethodHandle mh;
        final Throwable ex;
        final byte kind;
        final Member mem;
        final int var;
        UnreflectResult(MethodHandle mh, byte kind, Member mem, int var) {
            this.mh = mh;
            this.ex = null;
            this.kind = kind;
            this.mem = mem;
            this.var = var;
        }
        UnreflectResult(Throwable ex, byte kind, Member mem, int var) {
            this.mh = null;
            this.ex = ex;
            this.kind = kind;
            this.mem = mem;
            this.var = var;
        }
        public String toString() {
            return toInfoString()+"/v"+var;
        }
        public String toInfoString() {
            return String.format("%s %s.%s:%s", MethodHandleInfo.referenceKindToString(kind),
                                 mem.getDeclaringClass().getName(), name(mem), type(mem, kind));
        }
        static String name(Member mem) {
            if (mem instanceof Constructor)  return "<init>";
            return mem.getName();
        }
        static MethodType type(Member mem, byte kind) {
            if (mem instanceof Field) {
                Class<?> type = ((Field)mem).getType();
                if (kind == REF_putStatic || kind == REF_putField)
                    return methodType(void.class, type);
                return methodType(type);
            } else if (mem instanceof SignaturePolymorphicMethod) {
                return ((SignaturePolymorphicMethod)mem).getMethodType();
            }
            Class<?>[] params = ((Executable)mem).getParameterTypes();
            if (mem instanceof Constructor)
                return methodType(void.class, params);
            Class<?> type = ((Method)mem).getReturnType();
            return methodType(type, params);
        }
    }
    static UnreflectResult unreflectMember(Lookup lookup, Member mem, int variation) {
        byte[] refKind = {0};
        try {
            return unreflectMemberOrThrow(lookup, mem, variation, refKind);
        } catch (ReflectiveOperationException|SecurityException ex) {
            return new UnreflectResult(ex, refKind[0], mem, variation);
        }
    }
    static UnreflectResult unreflectMemberOrThrow(Lookup lookup, Member mem, int variation,
                                                  byte[] refKind) throws ReflectiveOperationException {
        Class<?> cls = lookup.lookupClass();
        Class<?> defc = mem.getDeclaringClass();
        String   name = mem.getName();
        int      mods = mem.getModifiers();
        boolean isStatic = Modifier.isStatic(mods);
        MethodHandle mh = null;
        byte kind = 0;
        if (mem instanceof Method) {
            Method m = (Method) mem;
            MethodType type = methodType(m.getReturnType(), m.getParameterTypes());
            boolean canBeSpecial = (!isStatic &&
                                    (lookup.lookupModes() & Modifier.PRIVATE) != 0 &&
                                    defc.isAssignableFrom(cls) &&
                                    (!defc.isInterface() || Arrays.asList(cls.getInterfaces()).contains(defc)));
            if (variation >= 2)
                kind = REF_invokeSpecial;
            else if (isStatic)
                kind = REF_invokeStatic;
            else if (defc.isInterface())
                kind = REF_invokeInterface;
            else
                kind = REF_invokeVirtual;
            refKind[0] = kind;
            switch (variation) {
            case 0:
                mh = lookup.unreflect(m);
                break;
            case 1:
                if (defc == MethodHandle.class &&
                    !isStatic &&
                    m.isVarArgs() &&
                    Modifier.isFinal(mods) &&
                    Modifier.isNative(mods)) {
                    break;
                }
                if (isStatic)
                    mh = lookup.findStatic(defc, name, type);
                else
                    mh = lookup.findVirtual(defc, name, type);
                break;
            case 2:
                if (!canBeSpecial)
                    break;
                mh = lookup.unreflectSpecial(m, lookup.lookupClass());
                break;
            case 3:
                if (!canBeSpecial)
                    break;
                mh = lookup.findSpecial(defc, name, type, lookup.lookupClass());
                break;
            }
        } else if (mem instanceof SignaturePolymorphicMethod) {
            SignaturePolymorphicMethod m = (SignaturePolymorphicMethod) mem;
            MethodType type = methodType(m.getReturnType(), m.getParameterTypes());
            kind = REF_invokeVirtual;
            refKind[0] = kind;
            switch (variation) {
            case 0:
                mh = lookup.findVirtual(defc, name, type);
                break;
            }
        } else if (mem instanceof Constructor) {
            name = "<init>";  // not used
            Constructor<?> m = (Constructor<?>) mem;
            MethodType type = methodType(void.class, m.getParameterTypes());
            kind = REF_newInvokeSpecial;
            refKind[0] = kind;
            switch (variation) {
            case 0:
                mh = lookup.unreflectConstructor(m);
                break;
            case 1:
                mh = lookup.findConstructor(defc, type);
                break;
            }
        } else if (mem instanceof Field) {
            Field m = (Field) mem;
            Class<?> type = m.getType();
            boolean canHaveSetter = !Modifier.isFinal(mods);
            if (variation >= 2)
                kind = (byte)(isStatic ? REF_putStatic : REF_putField);
            else
                kind = (byte)(isStatic ? REF_getStatic : REF_getField);
            refKind[0] = kind;
            switch (variation) {
            case 0:
                mh = lookup.unreflectGetter(m);
                break;
            case 1:
                if (isStatic)
                    mh = lookup.findStaticGetter(defc, name, type);
                else
                    mh = lookup.findGetter(defc, name, type);
                break;
            case 3:
                if (!canHaveSetter)
                    break;
                mh = lookup.unreflectSetter(m);
                break;
            case 2:
                if (!canHaveSetter)
                    break;
                if (isStatic)
                    mh = lookup.findStaticSetter(defc, name, type);
                else
                    mh = lookup.findSetter(defc, name, type);
                break;
            }
        } else {
            throw new IllegalArgumentException(String.valueOf(mem));
        }
        if (mh == null)
            // ran out of valid variations; return null to caller
            return null;
        return new UnreflectResult(mh, kind, mem, variation);
    }
    static boolean canBeReached(Member mem, Class<?> cls) {
        Class<?> defc = mem.getDeclaringClass();
        String   name = mem.getName();
        int      mods = mem.getModifiers();
        if (mem instanceof Constructor) {
            name = "<init>";  // according to 292 spec.
        }
        if (defc == cls)
            return true;
        if (name.startsWith("<"))
            return false;  // only my own constructors
        if (Modifier.isPrivate(mods))
            return false;  // only my own constructors
        if (defc.getPackage() == cls.getPackage())
            return true;   // package access or greater OK
        if (Modifier.isPublic(mods))
            return true;   // publics always OK
        if (Modifier.isProtected(mods) && defc.isAssignableFrom(cls))
            return true;   // protected OK
        return false;
    }
    static boolean consistent(UnreflectResult res, MethodHandleInfo info) {
        assert(res.mh != null);
        assertEquals(res.kind, info.getReferenceKind());
        assertEquals(res.mem.getModifiers(), info.getModifiers());
        assertEquals(res.mem.getDeclaringClass(), info.getDeclaringClass());
        String expectName = res.mem.getName();
        if (res.kind == REF_newInvokeSpecial)
            expectName = "<init>";
        assertEquals(expectName, info.getName());
        MethodType expectType = res.mh.type();
        if ((res.kind & 1) == (REF_getField & 1))
            expectType = expectType.dropParameterTypes(0, 1);
        if (res.kind == REF_newInvokeSpecial)
            expectType = expectType.changeReturnType(void.class);
        assertEquals(expectType, info.getMethodType());
        assertEquals(res.mh.isVarargsCollector(), isVarArgs(info));
        assertEquals(res.toInfoString(), info.toString());
        assertEquals(res.toInfoString(), MethodHandleInfo.toString(info.getReferenceKind(), info.getDeclaringClass(), info.getName(), info.getMethodType()));
        return true;
    }
    static boolean isVarArgs(MethodHandleInfo info) {
        return info.isVarArgs();
    }
    static boolean consistent(Member mem, Member mem2) {
        assertEquals(mem, mem2);
        return true;
    }
    static boolean consistent(MethodHandleInfo info, MethodHandleInfo info2) {
        assertEquals(info.getReferenceKind(), info2.getReferenceKind());
        assertEquals(info.getModifiers(), info2.getModifiers());
        assertEquals(info.getDeclaringClass(), info2.getDeclaringClass());
        assertEquals(info.getName(), info2.getName());
        assertEquals(info.getMethodType(), info2.getMethodType());
        assertEquals(isVarArgs(info), isVarArgs(info));
        return true;
    }
    static boolean consistent(MethodHandle mh, MethodHandle mh2) {
        assertEquals(mh.type(), mh2.type());
        assertEquals(mh.isVarargsCollector(), mh2.isVarargsCollector());
        return true;
    }
    int[] failureModeCounts;
    static final int NO_FAIL=0, FAIL_LOOKUP=1, FAIL_REVEAL=2, FAIL_REFLECT=3, FAIL_MODE_COUNT=4;
    void testWithMember(Member mem,
                        Lookup lookup,      // initial lookup of member => MH
                        Lookup revLookup,   // reveal MH => info
                        Lookup refLookup,   // reflect info => member
                        int failureMode) throws Throwable {
        boolean expectEx1 = (failureMode == FAIL_LOOKUP);   // testOnMembersNoLookup
        boolean expectEx2 = (failureMode == FAIL_REVEAL);   // testOnMembersNoReveal
        boolean expectEx3 = (failureMode == FAIL_REFLECT);  // testOnMembersNoReflect
        for (int variation = 0; ; variation++) {
            UnreflectResult res = unreflectMember(lookup, mem, variation);
            failureModeCounts[failureMode] += 1;
            if (variation == 0)  assert(res != null);
            if (res == null)  break;
            if (VERBOSE && variation == 0)
                System.out.println("from "+mem.getDeclaringClass().getSimpleName());
            MethodHandle mh = res.mh;
            Throwable   ex1 = res.ex;
            if (VERBOSE)  System.out.println("  "+variation+": "+res+"  << "+(mh != null ? mh : ex1));
            if (expectEx1 && ex1 != null)
                continue;  // this is OK; we expected that lookup to fail
            if (expectEx1)
                throw new AssertionError("unexpected lookup for negative test");
            if (ex1 != null && !expectEx1) {
                if (failureMode != NO_FAIL)
                    throw new AssertionError("unexpected lookup failure for negative test", ex1);
                throw ex1;
            }
            MethodHandleInfo info;
            try {
                info = revLookup.revealDirect(mh);
                if (expectEx2)  throw new AssertionError("unexpected revelation for negative test");
            } catch (IllegalArgumentException|SecurityException ex2) {
                if (VERBOSE)  System.out.println("  "+variation+": "+res+" => "+mh.getClass().getName()+" => (EX2)"+ex2);
                if (expectEx2)
                    continue;  // this is OK; we expected the reflect to fail
                if (failureMode != NO_FAIL)
                    throw new AssertionError("unexpected revelation failure for negative test", ex2);
                throw ex2;
            }
            assert(consistent(res, info));
            Member mem2;
            try {
                mem2 = info.reflectAs(Member.class, refLookup);
                if (expectEx3)  throw new AssertionError("unexpected reflection for negative test");
                assert(!(mem instanceof SignaturePolymorphicMethod));
            } catch (IllegalArgumentException ex3) {
                if (VERBOSE)  System.out.println("  "+variation+": "+info+" => (EX3)"+ex3);
                if (expectEx3)
                    continue;  // this is OK; we expected the reflect to fail
                if (mem instanceof SignaturePolymorphicMethod)
                    continue;  // this is OK; we cannot reflect MH.invokeExact(a,b,c)
                if (failureMode != NO_FAIL)
                    throw new AssertionError("unexpected reflection failure for negative test", ex3);
                throw ex3;
            }
            assert(consistent(mem, mem2));
            UnreflectResult res2 = unreflectMember(lookup, mem2, variation);
            MethodHandle mh2 = res2.mh;
            assert(consistent(mh, mh2));
            MethodHandleInfo info2 = lookup.revealDirect(mh2);
            assert(consistent(info, info2));
            assert(consistent(res, info2));
            Member mem3;
            if (hasSM())
                mem3 = info2.reflectAs(Member.class, lookup);
            else
                mem3 = MethodHandles.reflectAs(Member.class, mh2);
            assert(consistent(mem2, mem3));
            if (hasSM()) {
                try {
                    MethodHandles.reflectAs(Member.class, mh2);
                    throw new AssertionError("failed to throw on "+mem3);
                } catch (SecurityException ex3) {
                    // OK...
                }
            }
        }
    }
}
