Merge
authormockner
Tue, 29 Mar 2016 20:51:59 +0200
changeset 37204 c57d749ef4fb
parent 37203 90eabed33a6c (current diff)
parent 37201 928cf689af1a (diff)
child 37205 dd547442bfea
Merge
hotspot/src/share/vm/logging/logTag.hpp
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/src/share/vm/runtime/globals.hpp
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -160,6 +160,11 @@
 // Create a new table and using alternate hash code, populate the new table
 // with the existing strings.   Set flag to use the alternate hash code afterwards.
 void SymbolTable::rehash_table() {
+  if (DumpSharedSpaces) {
+    tty->print_cr("Warning: rehash_table should not be called while dumping archive");
+    return;
+  }
+
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   // This should never happen with -Xshare:dump but it might in testing mode.
   if (DumpSharedSpaces) return;
@@ -201,6 +206,11 @@
 
 Symbol* SymbolTable::lookup_shared(const char* name,
                                    int len, unsigned int hash) {
+  if (use_alternate_hashcode()) {
+    // hash_code parameter may use alternate hashing algorithm but the shared table
+    // always uses the same original hash code.
+    hash = hash_shared_symbol(name, len);
+  }
   return _shared_table.lookup(name, hash, len);
 }
 
@@ -234,6 +244,10 @@
            java_lang_String::hash_code((const jbyte*)s, len);
 }
 
+unsigned int SymbolTable::hash_shared_symbol(const char* s, int len) {
+  return java_lang_String::hash_code((const jbyte*)s, len);
+}
+
 
 // We take care not to be blocking while holding the
 // SymbolTable_lock. Otherwise, the system might deadlock, since the
@@ -536,7 +550,7 @@
     HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
     for ( ; p != NULL; p = p->next()) {
       Symbol* s = (Symbol*)(p->literal());
-      unsigned int fixed_hash = hash_symbol((char*)s->bytes(), s->utf8_length());
+      unsigned int fixed_hash =  hash_shared_symbol((char*)s->bytes(), s->utf8_length());
       assert(fixed_hash == p->hash(), "must not rehash during dumping");
       ch_table.add(fixed_hash, s);
     }
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -175,6 +175,7 @@
   }
 
   static unsigned int hash_symbol(const char* s, int len);
+  static unsigned int hash_shared_symbol(const char* s, int len);
 
   static Symbol* lookup(const char* name, int len, TRAPS);
   // lookup only, won't add. Also calculate hash.
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -102,7 +102,6 @@
   template(java_security_SecureClassLoader,           "java/security/SecureClassLoader")          \
   template(java_net_URL,                              "java/net/URL")                             \
   template(java_util_jar_Manifest,                    "java/util/jar/Manifest")                   \
-  template(impliesCreateAccessControlContext_name,    "impliesCreateAccessControlContext")        \
   template(java_io_OutputStream,                      "java/io/OutputStream")                     \
   template(java_io_Reader,                            "java/io/Reader")                           \
   template(java_io_BufferedReader,                    "java/io/BufferedReader")                   \
@@ -326,7 +325,6 @@
   template(java_lang_StackFrameInfo,                  "java/lang/StackFrameInfo")                 \
   template(java_lang_LiveStackFrameInfo,              "java/lang/LiveStackFrameInfo")             \
   template(java_lang_StackStreamFactory_AbstractStackWalker, "java/lang/StackStreamFactory$AbstractStackWalker") \
-  template(doStackWalk_name,                          "doStackWalk")                              \
   template(doStackWalk_signature,                     "(JIIII)Ljava/lang/Object;")                \
   template(asPrimitive_name,                          "asPrimitive")                              \
   template(asPrimitive_int_signature,                 "(I)Ljava/lang/LiveStackFrame$PrimitiveValue;") \
@@ -377,8 +375,6 @@
   template(type_name,                                 "type")                                     \
   template(findNative_name,                           "findNative")                               \
   template(deadChild_name,                            "deadChild")                                \
-  template(addClass_name,                             "addClass")                                 \
-  template(throwIllegalAccessError_name,              "throwIllegalAccessError")                  \
   template(getFromClass_name,                         "getFromClass")                             \
   template(dispatch_name,                             "dispatch")                                 \
   template(getSystemClassLoader_name,                 "getSystemClassLoader")                     \
@@ -473,10 +469,6 @@
   template(url_code_signer_array_void_signature,      "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \
   template(module_entry_name,                         "module_entry")                             \
                                                                                                   \
-  /* non-intrinsic name/signature pairs: */                                                       \
-  template(register_method_name,                      "register")                                 \
-  do_alias(register_method_signature,         object_void_signature)                              \
-                                                                                                  \
   /* name symbols needed by intrinsics */                                                         \
   VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, template, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
                                                                                                   \
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -2536,7 +2536,7 @@
         _blocks_to_claim[i].sample(
           MAX2(CMSOldPLABMin,
           MIN2(CMSOldPLABMax,
-               _global_num_blocks[i]/(_global_num_workers[i]*CMSOldPLABNumRefills))));
+               _global_num_blocks[i]/_global_num_workers[i]/CMSOldPLABNumRefills)));
       }
       // Reset counters for next round
       _global_num_workers[i] = 0;
--- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -233,11 +233,15 @@
     if (word_sz * 100 < ParallelGCBufferWastePct * plab->word_sz()) {
       // Is small enough; abandon this buffer and start a new one.
       plab->retire();
-      size_t buf_size = plab->word_sz();
+      // The minimum size has to be twice SurvivorAlignmentInBytes to
+      // allow for padding used in the alignment of 1 word.  A padding
+      // of 1 is too small for a filler word so the padding size will
+      // be increased by SurvivorAlignmentInBytes.
+      size_t min_usable_size = 2 * static_cast<size_t>(SurvivorAlignmentInBytes >> LogHeapWordSize);
+      size_t buf_size = MAX2(plab->word_sz(), min_usable_size);
       HeapWord* buf_space = sp->par_allocate(buf_size);
       if (buf_space == NULL) {
-        const size_t min_bytes =
-          PLAB::min_size() << LogHeapWordSize;
+        const size_t min_bytes = MAX2(PLAB::min_size(), min_usable_size) << LogHeapWordSize;
         size_t free_bytes = sp->free();
         while(buf_space == NULL && free_bytes >= min_bytes) {
           buf_size = free_bytes >> LogHeapWordSize;
@@ -253,7 +257,10 @@
         // Note that we cannot compare buf_size < word_sz below
         // because of AlignmentReserve (see PLAB::allocate()).
         assert(obj != NULL || plab->words_remaining() < word_sz,
-               "Else should have been able to allocate");
+               "Else should have been able to allocate requested object size "
+               SIZE_FORMAT ", PLAB size " SIZE_FORMAT ", SurvivorAlignmentInBytes "
+               SIZE_FORMAT ", words_remaining " SIZE_FORMAT,
+               word_sz, buf_size, SurvivorAlignmentInBytes, plab->words_remaining());
         // It's conceivable that we may be able to use the
         // buffer we just grabbed for subsequent small requests
         // even if not for this one.
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -76,7 +76,6 @@
 }
 
 void ConcurrentG1RefineThread::wait_for_completed_buffers() {
-  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
   while (!should_terminate() && !is_active()) {
     _monitor->wait(Mutex::_no_safepoint_check_flag);
@@ -126,7 +125,12 @@
     {
       SuspendibleThreadSetJoiner sts_join;
 
-      do {
+      while (!should_terminate()) {
+        if (sts_join.should_yield()) {
+          sts_join.yield();
+          continue;             // Re-check for termination after yield delay.
+        }
+
         size_t curr_buffer_num = dcqs.completed_buffers_num();
         // If the number of the buffers falls down into the yellow zone,
         // that means that the transition period after the evacuation pause has ended.
@@ -138,17 +142,23 @@
         if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
           _next->activate();
         }
-      } while (dcqs.apply_closure_to_completed_buffer(_refine_closure,
-                                                      _worker_id + _worker_id_offset,
-                                                      _deactivation_threshold,
-                                                      false /* during_pause */));
 
-      deactivate();
-      log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
-                            _worker_id, _deactivation_threshold,
-                            dcqs.completed_buffers_num());
+        // Process the next buffer, if there are enough left.
+        if (!dcqs.apply_closure_to_completed_buffer(_refine_closure,
+                                                    _worker_id + _worker_id_offset,
+                                                    _deactivation_threshold,
+                                                    false /* during_pause */)) {
+          break; // Deactivate, number of buffers fell below threshold.
+        }
+      }
     }
 
+    deactivate();
+    log_debug(gc, refine)("Deactivated %d, off threshold: " SIZE_FORMAT
+                          ", current: " SIZE_FORMAT,
+                          _worker_id, _deactivation_threshold,
+                          dcqs.completed_buffers_num());
+
     if (os::supports_vtime()) {
       _vtime_accum = (os::elapsedVTime() - _vtime_start);
     } else {
--- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -155,42 +155,52 @@
                                                 bool consume,
                                                 uint worker_i) {
   if (cl == NULL) return true;
+  bool result = true;
   void** buf = BufferNode::make_buffer_from_node(node);
   size_t limit = DirtyCardQueue::byte_index_to_index(buffer_size());
-  size_t start = DirtyCardQueue::byte_index_to_index(node->index());
-  for (size_t i = start; i < limit; ++i) {
+  size_t i = DirtyCardQueue::byte_index_to_index(node->index());
+  for ( ; i < limit; ++i) {
     jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
     assert(card_ptr != NULL, "invariant");
     if (!cl->do_card_ptr(card_ptr, worker_i)) {
-      if (consume) {
-        size_t new_index = DirtyCardQueue::index_to_byte_index(i + 1);
-        assert(new_index <= buffer_size(), "invariant");
-        node->set_index(new_index);
-      }
-      return false;
+      result = false;           // Incomplete processing.
+      break;
     }
   }
   if (consume) {
-    node->set_index(buffer_size());
+    size_t new_index = DirtyCardQueue::index_to_byte_index(i);
+    assert(new_index <= buffer_size(), "invariant");
+    node->set_index(new_index);
   }
-  return true;
+  return result;
 }
 
+#ifndef ASSERT
+#define assert_fully_consumed(node, buffer_size)
+#else
+#define assert_fully_consumed(node, buffer_size)                \
+  do {                                                          \
+    size_t _afc_index = (node)->index();                        \
+    size_t _afc_size = (buffer_size);                           \
+    assert(_afc_index == _afc_size,                             \
+           "Buffer was not fully consumed as claimed: index: "  \
+           SIZE_FORMAT ", size: " SIZE_FORMAT,                  \
+            _afc_index, _afc_size);                             \
+  } while (0)
+#endif // ASSERT
+
 bool DirtyCardQueueSet::mut_process_buffer(BufferNode* node) {
   guarantee(_free_ids != NULL, "must be");
 
-  // claim a par id
-  uint worker_i = _free_ids->claim_par_id();
+  uint worker_i = _free_ids->claim_par_id(); // temporarily claim an id
+  bool result = apply_closure_to_buffer(_mut_process_closure, node, true, worker_i);
+  _free_ids->release_par_id(worker_i); // release the id
 
-  bool b = apply_closure_to_buffer(_mut_process_closure, node, true, worker_i);
-  if (b) {
+  if (result) {
+    assert_fully_consumed(node, buffer_size());
     Atomic::inc(&_processed_buffers_mut);
   }
-
-  // release the id
-  _free_ids->release_par_id(worker_i);
-
-  return b;
+  return result;
 }
 
 
@@ -227,15 +237,16 @@
     return false;
   } else {
     if (apply_closure_to_buffer(cl, nd, true, worker_i)) {
+      assert_fully_consumed(nd, buffer_size());
       // Done with fully processed buffer.
       deallocate_buffer(nd);
       Atomic::inc(&_processed_buffers_rs_thread);
-      return true;
     } else {
       // Return partially processed buffer to the queue.
+      guarantee(!during_pause, "Should never stop early");
       enqueue_complete_buffer(nd);
-      return false;
     }
+    return true;
   }
 }
 
--- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -82,7 +82,8 @@
   // returns true.  Stops processing after the first closure
   // application that returns false, and returns false from this
   // function.  If "consume" is true, the node's index is updated to
-  // follow the last processed element.
+  // exclude the processed elements, e.g. up to the element for which
+  // the closure returned false.
   bool apply_closure_to_buffer(CardTableEntryClosure* cl,
                                BufferNode* node,
                                bool consume,
@@ -121,14 +122,18 @@
 
   static void handle_zero_index_for_thread(JavaThread* t);
 
-  // If there exists some completed buffer, pop it, then apply the
-  // specified closure to its active elements.  If all active elements
-  // are processed, returns "true".  If no completed buffers exist,
-  // returns false.  If a completed buffer exists, but is only
-  // partially completed before a "yield" happens, the partially
-  // completed buffer (with its index updated to exclude the processed
-  // elements) is returned to the completed buffer set, and this call
-  // returns false.
+  // If there are more than stop_at completed buffers, pop one, apply
+  // the specified closure to its active elements, and return true.
+  // Otherwise return false.
+  //
+  // A completely processed buffer is freed.  However, if a closure
+  // invocation returns false, processing is stopped and the partially
+  // processed buffer (with its index updated to exclude the processed
+  // elements, e.g. up to the element for which the closure returned
+  // false) is returned to the completed buffer set.
+  //
+  // If during_pause is true, stop_at must be zero, and the closure
+  // must never return false.
   bool apply_closure_to_completed_buffer(CardTableEntryClosure* cl,
                                          uint worker_i,
                                          size_t stop_at,
--- a/hotspot/src/share/vm/gc/g1/suspendibleThreadSet.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/suspendibleThreadSet.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/g1/suspendibleThreadSet.hpp"
 #include "runtime/mutexLocker.hpp"
+#include "runtime/semaphore.hpp"
 #include "runtime/thread.inline.hpp"
 
 uint   SuspendibleThreadSet::_nthreads          = 0;
@@ -32,6 +33,19 @@
 bool   SuspendibleThreadSet::_suspend_all       = false;
 double SuspendibleThreadSet::_suspend_all_start = 0.0;
 
+static Semaphore* _synchronize_wakeup = NULL;
+
+void SuspendibleThreadSet_init() {
+  assert(_synchronize_wakeup == NULL, "STS already initialized");
+  _synchronize_wakeup = new Semaphore();
+}
+
+bool SuspendibleThreadSet::is_synchronized() {
+  assert_lock_strong(STS_lock);
+  assert(_nthreads_stopped <= _nthreads, "invariant");
+  return _nthreads_stopped == _nthreads;
+}
+
 void SuspendibleThreadSet::join() {
   assert(!Thread::current()->is_suspendible_thread(), "Thread already joined");
   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
@@ -48,31 +62,30 @@
   assert(_nthreads > 0, "Invalid");
   DEBUG_ONLY(Thread::current()->clear_suspendible_thread();)
   _nthreads--;
-  if (_suspend_all) {
-    ml.notify_all();
+  if (_suspend_all && is_synchronized()) {
+    // This leave completes a request, so inform the requestor.
+    _synchronize_wakeup->signal();
   }
 }
 
 void SuspendibleThreadSet::yield() {
   assert(Thread::current()->is_suspendible_thread(), "Must have joined");
+  MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
   if (_suspend_all) {
-    MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
-    if (_suspend_all) {
-      _nthreads_stopped++;
-      if (_nthreads_stopped == _nthreads) {
-        if (ConcGCYieldTimeout > 0) {
-          double now = os::elapsedTime();
-          guarantee((now - _suspend_all_start) * 1000.0 < (double)ConcGCYieldTimeout, "Long delay");
-        }
+    _nthreads_stopped++;
+    if (is_synchronized()) {
+      if (ConcGCYieldTimeout > 0) {
+        double now = os::elapsedTime();
+        guarantee((now - _suspend_all_start) * 1000.0 < (double)ConcGCYieldTimeout, "Long delay");
       }
-      ml.notify_all();
-      while (_suspend_all) {
-        ml.wait(Mutex::_no_safepoint_check_flag);
-      }
-      assert(_nthreads_stopped > 0, "Invalid");
-      _nthreads_stopped--;
-      ml.notify_all();
+      // This yield completes the request, so inform the requestor.
+      _synchronize_wakeup->signal();
     }
+    while (_suspend_all) {
+      ml.wait(Mutex::_no_safepoint_check_flag);
+    }
+    assert(_nthreads_stopped > 0, "Invalid");
+    _nthreads_stopped--;
   }
 }
 
@@ -81,18 +94,41 @@
   if (ConcGCYieldTimeout > 0) {
     _suspend_all_start = os::elapsedTime();
   }
+  {
+    MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
+    assert(!_suspend_all, "Only one at a time");
+    _suspend_all = true;
+    if (is_synchronized()) {
+      return;
+    }
+  } // Release lock before semaphore wait.
+
+  // Semaphore initial count is zero.  To reach here, there must be at
+  // least one not yielded thread in the set, e.g. is_synchronized()
+  // was false before the lock was released.  A thread in the set will
+  // signal the semaphore iff it is the last to yield or leave while
+  // there is an active suspend request.  So there will be exactly one
+  // signal, which will increment the semaphore count to one, which
+  // will then be consumed by this wait, returning it to zero.  No
+  // thread can exit yield or enter the set until desynchronize is
+  // called, so there are no further opportunities for the semaphore
+  // being signaled until we get back here again for some later
+  // synchronize call.  Hence, there is no need to re-check for
+  // is_synchronized after the wait; it will always be true there.
+  _synchronize_wakeup->wait();
+
+#ifdef ASSERT
   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
-  assert(!_suspend_all, "Only one at a time");
-  _suspend_all = true;
-  while (_nthreads_stopped < _nthreads) {
-    ml.wait(Mutex::_no_safepoint_check_flag);
-  }
+  assert(_suspend_all, "STS not synchronizing");
+  assert(is_synchronized(), "STS not synchronized");
+#endif
 }
 
 void SuspendibleThreadSet::desynchronize() {
   assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
   MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
-  assert(_nthreads_stopped == _nthreads, "Invalid");
+  assert(_suspend_all, "STS not synchronizing");
+  assert(is_synchronized(), "STS not synchronized");
   _suspend_all = false;
   ml.notify_all();
 }
--- a/hotspot/src/share/vm/gc/g1/suspendibleThreadSet.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/suspendibleThreadSet.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -45,6 +45,8 @@
   static bool   _suspend_all;
   static double _suspend_all_start;
 
+  static bool is_synchronized();
+
   // Add the current thread to the set. May block if a suspension is in progress.
   static void join();
 
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -460,11 +460,11 @@
                   (HeapWord*)_virtual_space.high());
     gch->barrier_set()->resize_covered_region(cmr);
 
-    log_debug(gc, heap, ergo)(
+    log_debug(gc, ergo, heap)(
         "New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden=" SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]",
         new_size_before/K, _virtual_space.committed_size()/K,
         eden()->capacity()/K, from()->capacity()/K);
-    log_trace(gc, heap, ergo)(
+    log_trace(gc, ergo, heap)(
         "  [allowed " SIZE_FORMAT "K extra for %d threads]",
           thread_increase_size/K, threads_count);
       }
--- a/hotspot/src/share/vm/gc/shared/gcTraceTime.inline.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/gc/shared/gcTraceTime.inline.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -39,24 +39,27 @@
 
 template <LogLevelType Level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag >
 void GCTraceTimeImpl<Level, T0, T1, T2, T3, T4, GuardTag>::log_start(jlong start_counter) {
-  if (Log<PREFIX_LOG_TAG(start), T0, T1, T2, T3>::is_level(Level)) {
+  STATIC_ASSERT(T0 != LogTag::__NO_TAG); // Need some tag to log on.
+  STATIC_ASSERT(T4 == LogTag::__NO_TAG); // Need to leave at least the last tag for the "start" tag in log_start()
+
+  // Get log with start tag appended (replace first occurrence of NO_TAG)
+  const LogTagType start_tag = PREFIX_LOG_TAG(start);
+  const LogTagType no_tag = PREFIX_LOG_TAG(_NO_TAG);
+  Log<T0,
+      T1 == no_tag ? start_tag : T1,
+      T1 != no_tag && T2 == no_tag ? start_tag : T2,
+      T2 != no_tag && T3 == no_tag ? start_tag : T3,
+      T3 != no_tag && T4 == no_tag ? start_tag : T4
+    > log;
+
+  if (log.is_level(Level)) {
     FormatBuffer<> start_msg("%s", _title);
     if (_gc_cause != GCCause::_no_gc) {
       start_msg.append(" (%s)", GCCause::to_string(_gc_cause));
     }
     start_msg.append(" (%.3fs)", TimeHelper::counter_to_seconds(start_counter));
     // Make sure to put the "start" tag last in the tag set
-    STATIC_ASSERT(T0 != LogTag::__NO_TAG); // Need some tag to log on.
-    STATIC_ASSERT(T4 == LogTag::__NO_TAG); // Need to leave at least the last tag for the "start" tag in log_start()
-    if (T1 == LogTag::__NO_TAG) {
-      Log<T0, PREFIX_LOG_TAG(start)>::template write<Level>("%s", start_msg.buffer());
-    } else if (T2 == LogTag::__NO_TAG) {
-      Log<T0, T1, PREFIX_LOG_TAG(start)>::template write<Level>("%s", start_msg.buffer());
-    } else if (T3 == LogTag::__NO_TAG) {
-      Log<T0, T1, T2, PREFIX_LOG_TAG(start)>::template write<Level>("%s", start_msg.buffer());
-    } else {
-      Log<T0, T1, T2, T3, PREFIX_LOG_TAG(start)>::template write<Level>("%s", start_msg.buffer());
-    }
+    log.template write<Level>("%s", start_msg.buffer());
   }
 }
 
--- a/hotspot/src/share/vm/logging/log.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/logging/log.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -23,6 +23,24 @@
  */
 
 #include "precompiled.hpp"
+#include "logging/log.hpp"
+#include "memory/allocation.inline.hpp"
+
+void LogWriteHelper::write_large(LogTagSet& lts,
+                                 LogLevelType level,
+                                 const char* prefix,
+                                 size_t prefix_len,
+                                 size_t msg_len,
+                                 const char* fmt,
+                                 va_list args) {
+  size_t newbuf_len = prefix_len + msg_len + 1;
+  char* newbuf = NEW_C_HEAP_ARRAY(char, newbuf_len, mtLogging);
+  memcpy(newbuf, prefix, prefix_len);
+  int ret = os::log_vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, args);
+  assert(ret >= 0, "Log message buffer issue");
+  lts.log(level, newbuf);
+  FREE_C_HEAP_ARRAY(char, newbuf);
+}
 
 /////////////// Unit tests ///////////////
 
@@ -33,66 +51,6 @@
 #include "logging/logOutput.hpp"
 #include "memory/resourceArea.hpp"
 
-void Test_log_length() {
-  remove("loglengthoutput.txt");
-
-  // Write long message to output file
-  ResourceMark rm;
-  LogHandle(logging) log;
-  bool success = LogConfiguration::parse_log_arguments("loglengthoutput.txt", "logging=trace",
-    NULL, NULL, log.error_stream());
-  assert(success, "test unable to configure logging");
-  log.trace("01:1234567890-"
-            "02:1234567890-"
-            "03:1234567890-"
-            "04:1234567890-"
-            "05:1234567890-"
-            "06:1234567890-"
-            "07:1234567890-"
-            "08:1234567890-"
-            "09:1234567890-"
-            "10:1234567890-"
-            "11:1234567890-"
-            "12:1234567890-"
-            "13:1234567890-"
-            "14:1234567890-"
-            "15:1234567890-"
-            "16:1234567890-"
-            "17:1234567890-"
-            "18:1234567890-"
-            "19:1234567890-"
-            "20:1234567890-"
-            "21:1234567890-"
-            "22:1234567890-"
-            "23:1234567890-"
-            "24:1234567890-"
-            "25:1234567890-"
-            "26:1234567890-"
-            "27:1234567890-"
-            "28:1234567890-"
-            "29:1234567890-"
-            "30:1234567890-"
-            "31:1234567890-"
-            "32:1234567890-"
-            "33:1234567890-"
-            "34:1234567890-"
-            "35:1234567890-"
-            "36:1234567890-"
-            "37:1234567890-");
-  LogConfiguration::parse_log_arguments("loglengthoutput.txt", "all=off",
-    NULL, NULL, log.error_stream());
-
-  // Look for end of message in output file
-  FILE* fp = fopen("loglengthoutput.txt", "r");
-  assert(fp, "File read error");
-  char output[600];
-  if (fgets(output, 600, fp) != NULL) {
-    assert(strstr(output, "37:1234567890-"), "logging print size error");
-  }
-  fclose(fp);
-  remove("loglengthoutput.txt");
-}
-
 #define assert_str_eq(s1, s2) \
   assert(strcmp(s1, s2) == 0, "Expected '%s' to equal '%s'", s1, s2)
 
@@ -102,14 +60,67 @@
 #define assert_char_not_in(c, s) \
   assert(strchr(s, c) == NULL, "Expected '%s' to *not* contain character '%c'", s, c)
 
+class TestLogFile {
+ private:
+  char file_name[256];
+
+  void set_name(const char* test_name) {
+    const char* tmpdir = os::get_temp_directory();
+    int pos = jio_snprintf(file_name, sizeof(file_name), "%s%svmtest.%s.%d.log", tmpdir, os::file_separator(), test_name, os::current_process_id());
+    assert(pos > 0, "too small log file name buffer");
+    assert((size_t)pos < sizeof(file_name), "too small log file name buffer");
+  }
+
+ public:
+  TestLogFile(const char* test_name) {
+    set_name(test_name);
+    remove(name());
+  }
+
+  ~TestLogFile() {
+    remove(name());
+  }
+
+  const char* name() {
+    return file_name;
+  }
+};
+
+class TestLogSavedConfig {
+ private:
+  char* _saved_config;
+  char* _new_output;
+  LogHandle(logging) _log;
+ public:
+  TestLogSavedConfig(const char* apply_output = NULL, const char* apply_setting = NULL) : _new_output(0) {
+    _saved_config = os::strdup_check_oom(LogOutput::Stdout->config_string());
+    bool success = LogConfiguration::parse_log_arguments("stdout", "all=off", NULL, NULL, _log.error_stream());
+    assert(success, "test unable to turn all off");
+
+    if (apply_output) {
+      _new_output = os::strdup_check_oom(apply_output);
+      bool success = LogConfiguration::parse_log_arguments(_new_output, apply_setting,  NULL, NULL, _log.error_stream());
+      assert(success, "test unable to apply test log configuration");
+    }
+  }
+
+  ~TestLogSavedConfig() {
+    if (_new_output) {
+      bool success = LogConfiguration::parse_log_arguments(_new_output, "all=off", NULL, NULL, _log.error_stream());
+      assert(success, "test unable to turn all off");
+      os::free(_new_output);
+    }
+
+    bool success = LogConfiguration::parse_log_arguments("stdout", _saved_config, NULL, NULL, _log.error_stream());
+    assert(success, "test unable to restore log configuration");
+    os::free(_saved_config);
+  }
+};
+
 void Test_configure_stdout() {
   ResourceMark rm;
-  LogHandle(logging) log;
   LogOutput* stdoutput = LogOutput::Stdout;
-
-  // Save current stdout config and clear it
-  char* saved_config = os::strdup_check_oom(stdoutput->config_string());
-  LogConfiguration::parse_log_arguments("stdout", "all=off", NULL, NULL, log.error_stream());
+  TestLogSavedConfig tlsc;
 
   // Enable 'logging=info', verifying it has been set
   LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(logging));
@@ -131,10 +142,6 @@
   LogConfiguration::configure_stdout(LogLevel::Off, false, LOG_TAGS(gc));
   LogConfiguration::configure_stdout(LogLevel::Off, true, LOG_TAGS(logging));
   assert_str_eq("all=off", stdoutput->config_string());
-
-  // Restore saved configuration
-  LogConfiguration::parse_log_arguments("stdout", saved_config, NULL, NULL, log.error_stream());
-  os::free(saved_config);
 }
 
 static int Test_logconfiguration_subscribe_triggered = 0;
@@ -147,6 +154,8 @@
   ResourceMark rm;
   LogHandle(logging) log;
 
+  TestLogSavedConfig log_cfg("stdout", "logging+test=trace");
+
   LogConfiguration::register_update_listener(&Test_logconfiguration_subscribe_helper);
 
   LogConfiguration::parse_log_arguments("stdout", "logging=trace", NULL, NULL, log.error_stream());
@@ -157,6 +166,105 @@
 
   LogConfiguration::disable_logging();
   assert(Test_logconfiguration_subscribe_triggered == 3, "subscription not triggered (3)");
+
+  // We need to renable stderr error logging since "disable_logging" disable it all.
+  // TestLogSavedConfig log_cfg will only renable stdout for us.
+  LogConfiguration::parse_log_arguments("stderr", "all=warning", NULL, NULL, log.error_stream());
+  assert(Test_logconfiguration_subscribe_triggered == 4, "subscription not triggered (3)");
+}
+
+#define LOG_PREFIX_STR "THE_PREFIX "
+#define LOG_LINE_STR "a log line"
+
+size_t Test_log_prefix_prefixer(char* buf, size_t len) {
+  int ret = jio_snprintf(buf, len, LOG_PREFIX_STR);
+  assert(ret > 0, "Failed to print prefix. Log buffer too small?");
+  return (size_t) ret;
+}
+
+void Test_log_prefix() {
+  ResourceMark rm;
+  TestLogFile log_file("log_prefix");
+  TestLogSavedConfig log_cfg(log_file.name(), "logging+test=trace");
+
+  log_trace(logging, test)(LOG_LINE_STR);
+
+  FILE* fp = fopen(log_file.name(), "r");
+  assert(fp, "File read error");
+  char output[1024];
+  if (fgets(output, 1024, fp) != NULL) {
+    assert(strstr(output, LOG_PREFIX_STR LOG_LINE_STR), "logging prefix error");
+  }
+  fclose(fp);
+}
+
+void Test_log_big() {
+  char big_msg[4096] = {0};
+  char Xchar = '~';
+
+  ResourceMark rm;
+  TestLogFile log_file("log_big");
+  TestLogSavedConfig log_cfg(log_file.name(), "logging+test=trace");
+
+  memset(big_msg, Xchar, sizeof(big_msg) - 1);
+
+  log_trace(logging, test)("%s", big_msg);
+
+  FILE* fp = fopen(log_file.name(), "r");
+  assert(fp, "File read error");
+  char output[sizeof(big_msg)+128 /*decorators*/ ];
+  if (fgets(output, sizeof(output), fp) != NULL) {
+    assert(strstr(output, LOG_PREFIX_STR), "logging prefix error");
+    size_t count = 0;
+    for (size_t ps = 0 ; output[ps + count] != '\0'; output[ps + count] == Xchar ? count++ : ps++);
+    assert(count == (sizeof(big_msg) - 1) , "logging msg error");
+  }
+  fclose(fp);
+}
+
+void Test_logtagset_duplicates() {
+  for (LogTagSet* ts = LogTagSet::first(); ts != NULL; ts = ts->next()) {
+    char ts_name[512];
+    ts->label(ts_name, sizeof(ts_name), ",");
+
+    // verify that NO_TAG is never followed by a real tag
+    for (size_t i = 0; i < LogTag::MaxTags; i++) {
+      if (ts->tag(i) == LogTag::__NO_TAG) {
+        for (i++; i < LogTag::MaxTags; i++) {
+          assert(ts->tag(i) == LogTag::__NO_TAG,
+                 "NO_TAG was followed by a real tag (%s) in tagset %s",
+                 LogTag::name(ts->tag(i)), ts_name);
+        }
+      }
+    }
+
+    // verify that there are no duplicate tagsets (same tags in different order)
+    for (LogTagSet* other = ts->next(); other != NULL; other = other->next()) {
+      if (ts->ntags() != other->ntags()) {
+        continue;
+      }
+      bool equal = true;
+      for (size_t i = 0; i < ts->ntags(); i++) {
+        LogTagType tag = ts->tag(i);
+        if (!other->contains(tag)) {
+          equal = false;
+          break;
+        }
+      }
+      // Since tagsets are implemented using template arguments, using both of
+      // the (logically equivalent) tagsets (t1, t2) and (t2, t1) somewhere will
+      // instantiate two different LogTagSetMappings. This causes multiple
+      // tagset instances to be created for the same logical set. We want to
+      // avoid this to save time, memory and prevent any confusion around it.
+      if (equal) {
+        char other_name[512];
+        other->label(other_name, sizeof(other_name), ",");
+        assert(false, "duplicate LogTagSets found: '%s' vs '%s' "
+               "(tags must always be specified in the same order for each tagset)",
+               ts_name, other_name);
+      }
+    }
+  }
 }
 
 #endif // PRODUCT
--- a/hotspot/src/share/vm/logging/log.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/logging/log.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -29,7 +29,6 @@
 #include "logging/logTagSet.hpp"
 #include "logging/logTag.hpp"
 #include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/ostream.hpp"
@@ -87,6 +86,26 @@
 //
 #define LogHandle(...)  Log<LOG_TAGS(__VA_ARGS__)>
 
+template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+class Log;
+
+// Non-template helper class for implementing write-slowpath in cpp
+class LogWriteHelper : AllStatic {
+ private:
+
+  template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+  friend class Log;
+
+  ATTRIBUTE_PRINTF(6, 0)
+  static void write_large(LogTagSet& lts,
+                          LogLevelType level,
+                          const char* prefix,
+                          size_t prefix_len,
+                          size_t msg_len,
+                          const char* fmt,
+                          va_list args);
+};
+
 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG,
           LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
 class Log VALUE_OBJ_CLASS_SPEC {
@@ -133,21 +152,14 @@
     // Check that string fits in buffer; resize buffer if necessary
     int ret = os::log_vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
     assert(ret >= 0, "Log message buffer issue");
-    if ((size_t)ret >= sizeof(buf)) {
-      size_t newbuf_len = prefix_len + ret + 1;
-      char* newbuf = NEW_C_HEAP_ARRAY(char, newbuf_len, mtLogging);
-      prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(newbuf, newbuf_len);
-      ret = os::log_vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, saved_args);
-      assert(ret >= 0, "Log message buffer issue");
-      puts(level, newbuf);
-      FREE_C_HEAP_ARRAY(char, newbuf);
+    size_t msg_len = ret;
+    LogTagSet& lts = LogTagSetMapping<T0, T1, T2, T3, T4>::tagset();
+    if (msg_len >= sizeof(buf)) {
+      LogWriteHelper::write_large(lts, level, buf, prefix_len, msg_len, fmt, saved_args);
     } else {
-      puts(level, buf);
+      lts.log(level, buf);
     }
-  }
-
-  static void puts(LogLevelType level, const char* string) {
-    LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().log(level, string);
+    va_end(saved_args);
   }
 
 #define LOG_LEVEL(level, name) ATTRIBUTE_PRINTF(2, 0) \
--- a/hotspot/src/share/vm/logging/logPrefix.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/logging/logPrefix.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -38,6 +38,10 @@
 // List of prefixes for specific tags and/or tagsets.
 // Syntax: LOG_PREFIX(<name of prefixer function>, LOG_TAGS(<chosen log tags>))
 // Where the prefixer function matches the following signature: size_t (*)(char*, size_t)
+
+// Prefix function for internal vm test
+DEBUG_ONLY(size_t Test_log_prefix_prefixer(char* buf, size_t len);)
+
 #define LOG_PREFIX_LIST \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, age)) \
@@ -72,6 +76,7 @@
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, start)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, stats)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, time)) \
+  DEBUG_ONLY(LOG_PREFIX(Test_log_prefix_prefixer, LOG_TAGS(logging, test))) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, tlab))
 
 
--- a/hotspot/src/share/vm/logging/logTag.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/logging/logTag.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -90,6 +90,7 @@
   LOG_TAG(survivor) \
   LOG_TAG(sweep) \
   LOG_TAG(task) \
