8078112: [TESTBUG] Integrate Selection/Resolution test suite into jtreg tests
authorddmitriev
Fri, 25 Mar 2016 15:54:18 +0300
changeset 37196 f3f7367e8c53
parent 37195 88b6f1271f64
child 37197 282fa21230c3
8078112: [TESTBUG] Integrate Selection/Resolution test suite into jtreg tests Reviewed-by: ctornqvi, acorn Contributed-by: eric.mccorkle@oracle.com
hotspot/test/TEST.groups
hotspot/test/runtime/SelectionResolution/AbstractMethodErrorTest.java
hotspot/test/runtime/SelectionResolution/IllegalAccessErrorTest.java
hotspot/test/runtime/SelectionResolution/InvokeInterfaceICCE.java
hotspot/test/runtime/SelectionResolution/InvokeInterfaceSuccessTest.java
hotspot/test/runtime/SelectionResolution/InvokeSpecialICCE.java
hotspot/test/runtime/SelectionResolution/InvokeSpecialSuccessTest.java
hotspot/test/runtime/SelectionResolution/InvokeStaticICCE.java
hotspot/test/runtime/SelectionResolution/InvokeStaticSuccessTest.java
hotspot/test/runtime/SelectionResolution/InvokeVirtualICCE.java
hotspot/test/runtime/SelectionResolution/InvokeVirtualSuccessTest.java
hotspot/test/runtime/SelectionResolution/NoSuchMethodErrorTest.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Builder.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/ByteCodeClassLoader.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/ClassBuilder.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/ClassConstruct.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/ClassData.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Clazz.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/HierarchyShape.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Interface.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Method.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/MethodData.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Result.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/SelectionResolutionTest.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/SelectionResolutionTestCase.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Template.java
hotspot/test/runtime/SelectionResolution/classes/selectionresolution/TestBuilder.java
--- a/hotspot/test/TEST.groups	Fri Mar 25 12:54:16 2016 +0300
+++ b/hotspot/test/TEST.groups	Fri Mar 25 15:54:18 2016 +0300
@@ -334,6 +334,15 @@
  -runtime/memory/ReserveMemory.java \
  -runtime/memory/RunUnitTestsConcurrently.java \
  -runtime/Unsafe/RangeCheck.java \