+  DEBUG_ONLY(LOG_TAG(test)) \
   LOG_TAG(thread) \
   LOG_TAG(tlab) \
   LOG_TAG(time) \
--- a/hotspot/src/share/vm/logging/logTagSet.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -68,6 +68,10 @@
     return _ntags;
   }
 
+  LogTagType tag(size_t idx) const {
+    return _tag[idx];
+  }
+
   bool contains(LogTagType tag) const {
     for (size_t i = 0; _tag[i] != LogTag::__NO_TAG; i++) {
       if (tag == _tag[i]) {
--- a/hotspot/src/share/vm/memory/universe.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/memory/universe.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -878,6 +878,57 @@
   return UnscaledNarrowOop;
 }
 
+void initialize_known_method(LatestMethodCache* method_cache,
+                             InstanceKlass* ik,
+                             const char* method,
+                             Symbol* signature,
+                             bool is_static, TRAPS)
+{
+  TempNewSymbol name = SymbolTable::new_symbol(method, CHECK);
+  Method* m = NULL;
+  // The klass must be linked before looking up the method.
+  if (!ik->link_class_or_fail(THREAD) ||
+      ((m = ik->find_method(name, signature)) == NULL) ||
+      is_static != m->is_static()) {
+    ResourceMark rm(THREAD);
+    // NoSuchMethodException doesn't actually work because it tries to run the
+    // <init> function before java_lang_Class is linked. Print error and exit.
+    vm_exit_during_initialization(err_msg("Unable to link/verify %s.%s method",
+                                 ik->name()->as_C_string(), method));
+  }
+  method_cache->init(ik, m);
+}
+
+void Universe::initialize_known_methods(TRAPS) {
+  // Set up static method for registering finalizers
+  initialize_known_method(_finalizer_register_cache,
+                          SystemDictionary::Finalizer_klass(),
+                          "register",
+                          vmSymbols::object_void_signature(), true, CHECK);
+
+  initialize_known_method(_throw_illegal_access_error_cache,
+                          SystemDictionary::internal_Unsafe_klass(),
+                          "throwIllegalAccessError",
+                          vmSymbols::void_method_signature(), true, CHECK);
+
+  // Set up method for registering loaded classes in class loader vector
+  initialize_known_method(_loader_addClass_cache,
+                          SystemDictionary::ClassLoader_klass(),
+                          "addClass",
+                          vmSymbols::class_void_signature(), false, CHECK);
+
+  // Set up method for checking protection domain
+  initialize_known_method(_pd_implies_cache,
+                          SystemDictionary::ProtectionDomain_klass(),
+                          "impliesCreateAccessControlContext",
+                          vmSymbols::void_boolean_signature(), false, CHECK);
+
+  // Set up method for stack walking
+  initialize_known_method(_do_stack_walk_cache,
+                          SystemDictionary::AbstractStackWalker_klass(),
+                          "doStackWalk",
+                          vmSymbols::doStackWalk_signature(), false, CHECK);
+}
 
 void universe2_init() {
   EXCEPTION_MARK;
@@ -906,46 +957,46 @@
   HandleMark hm(THREAD);
   Klass* k;
   instanceKlassHandle k_h;
-    // Setup preallocated empty java.lang.Class array
-    Universe::_the_empty_class_klass_array = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_false);
+  // Setup preallocated empty java.lang.Class array
+  Universe::_the_empty_class_klass_array = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_false);
 
-    // Setup preallocated OutOfMemoryError errors
-    k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false);
-    k_h = instanceKlassHandle(THREAD, k);
-    Universe::_out_of_memory_error_java_heap = k_h->allocate_instance(CHECK_false);
-    Universe::_out_of_memory_error_metaspace = k_h->allocate_instance(CHECK_false);
-    Universe::_out_of_memory_error_class_metaspace = k_h->allocate_instance(CHECK_false);
-    Universe::_out_of_memory_error_array_size = k_h->allocate_instance(CHECK_false);
-    Universe::_out_of_memory_error_gc_overhead_limit =
-      k_h->allocate_instance(CHECK_false);
-    Universe::_out_of_memory_error_realloc_objects = k_h->allocate_instance(CHECK_false);
+  // Setup preallocated OutOfMemoryError errors
+  k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_OutOfMemoryError(), true, CHECK_false);
+  k_h = instanceKlassHandle(THREAD, k);
+  Universe::_out_of_memory_error_java_heap = k_h->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_metaspace = k_h->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_class_metaspace = k_h->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_array_size = k_h->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_gc_overhead_limit =
+    k_h->allocate_instance(CHECK_false);
+  Universe::_out_of_memory_error_realloc_objects = k_h->allocate_instance(CHECK_false);
 