+ -runtime/SelectionResolution/AbstractMethodErrorTest.java \
+ -runtime/SelectionResolution/IllegalAccessErrorTest.java \
+ -runtime/SelectionResolution/InvokeInterfaceICCE.java \
+ -runtime/SelectionResolution/InvokeInterfaceSuccessTest.java \
+ -runtime/SelectionResolution/InvokeSpecialICCE.java \
+ -runtime/SelectionResolution/InvokeSpecialSuccessTest.java \
+ -runtime/SelectionResolution/InvokeStaticICCE.java \
+ -runtime/SelectionResolution/InvokeVirtualICCE.java \
+ -runtime/SelectionResolution/InvokeVirtualSuccessTest.java \
  -runtime/SharedArchiveFile/CdsSameObjectAlignment.java \
  -runtime/SharedArchiveFile/DefaultUseWithClient.java \
  -runtime/Thread/CancellableThreadTest.java \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/AbstractMethodErrorTest.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,875 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate AbstractMethodErrorTest
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm/timeout=300 -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies AbstractMethodErrorTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.Result;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class AbstractMethodErrorTest extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.setResult(Result.AME);
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokevirtual tests */
+                /* Group 63: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 64: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 65: callsite = methodref = resolved, possibly
+                 * skip different package in selection.
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionPackageSkipNoOverride),
+                /* Group 66: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsIface),
+                /* Group 67: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 68: callsite :> methodref, methodref = expected,
+                 * possibly skip different package in selection.
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionPackageSkipNoOverride),
+                /* Group 69: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 70: callsite :> methodref, methodref != expected,
+                 * possibly skip different package in selection
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionPackageSkipNoOverride),
+                /* Group 71: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsIface),
+                /* Group 72: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 73: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionPackageSkipNoOverride),
+                /* Group 74: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 75: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionPackageSkipNoOverride),
+                /* Group 76: callsite unrelated to methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsIface),
+                /* Group 77: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 78: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsIface),
+                /* Group 79: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+
+                /* Group 80: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 81: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsIface),
+                /* Group 82: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 83: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 84: callsite unrelated to methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsIface),
+
+                /* Reabstraction during selection */
+                /* Group 85: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 86: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 87: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ReabstractMethodrefResolvedIface),
+                /* Group 88: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 89: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 90: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ReabstractMethodrefResolvedIface),
+                /* Group 91: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 92: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 93: callsite unrelated to methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.ReabstractMethodrefResolvedIface),
+                /* Group 94: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 95: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ReabstractMethodrefResolvedIface),
+                /* Group 96: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+
+                /* Group 97: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 98: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ReabstractMethodrefResolvedIface),
+                /* Group 99: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 100: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.ReabstractMethodrefResolvedClass),
+                /* Group 101: callsite unrelated to methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.ReabstractMethodrefResolvedIface),
+
+                /* invokeinterface */
+                /* Group 102: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteEqualsMethodref,
+                        Template.IfaceMethodrefSelection),
+                /* Group 103: callsite = methodref, methodref != expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteEqualsMethodref,
+                        Template.IfaceMethodrefSelection),
+                /* Group 104: callsite :> methodref, methodref = expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteSubclassMethodref,
+                        Template.IfaceMethodrefSelection),
+                /* Group 105: callsite :> methodref, methodref != expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteSubclassMethodref,
+                        Template.IfaceMethodrefSelection),
+                /* Group 106: callsite unrelated to methodref, methodref = expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.IfaceMethodrefSelection),
+                /* Group 107: callsite unrelated to methodref, methodref != expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.IfaceMethodrefSelection),
+
+                /* Reabstraction during selection */
+                /* Group 108: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ReabstractIfaceMethodrefResolved),
+                /* Group 109: callsite = methodref, methodref != expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ReabstractIfaceMethodrefResolved),
+                /* Group 110: callsite :> methodref, methodref = expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ReabstractIfaceMethodrefResolved),
+                /* Group 111: callsite :> methodref, methodref != expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ReabstractIfaceMethodrefResolved),
+                /* Group 112: callsite unrelated to methodref, methodref = expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.ReabstractIfaceMethodrefResolved),
+                /* Group 113: callsite unrelated to methodref, methodref != expected,
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.ReabstractIfaceMethodrefResolved),
+
+                /* invokespecial tests */
+                /* Group 114: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 115: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 116: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 117: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 118: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 119: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 120: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 121: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 122: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+
+                /* Group 123: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.ReabstractExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 124: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.ReabstractExpectedIface,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite)
+            );
+
+    private AbstractMethodErrorTest() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new AbstractMethodErrorTest().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/IllegalAccessErrorTest.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,517 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate IllegalAccessErrorTest
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies IllegalAccessErrorTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.Result;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class IllegalAccessErrorTest extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.setResult(Result.IAE);
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokestatic tests */
+                /* Group 125 : callsite = methodref, methodref !=
+                 * expected, expected is class
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.TrivialObjectref),
+                /* Group 126: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 127: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 128: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+                /* Group 129: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+                /* Group 130: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE,
+                                                        MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.TrivialObjectref),
+                /* Group 131: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE,
+                                                        MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 132: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE,
+                                                        MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 133: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+                /* Group 134: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+
+                /* invokevirtual tests */
+                /* Group 135: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 136: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 137: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 138: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 139: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 140: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 141: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 142: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 143: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE,
+                                                        // protected causes verifier error.
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 144: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE,
+                                                        // protected causes verifier error.
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass),
+
+                /* invokeinterface tests */
+                /* Group 145: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.IfaceMethodrefSelectionOverrideNonPublic),
+                /* Group 146: callsite = methodref, methodref != expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.IfaceMethodrefSelectionOverrideNonPublic),
+                /* Group 147: callsite :> methodref, methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.IfaceMethodrefSelectionOverrideNonPublic),
+                /* Group 148: callsite :> methodref, methodref != expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.IfaceMethodrefSelectionOverrideNonPublic),
+                /* Group 149: callsite unrelated to methodref, methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.IfaceMethodrefSelectionOverrideNonPublic),
+                /* Group 150: callsite unrelated to methodref, methodref != expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.IfaceMethodrefSelectionOverrideNonPublic),
+
+                /* invokespecial tests */
+                /* Group 151: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 152: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 153: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 154: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 155: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite),
+                /* Group 156: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefExactSubclassOfCallsite)
+            );
+
+    private IllegalAccessErrorTest() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new IllegalAccessErrorTest().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/InvokeInterfaceICCE.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate IncompatibleClassChangeError
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm/timeout=500 -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies InvokeInterfaceICCE
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.Result;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class InvokeInterfaceICCE extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.setResult(Result.ICCE);
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokeinterface tests */
+
+                /* resolved method is static*/
+                /* Group 168: methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.IfaceMethodrefSelection),
+                /* Group 169: methodref != expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.IfaceMethodrefSelection),
+
+                /* methodref is a class */
+                /* Group 170: methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 171: methodref != expected, expected is class */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 172: methodref != expected expected is interface */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.MethodrefSelectionResolvedIsIface),
+                /* Group 173: ambiguous resolution */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefAmbiguous,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.IfaceMethodrefSelectionNoOverride),
+                /* Group 174: ambiguous selection */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.IfaceMethodrefAmbiguousResolvedIsIface),
+
+                /* Group 175: private method in interface */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.IfaceMethodrefSelection)
+            );
+
+    private InvokeInterfaceICCE() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new InvokeInterfaceICCE().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/InvokeInterfaceSuccessTest.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate InvokeInterfaceSuccessTest
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm/timeout=300 -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies InvokeInterfaceSuccessTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class InvokeInterfaceSuccessTest extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.invoke = SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE;
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokeinterface tests */
+
+                /* Group 40: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.IfaceMethodrefSelection,
+                        Template.SelectionOverrideAbstract),
+                /* Group 41: callsite = methodref, methodref != expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.IfaceMethodrefSelection,
+                        Template.SelectionOverrideAbstract),
+                /* Group 42: callsite :> methodref, methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.IfaceMethodrefSelection,
+                        Template.SelectionOverrideAbstract),
+                /* Group 43: callsite :> methodref, methodref != expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.IfaceMethodrefSelection,
+                        Template.SelectionOverrideAbstract),
+                /* Group 44: callsite unrelated to methodref, methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.IfaceMethodrefSelection,
+                        Template.SelectionOverrideAbstract),
+                /* Group 45: callsite unrelated to methodref, methodref != expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.IfaceMethodrefSelection,
+                        Template.SelectionOverrideAbstract)
+            );
+
+    private InvokeInterfaceSuccessTest() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new InvokeInterfaceSuccessTest().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/InvokeSpecialICCE.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate IncompatibleClassChangeError
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies InvokeSpecialICCE
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.Result;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class InvokeSpecialICCE extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.setResult(Result.ICCE);
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokespecial tests */
+                /* resolved method is static*/
+                /* Group 170: methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.InvokespecialCallsiteCases,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 171: methodref != expected, expected is class */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.InvokespecialCallsiteCases,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 172: methodref != expected, expected is interface */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.InvokespecialCallsiteCases,
+                        Template.ObjectrefAssignableToCallsite),
+
+                /* Group 173: Ambiguous resolution */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.allOf(MethodData.Context.class),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefAmbiguous,
+                        Template.IgnoredAbstract,
+                        Template.InvokespecialCallsiteCases,
+                        Template.ObjectrefAssignableToCallsite)
+            );
+
+    private InvokeSpecialICCE() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new InvokeSpecialICCE().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/InvokeSpecialSuccessTest.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate InvokeSpecialSuccessTest
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies InvokeSpecialSuccessTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class InvokeSpecialSuccessTest extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.invoke = SelectionResolutionTestCase.InvokeInstruction.INVOKESPECIAL;
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* Group 46: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 47: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 48: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 49: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 50: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 51: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 52: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 53: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 54: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+
+                /* Group 55: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 56: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+
+                /* Funny cases */
+                /* Group 57: callsite = methodref, methodref =
+                 * expected expected is interface, expected and
+                 * callsite in a different package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefEqualsOrExactSubclassOfCallsite),
+                /* Group 58: callsite = methodref, methodref \!=
+                 * expected expected is interface, expected and
+                 * callsite in a different package */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.ObjectrefEqualsOrExactSubclassOfCallsite),
+                /* Group 59: callsite subclass methodref, methodref =
+                 * expected expected is interface, expected and
+                 * callsite in a different package */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefEqualsOrExactSubclassOfCallsite),
+                /* Group 60: callsite subclass methodref, methodref
+                 * \!= expected expected is interface, expected and
+                 * callsite in a different package */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefEqualsOrExactSubclassOfCallsite),
+
+                /* Methodref is an interface */
+                /* Group 61: callsite :> methodref, methodref = expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite),
+                /* Group 62: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.ObjectrefAssignableToCallsite)
+            );
+
+    private InvokeSpecialSuccessTest() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new InvokeSpecialSuccessTest().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/InvokeStaticICCE.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016, 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 Test of invokestatic method selection and resolution cases that
+ * generate IncompatibleClassChangeError
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies InvokeStaticICCE
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.Result;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class InvokeStaticICCE extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.setResult(Result.ICCE);
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokestatic tests */
+                /* Group 157: methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.AllCallsiteCases,
+                        Template.TrivialObjectref),
+                /* Group 158: methodref = expected, expected is interface */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.AllCallsiteCases,
+                        Template.TrivialObjectref),
+                /* Group 159: methodref != expected, expected is class
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.AllCallsiteCases,
+                        Template.TrivialObjectref),
+                /* Group 160: methodref = expected, expected is interface */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.AllCallsiteCases,
+                        Template.TrivialObjectref)
+            );
+
+    private InvokeStaticICCE() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new InvokeStaticICCE().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/InvokeStaticSuccessTest.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate InvokeStaticSuccessTest
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main InvokeStaticSuccessTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class InvokeStaticSuccessTest extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.invoke = SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC;
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokestatic tests */
+                /* Group 1: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteEqualsMethodref,
+                        Template.TrivialObjectref),
+                /* Group 2: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.TrivialObjectref),
+                /* Group 3: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 4: callsite :> methodref, methodref = expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 5: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 6: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+                /* Group 7: callsite unrelated to methodref, methodref = expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+                /* Group 8: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+                /* Group 9: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteEqualsMethodref,
+                        Template.TrivialObjectref),
+                /* Group 10: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 11: callsite :> methodref, methodref = expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 12: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteSubclassMethodref,
+                        Template.TrivialObjectref),
+                /* Group 13: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+                /* Group 14: callsite unrelated to methodref, methodref = expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefEqualsExpected,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref),
+                /* Group 15: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.TrivialObjectref)
+            );
+
+    private InvokeStaticSuccessTest() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new InvokeStaticSuccessTest().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/InvokeVirtualICCE.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate IncompatibleClassChangeError
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm/timeout=1200 -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies InvokeVirtualICCE
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.Result;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class InvokeVirtualICCE extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.setResult(Result.ICCE);
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokevirtual tests */
+
+                /* resolved method is static*/
+                /* Group 161: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 162: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PACKAGE,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.MethodrefSelectionResolvedIsClass),
+                /* Group 163: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.STATIC),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.MethodrefSelectionResolvedIsIface),
+
+                /* methodref is an interface */
+                /* Group 164: callsite = methodref = expected */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.allOf(MethodData.Context.class),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.IfaceMethodrefSelection),
+                /* Group 165: callsite = methodref, methodref != expected,
+                 * expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PRIVATE),
+                                             EnumSet.allOf(MethodData.Context.class),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.IfaceMethodrefSelection),
+
+                /* Group 166: Ambiguous resolution tests */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.allOf(MethodData.Context.class),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefAmbiguous,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.MethodrefSelectionResolvedIsIfaceNoOverride),
+                /* Group 167: ambiguous selection */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.AllCallsiteCases,
+                        Template.MethodrefAmbiguousResolvedIsIface)
+                );
+
+    private InvokeVirtualICCE() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new InvokeVirtualICCE().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/InvokeVirtualSuccessTest.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate InvokeVirtualSuccessTest
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main/othervm/timeout=400 -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies InvokeVirtualSuccessTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class InvokeVirtualSuccessTest extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.invoke = SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL;
+    }
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokevirtual tests */
+                /* Group 16: callsite = methodref = expected, no override */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClassNoOverride),
+                /* Group 17: callsite = methodref = expected, override allowed */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PROTECTED,
+                                                        MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 18: callsite = methodref = resolved, possibly
+                 * skip different package in selection.
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionPackageSkip,
+                        Template.SelectionOverrideAbstract),
+                /* Group 19: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 20: callsite = methodref, methodref \!=
+                 * expected, possibly skip different package in
+                 * selection.
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionPackageSkip,
+                        Template.SelectionOverrideAbstract),
+                /* Group 21: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsIface,
+                        Template.SelectionOverrideAbstract),
+                /* Group 22: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 23: callsite :>, methodref = expected,
+                 * possibly skip different package in selection
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionPackageSkip,
+                        Template.SelectionOverrideAbstract),
+                /* Group 24: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 25: callsite :>, methodref = expected,
+                 * possibly skip different package in selection
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionPackageSkip,
+                        Template.SelectionOverrideAbstract),
+                /* Group 26: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsIface,
+                        Template.SelectionOverrideAbstract),
+                /* Group 27: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 28: callsite unrelated to methodref,
+                 * methodref = expected, possibly skip different
+                 * package in selection
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionPackageSkip,
+                        Template.SelectionOverrideAbstract),
+                /* Group 29: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 30: callsite unrelated to methodref,
+                 * methodref \!= expected, possibly skip different
+                 * package in selection
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PACKAGE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionPackageSkip,
+                        Template.SelectionOverrideAbstract),
+                /* Group 31: callsite unrelated to methodref, methodref != expected,
+                 * expected is interface, expected and callsite in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsIface,
+                        Template.SelectionOverrideAbstract),
+                /* Group 32: callsite = methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC,
+                                                        MethodData.Access.PROTECTED),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 33: callsite = methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteEqualsMethodref,
+                        Template.MethodrefSelectionResolvedIsIface,
+                        Template.SelectionOverrideAbstract),
+                /* Group 34: callsite :> methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+
+                /* Group 35: callsite :> methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 36: callsite :> methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteSubclassMethodref,
+                        Template.MethodrefSelectionResolvedIsIface,
+                        Template.SelectionOverrideAbstract),
+                /* Group 37: callsite unrelated to methodref, methodref = expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefEqualsExpected,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 38: callsite unrelated to methodref, methodref != expected,
+                 * expected is class, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.CLASS),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedClass,
+                        Template.MethodrefNotEqualsExpectedClass,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsClass,
+                        Template.SelectionOverrideAbstract),
+                /* Group 39: callsite unrelated to methodref, methodref != expected,
+                 * expected is interface, expected and callsite not in the same package
+                 */
+                new TestGroup.Simple(initBuilder,
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PUBLIC),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.DIFFERENT)),
+                        Template.OverrideAbstractExpectedIface,
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.IgnoredAbstract,
+                        Template.CallsiteUnrelatedToMethodref,
+                        Template.MethodrefSelectionResolvedIsIface,
+                        Template.SelectionOverrideAbstract)
+            );
+
+    private InvokeVirtualSuccessTest() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new InvokeVirtualSuccessTest().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/NoSuchMethodErrorTest.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2016, 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 Test of method selection and resolution cases that
+ * generate NoSuchMethodError
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @library /runtime/SelectionResolution/classes
+ * @build selectionresolution.*
+ * @run main NoSuchMethodErrorTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumSet;
+import selectionresolution.ClassData;
+import selectionresolution.MethodData;
+import selectionresolution.Result;
+import selectionresolution.SelectionResolutionTest;
+import selectionresolution.SelectionResolutionTestCase;
+import selectionresolution.Template;
+
+public class NoSuchMethodErrorTest extends SelectionResolutionTest {
+
+    private static final SelectionResolutionTestCase.Builder initBuilder =
+        new SelectionResolutionTestCase.Builder();
+
+    static {
+        initBuilder.setResult(Result.NSME);
+    }
+
+    private static final MethodData concreteMethod =
+        new MethodData(MethodData.Access.PUBLIC, MethodData.Context.INSTANCE);
+
+    private static final MethodData staticMethod =
+        new MethodData(MethodData.Access.PUBLIC, MethodData.Context.STATIC);
+
+    private static final MethodData privateMethod =
+        new MethodData(MethodData.Access.PRIVATE, MethodData.Context.INSTANCE);
+
+    private static final ClassData withDef =
+        new ClassData(ClassData.Package.SAME, concreteMethod);
+
+    private static final ClassData withStaticDef =
+        new ClassData(ClassData.Package.SAME, staticMethod);
+
+    private static final ClassData withPrivateDef =
+        new ClassData(ClassData.Package.SAME, staticMethod);
+
+    private static final Template NoMethodResolutionTemplateClassBottom =
+        new Template("NoMethodResolutionTemplate",
+                    /* Empty single class
+                     *
+                     * C[]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        builder.methodref = C;
+                    },
+                    /* Class bottom, inherit empty class
+                     *
+                     * C2[]()
+                     * C1[C2]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int C2 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        builder.hier.addInherit(C1, C2);
+                        builder.methodref = C1;
+                    },
+                    /* Class bottom, inherit empty interface
+                     *
+                     * I[]()
+                     * C[I]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.hier.addInherit(C, I);
+                        builder.methodref = C;
+                    },
+                    /* Class bottom, inherit empty class and interface
+                     *
+                     * C2[](), I[]()
+                     * C1[C2,I]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int C2 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.methodref = C1;
+                    },
+                    /* Class bottom, unrelated class defines
+                     *
+                     * C20[](con)
+                     * C1[]()
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        builder.addClass(withDef);
+                        builder.methodref = C;
+                    },
+                    /* Class bottom, interface defines static
+                     *
+                     * I[](stat)
+                     * C[]()
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.addInterface(withStaticDef);
+                        builder.hier.addInherit(C, I);
+                        builder.methodref = C;
+                    },
+                    /* Class bottom, interface defines private
+                     *
+                     * I[](priv)
+                     * C[]()
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.addInterface(withPrivateDef);
+                        builder.hier.addInherit(C, I);
+                        builder.methodref = C;
+                    });
+
+    private static final Template NoMethodResolutionTemplateIfaceBottom =
+        new Template("NoMethodResolutionTemplate",
+                    /* Empty single interface
+                     *
+                     * I[]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.methodref = I;
+                    },
+                    /* Interface bottom, inherit empty interface
+                     *
+                     * I2[]()
+                     * I1[I2]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int I1 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        final int I2 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.hier.addInherit(I1, I2);
+                        builder.methodref = I1;
+                    },
+                    /* Interface bottom, unrelated class defines
+                     *
+                     * C0[](con)
+                     * I[]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.addClass(withDef);
+                        builder.methodref = I;
+                    },
+                    /* Interface bottom, interface defines static
+                     *
+                     * I2[](stat)
+                     * I1[I2]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int I1 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        final int I2 = builder.addInterface(withStaticDef);
+                        builder.hier.addInherit(I1, I2);
+                        builder.methodref = I1;
+                    },
+                    /* Interface bottom, interface defines private
+                     *
+                     * I2[](stat)
+                     * I1[I2]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int I1 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        final int I2 = builder.addInterface(withPrivateDef);
+                        builder.hier.addInherit(I1, I2);
+                        builder.methodref = I1;
+                    });
+
+    private static final Template NoMethodSelectionTemplateClassMethodref =
+        new Template("NoMethodSelectionTemplate",
+                    /* objectref = methodref
+                     *
+                     * C[]() = mref = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        builder.objectref = builder.methodref;
+                    },
+                    /* Inherit methodref
+                     *
+                     * C2[]() = mref
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int C2 = builder.methodref;
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Inherit methodref and interface
+                     *
+                     * C2[]() = mref, I[]()
+                     * C1[C2,I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.objectref = C1;
+                    },
+                    /* objectref = methodref, unrelated class defines
+                     *
+                     * C0[](def)
+                     * C[]() = mref = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        builder.addClass(withDef);
+                        builder.objectref = builder.methodref;
+                    },
+                    /* Inherit methodref, unrelated class defines
+                     *
+                     * C0[](def)
+                     * C2[]() = mref
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int C2 = builder.methodref;
+                        builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Inherit methodref and interface, unrelated class defines.
+                     *
+                     * C0[](def)
+                     * C2[]() = mref, I[]()
+                     * C1[C2,I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.objectref = C1;
+                    },
+                    /* objectref = methodref, unrelated interface defines
+                     *
+                     * I0[](def)
+                     * C[]() = mref = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        builder.addInterface(withDef);
+                        builder.objectref = builder.methodref;
+                    },
+                    /* Inherit methodref, interface defines static
+                     *
+                     * C2[]() = mref, I0[](stat)
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int C2 = builder.methodref;
+                        final int I0 = builder.addInterface(withStaticDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I0);
+                        builder.objectref = C1;
+                    },
+                    /* Inherit methodref, interface defines private
+                     *
+                     * C2[]() = mref, I0[](stat)
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C1 = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int C2 = builder.methodref;
+                        final int I0 = builder.addInterface(withPrivateDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I0);
+                        builder.objectref = C1;
+                    });
+
+    private static final Template NoMethodSelectionTemplateIfaceMethodref =
+        new Template("NoMethodSelectionTemplate",
+                    /* Inherit methodref
+                     *
+                     * I[]() = mref
+                     * C[I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.methodref;
+                        builder.hier.addInherit(C, I);
+                        builder.objectref = C;
+                    },
+                    /* Inherit methodref and interface
+                     *
+                     * I1[]() = mref, I2[]()
+                     * C[T,I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int I1 = builder.methodref;
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I2 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.hier.addInherit(C, I1);
+                        builder.hier.addInherit(C, I2);
+                        builder.objectref = C;
+                    },
+                    /* Inherit methodref, unrelated class defines
+                     *
+                     * C0[](def)
+                     * I[]() = mref
+                     * C[I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.methodref;
+                        builder.addClass(withDef);
+                        builder.hier.addInherit(C, I);
+                        builder.objectref = C;
+                    },
+                    /* Inherit methodref and interface, unrelated class defines
+                     *
+                     * C0[](def)
+                     * I1[]() = mref, I2[]()
+                     * C[I1,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int I1 = builder.methodref;
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I2 = builder.addInterface(Template.emptyClass(ClassData.Package.SAME));
+                        builder.addClass(withDef);
+                        builder.hier.addInherit(C, I1);
+                        builder.hier.addInherit(C, I2);
+                        builder.objectref = C;
+                    },
+                    /* Inherit methodref, interface defines static
+                     *
+                     * I[]() = mref, I0[](stat)
+                     * C[I,I0]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.methodref;
+                        final int I0 = builder.addInterface(withStaticDef);
+                        builder.hier.addInherit(C, I);
+                        builder.hier.addInherit(C, I0);
+                        builder.objectref = C;
+                    },
+                    /* Inherit methodref, unrelated class defines private
+                     *
+                     * I[]() = mref, I0[](priv)
+                     * C[I,I0]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final int C = builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+                        final int I = builder.methodref;
+                        final int I0 = builder.addInterface(withPrivateDef);
+                        builder.hier.addInherit(C, I);
+                        builder.hier.addInherit(C, I0);
+                        builder.objectref = C;
+                    });
+
+    private static final Collection<TestGroup> testgroups =
+        Arrays.asList(
+                /* invokestatic tests */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        NoMethodResolutionTemplateClassBottom,
+                        Template.AllCallsiteCases,
+                        Template.TrivialObjectref),
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKESTATIC),
+                        NoMethodResolutionTemplateIfaceBottom,
+                        Template.CallsiteNotEqualsMethodref,
+                        Template.TrivialObjectref),
+                /* invokevirtual tests */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        NoMethodResolutionTemplateClassBottom,
+                        Template.AllCallsiteCases,
+                        NoMethodSelectionTemplateClassMethodref),
+                /* invokeinterface tests */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        NoMethodResolutionTemplateIfaceBottom,
+                        Template.CallsiteNotEqualsMethodref,
+                        NoMethodSelectionTemplateIfaceMethodref),
+
+                /* Hiding of private interface methods */
+                /* invokevirtual */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEVIRTUAL),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.MethodrefNotEqualsExpectedIface,
+                        Template.AllCallsiteCases,
+                        Template.TrivialObjectref),
+                /* invokeinterface */
+                new TestGroup.Simple(initBuilder,
+                        Template.SetInvoke(SelectionResolutionTestCase.InvokeInstruction.INVOKEINTERFACE),
+                        Template.ResultCombo(EnumSet.of(Template.Kind.INTERFACE),
+                                             EnumSet.of(MethodData.Access.PRIVATE),
+                                             EnumSet.of(MethodData.Context.INSTANCE,
+                                                        MethodData.Context.ABSTRACT),
+                                             EnumSet.of(ClassData.Package.SAME,
+                                                        ClassData.Package.DIFFERENT)),
+                        Template.IfaceMethodrefNotEqualsExpected,
+                        Template.AllCallsiteCases,
+                        Template.TrivialObjectrefNotEqualMethodref)
+            );
+
+    private NoSuchMethodErrorTest() {
+        super(testgroups);
+    }
+
+    public static void main(final String... args) {
+        new NoSuchMethodErrorTest().run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Builder.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import java.util.HashMap;
+
+abstract class Builder {
+    protected final SelectionResolutionTestCase testcase;
+    protected final HierarchyShape hier;
+    protected final HashMap<Integer,ClassData> classdata;
+
+    public Builder(SelectionResolutionTestCase testcase) {
+        this.testcase = testcase;
+        this.hier = testcase.hier;
+        this.classdata = testcase.classdata;
+    }
+
+    protected String getName(int id) {
+        StringBuilder name = new StringBuilder();
+
+        name.append(getPackageName(classdata.get(id).packageId.ordinal()));
+
+        // Name classes C<id> and interfaces I<id>
+        name.append(getClassName(id));
+
+        return name.toString();
+    }
+
+    protected String getPackageName(int packageId) {
+        return "P" + packageId + "/";
+    }
+
+    protected String getClassName(int id) {
+        // Name classes C<id> and interfaces I<id>
+        if (isClass(id)) {
+            return "C" + id;
+        } else {
+            return "I" + id;
+        }
+    }
+
+    protected boolean isClass(int id) {
+        return hier.isClass(id);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/ByteCodeClassLoader.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+
+public class ByteCodeClassLoader extends ClassLoader {
+    ArrayList<ClassConstruct> classes = new ArrayList<>();
+    HashMap<String, Class> loadedClasses = new HashMap<>();
+
+    public void addClasses(ClassConstruct... classes) {
+        this.classes.addAll(Arrays.asList(classes));
+    }
+
+    public void loadAll() throws ClassNotFoundException {
+        for (ClassConstruct clazz : classes) {
+            findClass(clazz.getDottedName());
+        }
+    }
+
+
+    @Override
+    public Class findClass(String name) throws ClassNotFoundException {
+
+        Class cls = loadedClasses.get(name);
+
+        if (cls != null) {
+            return cls;
+        }
+
+        for (ClassConstruct clazz : classes) {
+            if (clazz.getDottedName().equals(name)) {
+                return load(clazz);
+            }
+        }
+
+        throw new ClassNotFoundException(name);
+    }
+
+    @Override
+    public Class loadClass(String name) throws ClassNotFoundException {
+        try {
+            return findClass(name);
+        } catch (ClassNotFoundException e) {
+            return super.loadClass(name);
+        }
+    }
+
+    private Class load(ClassConstruct clazz) {
+        byte[] bytecode = clazz.generateBytes();
+        Class loadedClass = defineClass(clazz.getDottedName(), bytecode, 0, bytecode.length);
+        loadedClasses.put(clazz.getDottedName(), loadedClass);
+        return loadedClass;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/ClassBuilder.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_ABSTRACT;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PROTECTED;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
+
+/**
+ * Constructs classes and interfaces based on the information from a
+ * DefaultMethodTestCase
+ *
+ */
+public class ClassBuilder extends Builder {
+    private final ArrayList<ClassConstruct> classes;
+
+    // Add a class in every package to be able to instantiate package
+    // private classes from outside the package
+    private final Clazz[] helpers = new Clazz[4];
+    private ClassConstruct callsiteClass;
+
+    public enum ExecutionMode { DIRECT, INDY, MH_INVOKE_EXACT, MH_INVOKE_GENERIC}
+    private final ExecutionMode execMode;
+
+    public ClassBuilder(SelectionResolutionTestCase testcase,
+                        ExecutionMode execMode) {
+        super(testcase);
+        this.classes = new ArrayList<>();
+        this.execMode = execMode;
+    }
+
+    public ClassConstruct[] build() throws Exception {
+        buildClassConstructs();
+        return classes.toArray(new ClassConstruct[0]);
+    }
+
+    public ClassConstruct getCallsiteClass() {
+        return callsiteClass;
+    }
+
+    private void buildClassConstructs() throws Exception {
+        TestBuilder tb = new TestBuilder(testcase.methodref, testcase);
+
+        classes.add(new Clazz("Test", ACC_PUBLIC, -1));
+
+        for (int classId = 0; classId < classdata.size(); classId++) {
+            ClassConstruct C;
+            String[] interfaces = getInterfaces(classId);
+            ClassData data = classdata.get(classId);
+
+            if (isClass(classId)) {
+                C = new Clazz(getName(classId),
+                              getExtending(classId),
+                              getClassModifiers(data),
+                              classId,
+                              interfaces);
+
+                addHelperMethod(classId);
+
+            } else {
+                C = new Interface(getName(classId),
+                                  getAccessibility(data.access),
+                                  classId, interfaces);
+            }
+
+            // Add a method "m()LTestObject;" if applicable
+            if (containsMethod(data)) {
+                // Method will either be abstract or concrete depending on the
+                // abstract modifier
+                C.addTestMethod(getMethodModifiers(data));
+            }
+
+            if (classId == testcase.callsite) {
+                // Add test() method
+                tb.addTest(C, execMode);
+                callsiteClass = C;
+            }
+
+            classes.add(C);
+        }
+        classes.add(tb.getMainTestClass());
+
+    }
+
+    private void addHelperMethod(int classId) {
+        int packageId = classdata.get(classId).packageId.ordinal();
+        Clazz C = helpers[packageId];
+        if (C == null) {
+            C = new Clazz(getPackageName(packageId) + "Helper", -1, ACC_PUBLIC);
+            helpers[packageId] = C;
+            classes.add(C);
+        }
+
+        Method m = C.addMethod("get" + getClassName(classId),
+                               "()L" + getName(classId) + ";",
+                               ACC_PUBLIC + ACC_STATIC);
+        m.makeInstantiateMethod(getName(classId));
+    }
+
+    private String[] getInterfaces(int classId) {
+        ArrayList<String> interfaces = new ArrayList<>();
+
+        // Figure out if we're extending/implementing an interface
+        for (final int intf : hier.interfaces()) {
+            if (hier.inherits(classId, intf)) {
+                interfaces.add(getName(intf));
+            }
+        }
+        return interfaces.toArray(new String[0]);
+    }
+
+    private String getExtending(int classId) {
+        int extending = -1;
+
+        // See if we're extending another class
+        for (final int extendsClass : hier.classes()) {
+            if (hier.inherits(classId, extendsClass)) {
+                // Sanity check that we haven't already found an extending class
+                if (extending != -1) {
+                    throw new RuntimeException("Multiple extending classes");
+                }
+                extending = extendsClass;
+            }
+        }
+
+        return extending == -1 ? null : getName(extending);
+    }
+
+    /**
+     * Returns modifiers for a Class
+     * @param cd ClassData for the Class
+     * @return ASM modifiers for a Class
+     */
+    private int getClassModifiers(ClassData cd) {
+        // For Classes we only care about accessibility (public, private etc)
+        return getAccessibility(cd.access) | getAbstraction(cd.abstraction);
+    }
+
+    /**
+     * Returns modifiers for Method type
+     * @param cd ClassData for the Class or Interface where the Method resides
+     * @return ASM modifiers for the Method
+     */
+    private int getMethodModifiers(ClassData cd) {
+        int mod = 0;
+
+        // For methods we want everything
+        mod += getAccessibility(cd.methoddata.access);
+        mod += getAbstraction(cd.methoddata.context);
+        mod += getContext(cd.methoddata.context);
+        mod += getExtensibility();
+        return mod;
+    }
+
+
+    /**
+     * Convert ClassData access type to ASM
+     * @param access
+     * @return ASM version of accessibility (public / private / protected)
+     */
+    private int getAccessibility(MethodData.Access access) {
+        switch(access) {
+        case PACKAGE:
+            //TODO: Do I need to set this or will this be the default?
+            return 0;
+        case PRIVATE:
+            return ACC_PRIVATE;
+        case PROTECTED:
+            return ACC_PROTECTED;
+        case PUBLIC:
+            return ACC_PUBLIC;
+        default:
+            throw new RuntimeException("Illegal accessibility modifier: " + access);
+        }
+    }
+
+    /**
+     * Convert ClassData abstraction type to ASM
+     * @param abstraction
+     * @return ASM version of abstraction (abstract / non-abstract)
+     */
+    private int getAbstraction(MethodData.Context context) {
+        return context == MethodData.Context.ABSTRACT ? ACC_ABSTRACT : 0;
+    }
+
+    /**
+     * Convert ClassData context type to ASM
+     * @param context
+     * @return ASM version of context (static / non-static)
+     */
+    private int getContext(MethodData.Context context) {
+        return context == MethodData.Context.STATIC ? ACC_STATIC : 0;
+    }
+
+    /**
+     * Convert ClassData extensibility type to ASM
+     * @param extensibility
+     * @return ASM version of extensibility (final / non-final)
+     */
+    private int getExtensibility() {
+        return 0;
+    }
+
+    /**
+     * Determine if we need a method at all, abstraction is set to null if this
+     * Class/Interface should not have a test method
+     * @param cd
+     * @return
+     */
+    private boolean containsMethod(ClassData cd) {
+        return cd.methoddata != null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/ClassConstruct.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+public abstract class ClassConstruct {
+    private final ClassWriter cw;
+    private final String name;
+    private final boolean isInterface;
+    private final int index;
+
+    /**
+     * Base constructor for building a Class or Interface
+     * @param name Name of Class/Interface, including package name
+     * @param extending Name of extending Class if any
+     * @param access Access for Class/Interface
+     * @param classFileVersion Class file version
+     * @param interfaces Interface implemented
+     */
+    public ClassConstruct(String name,
+                          String extending,
+                          int access,
+                          int classFileVersion,
+                          int index,
+                          String... interfaces) {
+        this.name = name;
+        isInterface = (access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE;
+        cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+        cw.visit(classFileVersion, access, name, null, extending, interfaces == null ?  new String[] { } : interfaces);
+        this.index = index;
+    }
+
+    /**
+     * Get full Class/Interface name including package name, as it
+     * should appear in a classfile.
+     *
+     * @return The full Class/Interface name including package name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the name of the class, including package as it would appear
+     * in Java source.
+     *
+     * @return The name of the class as it would appear in Java source.
+     */
+    public String getDottedName() {
+        return name.replace("/", ".");
+    }
+
+    public String getPackageName() {
+        final int idx = name.lastIndexOf('/');
+        if (idx != -1) {
+            return name.substring(0, name.indexOf('/'));
+        } else {
+            return null;
+        }
+    }
+
+    public String getClassName() {
+        final int idx = name.lastIndexOf('/');
+        if (idx != -1) {
+            return name.substring(name.indexOf('/'));
+        } else {
+            return name;
+        }
+    }
+
+    /**
+     * Add a method, no code associated with it yet
+     * @param name Name of method
+     * @param descriptor Descriptor for method
+     * @param access Access for the method
+     * @return Method object that can be used for constructing a method body
+     */
+    public Method addMethod(String name,
+                            String descriptor,
+                            int access) {
+        return addMethod(name, descriptor, access, null);
+    }
+
+    /**
+     * Add a method, no code associated with it yet
+     * @param name Name of method
+     * @param descriptor Descriptor for method
+     * @param access Access for the method
+     * @param execMode The execution mode for the method.
+     * @return Method object that can be used for constructing a method body
+     */
+    public Method addMethod(String name,
+                            String descriptor,
+                            int access,
+                            ClassBuilder.ExecutionMode execMode) {
+        return new Method(this, cw, name, descriptor, access, execMode);
+    }
+
+    /**
+     * Adds a m()LTestObject; method which returns null unless the method is abstract
+     * @param access Access for the method
+     */
+    public void addTestMethod(int access) {
+        Method m = new Method(this, cw, Method.defaultMethodName, Method.defaultMethodDescriptor, access, null);
+        if ((access & Opcodes.ACC_ABSTRACT) != Opcodes.ACC_ABSTRACT) {
+            m.makeDefaultMethod();
+        }
+    }
+
+    /**
+     * Construct the class to a byte[]
+     * @return byte[] with class file
+     */
+    public byte[] generateBytes() {
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+
+    /**
+     * Write out a class to a file in the specified directory.
+     *
+     * @param dir Directory to which to write out the file.
+     */
+    public void writeClass(final File dir) throws Exception {
+        final String pkgname = getPackageName();
+        final File pkgdir = pkgname != null ? new File(dir, getPackageName()) : dir;
+        pkgdir.mkdirs();
+        final File out = new File(pkgdir, getClassName() + ".class");
+        out.createNewFile();
+        try (final FileOutputStream fos = new FileOutputStream(out)) {
+            fos.write(generateBytes());
+        }
+    }
+
+    public boolean isInterface() {
+        return isInterface;
+    }
+
+    public Integer getIndex() {
+        return index;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/ClassData.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package selectionresolution;
+
+/**
+ * A representation of information about a class.  Note that classes
+ * here define only one method.
+ */
+public class ClassData {
+
+    public enum Package {
+        /**
+         * Same package as the callsite.
+         */
+        SAME,
+        /**
+         * Different package from the callsite.
+         */
+        DIFFERENT,
+        /**
+         * Same as DIFFERENT, and also implies that the class access
+         * is package-private.
+         */
+        INACCESSIBLE,
+        /**
+         * Different from everything else.  Used in selection only, to
+         * test skipping package-private definitions.
+         */
+        OTHER,
+        /**
+         * Placeholder, used solely by the template dumper for
+         * printing out the effects of templates.  Don't use for
+         * anything else.
+         */
+        PLACEHOLDER;
+    }
+
+    /**
+     * The package ID for the class.
+     */
+    public final Package packageId;
+
+    /**
+     * The method data for the method definition.  If there is no
+     * method definition, this will be null.
+     */
+    public final MethodData methoddata;
+
+    /**
+     * The class access.  Note that this is controlled by the packageId.
+     */
+    public final MethodData.Access access;
+
+    // This is a hardwired value necessary for ClassBuilder
+    public final MethodData.Context abstraction = MethodData.Context.INSTANCE;
+
+    public ClassData(final Package packageId,
+                     final MethodData methoddata) {
+        this.packageId = packageId;
+        this.methoddata = methoddata;
+
+        if (packageId == Package.INACCESSIBLE)
+            access = MethodData.Access.PACKAGE;
+        else
+            access = MethodData.Access.PUBLIC;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(" { ");
+
+        if (methoddata != null) {
+            sb.append(methoddata);
+        }
+
+        sb.append(" }\n\n");
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Clazz.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
+import static jdk.internal.org.objectweb.asm.Opcodes.V1_8;
+
+
+class Clazz extends ClassConstruct {
+
+    /**
+     * Construct a Class
+     * @param name Name of Class
+     * @param access Access for the Class
+     */
+    public Clazz(String name, int access, int index) {
+        this(name, null, access, V1_8, index, new String[] { });
+    }
+
+    /**
+     * Construct a Class
+     * @param name Name of Class
+     * @param extending Class being extended
+     * @param access Access for the Class
+     */
+    public Clazz(String name, String extending, int access, int index) {
+        this(name, extending, access, V1_8, index, new String[] { });
+    }
+
+    /**
+     * Construct a Class
+     * @param name Name of Class
+     * @param extending Class being extended
+     * @param access access for the Class
+     * @param implementing Interfaces implemented
+     */
+    public Clazz(String name, String extending, int access, int index, String... implementing) {
+        this(name, extending, access, V1_8, index, implementing);
+    }
+
+    /**
+     * Construct a Class
+     * @param name Name of Class
+     * @param extending Class being extended
+     * @param access Access for the Class
+     * @param classFileVersion Class file version
+     * @param implementing Interfaces implemented
+     */
+    public Clazz(String name, String extending, int access, int classFileVersion, int index, String... implementing) {
+        super(name, extending == null ? "java/lang/Object" : extending, access + ACC_SUPER, classFileVersion, index, implementing);
+        // Add the default constructor
+        addMethod("<init>", "()V", ACC_PUBLIC).makeConstructor(extending);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/HierarchyShape.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Map;
+
+/**
+ * A representation of a class/interface hierarchy graph (just the
+ * graph; the class data is represented elsewhere).
+ */
+public class HierarchyShape {
+    public static final int OBJECT_CLASS = -1;
+
+    protected int maxId;
+
+    /**
+     * The names of all the classes.
+     */
+    private final HashSet<Integer> classes;
+
+    /**
+     * The names of all the interfaces.
+     */
+    private final HashSet<Integer> interfaces;
+    private final HashMap<Integer, HashSet<Integer>> extensions;
+
+    /**
+     * Create an empty hierarchy shape.
+     */
+    public HierarchyShape() {
+        this(0, new HashSet<>(), new HashSet<>(), new HashMap<>());
+    }
+
+    private HierarchyShape(final int maxId,
+                          final HashSet<Integer> classes,
+                          final HashSet<Integer> interfaces,
+                          final HashMap<Integer, HashSet<Integer>> extensions) {
+        this.maxId = maxId;
+        this.classes = classes;
+        this.interfaces = interfaces;
+        this.extensions = extensions;
+    }
+
+    /**
+     * Make a copy of this hierarchy shape.
+     */
+    public HierarchyShape copy() {
+        final HashMap<Integer, HashSet<Integer>> newextensions = new HashMap<>();
+
+        for(final Map.Entry<Integer, HashSet<Integer>> entry :
+                extensions.entrySet()) {
+            newextensions.put(entry.getKey(),
+                              (HashSet<Integer>)entry.getValue().clone());
+        }
+
+        return new HierarchyShape(maxId, (HashSet<Integer>) classes.clone(),
+                                  (HashSet<Integer>) interfaces.clone(),
+                                  newextensions);
+    }
+
+    /**
+     * Add a class, and return its id.
+     *
+     * @return The new class id.
+     */
+    public int addClass() {
+        final int id = maxId++;
+        classes.add(id);
+        return id;
+    }
+
+    /**
+     * Add an interface, and return its id.
+     *
+     * @return The new interface id.
+     */
+    public int addInterface() {
+        final int id = maxId++;
+        interfaces.add(id);
+        return id;
+    }
+
+    /**
+     * Add an inheritance.
+     *
+     * @param sub The sub class/interface.
+     * @param sup The super class/interface
+     */
+    public void addInherit(final int sub,
+                           final int sup) {
+        HashSet<Integer> ext = extensions.get(sub);
+
+        if (ext == null) {
+            ext = new HashSet<>();
+            extensions.put(sub, ext);
+        }
+
+        ext.add(sup);
+    }
+
+    @Override
+    public String toString() {
+        String out = "";
+        for(int i = maxId - 1; i >= 0; i--) {
+            out += i + ": ";
+            for(int j = 0; j < maxId; j++) {
+                out += "[" + (inherits(i, j) ? "1" : "0") + "]";
+            }
+            out += "\n";
+        }
+        return out;
+    }
+
+    /**
+     * Indicate whether the first class inherits from the second.
+     *
+     * @param sub The possible subtype.
+     * @param sup The possible supertype.
+     * @return Whether or not {@code sub} inherits from {@code sup}.
+     */
+    public boolean inherits(final int sub, final int sup) {
+        final Set<Integer> ext = extensions.get(sub);
+        if (ext != null) {
+            return ext.contains(sup);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Indicate whether a given type name is a class.
+     *
+     * @param id The type in question.
+     * @return Whether or not the type is a class.
+     */
+    public boolean isClass(final int id) {
+        if (id == OBJECT_CLASS) {
+            return true;
+        }
+        return classes.contains(id);
+    }
+
+    /**
+     * Indicate whether a given type name is an interface.
+     *
+     * @param id The type in question.
+     * @return Whether or not the type is an interface.
+     */
+    public boolean isInterface(final int id) {
+        if (id == OBJECT_CLASS) {
+            return false;
+        }
+        return interfaces.contains(id);
+    }
+
+    /**
+     * Get an iterator over the classes.
+     *
+     * @return An iterator over classes.
+     */
+    public Collection<Integer> classes() {
+        return classes;
+    }
+
+    /**
+     * Get an iterator over the interfaces.
+     *
+     * @return An iterator over interfaces.
+     */
+    public Collection<Integer> interfaces() {
+        return interfaces;
+    }
+
+    /**
+     * Get an iterator over all types.
+     *
+     * @return An iterator over all types.
+     */
+    public Collection<Integer> types() {
+        final Set<Integer> combined = new HashSet(classes);
+        combined.addAll(interfaces);
+        return combined;
+    }
+
+    public int numClasses() {
+        return classes.size();
+    }
+
+    public int numInterfaces() {
+        return interfaces.size();
+    }
+
+    public int numTypes() {
+        return numClasses() + numInterfaces();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Interface.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_ABSTRACT;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_INTERFACE;
+import static jdk.internal.org.objectweb.asm.Opcodes.V1_8;
+
+class Interface extends ClassConstruct {
+
+    public Interface(String name, int access, int index) {
+        this(name, V1_8, access, index, (String)null);
+    }
+
+    public Interface(String name, int index) {
+        this(name, V1_8, index, (String)null);
+    }
+
+
+    public Interface(String name, int access, int index, String... extending) {
+        this(name, V1_8, access, index, extending);
+    }
+
+    public Interface(String name, int classFileVersion, int access, int index, String... extending) {
+        super(name, "java/lang/Object", access + ACC_ABSTRACT + ACC_INTERFACE, classFileVersion, index, extending);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Method.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
+import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
+import static jdk.internal.org.objectweb.asm.Opcodes.POP;
+import static jdk.internal.org.objectweb.asm.Opcodes.NEW;
+import static jdk.internal.org.objectweb.asm.Opcodes.SWAP;
+import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE;
+import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE;
+import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESPECIAL;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEINTERFACE;
+import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL;
+
+class Method {
+    public static final String defaultMethodName        = "m";
+    public static final String defaultMethodDescriptor  = "()Ljava/lang/Integer;";
+    public static final String methodDescriptorTemplate = "(L%s;)Ljava/lang/Integer;";
+    private final ClassConstruct ownerClass;
+    private final String ownerClassName;
+    private final ClassVisitor cv;
+    private final MethodVisitor mv;
+    private final boolean isInterface;
+    private final ClassBuilder.ExecutionMode execMode;
+
+    public Method(ClassConstruct ownerClass, ClassVisitor cv, String name, String descriptor, int access,
+                  ClassBuilder.ExecutionMode execMode) {
+        this.ownerClassName = ownerClass.getName();
+        this.ownerClass = ownerClass;
+        this.isInterface = ownerClass.isInterface();
+        this.execMode = execMode;
+        this.cv = cv;
+        mv = cv.visitMethod(access, name, descriptor, null, null);
+        mv.visitCode();
+    }
+    /**
+     * Add code for the m()Ljava/lang/Integer; method, always returns null
+     */
+    public void makeDefaultMethod() {
+        mv.visitTypeInsn(NEW, "java/lang/Integer");
+        mv.visitInsn(DUP);
+        mv.visitLdcInsn(ownerClass.getIndex());
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Integer", "<init>", "(I)V");
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    public void makePrivateCallMethod(String className) {
+        makeSuperCallMethod(INVOKESPECIAL, className);
+    }
+
+    public void makeSuperCallMethod(int invokeInstruction, String className) {
+        mv.visitVarInsn(ALOAD, 0);
+        makeCall(invokeInstruction, className);
+        mv.visitInsn(POP);
+        done();
+    }
+
+    public void defaultInvoke(int instr, String className, String objectRef) {
+        switch (instr) {
+            case INVOKEVIRTUAL:
+                defaultInvokeVirtual(className, objectRef);
+                break;
+            case INVOKEINTERFACE:
+                defaultInvokeInterface(className, objectRef);
+                break;
+            case INVOKESTATIC:
+                defaultInvokeStatic(className);
+                break;
+            case INVOKESPECIAL:
+                defaultInvokeSpecial(className, objectRef);
+                break;
+            default:
+                break;
+        }
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    public void defaultInvokeVirtual(String className, String objectRef) {
+        String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/"));
+        makeNewObject(objectRef, objectRefPackageName);
+        makeCall(INVOKEVIRTUAL, className, false);
+    }
+
+    public void defaultInvokeInterface(String className, String objectRef) {
+        String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/"));
+        makeNewObject(objectRef, objectRefPackageName);
+        makeCall(INVOKEINTERFACE, className, true);
+    }
+
+    public void defaultInvokeSpecial(String className, String objectRef) {
+        String objectRefPackageName = objectRef.substring(0, objectRef.lastIndexOf("/"));
+        makeNewObject(objectRef, objectRefPackageName);
+        makeCall(INVOKESPECIAL, className, false);
+    }
+
+    public void defaultInvokeStatic(String className) {
+        makeCall(INVOKESTATIC, className);
+    }
+
+    private Method makeCall(int invokeInstruction, String className) {
+        return makeCall(invokeInstruction, className, isInterface);
+    }
+
+    private Method makeCall(int invokeInstruction, String className, boolean isInterface) {
+        switch(execMode) {
+            case DIRECT: {
+                mv.visitMethodInsn(invokeInstruction, className, defaultMethodName, defaultMethodDescriptor, isInterface);
+                break;
+            }
+            case INDY: {
+                Handle m = convertToHandle(invokeInstruction, className, defaultMethodName, defaultMethodDescriptor);
+                Handle bsm = generateBootstrapMethod(m);
+                mv.visitInvokeDynamicInsn(defaultMethodName, defaultMethodDescriptor, bsm);
+                break;
+            }
+            case MH_INVOKE_EXACT:
+            case MH_INVOKE_GENERIC: {
+                String invokerName = execMode == ClassBuilder.ExecutionMode.MH_INVOKE_GENERIC
+                        ? "invoke" : "invokeExact";
+
+                Handle m = convertToHandle(invokeInstruction, className, defaultMethodName, defaultMethodDescriptor);
+                mv.visitLdcInsn(m);
+                mv.visitInsn(SWAP);
+                mv.visitMethodInsn(INVOKEVIRTUAL,
+                        "java/lang/invoke/MethodHandle",
+                        invokerName,
+                        String.format(methodDescriptorTemplate, className),
+                        false);
+                break;
+            }
+            default:
+                throw new Error("Unknown execution mode: " + execMode);
+
+        }
+        return this;
+    }
+
+    private Handle generateBootstrapMethod(Handle h) {
+        String bootstrapName = "bootstrapMethod";
+        MethodType bootstrapType = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
+
+        MethodVisitor bmv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, bootstrapName, bootstrapType.toMethodDescriptorString(), null, null);
+        bmv.visitCode();
+
+        String constCallSite = "java/lang/invoke/ConstantCallSite";
+        bmv.visitTypeInsn(NEW, constCallSite);
+        bmv.visitInsn(DUP);
+
+        bmv.visitLdcInsn(h);
+
+        bmv.visitMethodInsn(INVOKESPECIAL, constCallSite, "<init>", "(Ljava/lang/invoke/MethodHandle;)V", false);
+        bmv.visitInsn(ARETURN);
+
+        bmv.visitMaxs(0,0);
+        bmv.visitEnd();
+
+        return new Handle(H_INVOKESTATIC, ownerClassName, bootstrapName, bootstrapType.toMethodDescriptorString());
+    }
+
+
+    private static Handle convertToHandle(int invokeInstruction, String className, String methodName, String methodDesc) {
+        int tag;
+        switch (invokeInstruction) {
+            case INVOKEVIRTUAL:   tag = H_INVOKEVIRTUAL;   break;
+            case INVOKEINTERFACE: tag = H_INVOKEINTERFACE; break;
+            case INVOKESPECIAL:   tag = H_INVOKESPECIAL;   break;
+            case INVOKESTATIC:    tag = H_INVOKESTATIC;    break;
+            default:
+                throw new Error("Unknown invoke instruction: "+invokeInstruction);
+        }
+
+        return new Handle(tag, className, methodName, methodDesc);
+    }
+
+    private void makeNewObject(String objectRef, String objectRefPackageName) {
+        String className = objectRef.substring(objectRef.lastIndexOf("/") + 1);
+        makeStaticCall( objectRefPackageName + "/Helper",
+                        "get" + className,
+                        "()L" + objectRef + ";");
+        mv.visitVarInsn(ASTORE, 1);
+        mv.visitVarInsn(ALOAD, 1);
+    }
+
+    public void makeTestCall(String className) {
+        mv.visitTypeInsn(NEW, className);
+        mv.visitInsn(DUP);
+        mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V", false);
+        mv.visitVarInsn(ASTORE, 1);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, className, "test", "()Ljava/lang/Integer;", false);
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(2, 2);
+        mv.visitEnd();
+    }
+
+    public Method makeStaticCall(String classname, String method, String descriptor) {
+        mv.visitMethodInsn(INVOKESTATIC, classname, method, descriptor, isInterface);
+        return this;
+    }
+
+    public void makeConstructor(String extending) {
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKESPECIAL, extending == null ? "java/lang/Object" : extending, "<init>", "()V", isInterface);
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    public void makeInstantiateMethod(String className) {
+        mv.visitTypeInsn(NEW, className);
+        mv.visitInsn(DUP);
+        mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V", false);
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    public void done() {
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/MethodData.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+/**
+ * A representation of a method definition.
+ */
+public class MethodData {
+
+    public enum Access {
+        PUBLIC(1),
+        PACKAGE(0),
+        PROTECTED(4),
+        PRIVATE(2),
+        /**
+         * Placeholder, used solely for printing out the effects of
+         * templates.  Don't use.
+         */
+        PLACEHOLDER(-1);
+
+        public final int flag;
+
+        Access(int flag) {
+            this.flag = flag;
+        }
+    }
+
+    public enum Context {
+        ABSTRACT,
+        INSTANCE,
+        STATIC,
+        /**
+         * Placeholder, used solely for printing out the effects of
+         * templates.  Don't use.
+         */
+        PLACEHOLDER;
+    };
+
+    /**
+     * Access for the method.
+     */
+    public final Access access;
+
+    /**
+     * Context (static, instance, abstract) for the method.
+     */
+    public final Context context;
+
+    /**
+     * Create method data.
+     */
+    public MethodData(final Access access,
+                      final Context context) {
+
+        this.access = access;
+        this.context = context;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        switch (access) {
+        case PUBLIC: sb.append("public"); break;
+        case PACKAGE: sb.append("package"); break;
+        case PROTECTED: sb.append("protected"); break;
+        case PRIVATE: sb.append("private"); break;
+        case PLACEHOLDER: sb.append(" _"); break;
+        default: throw new RuntimeException("Impossible case");
+        }
+
+        switch (context) {
+        case STATIC: sb.append(" static"); break;
+        case INSTANCE: sb.append(" instance"); break;
+        case ABSTRACT: sb.append("  abstract"); break;
+        case PLACEHOLDER: sb.append(" _"); break;
+        default: throw new RuntimeException("Impossible case");
+        }
+        sb.append(" Integer m();");
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Result.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package selectionresolution;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+/**
+ * Representation of an expected result.
+ */
+public interface Result {
+    public static final Result ICCE = new Exception(IncompatibleClassChangeError.class);
+    public static final Result IAE  = new Exception(IllegalAccessError.class);
+    public static final Result NSME = new Exception(NoSuchMethodError.class);
+    public static final Result AME  = new Exception(AbstractMethodError.class);
+
+    // Factories
+
+    /**
+     * Create a result that expects the given class.
+     */
+    public static Result is(int id) {
+        return new Single(id);
+    }
+
+    /**
+     * Create a result that expects the given classes.
+     */
+    public static Result is(int... multiple) {
+        assert multiple.length > 0;
+
+        if (multiple.length == 1) {
+            return new Single(multiple[0]);
+        } else {
+            return new Any(multiple);
+        }
+    }
+
+    /**
+     * Create a result that expects the given exception to be thrown.
+     */
+    public static Result is(Class<? extends Throwable> exType) {
+        return new Exception(exType);
+    }
+
+    /**
+     * Create a result that expects the given exception to be thrown.
+     */
+    public static Result is(Throwable ex) {
+        return Result.is(ex.getClass());
+    }
+
+    public static final Result EMPTY = new Empty();
+
+    /**
+     * Create an empty Result.
+     */
+    public static Result empty() {
+        return EMPTY;
+    }
+
+
+    public boolean complyWith(int i);
+    public boolean complyWith(Throwable e);
+    public boolean complyWith(Result r);
+
+    static class Empty implements Result {
+        @Override
+        public boolean complyWith(int i) {
+            return false;
+        }
+
+        @Override
+        public boolean complyWith(Throwable e) {
+            return false;
+        }
+
+        @Override
+        public boolean complyWith(Result r) {
+            return false;
+        }
+    }
+
+    static class Single implements Result {
+        public int id;
+
+        public Single(int id) {
+            this.id = id;
+        }
+
+        @Override
+        public boolean complyWith(int i) {
+            return id == i;
+        }
+
+        @Override
+        public boolean complyWith(Throwable e) {
+            return false;
+        }
+
+        @Override
+        public boolean complyWith(Result r) {
+            if (r instanceof Single) {
+                return complyWith(((Single)r).id);
+            } else if (r instanceof Any) {
+                return r.complyWith(this);
+            }
+            return false;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof Single)) return false;
+
+            Single single = (Single) o;
+
+            return (id == single.id);
+        }
+
+        @Override
+        public int hashCode() {
+            return id;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuffer sb = new StringBuffer("Result=Single{");
+            sb.append("id=").append(id);
+            sb.append('}');
+            return sb.toString();
+        }
+    }
+
+    static class Any implements Result {
+        public int[] ids;
+        public Any(int[] ids) {
+            this.ids = ids;
+        }
+
+        @Override
+        public boolean complyWith(int i) {
+            return Arrays.stream(ids)
+                    .anyMatch(j -> j == i);
+        }
+
+        @Override
+        public boolean complyWith(Throwable e) {
+            return false;
+        }
+
+        @Override
+        public boolean complyWith(Result r) {
+            if (r instanceof Single) {
+                return complyWith(((Single)r).id);
+            }
+            if (r instanceof Any) {
+                return Arrays.equals(ids, ((Any) r).ids);
+            }
+            return false;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Any any = (Any) o;
+
+            return Arrays.equals(ids, any.ids);
+        }
+
+        @Override
+        public int hashCode() {
+            return Arrays.hashCode(ids);
+        }
+
+        @Override
+        public String toString() {
+            final StringBuffer sb = new StringBuffer("Result=Any{");
+            sb.append("ids=");
+            if (ids == null) sb.append("null");
+            else {
+                sb.append('[');
+                for (int i = 0; i < ids.length; ++i)
+                    sb.append(i == 0 ? "" : ", ").append(ids[i]);
+                sb.append(']');
+            }
+            sb.append('}');
+            return sb.toString();
+        }
+    }
+
+    static class Exception implements Result {
+        public Class<? extends Throwable> exc;
+        public Exception(Class<? extends Throwable> e) {
+            this.exc = e;
+        }
+
+        @Override
+        public boolean complyWith(int i) {
+            return false;
+        }
+
+        @Override
+        public boolean complyWith(Throwable e) {
+            return exc.isAssignableFrom(e.getClass());
+        }
+
+        @Override
+        public boolean complyWith(Result r) {
+            if (r instanceof Exception) {
+                return exc.isAssignableFrom(((Exception) r).exc);
+            }
+            return false;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof Exception)) return false;
+
+            Exception exception = (Exception) o;
+
+            return exc.equals(exception.exc);
+        }
+
+        @Override
+        public int hashCode() {
+            return exc.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            final StringBuffer sb = new StringBuffer("Result=Exception{");
+            sb.append("exc=").append(exc);
+            sb.append('}');
+            return sb.toString();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/SelectionResolutionTest.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package selectionresolution;
+
+import java.util.function.Consumer;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A master superclass for all selection/resolution tests.  Contains a
+ * couple of standard definitions that make writing these tests
+ * easier.
+ */
+public abstract class SelectionResolutionTest {
+
+    /**
+     * A unified output function, to ensure that all output goes to
+     * the right string (System.err).
+     *
+     * @param str The line to print.
+     */
+    protected void println(final String str) {
+        System.err.println(str);
+    }
+
+    /**
+     * A test group is a generator for a set of tests that should
+     * share common characteristics.  The Simple class provides a
+     * default implementation that should work for most purposes.
+     */
+    public static interface TestGroup {
+        /**
+         * Given an action that runs a given test case, generate and
+         * run all cases in this test group.
+         */
+        public void runCases(Consumer<SelectionResolutionTestCase> runner);
+
+        /**
+         * The basic implementation of TestGroup.  Produces one case
+         * for every possible combination of cases from each of its
+         * templates, by running them in order on an empty
+         * SelectionResolutionTestCase.Builder.  This should be good
+         * enough for writing most tests.
+         */
+        public static class Simple implements TestGroup {
+            private final Template[] templates;
+            private final SelectionResolutionTestCase.Builder initBuilder;
+
+            public Simple(final SelectionResolutionTestCase.Builder initBuilder,
+                          final Template... templates) {
+                this.templates = templates;
+                this.initBuilder = initBuilder;
+            }
+
+            @Override
+            public void runCases(final Consumer<SelectionResolutionTestCase> runner) {
+                Consumer<SelectionResolutionTestCase.Builder> curr = (builder) -> {
+                    runner.accept(builder.build());
+                };
+
+                for(int i = templates.length - 1; i >= 0; i--) {
+                    final Consumer<SelectionResolutionTestCase.Builder> next = curr;
+                    final Template template = templates[i];
+                    curr = (builder) -> {
+                        template.runCases(next, builder);
+                    };
+                }
+
+                curr.accept(initBuilder);
+            }
+        }
+    }
+
+    private final List<String> errs = new LinkedList<String>();
+
+    private final Collection<TestGroup> testGroups;
+
+    private int testcount = 0;
+
+    /**
+     * Create a test from a set of test groups.  Most actual tests can
+     * just define the test groups and pass them into this
+     * constructor, then call run.
+     */
+    protected SelectionResolutionTest(final Collection<TestGroup> testGroups) {
+        this.testGroups = testGroups;
+    }
+
+    /**
+     * Run all the tests, report errors if they happen.
+     */
+    protected void run() {
+        testGroups.stream().forEach(
+                (group) -> {
+                    group.runCases((final SelectionResolutionTestCase testcase) -> {
+                            testcount++;
+                            final String err = testcase.run();
+
+                            if (err != null) {
+                                errs.add(err);
+                            }
+                        });
+                });
+
+        println("Ran " + testcount + " cases");
+
+        if(!errs.isEmpty()) {
+            println("Errors occurred in test:");
+            for(final String err : errs) {
+                println(err);
+            }
+            throw new RuntimeException("Errors occurred in test");
+        } else {
+            println("All test cases succeeded");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/SelectionResolutionTestCase.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package selectionresolution;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.HashMap;
+
+/**
+ * One individual test case.  This class also defines a builder, which
+ * can be used to build up cases.
+ */
+public class SelectionResolutionTestCase {
+
+    public enum InvokeInstruction {
+        INVOKESTATIC,
+        INVOKESPECIAL,
+        INVOKEINTERFACE,
+        INVOKEVIRTUAL;
+    }
+
+    /**
+     * The class data (includes interface data).
+     */
+    public final HashMap<Integer, ClassData> classdata;
+    /**
+     * The hierarchy shape.
+     */
+    public final HierarchyShape hier;
+    /**
+     * The invoke instruction to use.
+     */
+    public final InvokeInstruction invoke;
+    /**
+     * Which class is the methodref (or interface methodref).
+     */
+    public final int methodref;
+    /**
+     * Which class is the objectref.
+     */
+    public final int objectref;
+    /**
+     * Which class is the callsite (this must be a class, not an interface.
+     */
+    public final int callsite;
+    /**
+     * The expected result.
+     */
+    public final Result result;
+
+    private SelectionResolutionTestCase(final HashMap<Integer, ClassData> classdata,
+                                        final HierarchyShape hier,
+                                        final InvokeInstruction invoke,
+                                        final int methodref,
+                                        final int objectref,
+                                        final int callsite,
+                                        final int expected) {
+        this.classdata = classdata;
+        this.hier = hier;
+        this.invoke = invoke;
+        this.methodref = methodref;
+        this.objectref = objectref;
+        this.callsite = callsite;
+        this.result = Result.is(expected);
+    }
+
+    private SelectionResolutionTestCase(final HashMap<Integer, ClassData> classdata,
+                                        final HierarchyShape hier,
+                                        final InvokeInstruction invoke,
+                                        final int methodref,
+                                        final int objectref,
+                                        final int callsite,
+                                        final Result result) {
+        this.classdata = classdata;
+        this.hier = hier;
+        this.invoke = invoke;
+        this.methodref = methodref;
+        this.objectref = objectref;
+        this.callsite = callsite;
+        this.result = result;
+    }
+
+    private static int currError = 0;
+
+    private String dumpClasses(final ClassConstruct[] classes)
+        throws Exception {
+        final String errorDirName = "error_" + currError++;
+        final File errorDir = new File(errorDirName);
+        errorDir.mkdirs();
+        for (int i = 0; i < classes.length; i++) {
+            classes[i].writeClass(errorDir);
+        }
+        try (final FileWriter fos =
+             new FileWriter(new File(errorDir, "description.txt"))) {
+            fos.write(this.toString());
+        }
+        return errorDirName;
+    }
+
+    /**
+     * Run this case, return an error message, or null.
+     *
+     * @return An error message, or null if the case succeeded.
+     */
+    public String run() {
+        /* Uncomment this line to print EVERY case */
+        //System.err.println("Running\n" + this);
+        final ClassBuilder builder =
+            new ClassBuilder(this, ClassBuilder.ExecutionMode.DIRECT);
+        try {
+            final ByteCodeClassLoader bcl = new ByteCodeClassLoader();
+            final ClassConstruct[] classes = builder.build();
+
+            try {
+                bcl.addClasses(classes);
+                bcl.loadAll();
+
+                // Grab the callsite class.
+                final Class testclass =
+                    bcl.findClass(builder.getCallsiteClass().getDottedName());
+
+                // Get the 'test' method out of it and call it.  The
+                // return value tess which class that got selected.
+                final java.lang.reflect.Method method =
+                    testclass.getDeclaredMethod("test");
+                final int actual = (Integer) method.invoke(null);
+                // Check the result.
+                if (!result.complyWith(actual)) {
+                    final String dump = dumpClasses(classes);
+                    return "Failed:\n" + this + "\nExpected " + result + " got " + actual + "\nClasses written to " + dump;
+                }
+            } catch (Throwable t) {
+                // This catch block is handling exceptions that we
+                // might expect to see.
+                final Throwable actual = t.getCause();
+                if (actual == null) {
+                    final String dump = dumpClasses(classes);
+                    System.err.println("Unexpected exception in test\n" + this + "\nClasses written to " + dump);
+                    throw t;
+                } else if (result == null) {
+                    final String dump = dumpClasses(classes);
+                    return "Failed:\n" + this + "\nUnexpected exception " + actual + "\nClasses written to " + dump;
+                } else if (!result.complyWith(actual)) {
+                    final String dump = dumpClasses(classes);
+                    return "Failed:\n" + this + "\nExpected " + this.result + " got " + actual + "\nClasses written to " + dump;
+                }
+            }
+        } catch(Throwable e) {
+            throw new RuntimeException(e);
+        }
+        return null;
+    }
+
+    private static void addPackage(final StringBuilder sb,
+                                  final ClassData cd) {
+        switch (cd.packageId) {
+        case SAME: sb.append("Same."); break;
+        case DIFFERENT: sb.append("Different."); break;
+        case OTHER: sb.append("Other."); break;
+        case PLACEHOLDER: sb.append("_."); break;
+        default: throw new RuntimeException("Impossible case");
+        }
+    }
+
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        //sb.append("hierarchy:\n" + hier + "\n");
+        sb.append("invoke:    " + invoke + "\n");
+        if (methodref != -1) {
+            if (hier.isClass(methodref)) {
+                sb.append("methodref: C" + methodref + "\n");
+            } else {
+                sb.append("methodref: I" + methodref + "\n");
+            }
+        }
+        if (objectref != -1) {
+            if (hier.isClass(objectref)) {
+                sb.append("objectref: C" + objectref + "\n");
+            } else {
+                sb.append("objectref: I" + objectref + "\n");
+            }
+        }
+        if (callsite != -1) {
+            if (hier.isClass(callsite)) {
+                sb.append("callsite: C" + callsite + "\n");
+            } else {
+                sb.append("callsite: I" + callsite + "\n");
+            }
+        }
+        sb.append("result: " + result + "\n");
+        sb.append("classes:\n\n");
+
+        for(int i = 0; classdata.containsKey(i); i++) {
+            final ClassData cd = classdata.get(i);
+
+            if (hier.isClass(i)) {
+                sb.append("class ");
+                addPackage(sb, cd);
+                sb.append("C" + i);
+            } else {
+                sb.append("interface ");
+                addPackage(sb, cd);
+                sb.append("I" + i);
+            }
+
+            boolean first = true;
+            for(final int j : hier.classes()) {
+                if (hier.inherits(i, j)) {
+                    if (first) {
+                        sb.append(" extends C" + j);
+                    } else {
+                        sb.append(", C" + j);
+                    }
+                }
+            }
+
+            first = true;
+            for(final int j : hier.interfaces()) {
+                if (hier.inherits(i, j)) {
+                    if (first) {
+                        sb.append(" implements I" + j);
+                    } else {
+                        sb.append(", I" + j);
+                    }
+                }
+            }
+
+            sb.append(cd);
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * A builder, facilitating building up test cases.
+     */
+    public static class Builder {
+        /**
+         * A map from class (or interface) id's to ClassDatas
+         */
+        public final HashMap<Integer, ClassData> classdata;
+        /**
+         * The hierarchy shape.
+         */
+        public final HierarchyShape hier;
+        /**
+         * Which invoke instruction to use.
+         */
+        public InvokeInstruction invoke;
+        /**
+         * The id of the methodref (or interface methodref).
+         */
+        public int methodref = -1;
+        /**
+         * The id of the object ref.  Note that for the generator
+         * framework to work, this must be set to something.  If an
+         * objectref isn't used, just set it to the methodref.
+         */
+        public int objectref = -1;
+        /**
+         * The id of the callsite.
+         */
+        public int callsite = -1;
+        /**
+         * The id of the expected result.  This is used to store the
+         * expected resolution result.
+         */
+        public int expected;
+        /**
+         * The expected result.  This needs to be set before the final
+         * test case is built.
+         */
+        public Result result;
+
+        /**
+         * Create an empty Builder object.
+         */
+        public Builder() {
+            classdata = new HashMap<>();
+            hier = new HierarchyShape();
+        }
+
+        private Builder(final HashMap<Integer, ClassData> classdata,
+                        final HierarchyShape hier,
+                        final InvokeInstruction invoke,
+                        final int methodref,
+                        final int objectref,
+                        final int callsite,
+                        final int expected,
+                        final Result result) {
+            this.classdata = classdata;
+            this.hier = hier;
+            this.invoke = invoke;
+            this.methodref = methodref;
+            this.objectref = objectref;
+            this.callsite = callsite;
+            this.expected = expected;
+            this.result = result;
+        }
+
+        private Builder(final Builder other) {
+            this((HashMap<Integer, ClassData>) other.classdata.clone(),
+                 other.hier.copy(), other.invoke, other.methodref, other.objectref,
+                 other.callsite, other.expected, other.result);
+        }
+
+        public SelectionResolutionTestCase build() {
+            if (result != null) {
+                return new SelectionResolutionTestCase(classdata, hier, invoke,
+                                                       methodref, objectref,
+                                                       callsite, result);
+            } else {
+                return new SelectionResolutionTestCase(classdata, hier, invoke,
+                                                       methodref, objectref,
+                                                       callsite, expected);
+            }
+        }
+
+        /**
+         * Set the expected result.
+         */
+        public void setResult(final Result result) {
+            this.result = result;
+        }
+
+        /**
+         * Add a class, and return its id.
+         *
+         * @return The new class' id.
+         */
+        public int addClass(final ClassData data) {
+            final int id = hier.addClass();
+            classdata.put(id, data);
+            return id;
+        }
+
+        /**
+         * Add an interface, and return its id.
+         *
+         * @return The new class' id.
+         */
+        public int addInterface(final ClassData data) {
+            final int id = hier.addInterface();
+            classdata.put(id, data);
+            return id;
+        }
+
+        /**
+         * Make a copy of this builder.
+         */
+        public Builder copy() {
+            return new Builder(this);
+        }
+
+        public String toString() {
+            final StringBuilder sb = new StringBuilder();
+            //sb.append("hierarchy:\n" + hier + "\n");
+            sb.append("invoke:    " + invoke + "\n");
+            if (methodref != -1) {
+                if (hier.isClass(methodref)) {
+                    sb.append("methodref: C" + methodref + "\n");
+                } else {
+                    sb.append("methodref: I" + methodref + "\n");
+                }
+            }
+            if (objectref != -1) {
+                if (hier.isClass(objectref)) {
+                    sb.append("objectref: C" + objectref + "\n");
+                } else {
+                    sb.append("objectref: I" + objectref + "\n");
+                }
+            }
+            if (callsite != -1) {
+                if (hier.isClass(callsite)) {
+                    sb.append("callsite: C" + callsite + "\n");
+                } else {
+                    sb.append("callsite: I" + callsite + "\n");
+                }
+            }
+            if (expected != -1) {
+                if (hier.isClass(expected)) {
+                    sb.append("expected: C" + expected + "\n");
+                } else {
+                    sb.append("expected: I" + expected + "\n");
+                }
+            }
+            sb.append("result: " + result + "\n");
+            sb.append("classes:\n\n");
+
+            for(int i = 0; classdata.containsKey(i); i++) {
+                final ClassData cd = classdata.get(i);
+
+                if (hier.isClass(i)) {
+                    sb.append("class ");
+                    addPackage(sb, cd);
+                    sb.append("C" + i);
+                } else {
+                    sb.append("interface ");
+                    addPackage(sb, cd);
+                    sb.append("I" + i);
+                }
+
+                boolean first = true;
+                for(final int j : hier.classes()) {
+                    if (hier.inherits(i, j)) {
+                        if (first) {
+                            sb.append(" extends C" + j);
+                        } else {
+                            sb.append(", C" + j);
+                        }
+                    }
+                }
+
+                first = true;
+                for(final int j : hier.interfaces()) {
+                    if (hier.inherits(i, j)) {
+                        if (first) {
+                            sb.append(" implements I" + j);
+                        } else {
+                            sb.append(", I" + j);
+                        }
+                    }
+                }
+
+                sb.append(cd);
+            }
+
+            return sb.toString();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/Template.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,5005 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package selectionresolution;
+
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.LinkedList;
+
+/**
+ * Templates are sets of transformations that are applied to a
+ * SelectionResolutionTestCase.Builder as part of building up a test
+ * case.  Templates should contain a collection of different
+ * transforms, all of which represent an "interesting" case in a
+ * general category of cases.
+ *
+ */
+public class Template {
+
+    public enum Kind { CLASS, INTERFACE; }
+
+    public final Collection<Consumer<SelectionResolutionTestCase.Builder>> cases;
+    public final String name;
+
+    /**
+     * Create a template from a collection of lambdas that modify a Builder.
+     *
+     * @param name The name of the template.
+     * @param cases The cases in the template.
+     */
+    public Template(final String name,
+                    final Collection<Consumer<SelectionResolutionTestCase.Builder>> cases) {
+        this.cases = cases;
+        this.name = name;
+    }
+
+    /**
+     * Build a template out of a set of lambdas that modify a Builder.
+     *
+     * @param name The name of the template.
+     * @param cases The cases in the template.
+     */
+    public Template(final String name,
+                    final Consumer<SelectionResolutionTestCase.Builder>... cases) {
+        this(name, Arrays.asList(cases));
+    }
+
+    /**
+     * Build a template out of a set of lambdas that modify a Builder.
+     * Also include all cases from another template.
+     *
+     * @param name The name of the template.
+     * @param include Include all cases from this template.
+     * @param cases The cases in the template.
+     */
+    public Template(final String name,
+                    final Template include,
+                    final Consumer<SelectionResolutionTestCase.Builder>... cases) {
+        this(name, new LinkedList(include.cases));
+        this.cases.addAll(Arrays.asList(cases));
+    }
+
+    /**
+     * Build a template out of a set of lambdas that modify a Builder.
+     * Also include all cases from another template.
+     *
+     * @param name The name of the template.
+     * @param include Include all cases from this template.
+     * @param cases The cases in the template.
+     */
+    public Template(final String name,
+                    final Template... others) {
+        this(name, new LinkedList());
+
+        for(final Template template : others) {
+            cases.addAll(template.cases);
+        }
+    }
+
+    /**
+     * Run all cases in the template.  This will run each action in
+     * the template and then call the next action on a separate copy
+     * of the builder parameter.
+     *
+     * @param The next action to perform of the Builder.
+     * @param The Builder to modify.
+     */
+    public void runCases(final Consumer<SelectionResolutionTestCase.Builder> next,
+                         final SelectionResolutionTestCase.Builder builder) {
+        for(final Consumer<SelectionResolutionTestCase.Builder> thiscase : cases) {
+            final SelectionResolutionTestCase.Builder localbuilder = builder.copy();
+            thiscase.accept(localbuilder);
+            next.accept(localbuilder);
+        }
+    }
+
+    public void printCases(final SelectionResolutionTestCase.Builder builder) {
+        int i = 1;
+        System.err.println("Template " + name + ":\n");
+        for(final Consumer<SelectionResolutionTestCase.Builder> thiscase : cases) {
+            final SelectionResolutionTestCase.Builder localbuilder = builder.copy();
+            thiscase.accept(localbuilder);
+            System.err.println("Case " + i++);
+            System.err.println(localbuilder);
+        }
+    }
+
+    /* Create an empty class in the given package */
+    public static final ClassData emptyClass(final ClassData.Package pck) {
+        return new ClassData(pck, null);
+    }
+
+    /* These are functions that are used to build callsite templates */
+    public static void callsiteIsMethodref(final SelectionResolutionTestCase.Builder builder) {
+        builder.callsite = builder.methodref;
+    }
+
+    public static void callsiteSubclassMethodref(final SelectionResolutionTestCase.Builder builder) {
+        final int callsite =
+            builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+        builder.hier.addInherit(callsite, builder.methodref);
+        builder.callsite = callsite;
+    }
+
+    public static void callsiteUnrelatedMethodref(final SelectionResolutionTestCase.Builder builder) {
+        final int callsite =
+            builder.addClass(Template.emptyClass(ClassData.Package.SAME));
+        builder.callsite = callsite;
+    }
+
+    public static void methodrefIsExpected(final SelectionResolutionTestCase.Builder builder) {
+        builder.methodref = builder.expected;
+    }
+
+    public static final Template MethodrefEqualsExpected =
+        new Template("MethodrefEqualsExpected",
+                     Template::methodrefIsExpected);
+
+    /*****************************
+     *    Set Invoke Template    *
+     *****************************/
+
+    public static final Template SetInvoke(final SelectionResolutionTestCase.InvokeInstruction invoke) {
+        return new Template("SetInvoke(" + invoke + ")",
+                            Collections.singleton((builder) -> {
+                                    builder.invoke = invoke;
+                                }));
+    }
+
+    /*****************************
+     *   Result Combo Template   *
+     *****************************/
+    public static Template ResultCombo(final EnumSet<Kind> kinds,
+                                       final EnumSet<MethodData.Access> accesses,
+                                       final EnumSet<MethodData.Context> contexts,
+                                       final EnumSet<ClassData.Package> packages) {
+        final LinkedList<Consumer<SelectionResolutionTestCase.Builder>> cases =
+            new LinkedList<>();
+
+        for (final Kind kind : kinds) {
+            for (final MethodData.Access acc : accesses) {
+                for (final MethodData.Context ctx : contexts) {
+                    if (!(acc == MethodData.Access.PRIVATE &&
+                          ctx == MethodData.Context.ABSTRACT)) {
+                        for (final ClassData.Package pck : packages) {
+                            cases.add((builder) -> {
+                                    final MethodData meth = new MethodData(acc, ctx);
+                                    final ClassData cls = new ClassData(pck, meth);
+                                    switch(kind) {
+                                    case CLASS:
+                                        builder.expected = builder.addClass(cls);
+                                        break;
+                                    case INTERFACE:
+                                        builder.expected = builder.addInterface(cls);
+                                        break;
+                                    }
+                                });
+                        }
+                    }
+                }
+            }
+        }
+
+        return new Template("ResultCombo", cases);
+    }
+
+    public static Template ResolutionOverride(final EnumSet<Kind> kinds,
+                                              final EnumSet<MethodData.Access> accesses,
+                                              final EnumSet<MethodData.Context> contexts,
+                                              final EnumSet<ClassData.Package> packages) {
+        final LinkedList<Consumer<SelectionResolutionTestCase.Builder>> cases =
+            new LinkedList<>();
+
+        for (final Kind kind : kinds) {
+            for (final MethodData.Access acc : accesses) {
+                for (final MethodData.Context ctx : contexts) {
+                    if (!(acc == MethodData.Access.PRIVATE &&
+                          ctx == MethodData.Context.ABSTRACT)) {
+                        for (final ClassData.Package pck : packages) {
+                            cases.add((builder) -> {
+                                    final MethodData meth = new MethodData(acc, ctx);
+                                    final ClassData cls = new ClassData(pck, meth);
+                                    int override = -1;
+                                    switch(kind) {
+                                    case CLASS:
+                                        override = builder.addClass(cls);
+                                        break;
+                                    case INTERFACE:
+                                        override = builder.addInterface(cls);
+                                        break;
+                                    }
+                                    builder.hier.addInherit(override, builder.expected);
+                                });
+                        }
+                    }
+                }
+            }
+        }
+
+        return new Template("ResultCombo", cases);
+    }
+
+    /******************************
+     *    Resolution Templates    *
+     ******************************/
+
+    private static MethodData getMethodData(final MethodData.Access acc,
+                                            final MethodData.Context ctx) {
+        if (!(acc == MethodData.Access.PUBLIC ||
+              acc == MethodData.Access.PLACEHOLDER) &&
+            ctx != MethodData.Context.STATIC) {
+            return null;
+        } else {
+            return new MethodData(MethodData.Access.PUBLIC, ctx);
+        }
+    }
+
+    public static final Template MethodrefNotEqualsExpectedClass =
+        new Template("MethodrefNotEqualsExpectedClass",
+                     /* Case 1: Inherit from super.
+                      *
+                      * C2[](res)
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final int C2 = builder.expected;
+                         final int C1 = builder.addClass(emptyClass(ClassData.Package.SAME));
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 2: Inherit from super.
+                      *
+                      * C2[](res), I[](def)
+                      * C1[C2,I]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int C2 = builder.expected;
+                         final int C1 = builder.addClass(emptyClass(ClassData.Package.SAME));
+                         final int I = builder.addInterface(withDef);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C1, I);
+                         builder.methodref = C1;
+                     },
+                     /* Case 3: Inherit from super's super.
+                      *
+                      * C3[](res)
+                      * C2[](), I[](def)
+                      * C1[C2,I]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int C3 = builder.expected;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(ClassData.Package.SAME));
+                         final int I = builder.addInterface(withDef);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C1, I);
+                         builder.methodref = C1;
+                     });
+
+    public static final Template IfaceMethodrefNotEqualsExpected =
+        new Template("IfaceMethodrefNotEqualsExpected",
+                     /* Case 1: Inherit from super.
+                      *
+                      * I2[](res)
+                      * I1[I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I2 = builder.expected;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.methodref = I1;
+                     },
+                     /* Case 2: Inherit from super, skip private.
+                      *
+                      * I2[](res)
+                      * I2[I3](priv)
+                      * I1[I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef = new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.addInterface(withPrivDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = I1;
+                     },
+                     /* Case 3: Inherit from super, skip static.
+                      *
+                      * I2[](res)
+                      * I2[I3](stat)
+                      * I1[I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.addInterface(withStatDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = I1;
+                     },
+                     /* Case 4: Maximally-specific.
+                      *
+                      * I3[](def)
+                      * I2[I3](res)
+                      * I1[I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int I3 = builder.addInterface(withDef);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = I1;
+                     },
+                     /* Case 5: Diamond, expected at top.
+                      *
+                      * I4[](res)
+                      * I2[I4](), I3[I4]()
+                      * I1[I2,I3]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I4 = builder.expected;
+                         final int I3 = builder.addInterface(emptyClass(pck));
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I4);
+                         builder.hier.addInherit(I3, I4);
+                         builder.methodref = I1;
+                     },
+                     /* Case 6: Diamond, skip private.
+                      *
+                      * I4[](res)
+                      * I2[I4](priv), I3[I4]()
+                      * I1[I2,I3]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef = new ClassData(pck, meth);
+                         final int I4 = builder.expected;
+                         final int I3 = builder.addInterface(emptyClass(pck));
+                         final int I2 = builder.addInterface(withPrivDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I4);
+                         builder.hier.addInherit(I3, I4);
+                         builder.methodref = I1;
+                     },
+                     /* Case 7: Diamond, skip static.
+                      *
+                      * I4[](res)
+                      * I2[I4](stat), I3[I4]()
+                      * I1[I2,I3]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I4 = builder.expected;
+                         final int I3 = builder.addInterface(emptyClass(pck));
+                         final int I2 = builder.addInterface(withStatDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I4);
+                         builder.hier.addInherit(I3, I4);
+                         builder.methodref = I1;
+                     },
+                     /* Case 8: Diamond, maximally-specific.
+                      *
+                      * I4[](def)
+                      * I2[I4](res), I3[I4]()
+                      * I1[I2,I3]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int I4 = builder.addInterface(withDef);
+                         final int I3 = builder.addInterface(emptyClass(pck));
+                         final int I2 = builder.expected;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I4);
+                         builder.hier.addInherit(I3, I4);
+                         builder.methodref = I1;
+                     },
+                     /* Case 9: Diamond, maximally-specific, skipping private.
+                      *
+                      * I4[](def)
+                      * I2[I4](res), I3[I4](priv)
+                      * I1[I2,I3]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef = new ClassData(pck, meth);
+                         final int I4 = builder.addInterface(withDef);
+                         final int I3 = builder.addInterface(withPrivDef);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I4);
+                         builder.hier.addInherit(I3, I4);
+                         builder.methodref = I1;
+                     },
+                     /* Case 10: Diamond, maximally-specific, skipping static.
+                      *
+                      * I4[](def)
+                      * I2[I4](res), I3[I4](stat)
+                      * I1[I2,I3]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I4 = builder.addInterface(withDef);
+                         final int I3 = builder.addInterface(withStatDef);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I4);
+                         builder.hier.addInherit(I3, I4);
+                         builder.methodref = I1;
+                     });
+
+    public static final Template MethodrefNotEqualsExpectedIface =
+        new Template("MethodrefNotEqualsExpectedIface",
+                    /* Case 1: Inherit from superinterface.
+                     *
+                     * I[](res)
+                     * C[I]() = mref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.expected).packageId;
+                        final int I = builder.expected;
+                        final int C = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C, I);
+                        builder.methodref = C;
+                     },
+                     /* Case 2: Diamond, expected at top.
+                      *
+                      * I3[](res)
+                      * I1[I3](), I2[I3]()
+                      * C[I1,I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I3 = builder.expected;
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = C;
+                     },
+                     /* Case 3: Diamond, skipping private.
+                      *
+                      * I3[](def)
+                      * I1[I3](priv), I2[I3]()
+                      * C[I1,I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef = new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(withPrivDef);
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = C;
+                     },
+                     /* Case 4: Diamond, skipping static.
+                      *
+                      * I3[](def)
+                      * I1[I3](stat), I2[I3]()
+                      * C[I1,I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(withStatDef);
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = C;
+                     },
+                     /* Case 5: Diamond, maximally-specific.
+                      *
+                      * I3[](def)
+                      * I1[I3](res), I2[I3]()
+                      * C[I1,I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int I3 = builder.addInterface(withDef);
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.expected;
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = C;
+                     },
+                     /* Case 6: Diamond, maximally-specific, skipping private.
+                      *
+                      * I3[](def)
+                      * I1[I3](res), I2[I3](priv)
+                      * C[I1,I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef = new ClassData(pck, meth);
+                         final int I3 = builder.addInterface(withDef);
+                         final int I2 = builder.addInterface(withPrivDef);
+                         final int I1 = builder.expected;
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = C;
+                     },
+                     /* Case 7: Diamond, maximally-specific, skipping static.
+                      *
+                      * I3[](def)
+                      * I1[I3](res), I2[I3](stat)
+                      * C[I1,I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I3 = builder.addInterface(withDef);
+                         final int I2 = builder.addInterface(withStatDef);
+                         final int I1 = builder.expected;
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.methodref = C;
+                     },
+                     /* Case 8: Diamond, with superclass, expected at top.
+                      *
+                      * I2[](res)
+                      * C2[I2](), I1[I2]()
+                      * C1[I1,C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I2 = builder.expected;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addInterface(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 9: Diamond with superclass, maximally-specific.
+                      *
+                      * I2[](def)
+                      * C2[I2](), I1[I2](res),
+                      * C1[I1,C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int I2 = builder.addInterface(withDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int I1 = builder.expected;
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 10: Inherit through superclass.
+                      *
+                      * I[](res)
+                      * C2[I]()
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I = builder.expected;
+                         final int C2 = builder.addInterface(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.methodref = C1;
+                     },
+                     /* Case 11: Diamond, inherit through superclass,
+                      * expected at top.
+                      *
+                      * I3[](res)
+                      * I1[I3](), I2[I3]()
+                      * C2[I1,I2]()
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I3 = builder.expected;
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 12: Diamond through superclass, skip private.
+                      *
+                      * I3[](res)
+                      * I1[I3](priv), I2[I3]()
+                      * C2[I1,I2]()
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef = new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(withPrivDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 13: Diamond through superclass, skip static.
+                      *
+                      * I3[](def)
+                      * I1[I3](stat), I2[I3]()
+                      * C2[I1,I2]()
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(withStatDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 14: Diamond through superclass, maximally-specific.
+                      *
+                      * I3[](def)
+                      * I1[I3](res), I2[I3]()
+                      * C2[I1,I2]()
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int I3 = builder.addInterface(withDef);
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.expected;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 15: Diamond through superclass,
+                      * maximally-specific, skip private.
+                      *
+                      * I3[](def)
+                      * I1[I3](res), I2[I3](priv)
+                      * C2[I1,I2]()
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef = new ClassData(pck, meth);
+                         final int I3 = builder.addInterface(withDef);
+                         final int I2 = builder.addInterface(withPrivDef);
+                         final int I1 = builder.expected;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 16: Diamond through superclass,
+                      * maximally-specific, skip static.
+                      *
+                      * I3[](pub)
+                      * I1[I3](res), I2[I3](stat)
+                      * C2[I1,I2]()
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I3 = builder.addInterface(withDef);
+                         final int I2 = builder.addInterface(withStatDef);
+                         final int I1 = builder.expected;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 17: Diamond, with superclass, inherit through
+                      * superclass, expected at top.
+                      *
+                      * I2[](res)
+                      * C3[I2](), I1[I2]()
+                      * C2[I1,C3]()
+                      * C1[C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I2 = builder.expected;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C3 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C3, I2);
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     },
+                     /* Case 18: Diamond, with superclass, inherit through
+                      * superclass, maximally-specific.
+                      *
+                      * I2[](def)
+                      * C3[I2](), I1[I2](res),
+                      * C2[I1,C3]()
+                      * C1[I1,C2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Context ctx =
+                             builder.classdata.get(builder.expected).methoddata.context;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata = getMethodData(acc, ctx);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int I2 = builder.addInterface(withDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int I1 = builder.expected;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C3, I2);
+                         builder.hier.addInherit(C1, C2);
+                         builder.methodref = C1;
+                     });
+
+    public static final Template IfaceMethodrefAmbiguous =
+        new Template("IfaceMethodrefAmbiguous",
+                     /* Ambiguous.
+                      *
+                      * I2[](def), I3[](def)
+                      * I1[I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData expected =
+                             builder.classdata.get(builder.expected);
+                         final int I3 = builder.addInterface(expected);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.methodref = I1;
+                     });
+
+    public static final Template MethodrefAmbiguous =
+        new Template("MethodrefAmbiguous",
+                     /* Ambiguous.
+                      *
+                      * I1[](def), I2[](def)
+                      * C[I2]() = mref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData expected =
+                             builder.classdata.get(builder.expected);
+                         final int I1 = builder.addInterface(expected);
+                         final int I2 = builder.expected;
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(C, I1);
+                         builder.methodref = C;
+                     });
+
+    /******************************
+     *     Callsite Templates     *
+     ******************************/
+
+    public static final Template AllCallsiteCases =
+        new Template("AllCallsiteCases",
+                     Template::callsiteIsMethodref,
+                     Template::callsiteSubclassMethodref,
+                     Template::callsiteUnrelatedMethodref);
+
+    public static final Template InvokespecialCallsiteCases =
+        new Template("InvokespecialCallsiteCases",
+                     Template::callsiteIsMethodref,
+                     Template::callsiteSubclassMethodref);
+
+    public static final Template CallsiteEqualsMethodref =
+        new Template("CallsiteEqualsMethodref",
+                     Template::callsiteIsMethodref);
+
+    public static final Template CallsiteSubclassMethodref =
+        new Template("CallsiteSubclassMethodref",
+                     Template::callsiteSubclassMethodref);
+
+    public static final Template CallsiteUnrelatedToMethodref =
+        new Template("CallsiteUnrelatedToMethodref",
+                     Template::callsiteUnrelatedMethodref);
+
+    public static final Template CallsiteNotEqualsMethodref =
+        new Template("CallsiteNotEqualsMethodref",
+                     Template::callsiteSubclassMethodref,
+                     Template::callsiteUnrelatedMethodref);
+
+    /*********************************
+     * AbstractMethodError Templates *
+     *********************************/
+
+    public static final Template ReabstractExpectedIface =
+        new Template("ReabstractExpectedIface",
+                     (builder) -> {},
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData expected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData.Package pck = expected.packageId;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata =
+                             getMethodData(acc, MethodData.Context.STATIC);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int C2 = builder.addInterface(withDef);
+                         final int C1 = builder.expected;
+                         builder.hier.addInherit(C1, C2);
+                     },
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData expected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData.Package pck = expected.packageId;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata =
+                             getMethodData(acc, MethodData.Context.INSTANCE);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int C2 = builder.addInterface(withDef);
+                         final int C1 = builder.expected;
+                         builder.hier.addInherit(C1, C2);
+                     });
+
+    public static final Template ReabstractExpectedClass =
+        new Template("ReabstractExpectedClass",
+                     ReabstractExpectedIface,
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData expected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData.Package pck = expected.packageId;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata =
+                             getMethodData(acc, MethodData.Context.STATIC);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.expected;
+                         builder.hier.addInherit(C1, C2);
+                     },
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData expected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData.Package pck = expected.packageId;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final MethodData mdata =
+                             getMethodData(acc, MethodData.Context.INSTANCE);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.expected;
+                         builder.hier.addInherit(C1, C2);
+                     });
+
+    public static final Template ReabstractMethodrefResolvedClass =
+        new Template("ReabstractMethodrefResolvedClass",
+                    /* Case 1: Objectref overrides.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2](res) = oref = expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C1;
+                    },
+                    /* Case 2: Objectref's super overrides.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 3: Objectref's super overrides, skip private.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef = new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 4: Objectref's super overrides, skip static.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2](stat) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef = new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withStatDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    });
+
+    public static final Template ReabstractMethodrefResolvedIface =
+        new Template("ReabstractMethodrefResolvedIface",
+                    /* Case 1: Objectref overrides.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2](res) = oref = expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C1;
+                    },
+                    /* Case 2: Objectref's super overrides.
+                     *
+                     * C3[](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 3: Objectref's super overrides, skip private.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef = new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 4: Objectref's super overrides, skip static.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2](stat) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef = new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withStatDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 5: Overlapping with new interface overriding.
+                     *
+                     * I2[*](def) = old expected
+                     * C2[*](*) = mref, I1[I2](res) = expected
+                     * C1[C2,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C2 = builder.methodref;
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                        builder.expected = I1;
+                    },
+                    /* Case 6: Overlapping with new interface, skip private.
+                     *
+                     * I2[*](def) = old expected
+                     * C2[*](*) = mref, I1[I2](res) = expected
+                     * C1[C2,I2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef = new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                        builder.expected = I1;
+                    },
+                    /* Case 7: Overlapping with new interface, skip static.
+                     *
+                     * I2[*](def) = old expected
+                     * C2[*](*) = mref, I1[I2](res) = expected
+                     * C1[C2,I2](stat) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef = new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(withStatDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                        builder.expected = I1;
+                    },
+                    /* Case 8: Overlap with objectref's super with new
+                     * interface overriding, inherit through class.
+                     *
+                     * I2[*](def) = old expected
+                     * C3[](*) = mref, I1[I2](res) = expected
+                     * C2[C3,I1]()
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C2, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                        builder.expected = I1;
+                    },
+                    /* Case 9: Overlap with objectref's super with new
+                     * interface double diamond, overriding.
+                     *
+                     * I3[*](def) = old expected
+                     * C3[](*) = mref, I2[I3](def)
+                     * C2[C3,I2](), I1[I2](res) = expected
+                     * C1[C2,I1]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I3 = builder.expected;
+                        final int I2 = builder.addInterface(withDef);
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(C2, I2);
+                        builder.hier.addInherit(I1, I2);
+                        builder.hier.addInherit(I2, I3);
+                        builder.objectref = C1;
+                        builder.expected = I1;
+                    },
+                    /* Case 10: Overlap with objectref's super with new
+                     * interface double diamond, skip private.
+                     *
+                     * I3[*](def) = old expected
+                     * C3[](*) = mref, I2[I3](res) = expected
+                     * C2[C3,I2](), I1[I2](priv)
+                     * C1[C2,I1]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef = new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I3 = builder.expected;
+                        final int I2 = builder.addInterface(withDef);
+                        final int I1 = builder.addInterface(withPrivDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(C2, I2);
+                        builder.hier.addInherit(I1, I2);
+                        builder.hier.addInherit(I2, I3);
+                        builder.objectref = C1;
+                        builder.expected = I2;
+                    },
+                    /* Case 11: Overlap with objectref's super with new
+                     * interface double diamond, skip static.
+                     *
+                     * I3[*](def) = old expected
+                     * C3[](*) = mref, I2[I3](res) = expected
+                     * C2[C3,I2](), I1[I2](stat)
+                     * C1[C2,I1]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef = new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I3 = builder.expected;
+                        final int I2 = builder.addInterface(withDef);
+                        final int I1 = builder.addInterface(withStatDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(C2, I2);
+                        builder.hier.addInherit(I1, I2);
+                        builder.hier.addInherit(I2, I3);
+                        builder.objectref = C1;
+                        builder.expected = I2;
+                    },
+                    /* Case 12: Objectref's super overrides, skip interface below.
+                     *
+                     * C3[](*) = mref
+                     * C2[C3](res) = expected, I[](def)
+                     * C1[C2,I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        final int I = builder.addInterface(withDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 13: Objectref's super overrides, skip interface above.
+                     *
+                     * C3[](*) = mref, I[](def)
+                     * C2[C3,I](res) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        final int I = builder.addInterface(withDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C2, I);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    });
+
+    public static final Template ReabstractIfaceMethodrefResolved =
+        new Template("ReabstractIfaceMethodrefResolved",
+                     /* Case 1: Objectref overrides.
+                      *
+                      * I[](*) = mref
+                      * C[I](res) = oref = expected
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final int I = builder.methodref;
+                         final int C = builder.addClass(withDef);
+                         builder.hier.addInherit(C, I);
+                         builder.objectref = C;
+                         builder.expected = C;
+                     },
+                     /* Case 2: Diamond, methodref at top, overriding.
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3](res) = expected
+                      * C[I1,I2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.objectref = C;
+                         builder.expected = I2;
+                     },
+                     /* Case 3: Diamond, methodref at top, skip static.
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3](res) = expected
+                      * C[I1,I2](stat) = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C = builder.addClass(withStatDef);
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.objectref = C;
+                         builder.expected = I2;
+                     },
+                     /* Case 4: Diamond, with superclass, methodref at top,
+                      * class overriding.
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](res) = expected, I1[I2]()
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 5: Diamond, with superclass, methodref at top,
+                      * class overriding, skip static.
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](res) = expected, I1[I2]()
+                      * C1[I1,C2](stat) = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final ClassData withDef =
+                            new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(withStatDef);
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 6: Diamond, with superclass, expected at top,
+                      * interface overriding
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](), I1[I2](res) = expected
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = I1;
+                     },
+                     /* Case 7: Diamond, with superclass, expected at top,
+                      * interface skip static
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](), I1[I2](res) = expected
+                      * C1[I1,C2](stat) = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(withStatDef);
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = I1;
+                     },
+                     /* Case 8: Y, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * C2[I2](res) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 9: Diamond, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * I2[](def) = old expected
+                      * C2[I2](res) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 10: Diamond, with superclass, overlaping, expected
+                      * at top, class overrides, skipping static
+                      *
+                      * I2[](def) = old expected
+                      * C2[I2](res) = expected, I1[](*) = mref
+                      * C1[I1,C2](stat) = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(withStatDef);
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 11: Superclass overrides.
+                      *
+                      * I[](*) = mref
+                      * C2[I](res) = expected
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final int I = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.objectref = C1;
+                     },
+                     /* Case 12: Superclass overrides, skipping static.
+                      *
+                      * I[](*) = mref
+                      * C2[I](res) = expected
+                      * C1[C2](stat) = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(withStatDef);
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.objectref = C1;
+                     },
+                     /* Case 13: Double diamond, with superclass, inherit through
+                      * superclass, expected at top.
+                      *
+                      * I3[](def) = old expected
+                      * C3[I3](), I2[*](*) = mref
+                      * C2[I2,C3](), I1[I2](res) = expected
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                         builder.expected = I1;
+                     },
+                     /* Case 14: Double diamond, with superclass, inherit through
+                      * superclass, expected at top.
+                      *
+                      * I3[](def) = mref
+                      * C3[I3](), I2[*](*) = expected
+                      * C2[I2,C3](), I1[I2](priv)
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef = new ClassData(pck, meth);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withDef);
+                         final int I1 = builder.addInterface(withPrivDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                         builder.expected = I2;
+                     },
+                     /* Case 15: Double diamond, with superclass, inherit through
+                      * superclass, expected at top.
+                      *
+                      * I3[](def) = mref
+                      * C3[I3](), I2[*](*) = expected
+                      * C2[I2,C3](), I1[I2](stat)
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData.Access acc =
+                             builder.classdata.get(builder.expected).methoddata.access;
+                         final ClassData withDef =
+                             new ClassData(pck, new MethodData(acc, MethodData.Context.ABSTRACT));
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef = new ClassData(pck, meth);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withDef);
+                         final int I1 = builder.addInterface(withStatDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                         builder.expected = I2;
+                     });
+
+    /******************************
+     *    Abstract Overrides      *
+     ******************************/
+
+    public static final Template OverrideAbstractExpectedIface =
+        Template.ResolutionOverride(EnumSet.of(Template.Kind.INTERFACE),
+                                    EnumSet.of(MethodData.Access.PUBLIC),
+                                    EnumSet.allOf(MethodData.Context.class),
+                                    EnumSet.of(ClassData.Package.SAME));
+
+    public static final Template OverrideAbstractExpectedClass =
+        Template.ResolutionOverride(EnumSet.allOf(Template.Kind.class),
+                                    EnumSet.of(MethodData.Access.PUBLIC),
+                                    EnumSet.allOf(MethodData.Context.class),
+                                    EnumSet.of(ClassData.Package.SAME));
+
+    public static final Template SelectionOverrideAbstract =
+        new Template("SelectionOverrideAbstract",
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData expected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData olddef =
+                             expected.methoddata;
+                         if (MethodData.Context.ABSTRACT == olddef.context) {
+                             final ClassData.Package pck = expected.packageId;
+                             final MethodData.Access acc = olddef.access;
+                             final MethodData mdata =
+                                 getMethodData(MethodData.Access.PUBLIC,
+                                               MethodData.Context.INSTANCE);
+                             final ClassData withDef = new ClassData(pck, mdata);
+                             final int C2 = builder.objectref;
+                             final int C1 = builder.addClass(withDef);
+                             builder.hier.addInherit(C1, C2);
+                             builder.objectref = C1;
+                             builder.expected = C1;
+                         }
+                     });
+
+
+    /******************************
+     * Ignored Abstract Templates *
+     ******************************/
+
+    public static final Template IgnoredAbstract =
+        new Template("IgnoredAbstract",
+                     (builder) -> {},
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData methodref =
+                             builder.classdata.get(builder.methodref);
+                         final ClassData.Package pck = methodref.packageId;
+                         final MethodData mdata =
+                             getMethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.ABSTRACT);
+                         final ClassData withDef = new ClassData(pck, mdata);
+                         final int C2 = builder.addInterface(withDef);
+                         final int C1 = builder.methodref;
+                         builder.hier.addInherit(C1, C2);
+                     });
+
+    /******************************
+     *     Selection Templates    *
+     ******************************/
+
+
+
+    public static final Template TrivialObjectref =
+        new Template("TrivialObjectref",
+                     Collections.singleton((builder) -> {
+                             builder.objectref = builder.methodref;
+                         }));
+
+    public static final Template TrivialObjectrefNotEqualMethodref =
+        new Template("TrivialObjectrefNotEqualMethodref",
+                     Collections.singleton(
+                         (final SelectionResolutionTestCase.Builder builder) -> {
+                             final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                             final ClassData.Package pck = oldexpected.packageId;
+                             final int C2 = builder.methodref;
+                             final int C1 = builder.addClass(emptyClass(pck));
+                             builder.hier.addInherit(C1, C2);
+                             builder.objectref = C1;
+                         }));
+
+    public static final Template MethodrefSelectionResolvedIsClassNoOverride =
+        new Template("MethodrefSelectionResolvedIsClassNoOverride",
+                    /* Trivial.
+                     *
+                     * C[](*) = mref = oref
+                     */
+                    (builder) -> {
+                        builder.objectref = builder.methodref;
+                    },
+                    /* Case 1: Inherit from super.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 2: Objectref has private def.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef = new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 3: Objectref has static def.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2](stat) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withDef = new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 4: Skip inherit from interface.
+                     *
+                     * C2[](*) = mref, I[](def)
+                     * C1[C2,I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData.Package pck = oldexpected.packageId;
+                        final MethodData.Context ctx =
+                            builder.classdata.get(builder.expected).methoddata.context;
+                        final MethodData.Access acc =
+                            builder.classdata.get(builder.expected).methoddata.access;
+                        final MethodData mdata = getMethodData(acc, ctx);
+                        final ClassData withDef = new ClassData(pck, mdata);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        final int I = builder.addInterface(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.objectref = C1;
+                    },
+                    /* Case 5: Objectref's super has a private def.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 6: Objectref's super has a static def.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    });
+
+    public static final Template MethodrefSelectionResolvedIsClassOverride =
+        new Template("MethodrefSelectionResolvedIsClassOverride",
+                    /* Case 7: Objectref overrides.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2](res) = oref = expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C1;
+                    },
+                    /* Case 8: Objectref's super overrides.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res)
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 9: Objectref's super overrides,
+                     *         objectref has a private def.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res)
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 10: Objectref's super overrides,
+                     *          objectref has a static def.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](res)
+                     * C1[C2](stat) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    });
+
+    public static final Template MethodrefSelectionResolvedIsClass =
+        new Template("MethodrefSelectionResolvedIsClass",
+                     MethodrefSelectionResolvedIsClassNoOverride,
+                     MethodrefSelectionResolvedIsClassOverride);
+
+    public static final Template MethodrefSelectionPackageSkipNoOverride =
+        new Template("MethodrefSelectionPackageSkipNoOverride",
+                     MethodrefSelectionResolvedIsClass,
+                    /* Case 11: Objectref has public def in other package.
+                     *
+                     * C2[](*) = mref
+                     * Other.C1[C2](pub) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 12: Objectref has package private def in other package.
+                     *
+                     * C2[](*) = mref
+                     * Other.C1[C2](pack) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PACKAGE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 13: Objectref has protected def in other package.
+                     *
+                     * C2[](*) = mref
+                     * Other.C1[C2](prot) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PROTECTED,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 14: Objectref's super has a public def in other package.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](pub) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 15: Objectref's super has a package
+                     * private def in other package.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](pack) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PACKAGE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 16: Objectref's super has a protected def
+                     * in other package.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](pack) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PROTECTED,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 18: Objectref's has a public def in other
+                     * package, skip private.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](priv)
+                     * C1[C2](pub) = oref, expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final MethodData privmeth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, privmeth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withPrivDef);
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 19: Objectref's has a package private def in other
+                     * package, skip private.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](priv)
+                     * C1[C2](pack) = oref, expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PACKAGE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final MethodData privmeth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, privmeth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withPrivDef);
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 20: Objectref's has a protected def in other
+                     * package, skip private.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](priv)
+                     * C1[C2](pro) = oref, expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PROTECTED,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final MethodData privmeth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, privmeth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withPrivDef);
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 21: Objectref's super has a public def in other
+                     * package, skip private.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](pub) = expected
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final MethodData privmeth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, privmeth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 22: Objectref's superhas a package private
+                     * def in other package, skip private.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](pack) = expected
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PACKAGE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final MethodData privmeth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, privmeth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 23: Objectref's super has a protected def
+                     * in other package, skip private.
+                     *
+                     * C3[*](*) = mref
+                     * Other.C2[C3](pro) = expected
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PROTECTED,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(ClassData.Package.OTHER, meth);
+                        final MethodData privmeth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, privmeth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withPrivDef);
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    });
+
+    public static final Template MethodrefSelectionPackageSkip =
+        new Template("MethodrefSelectionPackageSkip",
+                     MethodrefSelectionPackageSkipNoOverride,
+                    /* Case 17: Transitive override.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](pub)
+                     * Other.C1[C2](pack) = oref, expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.INSTANCE);
+                        final MethodData packmeth =
+                            new MethodData(MethodData.Access.PACKAGE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPubDef = new ClassData(pck, meth);
+                        final ClassData withPackDef =
+                            new ClassData(ClassData.Package.OTHER, packmeth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withPubDef);
+                        final int C1 = builder.addClass(withPackDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C1;
+                    },
+                    /* Case 24: Transitive override, skip private in between.
+                     *
+                     * C4[*](*) = mref
+                     * C3[C4](pub)
+                     * C2[C3](priv)
+                     * Other.C1[C2](pack) = oref, expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.INSTANCE);
+                        final MethodData packmeth =
+                            new MethodData(MethodData.Access.PACKAGE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPubDef = new ClassData(pck, meth);
+                        final ClassData withPackDef =
+                            new ClassData(ClassData.Package.OTHER, packmeth);
+                        final MethodData privmeth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, privmeth);
+                        final int C4 = builder.methodref;
+                        final int C3 = builder.addClass(withPubDef);
+                        final int C2 = builder.addClass(withPrivDef);
+                        final int C1 = builder.addClass(withPackDef);
+                        builder.hier.addInherit(C3, C4);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C1;
+                    },
+                    /* Case 25: Transitive override, skip private in between.
+                     *
+                     * C4[*](*) = mref
+                     * C3[C4](pub)
+                     * Other.C2[C3](pack) = expected
+                     * C1[C2](pack) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.INSTANCE);
+                        final MethodData packmeth =
+                            new MethodData(MethodData.Access.PACKAGE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPubDef = new ClassData(pck, meth);
+                        final ClassData withPackDef =
+                            new ClassData(ClassData.Package.OTHER, packmeth);
+                        final MethodData privmeth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, privmeth);
+                        final int C4 = builder.methodref;
+                        final int C3 = builder.addClass(withPubDef);
+                        final int C2 = builder.addClass(withPackDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C3, C4);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C2;
+                        builder.expected = C2;
+                    });
+
+    public static final Template MethodrefSelectionResolvedIsIfaceNoOverride =
+        new Template("MethodrefSelectionResolvedIsIfaceNoOverride",
+                    /* Trivial objectref.
+                     *
+                     * C[](*) = mref = oref
+                     */
+                    (builder) -> {
+                        builder.objectref = builder.methodref;
+                    },
+                    /* Case 1: Inherit from super.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 2: Objectref has private def.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef = new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 3: Objectref has static def.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2](stat) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withDef = new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 4: Overlapping.
+                     *
+                     * I[*](res) = expected
+                     * C2[*](*) = mref
+                     * C1[C2,I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final int C2 = builder.methodref;
+                        final int I = builder.expected;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.objectref = C1;
+                    },
+                    /* Case 5: Overlapping with new interface.
+                     *
+                     * I2[*](res) = expected
+                     * C2[*](*) = mref, I1[I2]()
+                     * C1[C2,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final int C2 = builder.methodref;
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(emptyClass(pck));
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 6: Overlapping with new interface with private def.
+                     *
+                     * I2[*](res) = expected
+                     * C2[*](*) = mref, I1[I2](priv)
+                     * C1[C2,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withPrivDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 7: Overlapping with new interface with static def.
+                     *
+                     * I2[*](res) = expected
+                     * C2[*](*) = mref, I1[I2](stat)
+                     * C1[C2,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef =
+                            new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withStatDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 8: Objectref's super has a private def.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](priv)
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 9: Objectref's super has a static def.
+                     *
+                     * C3[*](*) = mref
+                     * C2[C3](stat)
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 10: Overlap with objectref's super.
+                     *
+                     * I[*](res) = expected
+                     * C3[](*) = mref
+                     * C2[C3,I]()
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I = builder.expected;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C2, I);
+                        builder.objectref = C1;
+                    },
+                    /* Case 11: Overlap with objectref's super with new interface.
+                     *
+                     * I2[*](res) = expected
+                     * C3[](*) = mref, I1[I2]()
+                     * C2[C3,I1]()
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(emptyClass(pck));
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C2, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 12: Overlap with objectref's super with new
+                     * interface with private def.
+                     *
+                     * I2[*](res) = expected
+                     * C3[](*) = mref, I1[I2](priv)
+                     * C2[C3,I1]()
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withPrivDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C2, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 13: Overlap with objectref's super with new
+                     * interface with static def.
+                     *
+                     * I2[*](res) = expected
+                     * C3[](*) = mref, I1[I2](stat)
+                     * C2[C3,I1]()
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withStatDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C2, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 14: Overlap with objectref's super with new
+                     * interface double diamond.
+                     *
+                     * I3[*](res) = expected
+                     * C3[](*) = mref, I2[I3]()
+                     * C2[C3,I2](), I1[I2]()
+                     * C1[C2,I1]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I3 = builder.expected;
+                        final int I2 = builder.addInterface(emptyClass(pck));
+                        final int I1 = builder.addInterface(emptyClass(pck));
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(C2, I2);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                    },
+                    /* Case 15: Overlapping with new interface with private def.
+                     *
+                     * C2[*](*) = mref, I1[](priv)
+                     * C1[C2,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int I1 = builder.addInterface(withPrivDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.objectref = C1;
+                    },
+                    /* Case 16: Overlapping with new interface with static def.
+                     *
+                     * C2[*](*) = mref, I1[](stat)
+                     * C1[C2,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef =
+                            new ClassData(pck, meth);
+                        final int C2 = builder.methodref;
+                        final int I1 = builder.addInterface(withStatDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.objectref = C1;
+                    });
+
+    public static final Template MethodrefSelectionResolvedIsIface =
+        new Template("MethodrefSelectionResolvedIsIface",
+                     MethodrefSelectionResolvedIsIfaceNoOverride,
+                    /* Case 17: Objectref overrides.
+                     *
+                     * C2[](*) = mref
+                     * C1[C2](res) = oref = expected
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C1;
+                    },
+                    /* Case 18: Overlapping with new interface overriding.
+                     *
+                     * I2[*](def) = old expected
+                     * C2[*](*) = mref, I1[I2](res) = expected
+                     * C1[C2,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C2 = builder.methodref;
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                        builder.expected = I1;
+                    },
+                    /* Case 19: Objectref's super overrides.
+                     *
+                     * C3[](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 20: Overlap with objectref's super with
+                     * new interface overriding.
+                     *
+                     * I2[*](def) = old expected
+                     * C3[](*) = mref, I1[I2](res) = expected
+                     * C2[C3,I1]()
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I2 = builder.expected;
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C2, I1);
+                        builder.hier.addInherit(I1, I2);
+                        builder.objectref = C1;
+                        builder.expected = I1;
+                    },
+                    /* Case 21: Overlap with objectref's super with new
+                     * interface double diamond, overriding.
+                     *
+                     * I3[*](def) = old expected
+                     * C3[](*) = mref, I2[I3](def)
+                     * C2[C3,I2](), I1[I2](res) = expected
+                     * C1[C2,I1]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I3 = builder.expected;
+                        final int I2 = builder.addInterface(withDef);
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(C2, I2);
+                        builder.hier.addInherit(I1, I2);
+                        builder.hier.addInherit(I2, I3);
+                        builder.objectref = C1;
+                        builder.expected = I1;
+                    },
+                    /* Case 22: Objectref's super overrides, skip private.
+                     *
+                     * C3[](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2](priv) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, meth);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withPrivDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 23: Objectref's super overrides, skip static.
+                     *
+                     * C3[](*) = mref
+                     * C2[C3](res) = expected
+                     * C1[C2](stat) = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef =
+                            new ClassData(pck, meth);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(withStatDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 24: Overlap with objectref's super with new
+                     * interface double diamond, overriding, skip private.
+                     *
+                     * I3[*](def) = old expected
+                     * C3[](*) = mref, I2[I3](res) = expected
+                     * C2[C3,I2](), I1[I2](priv)
+                     * C1[C2,I1]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PRIVATE,
+                                           MethodData.Context.INSTANCE);
+                        final ClassData withPrivDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I3 = builder.expected;
+                        final int I2 = builder.addInterface(withDef);
+                        final int I1 = builder.addInterface(withPrivDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(C2, I2);
+                        builder.hier.addInherit(I1, I2);
+                        builder.hier.addInherit(I2, I3);
+                        builder.objectref = C1;
+                        builder.expected = I2;
+                    },
+                    /* Case 25: Overlap with objectref's super with new
+                     * interface double diamond, overriding, skip static.
+                     *
+                     * I3[*](def) = old expected
+                     * C3[](*) = mref, I2[I3](res) = expected
+                     * C2[C3,I2](), I1[I2](stat)
+                     * C1[C2,I1]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final MethodData meth =
+                            new MethodData(MethodData.Access.PUBLIC,
+                                           MethodData.Context.STATIC);
+                        final ClassData withStatDef =
+                            new ClassData(pck, meth);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int I3 = builder.expected;
+                        final int I2 = builder.addInterface(withDef);
+                        final int I1 = builder.addInterface(withStatDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(C2, I2);
+                        builder.hier.addInherit(I1, I2);
+                        builder.hier.addInherit(I2, I3);
+                        builder.objectref = C1;
+                        builder.expected = I2;
+                    },
+                    /* Case 26: Skip interface method after class overrides.
+                     *
+                     * C3[](*) = mref
+                     * C2[C3](res) = expected, I[](def)
+                     * C1[C2, I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        final int I = builder.addInterface(withDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 27: Skip interface method after class overrides.
+                     *
+                     * C3[](*) = mref, I[](def)
+                     * C2[C3,I](res) = expected
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        final int I = builder.addInterface(withDef);
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C2, I);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    },
+                    /* Case 28: Overlap with objectref's super with new
+                     * interface double diamond, overriding.
+                     *
+                     * I3[*](def) = old expected
+                     * C3[](*) = mref, I2[I3](def)
+                     * C2[C3,I2](res) = expected, I1[I2](def) = expected
+                     * C1[C2,I1]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                        final int C3 = builder.methodref;
+                        final int C2 = builder.addClass(withDef);
+                        final int I3 = builder.expected;
+                        final int I2 = builder.addInterface(withDef);
+                        final int I1 = builder.addInterface(withDef);
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I1);
+                        builder.hier.addInherit(C2, I2);
+                        builder.hier.addInherit(I1, I2);
+                        builder.hier.addInherit(I2, I3);
+                        builder.objectref = C1;
+                        builder.expected = C2;
+                    });
+
+    public static final Template IfaceMethodrefSelectionNoOverride =
+        new Template("IfaceMethodrefSelectionNoOverride",
+                     /* Case 1: Inherit from super.
+                      *
+                      * I[](*) = mref
+                      * C[I]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.methodref).packageId;
+                         final int I = builder.methodref;
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I);
+                         builder.objectref = C;
+                     },
+                     /* Case 2: Objectref has static def
+                      *
+                      * I[](*) = mref
+                      * C[I](stat) = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.methodref).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C = builder.addClass(withStatDef);
+                         builder.hier.addInherit(C, I);
+                         builder.objectref = C;
+                     },
+                     /* Case 3: Diamond, methodref at top.
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3]()
+                      * C[I1,I2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.objectref = C;
+                     },
+                     /* Case 4: Diamond, methodref at top, skip private def
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3](priv)
+                      * C[I1,I2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef =
+                             new ClassData(pck, meth);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withPrivDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.objectref = C;
+                     },
+                     /* Case 5: Diamond, methodref at top, skip static def
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3](stat)
+                      * C[I1,I2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withStatDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.objectref = C;
+                     },
+                     /* Case 6: Diamond, overlap with resolution.
+                      *
+                      * I3[](res) = expected
+                      * I1[I3](), I2[](*) = mref
+                      * C[I1,I2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.objectref = C;
+                     },
+                     /* Case 7: Diamond, with superclass, expected at top.
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](), I1[I2]()
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 8: Diamond, with superclass, expected at top,
+                      * class has static def.
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](stat), I1[I2]()
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(withStatDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 9: Diamond, with superclass, expected at top,
+                      * interface has private def
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](), I1[I2](priv)
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withPrivDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 10: Diamond, with superclass, expected at top,
+                      * interface has static def
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](), I1[I2](stat)
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withPrivDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withPrivDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 11: Y, with superclass, expected
+                      * at top.
+                      *
+                      * C2[](), I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 12: Y, with superclass, expected
+                      * at top, class has static def
+                      *
+                      * C2[](stat), I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 13: Diamond, with superclass, overlapping, expected
+                      * at top.
+                      *
+                      * I2[](res) = expected
+                      * C2[I2](), I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 14: Diamond, with superclass, overlapping, expected
+                      * at top, class has static def
+                      *
+                      * I2[](def) = expected
+                      * C2[I2](stat), I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withStatDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 15: Inherit through superclass.
+                      *
+                      * I[](*) = mref
+                      * C2[I]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I = builder.methodref;
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.objectref = C1;
+                     },
+                     /* Case 16: Superclass has static def.
+                      *
+                      * I[](*) = mref
+                      * C2[I](stat) = expected
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C2 = builder.addClass(withStatDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.objectref = C1;
+                     },
+                     /* Case 17: Diamond, inherit through superclass,
+                      * methodref at top.
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3]()
+                      * C2[I1,I2]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(emptyClass(pck));
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 18: Diamond, with superclass, inherit through
+                      * superclass, methodref at top.
+                      *
+                      * I2[](*) = mref
+                      * C3[I2](), I1[I2]()
+                      * C2[I1,C3]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C3, I2);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 19: Diamond, inherit through superclass,
+                      * expected at top, skip private.
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3](priv)
+                      * C2[I1,I2]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef =
+                             new ClassData(pck, meth);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withPrivDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 20: Diamond, inherit through superclass,
+                      * expected at top, skip static.
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3](stat)
+                      * C2[I1,I2]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withStatDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 21: Diamond, inherit through superclass,
+                      * overlapping, expected at top.
+                      *
+                      * I3[](res) = expected
+                      * I1[I3](), I2[*](*) = mref
+                      * C2[I1,I2]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 22: Y, with superclass, inherit through
+                      * superclass, expected at top.
+                      *
+                      * C3[](), I1[*](*) = mref
+                      * C2[I1,C3]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I1 = builder.methodref;
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 23: Diamond, with superclass, inherit through
+                      * superclass, overlapping, expected at top.
+                      *
+                      * I2[](res) = expected
+                      * C3[I2](), I1[*](*) = mref
+                      * C2[I1,C3]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I2);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                     },
+                     /* Case 24: Double diamond, with superclass, inherit through
+                      * superclass, overlapping expected at top.
+                      *
+                      * I3[](res) = expected
+                      * C3[I3](), I2[*](*) = mref
+                      * C2[I2,C3](), I1[I2]()
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                     },
+                     /* Case 25: Double diamond, with superclass, inherit through
+                      * superclass, skip private.
+                      *
+                      * I3[](def) = old expected
+                      * C3[I3](), I2[*](*) = mref
+                      * C2[I2,C3](), I1[I2](priv)
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef =
+                             new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withPrivDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                     },
+                     /* Case 26: Double diamond, with superclass, inherit through
+                      * superclass, skip static.
+                      *
+                      * I3[](def) = old expected
+                      * C3[I3](), I2[*](*) = mref
+                      * C2[I2,C3](), I1[I2](stat)
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withStatDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                     });
+
+    public static final Template IfaceMethodrefSelection =
+        new Template("IfaceMethodrefSelection",
+                     IfaceMethodrefSelectionNoOverride,
+                     /* Case 27: Objectref overrides.
+                      *
+                      * I[](*) = mref
+                      * C[I](res) = oref = expected
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.methodref).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                         final int I = builder.methodref;
+                         final int C = builder.addClass(withDef);
+                         builder.hier.addInherit(C, I);
+                         builder.objectref = C;
+                         builder.expected = C;
+                     },
+                     /* Case 28: Diamond, methodref at top, overriding.
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3](res) = expected
+                      * C[I1,I2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C, I1);
+                         builder.hier.addInherit(C, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.objectref = C;
+                         builder.expected = I2;
+                     },
+                     /* Case 29: Diamond, with superclass, expected at top,
+                      * class overriding.
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](res) = expected, I1[I2]()
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 30: Diamond, with superclass, expected at top,
+                      * interface overriding
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](), I1[I2](res) = expected
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = I1;
+                     },
+                     /* Case 31: Y, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * C2[](res) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 32: Diamond, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * I2[](def) = old expected
+                      * C2[I2](res) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 33: Superclass overrides.
+                      *
+                      * I[](*) = mref
+                      * C2[I](res) = expected
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData withDef =
+                            new ClassData(pck, oldexpected.methoddata);
+                         final int I = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.expected = C2;
+                         builder.objectref = C1;
+                     },
+                     /* Case 34: Diamond, inherit through superclass,
+                      * expected at top, override.
+                      *
+                      * I3[](*) = mref
+                      * I1[I3](), I2[I3](res) = expected
+                      * C2[I1,I2]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData withDef =
+                             new ClassData(pck, oldexpected.methoddata);
+                         final int I3 = builder.methodref;
+                         final int I2 = builder.addInterface(withDef);
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(I1, I3);
+                         builder.hier.addInherit(I2, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                         builder.expected = I2;
+                     },
+                     /* Case 35: Y, with superclass, inherit through
+                      * superclass, overlapping, expected at top.
+                      *
+                      * C3[](res) = expected, I1[*](*) = mref
+                      * C2[I1,C3]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData withDef =
+                             new ClassData(pck, oldexpected.methoddata);
+                         final int I1 = builder.methodref;
+                         final int C3 = builder.addClass(withDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                         builder.expected = C3;
+                     },
+                     /* Case 36: Diamond, with superclass, inherit through
+                      * superclass, overlapping, expected at top.
+                      *
+                      * I2[](*) = oldexpected
+                      * C3[I2](res) = expected, I1[*](*) = mref
+                      * C2[I1,C3]()
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData withDef =
+                             new ClassData(pck, oldexpected.methoddata);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C3 = builder.addClass(withDef);
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I1);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I2);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                         builder.expected = C3;
+                     },
+                     /* Case 37: Double diamond, with superclass, inherit through
+                      * superclass, overriding.
+                      *
+                      * I3[](def) = old expected
+                      * C3[I3](), I2[*](*) = mref
+                      * C2[I2,C3](), I1[I2](res) = expected
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData withDef =
+                             new ClassData(pck, oldexpected.methoddata);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                         builder.expected = I1;
+                     },
+                     /* Case 38: Double diamond, with superclass, inherit through
+                      * superclass, skip private.
+                      *
+                      * I3[](def) = old expected
+                      * C3[I3](), I2[*](*) = mref
+                      * C2[I2,C3](), I1[I2](priv)
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData withDef =
+                             new ClassData(pck, oldexpected.methoddata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withPrivDef =
+                             new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withPrivDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                     },
+                     /* Case 39: Double diamond, with superclass, inherit through
+                      * superclass, skip static.
+                      *
+                      * I3[](def) = old expected
+                      * C3[I3](), I2[*](*) = mref
+                      * C2[I2,C3](), I1[I2](stat)
+                      * C1[C2,I1]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final ClassData withDef =
+                             new ClassData(pck, oldexpected.methoddata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I3 = builder.expected;
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(withStatDef);
+                         final int C3 = builder.addClass(emptyClass(pck));
+                         final int C2 = builder.addClass(emptyClass(pck));
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C2, I2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C3, I3);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C1, I1);
+                         builder.objectref = C1;
+                     },
+                     /* Case 40: Superclass overrides.
+                      *
+                      * I[](*) = mref
+                      * C3[I](res) = expected
+                      * C2[C3](stat) = expected
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                         final ClassData withDef =
+                             new ClassData(pck, oldexpected.methoddata);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PUBLIC,
+                                            MethodData.Context.STATIC);
+                         final ClassData withStatDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C3 = builder.addClass(withDef);
+                         final int C2 = builder.addClass(withStatDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, C3);
+                         builder.hier.addInherit(C2, I);
+                         builder.expected = C3;
+                         builder.objectref = C1;
+                     });
+
+    public static final Template IfaceMethodrefSelectionOverrideNonPublic =
+        new Template("IfaceMethodrefSelection",
+                     /* Case 1: Objectref overrides.
+                      *
+                      * I[](*) = mref
+                      * C[I](priv) = oref = expected
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.methodref).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C = builder.addClass(withDef);
+                         builder.hier.addInherit(C, I);
+                         builder.objectref = C;
+                         builder.expected = C;
+                     },
+                     /* Case 2: Objectref overrides.
+                      *
+                      * I[](*) = mref
+                      * C[I](prot) = oref = expected
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.methodref).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PROTECTED,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C = builder.addClass(withDef);
+                         builder.hier.addInherit(C, I);
+                         builder.objectref = C;
+                         builder.expected = C;
+                     },
+                     /* Case 3: Objectref overrides package private.
+                      *
+                      * I[](*) = mref
+                      * C[I](pack) = oref = expected
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.methodref).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PACKAGE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C = builder.addClass(withDef);
+                         builder.hier.addInherit(C, I);
+                         builder.objectref = C;
+                         builder.expected = C;
+                     },
+                     /* Case 4: Diamond, with superclass, expected at top,
+                      * class overriding with private.
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](priv) = expected, I1[I2]()
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 5: Diamond, with superclass, expected at top,
+                      * class overriding with package private.
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](pack) = expected, I1[I2]()
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PACKAGE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 6: Diamond, with superclass, expected at top,
+                      * class overriding with protected.
+                      *
+                      * I2[](*) = mref
+                      * C2[I2](prot) = expected, I1[I2]()
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PROTECTED,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.methodref;
+                         final int I1 = builder.addInterface(emptyClass(pck));
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(I1, I2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 7: Y, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * C2[](priv) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(pck, meth);
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 8: Y, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * C2[](prot) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PROTECTED,
+                                            MethodData.Context.INSTANCE);
+                        final ClassData withDef =
+                            new ClassData(pck, meth);
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 9: Y, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * C2[](pack) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PACKAGE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 10: Diamond, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * I2[](def) = old expected
+                      * C2[I2](priv) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 11: Diamond, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * I2[](def) = old expected
+                      * C2[I2](pack) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PACKAGE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 12: Diamond, with superclass, overlaping, expected
+                      * at top, class overrides
+                      *
+                      * I2[](def) = old expected
+                      * C2[I2](prot) = expected, I1[](*) = mref
+                      * C1[I1,C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PROTECTED,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I2 = builder.expected;
+                         final int I1 = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I1);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I2);
+                         builder.objectref = C1;
+                         builder.expected = C2;
+                     },
+                     /* Case 13: Superclass overrides.
+                      *
+                      * I[](*) = mref
+                      * C2[I](priv) = expected
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PRIVATE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.expected = C2;
+                         builder.objectref = C1;
+                     },
+                     /* Case 14: Superclass overrides.
+                      *
+                      * I[](*) = mref
+                      * C2[I](prot) = expected
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PROTECTED,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.expected = C2;
+                         builder.objectref = C1;
+                     },
+                     /* Case 15: Superclass overrides.
+                      *
+                      * I[](*) = mref
+                      * C2[I](pack) = expected
+                      * C1[C2]() = oref
+                      */
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         final ClassData.Package pck =
+                             builder.classdata.get(builder.expected).packageId;
+                         final ClassData oldexpected =
+                             builder.classdata.get(builder.expected);
+                         final MethodData meth =
+                             new MethodData(MethodData.Access.PACKAGE,
+                                            MethodData.Context.INSTANCE);
+                         final ClassData withDef =
+                             new ClassData(pck, meth);
+                         final int I = builder.methodref;
+                         final int C2 = builder.addClass(withDef);
+                         final int C1 = builder.addClass(emptyClass(pck));
+                         builder.hier.addInherit(C1, I);
+                         builder.hier.addInherit(C1, C2);
+                         builder.hier.addInherit(C2, I);
+                         builder.expected = C2;
+                         builder.objectref = C1;
+                     });
+
+    /***********************
+     * Ambiguous selection *
+     ***********************/
+
+    public static final Template MethodrefAmbiguousResolvedIsIface =
+        new Template("MethodrefAmbiguousResolvedIsIface",
+                    /* Inherit from interface.
+                     *
+                     * C2[](*) = mref, I[](any)
+                     * C1[C2,I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData.Package pck = oldexpected.packageId;
+                        final MethodData.Context ctx = oldexpected.methoddata.context;
+                        final MethodData mdata =
+                            new MethodData(MethodData.Access.PUBLIC, ctx);
+                        final ClassData withDef = new ClassData(pck, mdata);
+                        final int C2 = builder.methodref;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        final int I = builder.addInterface(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.objectref = C1;
+                    });
+
+    public static final Template IfaceMethodrefAmbiguousResolvedIsIface =
+        new Template("IfaceMethodrefAmbiguousResolvedIsIface",
+                    /* Inherit from interface.
+                     *
+                     * I1[](*) = mref, I2[](any)
+                     * C1[I1,I2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData.Package pck = oldexpected.packageId;
+                        final MethodData.Context ctx = oldexpected.methoddata.context;
+                        final MethodData mdata =
+                            new MethodData(MethodData.Access.PUBLIC, ctx);
+                        final ClassData withDef = new ClassData(pck, mdata);
+                        final int I1 = builder.methodref;
+                        final int C = builder.addClass(emptyClass(pck));
+                        final int I2 = builder.addInterface(withDef);
+                        builder.hier.addInherit(C, I1);
+                        builder.hier.addInherit(C, I2);
+                        builder.objectref = C;
+                    });
+
+    public static final Template InvokespecialAmbiguousResolvedIsIface =
+        new Template("InvokespecialAmbiguousResolvedIsIface",
+                    /* Inherit from interface.
+                     *
+                     * C2[](*) = csite, I[](any)
+                     * C1[C2,I]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData oldexpected =
+                            builder.classdata.get(builder.expected);
+                        final ClassData.Package pck = oldexpected.packageId;
+                        final MethodData.Context ctx = oldexpected.methoddata.context;
+                        final MethodData mdata =
+                            new MethodData(MethodData.Access.PUBLIC, ctx);
+                        final ClassData withDef = new ClassData(pck, mdata);
+                        final int C2 = builder.callsite;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        final int I = builder.addInterface(withDef);
+                        builder.hier.addInherit(C1, C2);
+                        builder.hier.addInherit(C1, I);
+                        builder.objectref = C1;
+                    });
+
+    /******************************
+     *   invokespecial Templates  *
+     ******************************/
+
+    // Create this by taking MethodrefSelection and replacing
+    // methodref with callsite.
+    public static final Template ObjectrefAssignableToCallsite =
+        new Template("ObjectrefAssignableToCallsite",
+                    /* Case 1: Objectref equals callsite
+                     *
+                     * C[](*) = csite = oref
+                     */
+                    (builder) -> {
+                        builder.objectref = builder.callsite;
+                    },
+                    /* Case 2: Inherit from super.
+                     *
+                     * C2[](*) = csite
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.callsite).packageId;
+                        final int C2 = builder.callsite;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    });
+
+    public static final Template ObjectrefExactSubclassOfCallsite =
+        new Template("ObjectrefSubclassOfCallsite",
+                    /* Inherit from super.
+                     *
+                     * C2[](*) = csite
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.callsite).packageId;
+                        final int C2 = builder.callsite;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    });
+
+    public static final Template ObjectrefEqualsOrExactSubclassOfCallsite =
+        new Template("ObjectrefEqualsOrExactSubclassOfCallsite",
+                     (final SelectionResolutionTestCase.Builder builder) -> {
+                         builder.objectref = builder.callsite;
+                     },
+                    /* Inherit from super.
+                     *
+                     * C2[](*) = csite
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.callsite).packageId;
+                        final int C2 = builder.callsite;
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    });
+
+    public static final Template ObjectrefEqualsCallsite =
+        new Template("TrivialObjectref",
+                     Collections.singleton((builder) -> {
+                             builder.objectref = builder.callsite;
+                         }));
+
+    public static final Template ObjectrefSubclassOfSubclassOfCallsite =
+        new Template("ObjectrefSubclassOfCallsite",
+                    /* Inherit from super.
+                     *
+                     * C3[](*) = csite
+                     * C2[C3]()
+                     * C1[C2]() = oref
+                     */
+                    (final SelectionResolutionTestCase.Builder builder) -> {
+                        final ClassData.Package pck =
+                            builder.classdata.get(builder.callsite).packageId;
+                        final int C3 = builder.callsite;
+                        final int C2 = builder.addClass(emptyClass(pck));
+                        final int C1 = builder.addClass(emptyClass(pck));
+                        builder.hier.addInherit(C2, C3);
+                        builder.hier.addInherit(C1, C2);
+                        builder.objectref = C1;
+                    });
+
+    private static class Placeholder extends ClassData {
+        private final String placeholder;
+
+
+        private Placeholder(final String placeholder,
+                            final MethodData methoddata) {
+            super(ClassData.Package.PLACEHOLDER, methoddata);
+            this.placeholder = placeholder;
+        }
+
+        private Placeholder(final String placeholder) {
+            this(placeholder, null);
+        }
+
+        public String toString() {
+            return " = <Placeholder for " + placeholder + ">\n\n";
+        }
+
+        public static final Placeholder objectref = new Placeholder("objectref");
+        public static final Placeholder methodref = new Placeholder("methodref");
+        public static final Placeholder callsite = new Placeholder("callsite");
+        public static final Placeholder expected =
+            new Placeholder("expected",
+                            new MethodData(MethodData.Access.PLACEHOLDER,
+                                           MethodData.Context.PLACEHOLDER));
+    }
+
+    public static void main(String... args) {
+
+        System.err.println("*** Resolution Templates ***\n");
+        final SelectionResolutionTestCase.Builder withExpectedIface =
+            new SelectionResolutionTestCase.Builder();
+        withExpectedIface.expected =
+            withExpectedIface.addInterface(Placeholder.expected);
+        final SelectionResolutionTestCase.Builder withExpectedClass =
+            new SelectionResolutionTestCase.Builder();
+        withExpectedClass.expected =
+            withExpectedClass.addClass(Placeholder.expected);
+
+        MethodrefNotEqualsExpectedClass.printCases(withExpectedClass);
+        MethodrefNotEqualsExpectedIface.printCases(withExpectedIface);
+        IfaceMethodrefNotEqualsExpected.printCases(withExpectedIface);
+        MethodrefAmbiguous.printCases(withExpectedIface);
+        IfaceMethodrefAmbiguous.printCases(withExpectedIface);
+        ReabstractExpectedIface.printCases(withExpectedIface);
+        ReabstractExpectedClass.printCases(withExpectedClass);
+
+        final SelectionResolutionTestCase.Builder methodrefExpectedIface =
+            withExpectedIface.copy();
+        methodrefExpectedIface.methodref =
+            methodrefExpectedIface.addClass(Placeholder.methodref);
+        final SelectionResolutionTestCase.Builder methodrefExpectedClass =
+            withExpectedClass.copy();
+        methodrefExpectedClass.methodref =
+            methodrefExpectedClass.addClass(Placeholder.methodref);
+        final SelectionResolutionTestCase.Builder ifaceMethodref =
+            withExpectedIface.copy();
+        ifaceMethodref.methodref =
+            ifaceMethodref.addInterface(Placeholder.methodref);
+
+        IgnoredAbstract.printCases(methodrefExpectedIface);
+        MethodrefSelectionResolvedIsClass.printCases(methodrefExpectedClass);
+        MethodrefSelectionResolvedIsIface.printCases(methodrefExpectedIface);
+        IfaceMethodrefSelection.printCases(ifaceMethodref);
+        IfaceMethodrefSelectionOverrideNonPublic.printCases(ifaceMethodref);
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/classes/selectionresolution/TestBuilder.java	Fri Mar 25 15:54:18 2016 +0300
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package selectionresolution;
+
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
+
+class TestBuilder extends Builder {
+    private final ClassConstruct testClass;
+    private final Method mainMethod;
+
+    public TestBuilder(int classId, SelectionResolutionTestCase testcase) {
+        super(testcase);
+
+        // Make a public class Test that contains all our test methods
+        testClass = new Clazz("Test", null, -1, ACC_PUBLIC);
+
+        // Add a main method
+        mainMethod = testClass.addMethod("main", "([Ljava/lang/String;)V", ACC_PUBLIC + ACC_STATIC);
+
+    }
+
+    public ClassConstruct getMainTestClass() {
+        mainMethod.done();
+        return testClass;
+    }
+
+    public void addTest(ClassConstruct clazz, ClassBuilder.ExecutionMode execMode) {
+        Method m = clazz.addMethod("test", "()Ljava/lang/Integer;", ACC_PUBLIC + ACC_STATIC, execMode);
+        m.defaultInvoke(getInvokeInstruction(testcase.invoke),
+                    getName(testcase.methodref),
+                    getName(testcase.objectref));
+
+        mainMethod.makeStaticCall(clazz.getName(), "test", "()Ljava/lang/Integer;").done();
+    }
+
+    private static int getInvokeInstruction(SelectionResolutionTestCase.InvokeInstruction instr) {
+        switch (instr) {
+            case INVOKESTATIC:
+                return Opcodes.INVOKESTATIC;
+            case INVOKESPECIAL:
+                return Opcodes.INVOKESPECIAL;
+            case INVOKEINTERFACE:
+                return Opcodes.INVOKEINTERFACE;
+            case INVOKEVIRTUAL:
+                return Opcodes.INVOKEVIRTUAL;
+            default:
+                throw new AssertionError(instr.name());
+        }
+    }
+}