-    // Setup preallocated cause message for delayed StackOverflowError
-    if (StackReservedPages > 0) {
-      Universe::_delayed_stack_overflow_error_message =
-        java_lang_String::create_oop_from_str("Delayed StackOverflowError due to ReservedStackAccess annotated method", CHECK_false);
-    }
+  // Setup preallocated cause message for delayed StackOverflowError
+  if (StackReservedPages > 0) {
+    Universe::_delayed_stack_overflow_error_message =
+      java_lang_String::create_oop_from_str("Delayed StackOverflowError due to ReservedStackAccess annotated method", CHECK_false);
+  }
 
-    // Setup preallocated NullPointerException
-    // (this is currently used for a cheap & dirty solution in compiler exception handling)
-    k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_NullPointerException(), true, CHECK_false);
-    Universe::_null_ptr_exception_instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
-    // Setup preallocated ArithmeticException
-    // (this is currently used for a cheap & dirty solution in compiler exception handling)
-    k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ArithmeticException(), true, CHECK_false);
-    Universe::_arithmetic_exception_instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
-    // Virtual Machine Error for when we get into a situation we can't resolve
-    k = SystemDictionary::resolve_or_fail(
-      vmSymbols::java_lang_VirtualMachineError(), true, CHECK_false);
-    bool linked = InstanceKlass::cast(k)->link_class_or_fail(CHECK_false);
-    if (!linked) {
-      tty->print_cr("Unable to link/verify VirtualMachineError class");
-      return false; // initialization failed
-    }
-    Universe::_virtual_machine_error_instance =
-      InstanceKlass::cast(k)->allocate_instance(CHECK_false);
+  // Setup preallocated NullPointerException
+  // (this is currently used for a cheap & dirty solution in compiler exception handling)
+  k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_NullPointerException(), true, CHECK_false);
+  Universe::_null_ptr_exception_instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
+  // Setup preallocated ArithmeticException
+  // (this is currently used for a cheap & dirty solution in compiler exception handling)
+  k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ArithmeticException(), true, CHECK_false);
+  Universe::_arithmetic_exception_instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
+  // Virtual Machine Error for when we get into a situation we can't resolve
+  k = SystemDictionary::resolve_or_fail(
+    vmSymbols::java_lang_VirtualMachineError(), true, CHECK_false);
+  bool linked = InstanceKlass::cast(k)->link_class_or_fail(CHECK_false);
+  if (!linked) {
+    tty->print_cr("Unable to link/verify VirtualMachineError class");
+    return false; // initialization failed
+  }
+  Universe::_virtual_machine_error_instance =
+    InstanceKlass::cast(k)->allocate_instance(CHECK_false);
 
-    Universe::_vm_exception = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
+  Universe::_vm_exception = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
 
   if (!DumpSharedSpaces) {
     // These are the only Java fields that are currently set during shared space dumping.
@@ -986,71 +1037,7 @@
     Universe::_preallocated_out_of_memory_error_avail_count = (jint)len;
   }
 
-
-  // Setup static method for registering finalizers
-  // The finalizer klass must be linked before looking up the method, in
-  // case it needs to get rewritten.
-  SystemDictionary::Finalizer_klass()->link_class(CHECK_false);
-  Method* m = SystemDictionary::Finalizer_klass()->find_method(
-                                  vmSymbols::register_method_name(),
-                                  vmSymbols::register_method_signature());
-  if (m == NULL || !m->is_static()) {
-    tty->print_cr("Unable to link/verify Finalizer.register method");
-    return false; // initialization failed (cannot throw exception yet)
-  }
-  Universe::_finalizer_register_cache->init(
-    SystemDictionary::Finalizer_klass(), m);
-
-  SystemDictionary::internal_Unsafe_klass()->link_class(CHECK_false);
-  m = SystemDictionary::internal_Unsafe_klass()->find_method(
-                                  vmSymbols::throwIllegalAccessError_name(),
-                                  vmSymbols::void_method_signature());
-  if (m != NULL && !m->is_static()) {
-    // Note null is okay; this method is used in itables, and if it is null,
-    // then AbstractMethodError is thrown instead.
-    tty->print_cr("Unable to link/verify Unsafe.throwIllegalAccessError method");
-    return false; // initialization failed (cannot throw exception yet)
-  }
-  Universe::_throw_illegal_access_error_cache->init(
-    SystemDictionary::internal_Unsafe_klass(), m);
-
-  // Setup method for registering loaded classes in class loader vector
-  SystemDictionary::ClassLoader_klass()->link_class(CHECK_false);
-  m = SystemDictionary::ClassLoader_klass()->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature());
-  if (m == NULL || m->is_static()) {
-    tty->print_cr("Unable to link/verify ClassLoader.addClass method");
-    return false; // initialization failed (cannot throw exception yet)
-  }
-  Universe::_loader_addClass_cache->init(
-    SystemDictionary::ClassLoader_klass(), m);
-
-  // Setup method for checking protection domain
-  SystemDictionary::ProtectionDomain_klass()->link_class(CHECK_false);
-  m = SystemDictionary::ProtectionDomain_klass()->
-            find_method(vmSymbols::impliesCreateAccessControlContext_name(),
-                        vmSymbols::void_boolean_signature());
-  // Allow NULL which should only happen with bootstrapping.
-  if (m != NULL) {
-    if (m->is_static()) {
-      // NoSuchMethodException doesn't actually work because it tries to run the
-      // <init> function before java_lang_Class is linked. Print error and exit.
-      tty->print_cr("ProtectionDomain.impliesCreateAccessControlContext() has the wrong linkage");
-      return false; // initialization failed
-    }
-    Universe::_pd_implies_cache->init(
-      SystemDictionary::ProtectionDomain_klass(), m);
-  }
-
-  // Setup method for stack walking
-  InstanceKlass::cast(SystemDictionary::AbstractStackWalker_klass())->link_class(CHECK_false);
-  m = InstanceKlass::cast(SystemDictionary::AbstractStackWalker_klass())->
-            find_method(vmSymbols::doStackWalk_name(),
-                        vmSymbols::doStackWalk_signature());
-  // Allow NULL which should only happen with bootstrapping.
-  if (m != NULL) {
-    Universe::_do_stack_walk_cache->init(
-      SystemDictionary::AbstractStackWalker_klass(), m);
-  }
+  Universe::initialize_known_methods(CHECK_false);
 
   // This needs to be done before the first scavenge/gc, since
   // it's an input to soft ref clearing policy.
--- a/hotspot/src/share/vm/memory/universe.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/memory/universe.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -323,6 +323,9 @@
 
   static Method*      do_stack_walk_method()          { return _do_stack_walk_cache->get_method(); }
 
+  // Function to initialize these
+  static void initialize_known_methods(TRAPS);
+
   static oop          null_ptr_exception_instance()   { return _null_ptr_exception_instance;   }
   static oop          arithmetic_exception_instance() { return _arithmetic_exception_instance; }
   static oop          virtual_machine_error_instance() { return _virtual_machine_error_instance; }
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -461,8 +461,6 @@
 
 #endif //PRODUCT
 
-static int max_objArray_print_length = 4;
-
 void ObjArrayKlass::oop_print_value_on(oop obj, outputStream* st) {
   assert(obj->is_objArray(), "must be objArray");
   st->print("a ");
@@ -470,16 +468,6 @@
   int len = objArrayOop(obj)->length();
   st->print("[%d] ", len);
   obj->print_address_on(st);
-  if (NOT_PRODUCT(PrintOopAddress ||) PrintMiscellaneous && (WizardMode || Verbose)) {
-    st->print("{");
-    for (int i = 0; i < len; i++) {
-      if (i > max_objArray_print_length) {
-        st->print("..."); break;
-      }
-      st->print(" " INTPTR_FORMAT, (intptr_t)(void*)objArrayOop(obj)->obj_at(i));
-    }
-    st->print(" }");
-  }
 }
 
 const char* ObjArrayKlass::internal_name() const {
--- a/hotspot/src/share/vm/oops/oop.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/oops/oop.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -44,9 +44,8 @@
 }
 
 void oopDesc::print_address_on(outputStream* st) const {
-  if (PrintOopAddress) {
-    st->print("{" INTPTR_FORMAT "}", p2i(this));
-  }
+  st->print("{" INTPTR_FORMAT "}", p2i(this));
+
 }
 
 void oopDesc::print()         { print_on(tty);         }
@@ -76,7 +75,7 @@
     st->print("NULL");
   } else if (java_lang_String::is_instance(obj)) {
     java_lang_String::print(obj, st);
-    if (PrintOopAddress) print_address_on(st);
+    print_address_on(st);
   } else {
     klass()->oop_print_value_on(obj, st);
   }
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -2315,6 +2315,8 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////
+#if INCLUDE_SERVICES
+// Attach is disabled if SERVICES is not included
 
 // type for the Agent_OnAttach entry point
 extern "C" {
@@ -2416,6 +2418,7 @@
   return result;
 }
 
+#endif // INCLUDE_SERVICES
 ////////////////////////////////////////////////////////////////////////////////////////////////
 
 // Setup current current thread for event collection.
--- a/hotspot/src/share/vm/prims/jvmtiExport.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiExport.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -377,9 +377,11 @@
 
   static void transition_pending_onload_raw_monitors() NOT_JVMTI_RETURN;
 
+#if INCLUDE_SERVICES
   // attach support
   static jint load_agent_library(const char *agent, const char *absParam, const char *options, outputStream* out) NOT_JVMTI_RETURN_(JNI_ERR);
   static jint load_agent_library(AttachOperation* op, outputStream* out) NOT_JVMTI_RETURN_(JNI_ERR);
+#endif
 
   // SetNativeMethodPrefix support
   static char** get_all_native_method_prefixes(int* count_ptr) NOT_JVMTI_RETURN_(NULL);
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -66,15 +66,15 @@
 #define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp"
 #define DEFAULT_JAVA_LAUNCHER  "generic"
 
-#define UNSUPPORTED_GC_OPTION(gc)                                     \
-do {                                                                  \
-  if (gc) {                                                           \
-    if (FLAG_IS_CMDLINE(gc)) {                                        \
-      warning(#gc " is not supported in this VM.  Using Serial GC."); \
-    }                                                                 \
-    FLAG_SET_DEFAULT(gc, false);                                      \
-  }                                                                   \
-} while(0)
+#define UNSUPPORTED_GC_OPTION(gc)                         \
+  do {                                                    \
+    if (gc) {                                             \
+      if (FLAG_IS_CMDLINE(gc)) {                          \
+        warning("-XX:+" #gc " not supported in this VM"); \
+      }                                                   \
+      FLAG_SET_DEFAULT(gc, false);                        \
+    }                                                     \
+  } while(0)
 
 char*  Arguments::_jvm_flags_file               = NULL;
 char** Arguments::_jvm_flags_array              = NULL;
@@ -385,6 +385,7 @@
   { "JNIDetachReleasesMonitors",     JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "UseAltSigs",                    JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { "SegmentedHeapDumpThreshold",    JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "PrintOopAddress",               JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
 
 #ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
   { "dep > obs",                    JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
@@ -1936,26 +1937,45 @@
                                           CollectorPolicy::compute_heap_alignment());
 }
 
+bool Arguments::gc_selected() {
+#if INCLUDE_ALL_GCS
+  return UseSerialGC || UseParallelGC || UseParallelOldGC || UseConcMarkSweepGC || UseG1GC;
+#else
+  return UseSerialGC;
+#endif // INCLUDE_ALL_GCS
+}
+
 void Arguments::select_gc_ergonomically() {
+#if INCLUDE_ALL_GCS
   if (os::is_server_class_machine()) {
     if (should_auto_select_low_pause_collector()) {
-      FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true);
+      FLAG_SET_ERGO_IF_DEFAULT(bool, UseConcMarkSweepGC, true);
     } else {
 #if defined(JAVASE_EMBEDDED)
-      FLAG_SET_ERGO(bool, UseParallelGC, true);
+      FLAG_SET_ERGO_IF_DEFAULT(bool, UseParallelGC, true);
 #else
-      FLAG_SET_ERGO(bool, UseG1GC, true);
+      FLAG_SET_ERGO_IF_DEFAULT(bool, UseG1GC, true);
 #endif
     }
   } else {
-    FLAG_SET_ERGO(bool, UseSerialGC, true);
-  }
+    FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true);
+  }
+#else
+  UNSUPPORTED_GC_OPTION(UseG1GC);
+  UNSUPPORTED_GC_OPTION(UseParallelGC);
+  UNSUPPORTED_GC_OPTION(UseParallelOldGC);
+  UNSUPPORTED_GC_OPTION(UseConcMarkSweepGC);
+  UNSUPPORTED_GC_OPTION(UseParNewGC);
+  FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true);
+#endif // INCLUDE_ALL_GCS
 }
 
 void Arguments::select_gc() {
   if (!gc_selected()) {
     select_gc_ergonomically();
-    guarantee(gc_selected(), "No GC selected");
+    if (!gc_selected()) {
+      vm_exit_during_initialization("Garbage collector not selected (default collector explicitly disabled)", NULL);
+    }
   }
 }
 
@@ -2080,16 +2100,6 @@
   log_trace(gc)("ConcGCThreads: %u", ConcGCThreads);
 }
 
-#if !INCLUDE_ALL_GCS
-#ifdef ASSERT
-static bool verify_serial_gc_flags() {
-  return (UseSerialGC &&
-        !(UseParNewGC || (UseConcMarkSweepGC) || UseG1GC ||
-          UseParallelGC || UseParallelOldGC));
-}
-#endif // ASSERT
-#endif // INCLUDE_ALL_GCS
-
 void Arguments::set_gc_specific_flags() {
 #if INCLUDE_ALL_GCS
   // Set per-collector flags
@@ -2111,8 +2121,6 @@
     // Keeping the heap 100% free is hard ;-) so limit it to 99%.
     FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99);
   }
-#else // INCLUDE_ALL_GCS
-  assert(verify_serial_gc_flags(), "SerialGC unset");
 #endif // INCLUDE_ALL_GCS
 }
 
@@ -3955,17 +3963,6 @@
   }
 }
 
-#if !INCLUDE_ALL_GCS
-static void force_serial_gc() {
-  FLAG_SET_DEFAULT(UseSerialGC, true);
-  UNSUPPORTED_GC_OPTION(UseG1GC);
-  UNSUPPORTED_GC_OPTION(UseParallelGC);
-  UNSUPPORTED_GC_OPTION(UseParallelOldGC);
-  UNSUPPORTED_GC_OPTION(UseConcMarkSweepGC);
-  UNSUPPORTED_GC_OPTION(UseParNewGC);
-}
-#endif // INCLUDE_ALL_GCS
-
 // Sharing support
 // Construct the path to the archive
 static char* get_shared_archive_path() {
@@ -4360,9 +4357,6 @@
   // Set object alignment values.
   set_object_alignment();
 
-#if !INCLUDE_ALL_GCS
-  force_serial_gc();
-#endif // INCLUDE_ALL_GCS
 #if !INCLUDE_CDS
   if (DumpSharedSpaces || RequireSharedSpaces) {
     jio_fprintf(defaultStream::error_stream(),
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -567,7 +567,7 @@
   static jint adjust_after_os();
 
   static void set_gc_specific_flags();
-  static inline bool gc_selected(); // whether a gc has been selected
+  static bool gc_selected(); // whether a gc has been selected
   static void select_gc_ergonomically();
 #if INCLUDE_JVMCI
   // Check consistency of jvmci vm argument settings.
@@ -732,10 +732,6 @@
   static void check_unsupported_dumping_properties() NOT_CDS_RETURN;
 };
 
-bool Arguments::gc_selected() {
-  return UseConcMarkSweepGC || UseG1GC || UseParallelGC || UseParallelOldGC || UseSerialGC;
-}
-
 // Disable options not supported in this release, with a warning if they
 // were explicitly requested on the command-line
 #define UNSUPPORTED_OPTION(opt, description)                    \
--- a/hotspot/src/share/vm/runtime/globals.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -951,9 +951,6 @@
   notproduct(bool, PrintMallocFree, false,                                  \
           "Trace calls to C heap malloc/free allocation")                   \
                                                                             \
-  product(bool, PrintOopAddress, false,                                     \
-          "Always print the location of the oop")                           \
-                                                                            \
   notproduct(bool, VerifyCodeCache, false,                                  \
           "Verify code cache on memory allocation/deallocation")            \
                                                                             \
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -290,6 +290,12 @@
 
 #define FLAG_SET_CMDLINE(type, name, value) (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::COMMAND_LINE))
 #define FLAG_SET_ERGO(type, name, value)    (CommandLineFlagsEx::type##AtPut(FLAG_MEMBER_WITH_TYPE(name,type), (type)(value), Flag::ERGONOMIC))
+#define FLAG_SET_ERGO_IF_DEFAULT(type, name, value) \
+  do {                                              \
+    if (FLAG_IS_DEFAULT(name)) {                    \
+      FLAG_SET_ERGO(type, name, value);             \
+    }                                               \
+  } while (0)
 
 // Can't put the following in CommandLineFlags because
 // of a circular dependency on the enum definition.
--- a/hotspot/src/share/vm/runtime/init.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/runtime/init.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -47,6 +47,7 @@
 void mutex_init();
 void chunkpool_init();
 void perfMemory_init();
+void SuspendibleThreadSet_init() NOT_ALL_GCS_RETURN;
 
 // Initialization done by Java thread in init_globals()
 void management_init();
@@ -93,6 +94,7 @@
   mutex_init();
   chunkpool_init();
   perfMemory_init();
+  SuspendibleThreadSet_init();
 }
 
 
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -61,17 +61,19 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapInfoDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<FinalizerInfoDCmd>(full_export, true, false));
-#if INCLUDE_SERVICES // Heap dumping/inspection supported
+#if INCLUDE_SERVICES
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHierarchyDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SymboltableDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<StringtableDCmd>(full_export, true, false));
+#if INCLUDE_JVMTI // Both JVMTI and SERVICES have to be enabled to have this dcmd
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIAgentLoadDCmd>(full_export, true, false));
+#endif // INCLUDE_JVMTI
 #endif // INCLUDE_SERVICES
 #if INCLUDE_JVMTI
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIDataDumpDCmd>(full_export, true, false));
-  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JVMTIAgentLoadDCmd>(full_export, true, false));
 #endif // INCLUDE_JVMTI
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
@@ -255,6 +257,7 @@
   }
 }
 
+#if INCLUDE_SERVICES
 JVMTIAgentLoadDCmd::JVMTIAgentLoadDCmd(outputStream* output, bool heap) :
                                        DCmdWithParser(output, heap),
   _libpath("library path", "Absolute path of the JVMTI agent to load.",
@@ -314,6 +317,7 @@
     return 0;
   }
 }
+#endif // INCLUDE_SERVICES
 
 void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPS) {
   // load sun.misc.VMSupport
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp	Tue Mar 29 20:51:59 2016 +0200
@@ -174,6 +174,8 @@
   virtual void execute(DCmdSource source, TRAPS);
 };
 
+#if INCLUDE_SERVICES
+#if INCLUDE_JVMTI
 class JVMTIAgentLoadDCmd : public DCmdWithParser {
 protected:
   DCmdArgument<char*> _libpath;
@@ -193,6 +195,8 @@
   static int num_arguments();
   virtual void execute(DCmdSource source, TRAPS);
 };
+#endif // INCLUDE_JVMTI
+#endif // INCLUDE_SERVICES
 
 class VMDynamicLibrariesDCmd : public DCmd {
 public:
--- a/hotspot/src/share/vm/utilities/exceptions.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -508,12 +508,13 @@
   ResourceMark rm;
   Symbol* message = java_lang_Throwable::detail_message(exception());
   if (message != NULL) {
-    log_info(exceptions)("Exception <%s: %s> (" INTPTR_FORMAT ")\n thrown in %s",
+    log_info(exceptions)("Exception <%s: %s>\n thrown in %s",
                          exception->print_value_string(),
-                         message->as_C_string(), p2i(exception()), tempst.as_string());
+                         message->as_C_string(),
+                         tempst.as_string());
   } else {
-    log_info(exceptions)("Exception <%s> (" INTPTR_FORMAT ")\n thrown in %s",
+    log_info(exceptions)("Exception <%s>\n thrown in %s",
                          exception->print_value_string(),
-                         p2i(exception()), tempst.as_string());
+                         tempst.as_string());
   }
 }
--- a/hotspot/src/share/vm/utilities/internalVMTests.cpp	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp	Tue Mar 29 20:51:59 2016 +0200
@@ -67,9 +67,11 @@
   run_unit_test(Test_linked_list);
   run_unit_test(TestChunkedList_test);
   run_unit_test(JSON_test);
-  run_unit_test(Test_log_length);
   run_unit_test(Test_configure_stdout);
   run_unit_test(Test_logconfiguration_subscribe);
+  run_unit_test(Test_log_prefix);
+  run_unit_test(Test_log_big);
+  run_unit_test(Test_logtagset_duplicates);
   run_unit_test(DirectivesParser_test);
   run_unit_test(Test_TempNewSymbol);
 #if INCLUDE_VM_STRUCTS
--- a/hotspot/test/TEST.groups	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/test/TEST.groups	Tue Mar 29 20:51:59 2016 +0200
@@ -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/gc/arguments/TestDisableDefaultGC.java	Tue Mar 29 20:51:59 2016 +0200
@@ -0,0 +1,51 @@
+/*
+ * 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 TestDisableDefaultGC
+ * @summary Test that the VM complains when the default GC is disabled and no other GC is specified
+ * @bug 8068579
+ * @key gc
+ * @library /testlibrary
+ * @requires vm.gc=="null"
+ * @modules java.base/sun.misc
+ *          java.management
+ * @run driver TestDisableDefaultGC
+ */
+
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.OutputAnalyzer;
+
+public class TestDisableDefaultGC {
+    public static void main(String[] args) throws Exception {
+        // Start VM, disabling all possible default GCs
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:-UseSerialGC",
+                                                                  "-XX:-UseParallelGC",
+                                                                  "-XX:-UseG1GC",
+                                                                  "-XX:-UseConcMarkSweepGC",
+                                                                  "-version");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldMatch("Garbage collector not selected");
+        output.shouldHaveExitValue(1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java	Tue Mar 29 20:51:59 2016 +0200
@@ -0,0 +1,72 @@
+/*
+ * 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
+ * @bug 8060463
+ * @summary Verify that objects promoted from eden space to survivor space
+ *          with large values for SurvivorAlignmentInBytes succeed.
+ * @requires vm.opt.ExplicitGCInvokesConcurrent != true
+ * @run main/othervm -Xmx128m
+ *                   -XX:+UnlockExperimentalVMOptions
+ *                   -XX:SurvivorAlignmentInBytes=8 -XX:SurvivorRatio=1
+ *                   -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB
+ *                   TestPromotionLABLargeSurvivorAlignment
+ * @run main/othervm -Xmx128m
+ *                   -XX:+UnlockExperimentalVMOptions
+ *                   -XX:SurvivorAlignmentInBytes=16 -XX:SurvivorRatio=1
+ *                   -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB
+ *                   TestPromotionLABLargeSurvivorAlignment
+ * @run main/othervm -Xmx128m
+ *                   -XX:+UnlockExperimentalVMOptions
+ *                   -XX:SurvivorAlignmentInBytes=512 -XX:SurvivorRatio=1
+ *                   -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB
+ *                   TestPromotionLABLargeSurvivorAlignment
+ * @run main/othervm -Xmx128m
+ *                   -XX:+UnlockExperimentalVMOptions
+ *                   -XX:SurvivorAlignmentInBytes=1k -XX:SurvivorRatio=1
+ *                   -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB
+ *                   TestPromotionLABLargeSurvivorAlignment
+ * @run main/othervm -Xmx128m
+ *                   -XX:+UnlockExperimentalVMOptions
+ *                   -XX:SurvivorAlignmentInBytes=4k -XX:SurvivorRatio=1
+ *                   -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB
+ *                   TestPromotionLABLargeSurvivorAlignment
+ * @run main/othervm -Xmx128m
+ *                   -XX:+UnlockExperimentalVMOptions
+ *                   -XX:SurvivorAlignmentInBytes=16k -XX:SurvivorRatio=1
+ *                   -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB
+ *                   TestPromotionLABLargeSurvivorAlignment
+ */
+public class TestPromotionLABLargeSurvivorAlignment {
+    public static void main(String args[]) {
+        Object garbage[] = new Object[1000000];
+        for (int i = 0; i < garbage.length; i++) {
+            garbage[i] = new byte[0];
+        }
+        for (int i = 0; i < 2; i++) {
+            System.gc();
+        }
+    }
+}
+
--- a/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java	Tue Mar 29 20:51:59 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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
@@ -38,7 +38,7 @@
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-Xlog:exceptions=info", "NoClassFound");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("<a 'java/lang/ClassNotFoundException': NoClassFound>");
+        output.shouldContain("<a 'java/lang/ClassNotFoundException'").shouldContain(": NoClassFound>");
         output.shouldNotContain("<a 'java/lang/ClassNotFoundException'>");
         output.shouldHaveExitValue(1);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SelectionResolution/AbstractMethodErrorTest.java	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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	Tue Mar 29 20:51:59 2016 +0200
@@ -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());
+        }
+    }
+}
--- a/hotspot/test/runtime/logging/ExceptionsTest.java	Tue Mar 29 14:37:07 2016 -0400
+++ b/hotspot/test/runtime/logging/ExceptionsTest.java	Tue Mar 29 20:51:59 2016 +0200
@@ -45,7 +45,7 @@
 
     static void analyzeOutputOn(ProcessBuilder pb) throws Exception {
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("<a 'java/lang/RuntimeException': Test exception 1 for logging>");
+        output.shouldContain("<a 'java/lang/RuntimeException'").shouldContain(": Test exception 1 for logging>");
         output.shouldContain(" thrown in interpreter method ");
         output.shouldHaveExitValue(0);
     }