Merge
authorprr
Fri, 10 Feb 2017 08:57:42 -0800
changeset 43825 dc94c9d10e3a
parent 43824 a77cc25713e9 (current diff)
parent 43728 e188ba772b26 (diff)
child 43826 ff4d8d468f68
Merge
hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassCollector.java
hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionTest.java
hotspot/test/compiler/aot/fingerprint/CDSDumper.java
hotspot/test/compiler/aot/fingerprint/CDSRunner.java
hotspot/test/compiler/aot/fingerprint/SelfChanged.java
hotspot/test/compiler/aot/fingerprint/SelfChangedCDS.java
hotspot/test/compiler/aot/fingerprint/SuperChanged.java
hotspot/test/compiler/c2/cr7200264/Test7200264.sh
hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java
jaxws/src/java.annotations.common/share/classes/javax/annotation/Generated.java
jaxws/src/java.annotations.common/share/classes/javax/annotation/PostConstruct.java
jaxws/src/java.annotations.common/share/classes/javax/annotation/PreDestroy.java
jaxws/src/java.annotations.common/share/classes/javax/annotation/Resource.java
jaxws/src/java.annotations.common/share/classes/javax/annotation/Resources.java
jaxws/src/java.annotations.common/share/classes/module-info.java
jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXTimestampParameters.java
jdk/src/java.base/share/classes/sun/security/util/CertConstraintParameters.java
jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java
jdk/test/java/lang/StackWalker/CountLocalSlots.java
jdk/test/java/lang/StackWalker/LocalsCrash.java
jdk/test/java/lang/invoke/lambda/MetafactorySamReturnTest.java
jdk/test/java/lang/invoke/modules/ModuleAccessControlTest.java
jdk/test/java/lang/invoke/modules/src/m1/module-info.java
jdk/test/java/lang/invoke/modules/src/m1/p1/Main.java
jdk/test/java/lang/invoke/modules/src/m1/p1/Type1.java
jdk/test/java/lang/invoke/modules/src/m1/p2/Type2.java
jdk/test/java/lang/invoke/modules/src/m2/module-info.java
jdk/test/java/lang/invoke/modules/src/m2/q1/Type1.java
jdk/test/java/lang/invoke/modules/src/m2/q2/Type2.java
langtools/test/tools/javac/diags/examples/PackageEmptyOrNotFound/PackageEmptyOrNotFound.java
langtools/test/tools/javac/diags/examples/PackageEmptyOrNotFound/modulesourcepath/m1x/module-info.java
--- a/.hgtags	Fri Feb 10 13:32:11 2017 +0530
+++ b/.hgtags	Fri Feb 10 08:57:42 2017 -0800
@@ -398,3 +398,4 @@
 d7034ff7f8e257e81c9f95c7785dd4eaaa3c2afc jdk-9+153
 8c70d170e62c0c58b5bc3ba666bd140399b98c9c jdk-10+0
 45b751afd11e6c05991cf4913c5a0ac3304fcc4e jdk-9+154
+f4aff695ffe05cfdb69d8af25a4ddc6a029754ea jdk-9+155
--- a/.hgtags-top-repo	Fri Feb 10 13:32:11 2017 +0530
+++ b/.hgtags-top-repo	Fri Feb 10 08:57:42 2017 -0800
@@ -397,3 +397,4 @@
 ef056360ddf3977d7d2ddbeb456a4d612d19ea05 jdk-9+152
 816a6d03a7c44edfbd8780110529f1bdc3964fb9 jdk-9+153
 8d26916eaa21b689835ffc1c0dbf12470aa9be61 jdk-9+154
+688a3863c00ebc089ab17ee1fc46272cbbd96815 jdk-9+155
--- a/common/autoconf/basics.m4	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/basics.m4	Fri Feb 10 08:57:42 2017 -0800
@@ -746,7 +746,8 @@
     fi
 
     # set SDKROOT too, Xcode tools will pick it up
-    AC_SUBST(SDKROOT,$SYSROOT)
+    SDKROOT="$SYSROOT"
+    AC_SUBST(SDKROOT)
   fi
 
   # Prepend the extra path to the global path
@@ -831,9 +832,10 @@
   CONFIGURESUPPORT_OUTPUTDIR="$OUTPUT_ROOT/configure-support"
   $MKDIR -p "$CONFIGURESUPPORT_OUTPUTDIR"
 
-  AC_SUBST(SPEC, $OUTPUT_ROOT/spec.gmk)
-  AC_SUBST(CONF_NAME, $CONF_NAME)
-  AC_SUBST(OUTPUT_ROOT, $OUTPUT_ROOT)
+  SPEC="$OUTPUT_ROOT/spec.gmk"
+  AC_SUBST(SPEC)
+  AC_SUBST(CONF_NAME)
+  AC_SUBST(OUTPUT_ROOT)
   AC_SUBST(CONFIGURESUPPORT_OUTPUTDIR)
 
   # The spec.gmk file contains all variables for the make system.
--- a/common/autoconf/boot-jdk.m4	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/boot-jdk.m4	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -325,7 +325,6 @@
   fi
   AC_MSG_CHECKING([if Boot JDK is 32 or 64 bits])
   AC_MSG_RESULT([$BOOT_JDK_BITS])
-  AC_SUBST(BOOT_JDK_BITS)
 ])
 
 AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS],
--- a/common/autoconf/build-performance.m4	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/build-performance.m4	Fri Feb 10 08:57:42 2017 -0800
@@ -224,7 +224,7 @@
         AC_MSG_ERROR([On macosx, ccache 3.2 or later is required, found $CCACHE_VERSION])
       fi
     fi
-    if test "x$USE_PRECOMPILED_HEADER" = "x1"; then
+    if test "x$USE_PRECOMPILED_HEADER" = "xtrue"; then
       HAS_BAD_CCACHE=[`$ECHO $CCACHE_VERSION | \
           $GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]$'`]
       if test "x$HAS_BAD_CCACHE" != "x"; then
@@ -362,20 +362,20 @@
       [disable using precompiled headers when compiling C++ @<:@enabled@:>@])],
       [ENABLE_PRECOMPH=${enable_precompiled_headers}], [ENABLE_PRECOMPH=yes])
 
-  USE_PRECOMPILED_HEADER=1
+  USE_PRECOMPILED_HEADER=true
   AC_MSG_CHECKING([If precompiled header is enabled])
   if test "x$ENABLE_PRECOMPH" = xno; then
     AC_MSG_RESULT([no, forced])
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$ICECC" != "x"; then
     AC_MSG_RESULT([no, does not work effectively with icecc])
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     AC_MSG_RESULT([no, does not work with Solaris Studio])
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
     AC_MSG_RESULT([no, does not work with xlc])
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   else
     AC_MSG_RESULT([yes])
   fi
@@ -387,7 +387,7 @@
       echo "int alfa();" > conftest.h
       $CXX -x c++-header conftest.h -o conftest.hpp.gch 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD
       if test ! -f conftest.hpp.gch; then
-        USE_PRECOMPILED_HEADER=0
+        USE_PRECOMPILED_HEADER=false
         AC_MSG_RESULT([no])
       else
         AC_MSG_RESULT([yes])
--- a/common/autoconf/flags.m4	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/flags.m4	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -808,7 +808,7 @@
     						 IF_FALSE: [$2CXXSTD_CXXFLAG=""])
     $2CXXFLAGS_JDK="${$2CXXFLAGS_JDK} ${$2CXXSTD_CXXFLAG}"
     $2JVM_CFLAGS="${$2JVM_CFLAGS} ${$2CXXSTD_CXXFLAG}"
-    AC_SUBST([$2CXXSTD_CXXFLAG])
+    AC_SUBST($2CXXSTD_CXXFLAG)
   fi
   if test "x$OPENJDK_TARGET_OS" = xsolaris; then
     $2CFLAGS_JDK="${$2CFLAGS_JDK} -D__solaris__"
@@ -1440,18 +1440,6 @@
 
 AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC],
 [
-  # Some Zero and Shark settings.
-  # ZERO_ARCHFLAG tells the compiler which mode to build for
-  case "${OPENJDK_TARGET_CPU}" in
-    s390)
-      ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}31"
-      ;;
-    *)
-      ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
-  esac
-  FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$ZERO_ARCHFLAG], IF_FALSE: [ZERO_ARCHFLAG=""])
-  AC_SUBST(ZERO_ARCHFLAG)
-
   # Check that the compiler supports -mX (or -qX on AIX) flags
   # Set COMPILER_SUPPORTS_TARGET_BITS_FLAG to 'true' if it does
   FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}],
@@ -1476,15 +1464,7 @@
     AC_MSG_ERROR([--enable-warnings-as-errors accepts no argument])
   fi
 
-  if test "x$WARNINGS_AS_ERRORS" = "xfalse"; then
-    # Set legacy hotspot variable
-    HOTSPOT_SET_WARNINGS_AS_ERRORS="WARNINGS_ARE_ERRORS="
-  else
-    HOTSPOT_SET_WARNINGS_AS_ERRORS=""
-  fi
-
   AC_SUBST(WARNINGS_AS_ERRORS)
-  AC_SUBST(HOTSPOT_SET_WARNINGS_AS_ERRORS)
 
   case "${TOOLCHAIN_TYPE}" in
     microsoft)
--- a/common/autoconf/generated-configure.sh	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/generated-configure.sh	Fri Feb 10 08:57:42 2017 -0800
@@ -704,7 +704,6 @@
 FIXPATH
 BUILD_GTEST
 ENABLE_AOT
-INCLUDE_DTRACE
 GCOV_ENABLED
 ZIP_EXTERNAL_DEBUG_SYMBOLS
 COPY_DEBUG_SYMBOLS
@@ -712,10 +711,8 @@
 CFLAGS_WARNINGS_ARE_ERRORS
 BUILD_CC_DISABLE_WARNING_PREFIX
 DISABLE_WARNING_PREFIX
-HOTSPOT_SET_WARNINGS_AS_ERRORS
 WARNINGS_AS_ERRORS
 COMPILER_SUPPORTS_TARGET_BITS_FLAG
-ZERO_ARCHFLAG
 LDFLAGS_TESTEXE
 LDFLAGS_TESTLIB
 CXXFLAGS_TESTEXE
@@ -884,7 +881,6 @@
 CREATE_BUILDJDK
 JLINK
 JMOD
-BOOT_JDK_BITS
 JAVAC_FLAGS
 BOOT_JDK_MODULAR
 BOOT_JDK_SOURCETARGET
@@ -974,15 +970,12 @@
 ORIGINAL_TOPDIR
 TOPDIR
 PATH_SEP
-ZERO_ARCHDEF
 HOTSPOT_BUILD_CPU_DEFINE
 HOTSPOT_BUILD_CPU_ARCH
 HOTSPOT_BUILD_CPU
 HOTSPOT_BUILD_OS_TYPE
 HOTSPOT_BUILD_OS
 OPENJDK_BUILD_BUNDLE_PLATFORM
-OPENJDK_BUILD_CPU_BUNDLE
-OPENJDK_BUILD_OS_BUNDLE
 OPENJDK_BUILD_OS_EXPORT_DIR
 OPENJDK_BUILD_CPU_OSARCH
 OPENJDK_BUILD_CPU_ISADIR
@@ -994,10 +987,7 @@
 HOTSPOT_TARGET_OS_TYPE
 HOTSPOT_TARGET_OS
 DEFINE_CROSS_COMPILE_ARCH
-LP64
 OPENJDK_TARGET_BUNDLE_PLATFORM
-OPENJDK_TARGET_CPU_BUNDLE
-OPENJDK_TARGET_OS_BUNDLE
 OPENJDK_TARGET_OS_EXPORT_DIR
 OPENJDK_TARGET_CPU_OSARCH
 OPENJDK_TARGET_CPU_ISADIR
@@ -3818,7 +3808,7 @@
 
 # ... then the rest
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -3998,7 +3988,7 @@
 
 
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -4273,7 +4263,7 @@
 
 
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -4561,7 +4551,7 @@
 
 
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -4841,7 +4831,7 @@
 
 
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -5180,7 +5170,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1485508515
+DATE_WHEN_GENERATED=1486175373
 
 ###############################################################################
 #
@@ -15936,18 +15926,14 @@
   OPENJDK_TARGET_BUNDLE_PLATFORM="${OPENJDK_TARGET_OS_BUNDLE}-${OPENJDK_TARGET_CPU_BUNDLE}"
 
 
-
-
   if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
-    A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
-    # unpack200.exe
+    # unpack200.exe. This variable is used in
+    # FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER.
     if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xmacosx; then
       OPENJDK_TARGET_ADD_LP64="-D_LP64=1"
     fi
   fi
-  LP64=$A_LP64
-
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
@@ -16092,18 +16078,14 @@
   OPENJDK_BUILD_BUNDLE_PLATFORM="${OPENJDK_BUILD_OS_BUNDLE}-${OPENJDK_BUILD_CPU_BUNDLE}"
 
 
-
-
   if test "x$OPENJDK_BUILD_CPU_BITS" = x64; then
-    A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
-    # unpack200.exe
+    # unpack200.exe. This variable is used in
+    # FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER.
     if test "x$OPENJDK_BUILD_OS" = xlinux || test "x$OPENJDK_BUILD_OS" = xmacosx; then
       OPENJDK_BUILD_ADD_LP64="-D_LP64=1"
     fi
   fi
-  LP64=$A_LP64
-
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
@@ -16173,12 +16155,6 @@
 
 
 
-  # ZERO_ARCHDEF is used to enable architecture-specific code.
-  # This is used in legacy hotspot build.
-  ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
-
-
-
 
 
 # Continue setting up basic stuff. Most remaining code require fundamental tools.
@@ -17280,7 +17256,7 @@
     fi
 
     # set SDKROOT too, Xcode tools will pick it up
-    SDKROOT=$SYSROOT
+    SDKROOT="$SYSROOT"
 
   fi
 
@@ -17528,11 +17504,9 @@
   CONFIGURESUPPORT_OUTPUTDIR="$OUTPUT_ROOT/configure-support"
   $MKDIR -p "$CONFIGURESUPPORT_OUTPUTDIR"
 
-  SPEC=$OUTPUT_ROOT/spec.gmk
-
-  CONF_NAME=$CONF_NAME
-
-  OUTPUT_ROOT=$OUTPUT_ROOT
+  SPEC="$OUTPUT_ROOT/spec.gmk"
+
+
 
 
 
@@ -30730,7 +30704,6 @@
 
 
 
-
 # Check whether --with-build-jdk was given.
 if test "${with_build_jdk+set}" = set; then :
   withval=$with_build_jdk;
@@ -51480,282 +51453,6 @@
 
 
 
-  # Some Zero and Shark settings.
-  # ZERO_ARCHFLAG tells the compiler which mode to build for
-  case "${OPENJDK_TARGET_CPU}" in
-    s390)
-      ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}31"
-      ;;
-    *)
-      ZERO_ARCHFLAG="${COMPILER_TARGET_BITS_FLAG}${OPENJDK_TARGET_CPU_BITS}"
-  esac
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    # Execute function body
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    # Execute function body
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the C compiler supports \"$ZERO_ARCHFLAG\"" >&5
-$as_echo_n "checking if the C compiler supports \"$ZERO_ARCHFLAG\"... " >&6; }
-  supports=yes
-
-  saved_cflags="$CFLAGS"
-  CFLAGS="$CFLAGS $ZERO_ARCHFLAG"
-  ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-int i;
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-else
-  supports=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-  CFLAGS="$saved_cflags"
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
-$as_echo "$supports" >&6; }
-  if test "x$supports" = "xyes" ; then
-    :
-    C_COMP_SUPPORTS="yes"
-  else
-    :
-    C_COMP_SUPPORTS="no"
-  fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    # Execute function body
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the C++ compiler supports \"$ZERO_ARCHFLAG\"" >&5
-$as_echo_n "checking if the C++ compiler supports \"$ZERO_ARCHFLAG\"... " >&6; }
-  supports=yes
-
-  saved_cxxflags="$CXXFLAGS"
-  CXXFLAGS="$CXXFLAG $ZERO_ARCHFLAG"
-  ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-int i;
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-
-else
-  supports=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-  CXXFLAGS="$saved_cxxflags"
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
-$as_echo "$supports" >&6; }
-  if test "x$supports" = "xyes" ; then
-    :
-    CXX_COMP_SUPPORTS="yes"
-  else
-    :
-    CXX_COMP_SUPPORTS="no"
-  fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if both compilers support \"$ZERO_ARCHFLAG\"" >&5
-$as_echo_n "checking if both compilers support \"$ZERO_ARCHFLAG\"... " >&6; }
-  supports=no
-  if test "x$C_COMP_SUPPORTS" = "xyes" -a "x$CXX_COMP_SUPPORTS" = "xyes"; then supports=yes; fi
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports" >&5
-$as_echo "$supports" >&6; }
-  if test "x$supports" = "xyes" ; then
-    :
-
-  else
-    :
-    ZERO_ARCHFLAG=""
-  fi
-
-
-
-
-
-
-
-
   # Check that the compiler supports -mX (or -qX on AIX) flags
   # Set COMPILER_SUPPORTS_TARGET_BITS_FLAG to 'true' if it does
 
@@ -52054,14 +51751,6 @@
     as_fn_error $? "--enable-warnings-as-errors accepts no argument" "$LINENO" 5
   fi
 
-  if test "x$WARNINGS_AS_ERRORS" = "xfalse"; then
-    # Set legacy hotspot variable
-    HOTSPOT_SET_WARNINGS_AS_ERRORS="WARNINGS_ARE_ERRORS="
-  else
-    HOTSPOT_SET_WARNINGS_AS_ERRORS=""
-  fi
-
-
 
 
   case "${TOOLCHAIN_TYPE}" in
@@ -52916,7 +52605,6 @@
   fi
 
 
-
   # Check whether --enable-aot was given.
 if test "${enable_aot+set}" = set; then :
   enableval=$enable_aot;
@@ -63694,12 +63382,14 @@
   DEFAULT_LIBPNG=bundled
   # if user didn't specify, use DEFAULT_LIBPNG
   if test "x${with_libpng}" = "x"; then
-      with_libpng=${DEFAULT_LIBPNG}
+    with_libpng=${DEFAULT_LIBPNG}
   fi
 
   if test "x${with_libpng}" = "xbundled"; then
-      USE_EXTERNAL_LIBPNG=false
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
+    USE_EXTERNAL_LIBPNG=false
+    PNG_CFLAGS=""
+    PNG_LIBS=""
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
 $as_echo "bundled" >&6; }
   elif test "x${with_libpng}" = "xsystem"; then
 
@@ -63759,28 +63449,31 @@
 
 	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-                 LIBPNG_FOUND=no
+                LIBPNG_FOUND=no
 elif test $pkg_failed = untried; then
-	 LIBPNG_FOUND=no
+	LIBPNG_FOUND=no
 else
 	PNG_CFLAGS=$pkg_cv_PNG_CFLAGS
 	PNG_LIBS=$pkg_cv_PNG_LIBS
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-	 LIBPNG_FOUND=yes
-fi
-      if test "x${LIBPNG_FOUND}" = "xyes"; then
-          USE_EXTERNAL_LIBPNG=true
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5
+	LIBPNG_FOUND=yes
+fi
+    if test "x${LIBPNG_FOUND}" = "xyes"; then
+      # PKG_CHECK_MODULES will set PNG_CFLAGS and PNG_LIBS
+      USE_EXTERNAL_LIBPNG=true
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5
 $as_echo "system" >&6; }
-      else
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: system not found" >&5
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: system not found" >&5
 $as_echo "system not found" >&6; }
-          as_fn_error $? "--with-libpng=system specified, but no libpng found!" "$LINENO" 5
-      fi
-  else
-      as_fn_error $? "Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'" "$LINENO" 5
-  fi
+      as_fn_error $? "--with-libpng=system specified, but no libpng found!" "$LINENO" 5
+    fi
+  else
+    as_fn_error $? "Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'" "$LINENO" 5
+  fi
+
+
 
 
 
@@ -63888,11 +63581,13 @@
   DEFAULT_LCMS=bundled
   # If user didn't specify, use DEFAULT_LCMS
   if test "x${with_lcms}" = "x"; then
-      with_lcms=${DEFAULT_LCMS}
+    with_lcms=${DEFAULT_LCMS}
   fi
 
   if test "x${with_lcms}" = "xbundled"; then
     USE_EXTERNAL_LCMS=false
+    LCMS_CFLAGS=""
+    LCMS_LIBS=""
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
 $as_echo "bundled" >&6; }
   elif test "x${with_lcms}" = "xsystem"; then
@@ -63966,6 +63661,7 @@
 	LCMS_FOUND=yes
 fi
     if test "x${LCMS_FOUND}" = "xyes"; then
+      # PKG_CHECK_MODULES will set LCMS_CFLAGS and LCMS_LIBS
       USE_EXTERNAL_LCMS=true
     else
       as_fn_error $? "--with-lcms=system specified, but no lcms found!" "$LINENO" 5
@@ -63984,6 +63680,8 @@
 
 
 
+
+
   # Setup libm (the maths library)
   if test "x$OPENJDK_TARGET_OS" != "xwindows"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
@@ -64768,11 +64466,11 @@
 $as_echo_n "checking if elliptic curve crypto implementation is present... " >&6; }
 
   if test -d "${SRC_ROOT}/jdk/src/jdk.crypto.ec/share/native/libsunec/impl"; then
-    ENABLE_INTREE_EC=yes
+    ENABLE_INTREE_EC=true
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
   else
-    ENABLE_INTREE_EC=no
+    ENABLE_INTREE_EC=false
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
   fi
@@ -66139,25 +65837,25 @@
 fi
 
 
-  USE_PRECOMPILED_HEADER=1
+  USE_PRECOMPILED_HEADER=true
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking If precompiled header is enabled" >&5
 $as_echo_n "checking If precompiled header is enabled... " >&6; }
   if test "x$ENABLE_PRECOMPH" = xno; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, forced" >&5
 $as_echo "no, forced" >&6; }
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$ICECC" != "x"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work effectively with icecc" >&5
 $as_echo "no, does not work effectively with icecc" >&6; }
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work with Solaris Studio" >&5
 $as_echo "no, does not work with Solaris Studio" >&6; }
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, does not work with xlc" >&5
 $as_echo "no, does not work with xlc" >&6; }
-    USE_PRECOMPILED_HEADER=0
+    USE_PRECOMPILED_HEADER=false
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
@@ -66171,7 +65869,7 @@
       echo "int alfa();" > conftest.h
       $CXX -x c++-header conftest.h -o conftest.hpp.gch 2>&5 >&5
       if test ! -f conftest.hpp.gch; then
-        USE_PRECOMPILED_HEADER=0
+        USE_PRECOMPILED_HEADER=false
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
       else
@@ -66458,7 +66156,7 @@
         as_fn_error $? "On macosx, ccache 3.2 or later is required, found $CCACHE_VERSION" "$LINENO" 5
       fi
     fi
-    if test "x$USE_PRECOMPILED_HEADER" = "x1"; then
+    if test "x$USE_PRECOMPILED_HEADER" = "xtrue"; then
       HAS_BAD_CCACHE=`$ECHO $CCACHE_VERSION | \
           $GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]$'`
       if test "x$HAS_BAD_CCACHE" != "x"; then
--- a/common/autoconf/hotspot.m4	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/hotspot.m4	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -189,7 +189,6 @@
   else
     AC_MSG_ERROR([Invalid value for --enable-dtrace: $enable_dtrace])
   fi
-  AC_SUBST(INCLUDE_DTRACE)
 ])
 
 ################################################################################
--- a/common/autoconf/jdk-options.m4	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/jdk-options.m4	Fri Feb 10 08:57:42 2017 -0800
@@ -210,10 +210,10 @@
   AC_MSG_CHECKING([if elliptic curve crypto implementation is present])
 
   if test -d "${SRC_ROOT}/jdk/src/jdk.crypto.ec/share/native/libsunec/impl"; then
-    ENABLE_INTREE_EC=yes
+    ENABLE_INTREE_EC=true
     AC_MSG_RESULT([yes])
   else
-    ENABLE_INTREE_EC=no
+    ENABLE_INTREE_EC=false
     AC_MSG_RESULT([no])
   fi
 
@@ -479,5 +479,5 @@
     AC_MSG_ERROR([Invalid value for --enable-generate-classlist: $enable_generate_classlist])
   fi
 
-  AC_SUBST([ENABLE_GENERATE_CLASSLIST])
+  AC_SUBST(ENABLE_GENERATE_CLASSLIST)
 ])
--- a/common/autoconf/lib-bundled.m4	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/lib-bundled.m4	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -119,28 +119,31 @@
   DEFAULT_LIBPNG=bundled
   # if user didn't specify, use DEFAULT_LIBPNG
   if test "x${with_libpng}" = "x"; then
-      with_libpng=${DEFAULT_LIBPNG}
+    with_libpng=${DEFAULT_LIBPNG}
   fi
 
   if test "x${with_libpng}" = "xbundled"; then
-      USE_EXTERNAL_LIBPNG=false
-      AC_MSG_RESULT([bundled])
+    USE_EXTERNAL_LIBPNG=false
+    PNG_CFLAGS=""
+    PNG_LIBS=""
+    AC_MSG_RESULT([bundled])
   elif test "x${with_libpng}" = "xsystem"; then
-      PKG_CHECK_MODULES(PNG, libpng,
-                   [ LIBPNG_FOUND=yes ],
-                   [ LIBPNG_FOUND=no ])
-      if test "x${LIBPNG_FOUND}" = "xyes"; then
-          USE_EXTERNAL_LIBPNG=true
-          AC_MSG_RESULT([system])
-      else
-          AC_MSG_RESULT([system not found])
-          AC_MSG_ERROR([--with-libpng=system specified, but no libpng found!])
-      fi
+    PKG_CHECK_MODULES(PNG, libpng, [LIBPNG_FOUND=yes], [LIBPNG_FOUND=no])
+    if test "x${LIBPNG_FOUND}" = "xyes"; then
+      # PKG_CHECK_MODULES will set PNG_CFLAGS and PNG_LIBS
+      USE_EXTERNAL_LIBPNG=true
+      AC_MSG_RESULT([system])
+    else
+      AC_MSG_RESULT([system not found])
+      AC_MSG_ERROR([--with-libpng=system specified, but no libpng found!])
+    fi
   else
-      AC_MSG_ERROR([Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'])
+    AC_MSG_ERROR([Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'])
   fi
 
   AC_SUBST(USE_EXTERNAL_LIBPNG)
+  AC_SUBST(PNG_CFLAGS)
+  AC_SUBST(PNG_LIBS)
 ])
 
 ################################################################################
@@ -204,16 +207,19 @@
   DEFAULT_LCMS=bundled
   # If user didn't specify, use DEFAULT_LCMS
   if test "x${with_lcms}" = "x"; then
-      with_lcms=${DEFAULT_LCMS}
+    with_lcms=${DEFAULT_LCMS}
   fi
 
   if test "x${with_lcms}" = "xbundled"; then
     USE_EXTERNAL_LCMS=false
+    LCMS_CFLAGS=""
+    LCMS_LIBS=""
     AC_MSG_RESULT([bundled])
   elif test "x${with_lcms}" = "xsystem"; then
     AC_MSG_RESULT([system])
     PKG_CHECK_MODULES([LCMS], [lcms2], [LCMS_FOUND=yes], [LCMS_FOUND=no])
     if test "x${LCMS_FOUND}" = "xyes"; then
+      # PKG_CHECK_MODULES will set LCMS_CFLAGS and LCMS_LIBS
       USE_EXTERNAL_LCMS=true
     else
       AC_MSG_ERROR([--with-lcms=system specified, but no lcms found!])
@@ -223,4 +229,6 @@
   fi
 
   AC_SUBST(USE_EXTERNAL_LCMS)
+  AC_SUBST(LCMS_CFLAGS)
+  AC_SUBST(LCMS_LIBS)
 ])
--- a/common/autoconf/platform.m4	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/platform.m4	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -276,12 +276,6 @@
 [
   PLATFORM_SETUP_LEGACY_VARS_HELPER([TARGET])
   PLATFORM_SETUP_LEGACY_VARS_HELPER([BUILD])
-
-  # ZERO_ARCHDEF is used to enable architecture-specific code.
-  # This is used in legacy hotspot build.
-  ZERO_ARCHDEF="$HOTSPOT_TARGET_CPU_DEFINE"
-  AC_SUBST(ZERO_ARCHDEF)
-
 ])
 
 # $1 - Either TARGET or BUILD to setup the variables for.
@@ -360,19 +354,16 @@
     OPENJDK_$1_CPU_BUNDLE="$OPENJDK_$1_CPU"
   fi
   OPENJDK_$1_BUNDLE_PLATFORM="${OPENJDK_$1_OS_BUNDLE}-${OPENJDK_$1_CPU_BUNDLE}"
-  AC_SUBST(OPENJDK_$1_OS_BUNDLE)
-  AC_SUBST(OPENJDK_$1_CPU_BUNDLE)
   AC_SUBST(OPENJDK_$1_BUNDLE_PLATFORM)
 
   if test "x$OPENJDK_$1_CPU_BITS" = x64; then
-    A_LP64="LP64:="
     # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in
-    # unpack200.exe
+    # unpack200.exe. This variable is used in
+    # FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER.
     if test "x$OPENJDK_$1_OS" = xlinux || test "x$OPENJDK_$1_OS" = xmacosx; then
       OPENJDK_$1_ADD_LP64="-D_LP64=1"
     fi
   fi
-  AC_SUBST(LP64,$A_LP64)
 
   if test "x$COMPILE_TYPE" = "xcross"; then
     # FIXME: ... or should this include reduced builds..?
--- a/common/autoconf/spec.gmk.in	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/autoconf/spec.gmk.in	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -87,9 +87,8 @@
 HOTSPOT_TARGET_CPU_ARCH := @HOTSPOT_TARGET_CPU_ARCH@
 HOTSPOT_TARGET_CPU_DEFINE := @HOTSPOT_TARGET_CPU_DEFINE@
 
-OPENJDK_TARGET_CPU_BUNDLE:=@OPENJDK_TARGET_CPU_BUNDLE@
-OPENJDK_TARGET_OS_BUNDLE:=@OPENJDK_TARGET_OS_BUNDLE@
 OPENJDK_TARGET_BUNDLE_PLATFORM:=@OPENJDK_TARGET_BUNDLE_PLATFORM@
+JDK_ARCH_ABI_PROP_NAME := @JDK_ARCH_ABI_PROP_NAME@
 
 # We are building on this build system.
 # When not cross-compiling, it is the same as the target.
@@ -683,8 +682,7 @@
 
 # Build setup
 ENABLE_AOT:=@ENABLE_AOT@
-ENABLE_JFR=@ENABLE_JFR@
-ENABLE_INTREE_EC=@ENABLE_INTREE_EC@
+ENABLE_INTREE_EC:=@ENABLE_INTREE_EC@
 USE_EXTERNAL_LIBJPEG:=@USE_EXTERNAL_LIBJPEG@
 USE_EXTERNAL_LIBGIF:=@USE_EXTERNAL_LIBGIF@
 USE_EXTERNAL_LIBZ:=@USE_EXTERNAL_LIBZ@
--- a/common/bin/hgforest.sh	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/bin/hgforest.sh	Fri Feb 10 08:57:42 2017 -0800
@@ -309,8 +309,8 @@
 
       echo "serving root repo ${serving}" > ${status_output}
 
-      echo "hg${global_opts} serve" > ${status_output}
-      (PYTHONUNBUFFERED=true hg${global_opts} serve -A ${status_output} -E ${status_output} --pid-file ${tmp}/serve.pid --web-conf ${tmp}/serve.web-conf; echo "$?" > ${tmp}/serve.pid.rc ) 2>&1 &
+      echo "hg${global_opts} serve ${@}" > ${status_output}
+      (PYTHONUNBUFFERED=true hg${global_opts} serve -A ${status_output} -E ${status_output} --pid-file ${tmp}/serve.pid --web-conf ${tmp}/serve.web-conf "${@}"; echo "$?" > ${tmp}/serve.pid.rc ) 2>&1 &
     ) 2>&1 | sed -e "s@^@serve:   @" > ${status_output}
   ) &
 else
--- a/common/bin/unshuffle_list.txt	Fri Feb 10 13:32:11 2017 +0530
+++ b/common/bin/unshuffle_list.txt	Fri Feb 10 08:57:42 2017 -0800
@@ -60,7 +60,7 @@
 jaxws/src/java.activation/share/classes/com/sun/activation/registries : jaxws/src/share/jaf_classes/com/sun/activation/registries
 jaxws/src/java.activation/share/classes/javax/activation : jaxws/src/share/jaf_classes/javax/activation
 jaxws/src/java.activation/share/classes/META-INF : jaxws/src/share/jaf_classes/META-INF
-jaxws/src/java.annotations.common/share/classes/javax/annotation : jaxws/src/share/jaxws_classes/javax/annotation
+jaxws/src/java.xml.ws.annotation/share/classes/javax/annotation : jaxws/src/share/jaxws_classes/javax/annotation
 jaxws/src/java.xml.bind/share/classes/com/sun/istack/internal : jaxws/src/share/jaxws_classes/com/sun/istack/internal
 jaxws/src/java.xml.bind/share/classes/com/sun/istack/internal/localization : jaxws/src/share/jaxws_classes/com/sun/istack/internal/localization
 jaxws/src/java.xml.bind/share/classes/com/sun/istack/internal/logging/Logger.java : jaxws/src/share/jaxws_classes/com/sun/istack/internal/logging/Logger.java
@@ -1163,9 +1163,6 @@
 jdk/src/java.management/share/classes/sun/management/counter : jdk/src/share/classes/sun/management/counter
 jdk/src/java.management/share/classes/sun/management/counter/perf : jdk/src/share/classes/sun/management/counter/perf
 jdk/src/java.management/share/classes/sun/management : jdk/src/share/classes/sun/management
-jdk/src/java.management/share/classes/sun/management/jdp : jdk/src/share/classes/sun/management/jdp
-jdk/src/java.management/share/classes/sun/management/jmxremote : jdk/src/share/classes/sun/management/jmxremote
-jdk/src/java.management/share/classes/sun/management/resources : jdk/src/share/classes/sun/management/resources
 jdk/src/java.management/share/conf : jdk/src/share/lib/management
 jdk/src/java.management/share/native/include/jmm.h : jdk/src/share/javavm/export/jmm.h
 jdk/src/java.management/share/native/libmanagement : jdk/src/share/native/sun/management
@@ -1173,6 +1170,11 @@
 jdk/src/java.management/unix/native/libmanagement : jdk/src/solaris/native/sun/management
 jdk/src/java.management/windows/classes/sun/management : jdk/src/windows/classes/sun/management
 jdk/src/java.management/windows/native/libmanagement : jdk/src/windows/native/sun/management
+jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/ProxyRef.java : jdk/src/share/classes/com/sun/jmx/remote/internal/ProxyRef.java
+jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/RMIExporter.java : jdk/src/share/classes/com/sun/jmx/remote/internal/RMIExporter.java
+jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/Unmarshal.java : jdk/src/share/classes/com/sun/jmx/remote/internal/Unmarshal.java
+jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/protocol/rmi : jdk/src/share/classes/com/sun/jmx/remote/protocol/rmi
+jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi : jdk/src/share/classes/javax/management/remote/rmi
 jdk/src/java.naming/share/classes/com/sun/jndi/ldap/ext : jdk/src/share/classes/com/sun/jndi/ldap/ext
 jdk/src/java.naming/share/classes/com/sun/jndi/ldap : jdk/src/share/classes/com/sun/jndi/ldap
 jdk/src/java.naming/share/classes/com/sun/jndi/ldap/pool : jdk/src/share/classes/com/sun/jndi/ldap/pool
@@ -1330,9 +1332,9 @@
 jdk/src/jdk.jdwp.agent/unix/native/libjdwp : jdk/src/solaris/back
 jdk/src/jdk.jdwp.agent/windows/native/libdt_socket : jdk/src/windows/transport/socket
 jdk/src/jdk.jdwp.agent/windows/native/libjdwp : jdk/src/windows/back
-jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/monitor : jdk/src/share/classes/sun/jvmstat/monitor
-jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata : jdk/src/share/classes/sun/jvmstat/perfdata
-jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd : jdk/src/share/classes/sun/tools/jstatd
+jdk/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/monitor : jdk/src/share/classes/sun/jvmstat/monitor
+jdk/src/jdk.internal.jvmstat/share/classes/sun/jvmstat/perfdata : jdk/src/share/classes/sun/jvmstat/perfdata
+jdk/src/jdk.internal.jvmstat/share/classes/sun/tools/jstatd : jdk/src/share/classes/sun/tools/jstatd
 jdk/src/jdk.localedata/share/classes/sun/text/resources/ar : jdk/src/share/classes/sun/text/resources/ar
 jdk/src/jdk.localedata/share/classes/sun/text/resources/be : jdk/src/share/classes/sun/text/resources/be
 jdk/src/jdk.localedata/share/classes/sun/text/resources/bg : jdk/src/share/classes/sun/text/resources/bg
@@ -1421,6 +1423,9 @@
 jdk/src/jdk.localedata/share/classes/sun/util/resources/vi : jdk/src/share/classes/sun/util/resources/vi
 jdk/src/jdk.localedata/share/classes/sun/util/resources/zh : jdk/src/share/classes/sun/util/resources/zh
 jdk/src/jdk.management/share/classes/com/sun/management : jdk/src/share/classes/com/sun/management
+jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources : jdk/src/share/classes/sun/management/resources
+jdk/src/jdk.management.agent/share/classes/sun/management/jmxremote : jdk/src/share/classes/sun/management/jmxremote
+jdk/src/jdk.management.agent/share/classes/sun/management/jdp : jdk/src/share/classes/sun/management/jdp
 jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/dns : jdk/src/share/classes/com/sun/jndi/dns
 jdk/src/jdk.naming.dns/share/classes/com/sun/jndi/url/dns : jdk/src/share/classes/com/sun/jndi/url/dns
 jdk/src/jdk.naming.dns/share/classes/META-INF/services : jdk/src/share/classes/sun/net/spi/nameservice/dns/META-INF/services
--- a/corba/.hgtags	Fri Feb 10 13:32:11 2017 +0530
+++ b/corba/.hgtags	Fri Feb 10 08:57:42 2017 -0800
@@ -397,3 +397,4 @@
 ff8cb43c07c069b1debdee44cb88ca22db1ec757 jdk-9+152
 68a8e8658511093b322a46ed04b2a321e1da2a43 jdk-9+153
 078ebe23b584466dc8346e620d7821d91751e5a9 jdk-9+154
+a545f54babfa31aa7eb611f36031609acd617cbc jdk-9+155
--- a/hotspot/.hgtags	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/.hgtags	Fri Feb 10 08:57:42 2017 -0800
@@ -557,3 +557,4 @@
 31f1d26c60df7b2e516a4f84160d76ba017d4e09 jdk-9+152
 217ba81b9a4ce8698200370175aa2db86a39f66c jdk-9+153
 a9fdfd55835ef9dccb7f317b07249bd66653b874 jdk-9+154
+f3b3d77a1751897413aae43ac340a130b6fa2ae1 jdk-9+155
--- a/hotspot/make/ide/CreateVSProject.gmk	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/make/ide/CreateVSProject.gmk	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2017, 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
@@ -121,7 +121,7 @@
       -buildBase $(call FixPath, $(IDE_OUTPUTDIR)/vs-output) \
       -buildSpace $(call FixPath, $(IDE_OUTPUTDIR)) \
       -makeBinary $(call FixPath, $(MAKE)) \
-      -makeOutput $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-%f/libjvm) \
+      -makeOutput $(call FixPath, $(JDK_OUTPUTDIR)/bin/server) \
       -absoluteInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \
       -absoluteSrcInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \
       $(EXTRACTED_DEFINES_client) \
--- a/hotspot/make/lib/CompileJvm.gmk	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/make/lib/CompileJvm.gmk	Fri Feb 10 08:57:42 2017 -0800
@@ -63,7 +63,7 @@
 # INCLUDE_SUFFIX_* is only meant for including the proper
 # platform files. Don't use it to guard code. Use the value of
 # HOTSPOT_TARGET_CPU_DEFINE etc. instead.
-# Remaining TARGET_ARCH_* is needed to select the cpu specific 
+# Remaining TARGET_ARCH_* is needed to select the cpu specific
 # sources for 64-bit ARM ports (arm versus aarch64).
 JVM_CFLAGS_TARGET_DEFINES += \
     -DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \
@@ -132,7 +132,7 @@
     #
 
 # -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
-ifeq ($(USE_PRECOMPILED_HEADER), 0)
+ifeq ($(USE_PRECOMPILED_HEADER), false)
   JVM_CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
 endif
 
@@ -145,7 +145,7 @@
   JVM_EXCLUDE_PATTERNS += arm_64
 
 else ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), linux-aarch64)
-  # For 64-bit arm builds, we use the 64 bit hotspot/src/cpu/arm 
+  # For 64-bit arm builds, we use the 64 bit hotspot/src/cpu/arm
   # hotspot sources if HOTSPOT_TARGET_CPU_ARCH is set to arm.
   # Exclude the aarch64 and 32 bit arm files for this build.
   ifeq ($(HOTSPOT_TARGET_CPU_ARCH), arm)
--- a/hotspot/make/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/make/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -114,8 +114,8 @@
             tag(cfg, "CodeAnalysisRuleAssemblies");
         }
         for (BuildConfig cfg : allConfigs) {
-            tagData(cfg, "NMakeBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile import-hotspot LOG=info");
-            tagData(cfg, "NMakeReBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot import-hotspot LOG=info");
+            tagData(cfg, "NMakeBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile hotspot LOG=info");
+            tagData(cfg, "NMakeReBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot hotspot LOG=info");
             tagData(cfg, "NMakeCleanCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot LOG=info");
             tagData(cfg, "NMakeOutput", cfg.get("MakeOutput") + Util.sep + "jvm.dll");
             tagData(cfg, "NMakePreprocessorDefinitions", Util.join(";", cfg.getDefines()));
--- a/hotspot/make/symbols/symbols-unix	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/make/symbols/symbols-unix	Fri Feb 10 08:57:42 2017 -0800
@@ -192,4 +192,3 @@
 JVM_AddReadsModule
 JVM_DefineModule
 JVM_SetBootLoaderUnnamedModule
-JVM_GetModuleByPackageName
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Fri Feb 10 08:57:42 2017 -0800
@@ -1042,8 +1042,10 @@
   bool is_card_mark_membar(const MemBarNode *barrier);
   bool is_CAS(int opcode);
 
-  MemBarNode *leading_to_trailing(MemBarNode *leading);
-  MemBarNode *card_mark_to_leading(const MemBarNode *barrier);
+  MemBarNode *leading_to_normal(MemBarNode *leading);
+  MemBarNode *normal_to_leading(const MemBarNode *barrier);
+  MemBarNode *card_mark_to_trailing(const MemBarNode *barrier);
+  MemBarNode *trailing_to_card_mark(const MemBarNode *trailing);
   MemBarNode *trailing_to_leading(const MemBarNode *trailing);
 
   // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
@@ -1420,28 +1422,23 @@
   // leading MemBarRelease and a trailing MemBarVolatile as follows
   //
   //   MemBarRelease
-  //  {    ||        } -- optional
+  //  {      ||      } -- optional
   //  {MemBarCPUOrder}
-  //       ||       \\
-  //       ||     StoreX[mo_release]
-  //       | \ Bot    / ???
-  //       | MergeMem
-  //       | /
+  //         ||     \\
+  //         ||     StoreX[mo_release]
+  //         | \     /
+  //         | MergeMem
+  //         | /
   //   MemBarVolatile
   //
   // where
   //  || and \\ represent Ctl and Mem feeds via Proj nodes
   //  | \ and / indicate further routing of the Ctl and Mem feeds
   //
-  // Note that the memory feed from the CPUOrder membar to the
-  // MergeMem node is an AliasIdxBot slice while the feed from the
-  // StoreX is for a slice determined by the type of value being
-  // written.
-  //
-  // the diagram above shows the graph we see for non-object stores.
-  // for a volatile Object store (StoreN/P) we may see other nodes
-  // below the leading membar because of the need for a GC pre- or
-  // post-write barrier.
+  // this is the graph we see for non-object stores. however, for a
+  // volatile Object store (StoreN/P) we may see other nodes below the
+  // leading membar because of the need for a GC pre- or post-write
+  // barrier.
   //
   // with most GC configurations we with see this simple variant which
   // includes a post-write barrier card mark.
@@ -1449,7 +1446,7 @@
   //   MemBarRelease______________________________
   //         ||    \\               Ctl \        \\
   //         ||    StoreN/P[mo_release] CastP2X  StoreB/CM
-  //         | \ Bot  / oop                 . . .  /
+  //         | \     /                       . . .  /
   //         | MergeMem
   //         | /
   //         ||      /
@@ -1459,142 +1456,152 @@
   // the object address to an int used to compute the card offset) and
   // Ctl+Mem to a StoreB node (which does the actual card mark).
   //
-  // n.b. a StoreCM node is only ever used when CMS (with or without
-  // CondCardMark) or G1 is configured. This abstract instruction
-  // differs from a normal card mark write (StoreB) because it implies
-  // a requirement to order visibility of the card mark (StoreCM)
-  // after that of the object put (StoreP/N) using a StoreStore memory
-  // barrier. Note that this is /not/ a requirement to order the
-  // instructions in the generated code (that is already guaranteed by
-  // the order of memory dependencies). Rather it is a requirement to
-  // ensure visibility order which only applies on architectures like
-  // AArch64 which do not implement TSO. This ordering is required for
-  // both non-volatile and volatile puts.
-  //
-  // That implies that we need to translate a StoreCM using the
-  // sequence
+  // n.b. a StoreCM node will only appear in this configuration when
+  // using CMS. StoreCM differs from a normal card mark write (StoreB)
+  // because it implies a requirement to order visibility of the card
+  // mark (StoreCM) relative to the object put (StoreP/N) using a
+  // StoreStore memory barrier (arguably this ought to be represented
+  // explicitly in the ideal graph but that is not how it works). This
+  // ordering is required for both non-volatile and volatile
+  // puts. Normally that means we need to translate a StoreCM using
+  // the sequence
   //
   //   dmb ishst
   //   stlrb
   //
-  // This dmb cannot be omitted even when the associated StoreX or
-  // CompareAndSwapX is implemented using stlr. However, as described
-  // below there are circumstances where a specific GC configuration
-  // requires a stronger barrier in which case it can be omitted.
-  // 
-  // With the Serial or Parallel GC using +CondCardMark the card mark
-  // is performed conditionally on it currently being unmarked in
-  // which case the volatile put graph looks slightly different
+  // However, in the case of a volatile put if we can recognise this
+  // configuration and plant an stlr for the object write then we can
+  // omit the dmb and just plant an strb since visibility of the stlr
+  // is ordered before visibility of subsequent stores. StoreCM nodes
+  // also arise when using G1 or using CMS with conditional card
+  // marking. In these cases (as we shall see) we don't need to insert
+  // the dmb when translating StoreCM because there is already an
+  // intervening StoreLoad barrier between it and the StoreP/N.
+  //
+  // It is also possible to perform the card mark conditionally on it
+  // currently being unmarked in which case the volatile put graph
+  // will look slightly different
   //
   //   MemBarRelease____________________________________________
   //         ||    \\               Ctl \     Ctl \     \\  Mem \
   //         ||    StoreN/P[mo_release] CastP2X   If   LoadB     |
-  //         | \ Bot / oop                          \            |
+  //         | \     /                              \            |
   //         | MergeMem                            . . .      StoreB
   //         | /                                                /
   //         ||     /
   //   MemBarVolatile
   //
-  // It is worth noting at this stage that all the above
+  // It is worth noting at this stage that both the above
   // configurations can be uniquely identified by checking that the
   // memory flow includes the following subgraph:
   //
   //   MemBarRelease
   //  {MemBarCPUOrder}
-  //      |  \      . . .
-  //      |  StoreX[mo_release]  . . .
-  //  Bot |   / oop
-  //     MergeMem
-  //      |
+  //          |  \      . . .
+  //          |  StoreX[mo_release]  . . .
+  //          |   /
+  //         MergeMem
+  //          |
   //   MemBarVolatile
   //
-  // This is referred to as a *normal* volatile store subgraph. It can
-  // easily be detected starting from any candidate MemBarRelease,
-  // StoreX[mo_release] or MemBarVolatile node.
-  //
-  // A small variation on this normal case occurs for an unsafe CAS
-  // operation. The basic memory flow subgraph for a non-object CAS is
-  // as follows
+  // This is referred to as a *normal* subgraph. It can easily be
+  // detected starting from any candidate MemBarRelease,
+  // StoreX[mo_release] or MemBarVolatile.
+  //
+  // A simple variation on this normal case occurs for an unsafe CAS
+  // operation. The basic graph for a non-object CAS is
   //
   //   MemBarRelease
   //         ||
   //   MemBarCPUOrder
-  //          |     \\   . . .
-  //          |     CompareAndSwapX
-  //          |       |
-  //      Bot |     SCMemProj
-  //           \     / Bot
-  //           MergeMem
-  //           /
+  //         ||     \\   . . .
+  //         ||     CompareAndSwapX
+  //         ||       |
+  //         ||     SCMemProj
+  //         | \     /
+  //         | MergeMem
+  //         | /
   //   MemBarCPUOrder
   //         ||
   //   MemBarAcquire
   //
   // The same basic variations on this arrangement (mutatis mutandis)
-  // occur when a card mark is introduced. i.e. the CPUOrder MemBar
-  // feeds the extra CastP2X, LoadB etc nodes but the above memory
-  // flow subgraph is still present.
-  // 
-  // This is referred to as a *normal* CAS subgraph. It can easily be
-  // detected starting from any candidate MemBarRelease,
-  // StoreX[mo_release] or MemBarAcquire node.
-  //
-  // The code below uses two helper predicates, leading_to_trailing
-  // and trailing_to_leading to identify these normal graphs, one
-  // validating the layout starting from the top membar and searching
-  // down and the other validating the layout starting from the lower
-  // membar and searching up.
-  //
-  // There are two special case GC configurations when the simple
-  // normal graphs above may not be generated: when using G1 (which
-  // always employs a conditional card mark); and when using CMS with
-  // conditional card marking (+CondCardMark) configured. These GCs
-  // are both concurrent rather than stop-the world GCs. So they
-  // introduce extra Ctl+Mem flow into the graph between the leading
-  // and trailing membar nodes, in particular enforcing stronger
-  // memory serialisation beween the object put and the corresponding
-  // conditional card mark. CMS employs a post-write GC barrier while
-  // G1 employs both a pre- and post-write GC barrier.
-  //
-  // The post-write barrier subgraph for these configurations includes
-  // a MemBarVolatile node -- referred to as a card mark membar --
-  // which is needed to order the card write (StoreCM) operation in
-  // the barrier, the preceding StoreX (or CompareAndSwapX) and Store
-  // operations performed by GC threads i.e. a card mark membar
-  // constitutes a StoreLoad barrier hence must be translated to a dmb
-  // ish (whether or not it sits inside a volatile store sequence).
-  //
-  // Of course, the use of the dmb ish for the card mark membar also
-  // implies theat the StoreCM which follows can omit the dmb ishst
-  // instruction. The necessary visibility ordering will already be
-  // guaranteed by the dmb ish. In sum, the dmb ishst instruction only
-  // needs to be generated for as part of the StoreCM sequence with GC
-  // configuration +CMS -CondCardMark.
-  // 
-  // Of course all these extra barrier nodes may well be absent --
-  // they are only inserted for object puts. Their potential presence
-  // significantly complicates the task of identifying whether a
-  // MemBarRelease, StoreX[mo_release], MemBarVolatile or
-  // MemBarAcquire forms part of a volatile put or CAS when using
-  // these GC configurations (see below) and also complicates the
-  // decision as to how to translate a MemBarVolatile and StoreCM.
-  //
-  // So, thjis means that a card mark MemBarVolatile occurring in the
-  // post-barrier graph it needs to be distinguished from a normal
-  // trailing MemBarVolatile. Resolving this is straightforward: a
-  // card mark MemBarVolatile always projects a Mem feed to a StoreCM
-  // node and that is a unique marker
+  // occur when a card mark is introduced. i.e. we se the same basic
+  // shape but the StoreP/N is replaced with CompareAndSawpP/N and the
+  // tail of the graph is a pair comprising a MemBarCPUOrder +
+  // MemBarAcquire.
+  //
+  // So, in the case of a CAS the normal graph has the variant form
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder
+  //          |   \      . . .
+  //          |  CompareAndSwapX  . . .
+  //          |    |
+  //          |   SCMemProj
+  //          |   /  . . .
+  //         MergeMem
+  //          |
+  //   MemBarCPUOrder
+  //   MemBarAcquire
+  //
+  // This graph can also easily be detected starting from any
+  // candidate MemBarRelease, CompareAndSwapX or MemBarAcquire.
+  //
+  // the code below uses two helper predicates, leading_to_normal and
+  // normal_to_leading to identify these normal graphs, one validating
+  // the layout starting from the top membar and searching down and
+  // the other validating the layout starting from the lower membar
+  // and searching up.
+  //
+  // There are two special case GC configurations when a normal graph
+  // may not be generated: when using G1 (which always employs a
+  // conditional card mark); and when using CMS with conditional card
+  // marking configured. These GCs are both concurrent rather than
+  // stop-the world GCs. So they introduce extra Ctl+Mem flow into the
+  // graph between the leading and trailing membar nodes, in
+  // particular enforcing stronger memory serialisation beween the
+  // object put and the corresponding conditional card mark. CMS
+  // employs a post-write GC barrier while G1 employs both a pre- and
+  // post-write GC barrier. Of course the extra nodes may be absent --
+  // they are only inserted for object puts. This significantly
+  // complicates the task of identifying whether a MemBarRelease,
+  // StoreX[mo_release] or MemBarVolatile forms part of a volatile put
+  // when using these GC configurations (see below). It adds similar
+  // complexity to the task of identifying whether a MemBarRelease,
+  // CompareAndSwapX or MemBarAcquire forms part of a CAS.
+  //
+  // In both cases the post-write subtree includes an auxiliary
+  // MemBarVolatile (StoreLoad barrier) separating the object put and
+  // the read of the corresponding card. This poses two additional
+  // problems.
+  //
+  // Firstly, a card mark MemBarVolatile needs to be distinguished
+  // from a normal trailing MemBarVolatile. Resolving this first
+  // problem is straightforward: a card mark MemBarVolatile always
+  // projects a Mem feed to a StoreCM node and that is a unique marker
   //
   //      MemBarVolatile (card mark)
   //       C |    \     . . .
   //         |   StoreCM   . . .
   //       . . .
   //
-  // Returning to the task of translating the object put and the
-  // leading/trailing membar nodes: what do the node graphs look like
-  // for these 2 special cases? and how can we determine the status of
-  // a MemBarRelease, StoreX[mo_release] or MemBarVolatile in both
-  // normal and non-normal cases?
+  // The second problem is how the code generator is to translate the
+  // card mark barrier? It always needs to be translated to a "dmb
+  // ish" instruction whether or not it occurs as part of a volatile
+  // put. A StoreLoad barrier is needed after the object put to ensure
+  // i) visibility to GC threads of the object put and ii) visibility
+  // to the mutator thread of any card clearing write by a GC
+  // thread. Clearly a normal store (str) will not guarantee this
+  // ordering but neither will a releasing store (stlr). The latter
+  // guarantees that the object put is visible but does not guarantee
+  // that writes by other threads have also been observed.
+  //
+  // So, returning to the task of translating the object put and the
+  // leading/trailing membar nodes: what do the non-normal node graph
+  // look like for these 2 special cases? and how can we determine the
+  // status of a MemBarRelease, StoreX[mo_release] or MemBarVolatile
+  // in both normal and non-normal cases?
   //
   // A CMS GC post-barrier wraps its card write (StoreCM) inside an If
   // which selects conditonal execution based on the value loaded
@@ -1605,117 +1612,91 @@
   // which looks like this
   //
   //   MemBarRelease
-  //   MemBarCPUOrder_(leading)____________________
-  //     C |  | M \       \\               M |   C \
-  //       |  |    \    StoreN/P[mo_release] |  CastP2X
-  //       |  | Bot \    / oop      \        |
-  //       |  |    MergeMem          \      / 
-  //       |  |      /                |    /
-  //     MemBarVolatile (card mark)   |   /
-  //     C |  ||    M |               |  /
-  //       | LoadB    | Bot       oop | / Bot
-  //       |   |      |              / /
-  //       | Cmp      |\            / /
-  //       | /        | \          / /
-  //       If         |  \        / /
-  //       | \        |   \      / /
-  // IfFalse  IfTrue  |    \    / /
-  //       \     / \  |    |   / /
-  //        \   / StoreCM  |  / /
-  //         \ /      \   /  / /
-  //        Region     Phi  / /
-  //          | \   Raw |  / /
-  //          |  . . .  | / /
+  //   MemBarCPUOrder_(leading)__________________
+  //     C |    M \       \\                   C \
+  //       |       \    StoreN/P[mo_release]  CastP2X
+  //       |    Bot \    /
+  //       |       MergeMem
+  //       |         /
+  //      MemBarVolatile (card mark)
+  //     C |  ||    M |
+  //       | LoadB    |
+  //       |   |      |
+  //       | Cmp      |\
+  //       | /        | \
+  //       If         |  \
+  //       | \        |   \
+  // IfFalse  IfTrue  |    \
+  //       \     / \  |     \
+  //        \   / StoreCM    |
+  //         \ /      |      |
+  //        Region   . . .   |
+  //          | \           /
+  //          |  . . .  \  / Bot
   //          |       MergeMem
-  //          |           |
+  //          |          |
   //        MemBarVolatile (trailing)
   //
-  // Notice that there are two MergeMem nodes below the leading
-  // membar. The first MergeMem merges the AliasIdxBot Mem slice from
-  // the leading membar and the oopptr Mem slice from the Store into
-  // the card mark membar. The trailing MergeMem merges the
-  // AliasIdxBot Mem slice from the leading membar, the AliasIdxRaw
-  // slice from the StoreCM and an oop slice from the StoreN/P node
-  // into the trailing membar (n.b. the raw slice proceeds via a Phi
-  // associated with the If region).
-  //
-  // So, in the case of CMS + CondCardMark the volatile object store
-  // graph still includes a normal volatile store subgraph from the
-  // leading membar to the trailing membar. However, it also contains
-  // the same shape memory flow to the card mark membar. The two flows
-  // can be distinguished by testing whether or not the downstream
-  // membar is a card mark membar.
-  //
-  // The graph for a CAS also varies with CMS + CondCardMark, in
-  // particular employing a control feed from the CompareAndSwapX node
-  // through a CmpI and If to the card mark membar and StoreCM which
-  // updates the associated card. This avoids executing the card mark
-  // if the CAS fails. However, it can be seen from the diagram below
-  // that the presence of the barrier does not alter the normal CAS
-  // memory subgraph where the leading membar feeds a CompareAndSwapX,
-  // an SCMemProj, a MergeMem then a final trailing MemBarCPUOrder and
-  // MemBarAcquire pair.
+  // The first MergeMem merges the AliasIdxBot Mem slice from the
+  // leading membar and the oopptr Mem slice from the Store into the
+  // card mark membar. The trailing MergeMem merges the AliasIdxBot
+  // Mem slice from the card mark membar and the AliasIdxRaw slice
+  // from the StoreCM into the trailing membar (n.b. the latter
+  // proceeds via a Phi associated with the If region).
+  //
+  // The graph for a CAS varies slightly, the obvious difference being
+  // that the StoreN/P node is replaced by a CompareAndSwapP/N node
+  // and the trailing MemBarVolatile by a MemBarCPUOrder +
+  // MemBarAcquire pair. The other important difference is that the
+  // CompareAndSwap node's SCMemProj is not merged into the card mark
+  // membar - it still feeds the trailing MergeMem. This also means
+  // that the card mark membar receives its Mem feed directly from the
+  // leading membar rather than via a MergeMem.
   //
   //   MemBarRelease
-  //   MemBarCPUOrder__(leading)_______________________
-  //   C /  M |                        \\            C \
-  //  . . .   | Bot                CompareAndSwapN/P   CastP2X
-  //          |                  C /  M |
-  //          |                 CmpI    |
-  //          |                  /      |
-  //          |               . . .     |
-  //          |              IfTrue     |
-  //          |              /          |
-  //       MemBarVolatile (card mark)   |
-  //        C |  ||    M |              |
-  //          | LoadB    | Bot   ______/|
-  //          |   |      |      /       |
-  //          | Cmp      |     /      SCMemProj
-  //          | /        |    /         |
-  //          If         |   /         /
-  //          | \        |  /         / Bot
-  //     IfFalse  IfTrue | /         /
-  //          |   / \   / / prec    /
-  //   . . .  |  /  StoreCM        /
-  //        \ | /      | raw      /
-  //        Region    . . .      /
-  //           | \              /
-  //           |   . . .   \    / Bot
-  //           |        MergeMem
-  //           |          /
-  //         MemBarCPUOrder
-  //         MemBarAcquire (trailing)
+  //   MemBarCPUOrder__(leading)_________________________
+  //       ||                       \\                 C \
+  //   MemBarVolatile (card mark)  CompareAndSwapN/P  CastP2X
+  //     C |  ||    M |              |
+  //       | LoadB    |       ______/|
+  //       |   |      |      /       |
+  //       | Cmp      |     /      SCMemProj
+  //       | /        |    /         |
+  //       If         |   /         /
+  //       | \        |  /         /
+  // IfFalse  IfTrue  | /         /
+  //       \     / \  |/ prec    /
+  //        \   / StoreCM       /
+  //         \ /      |        /
+  //        Region   . . .    /
+  //          | \            /
+  //          |  . . .  \   / Bot
+  //          |       MergeMem
+  //          |          |
+  //        MemBarCPUOrder
+  //        MemBarAcquire (trailing)
   //
   // This has a slightly different memory subgraph to the one seen
-  // previously but the core of it has a similar memory flow to the
-  // CAS normal subgraph:
+  // previously but the core of it is the same as for the CAS normal
+  // sungraph
   //
   //   MemBarRelease
   //   MemBarCPUOrder____
-  //         |          \      . . .
-  //         |       CompareAndSwapX  . . .
-  //         |       C /  M |
-  //         |      CmpI    |
-  //         |       /      |
-  //         |      . .    /
-  //     Bot |   IfTrue   /
-  //         |   /       /
-  //    MemBarVolatile  /
-  //         | ...     /
-  //      StoreCM ... /
-  //         |       / 
-  //       . . .  SCMemProj
-  //      Raw \    / Bot
-  //        MergeMem
-  //           |
+  //      ||             \      . . .
+  //   MemBarVolatile  CompareAndSwapX  . . .
+  //      |  \            |
+  //        . . .   SCMemProj
+  //          |     /  . . .
+  //         MergeMem
+  //          |
   //   MemBarCPUOrder
   //   MemBarAcquire
   //
-  // The G1 graph for a volatile object put is a lot more complicated.
-  // Nodes inserted on behalf of G1 may comprise: a pre-write graph
-  // which adds the old value to the SATB queue; the releasing store
-  // itself; and, finally, a post-write graph which performs a card
-  // mark.
+  //
+  // G1 is quite a lot more complicated. The nodes inserted on behalf
+  // of G1 may comprise: a pre-write graph which adds the old value to
+  // the SATB queue; the releasing store itself; and, finally, a
+  // post-write graph which performs a card mark.
   //
   // The pre-write graph may be omitted, but only when the put is
   // writing to a newly allocated (young gen) object and then only if
@@ -1753,60 +1734,25 @@
   //       | CastP2X | StoreN/P[mo_release] |
   //       |         |         |            |
   //     C |       M |       M |          M |
-  //        \        | Raw     | oop       / Bot
+  //        \        |         |           /
   //                  . . .
   //          (post write subtree elided)
   //                    . . .
   //             C \         M /
   //         MemBarVolatile (trailing)
   //
-  // Note that the three memory feeds into the post-write tree are an
-  // AliasRawIdx slice associated with the writes in the pre-write
-  // tree, an oop type slice from the StoreX specific to the type of
-  // the volatile field and the AliasBotIdx slice emanating from the
-  // leading membar.
-  //
   // n.b. the LoadB in this subgraph is not the card read -- it's a
   // read of the SATB queue active flag.
   //
-  // The CAS graph is once again a variant of the above with a
-  // CompareAndSwapX node and SCMemProj in place of the StoreX.  The
-  // value from the CompareAndSwapX node is fed into the post-write
-  // graph aling with the AliasIdxRaw feed from the pre-barrier and
-  // the AliasIdxBot feeds from the leading membar and the ScMemProj.
-  //
-  //  MemBarRelease (leading)____________
-  //     C |  ||  M \   M \    M \  M \ . . .
-  //       | LoadB   \  LoadL  LoadN   \
-  //       | /        \                 \
-  //       If         |\                 \
-  //       | \        | \                 \
-  //  IfFalse  IfTrue |  \                 \
-  //       |     |    |   \                 \
-  //       |     If   |    \                 |
-  //       |     |          \                |
-  //       |                 \               |
-  //       |    . . .         \              |
-  //       | /       | /       \             |
-  //      Region  Phi[M]        \            |
-  //       | \       |           \           |
-  //       |  \_____ |            |          |
-  //     C | C \     |            |          |
-  //       | CastP2X |     CompareAndSwapX   |
-  //       |         |   res |     |         |
-  //     C |       M |       |  SCMemProj  M |
-  //        \        | Raw   |     | Bot    / Bot
-  //                  . . .
-  //          (post write subtree elided)
-  //                    . . .
-  //             C \         M /
-  //         MemBarVolatile (trailing)
+  // Once again the CAS graph is a minor variant on the above with the
+  // expected substitutions of CompareAndSawpX for StoreN/P and
+  // MemBarCPUOrder + MemBarAcquire for trailing MemBarVolatile.
   //
   // The G1 post-write subtree is also optional, this time when the
   // new value being written is either null or can be identified as a
   // newly allocated (young gen) object with no intervening control
   // flow. The latter cannot happen but the former may, in which case
-  // the card mark membar is omitted and the memory feeds from the
+  // the card mark membar is omitted and the memory feeds form the
   // leading membar and the SToreN/P are merged direct into the
   // trailing membar as per the normal subgraph. So, the only special
   // case which arises is when the post-write subgraph is generated.
@@ -1828,106 +1774,94 @@
   //
   //                (pre-write subtree elided)
   //        . . .                  . . .    . . .  . . .
-  //        C |               M |    M |    M |
-  //       Region            Phi[M] StoreN    |
-  //          |            Raw  |  oop |  Bot |
-  //         / \_______         |\     |\     |\
-  //      C / C \      . . .    | \    | \    | \
-  //       If   CastP2X . . .   |  \   |  \   |  \
-  //       / \                  |   \  |   \  |   \
-  //      /   \                 |    \ |    \ |    \
-  // IfFalse IfTrue             |      |      |     \
-  //   |       |                 \     |     /       |
-  //   |       If                 \    | \  /   \    |
-  //   |      / \                  \   |   /     \   |
-  //   |     /   \                  \  |  / \     |  |
-  //   | IfFalse IfTrue           MergeMem   \    |  |
-  //   |  . . .    / \                 |      \   |  |
-  //   |          /   \                |       |  |  |
-  //   |     IfFalse IfTrue            |       |  |  |
-  //   |      . . .    |               |       |  |  |
-  //   |               If             /        |  |  |
-  //   |               / \           /         |  |  |
-  //   |              /   \         /          |  |  |
-  //   |         IfFalse IfTrue    /           |  |  |
-  //   |           . . .   |      /            |  |  |
-  //   |                    \    /             |  |  |
-  //   |                     \  /              |  |  |
-  //   |         MemBarVolatile__(card mark  ) |  |  |
-  //   |              ||   C |     \           |  |  |
-  //   |             LoadB   If     |         /   |  |
-  //   |                    / \ Raw |        /   /  /
-  //   |                   . . .    |       /   /  /
-  //   |                        \   |      /   /  /
-  //   |                        StoreCM   /   /  /
-  //   |                           |     /   /  /
-  //   |                            . . .   /  /
-  //   |                                   /  /
-  //   |   . . .                          /  /
-  //   |    |             | /            /  /
-  //   |    |           Phi[M] /        /  /
-  //   |    |             |   /        /  /
-  //   |    |             |  /        /  /
-  //   |  Region  . . .  Phi[M]      /  /
-  //   |    |             |         /  /
-  //    \   |             |        /  /
-  //     \  | . . .       |       /  /
-  //      \ |             |      /  /
-  //      Region         Phi[M] /  /
-  //        |               \  /  /
-  //         \             MergeMem
-  //          \            /
-  //          MemBarVolatile
-  //
-  // As with CMS + CondCardMark the first MergeMem merges the
-  // AliasIdxBot Mem slice from the leading membar and the oopptr Mem
-  // slice from the Store into the card mark membar. However, in this
-  // case it may also merge an AliasRawIdx mem slice from the pre
-  // barrier write.
-  //
-  // The trailing MergeMem merges an AliasIdxBot Mem slice from the
-  // leading membar with an oop slice from the StoreN and an
-  // AliasRawIdx slice from the post barrier writes. In this case the
-  // AliasIdxRaw Mem slice is merged through a series of Phi nodes
-  // which combine feeds from the If regions in the post barrier
-  // subgraph.
-  //
-  // So, for G1 the same characteristic subgraph arises as for CMS +
-  // CondCardMark. There is a normal subgraph feeding the card mark
-  // membar and a normal subgraph feeding the trailing membar.
-  //
-  // The CAS graph when using G1GC also includes an optional
-  // post-write subgraph. It is very similar to the above graph except
-  // for a few details.
-  // 
-  // - The control flow is gated by an additonal If which tests the
-  // result from the CompareAndSwapX node
-  // 
-  //  - The MergeMem which feeds the card mark membar only merges the
-  // AliasIdxBot slice from the leading membar and the AliasIdxRaw
-  // slice from the pre-barrier. It does not merge the SCMemProj
-  // AliasIdxBot slice. So, this subgraph does not look like the
-  // normal CAS subgraph.
-  //
-  // - The MergeMem which feeds the trailing membar merges the
-  // AliasIdxBot slice from the leading membar, the AliasIdxRaw slice
-  // from the post-barrier and the SCMemProj AliasIdxBot slice i.e. it
-  // has two AliasIdxBot input slices. However, this subgraph does
-  // still look like the normal CAS subgraph.
-  //
-  // So, the upshot is:
-  //
-  // In all cases a volatile put graph will include a *normal*
-  // volatile store subgraph betwen the leading membar and the
-  // trailing membar. It may also include a normal volatile store
-  // subgraph betwen the leading membar and the card mark membar.
-  //
-  // In all cases a CAS graph will contain a unique normal CAS graph
-  // feeding the trailing membar.
-  //
-  // In all cases where there is a card mark membar (either as part of
-  // a volatile object put or CAS) it will be fed by a MergeMem whose
-  // AliasIdxBot slice feed will be a leading membar.
+  //        C |                    M |     M |    M |
+  //       Region                  Phi[M] StoreN    |
+  //          |                     / \      |      |
+  //         / \_______            /   \     |      |
+  //      C / C \      . . .            \    |      |
+  //       If   CastP2X . . .            |   |      |
+  //       / \                           |   |      |
+  //      /   \                          |   |      |
+  // IfFalse IfTrue                      |   |      |
+  //   |       |                         |   |     /|
+  //   |       If                        |   |    / |
+  //   |      / \                        |   |   /  |
+  //   |     /   \                        \  |  /   |
+  //   | IfFalse IfTrue                   MergeMem  |
+  //   |  . . .    / \                       /      |
+  //   |          /   \                     /       |
+  //   |     IfFalse IfTrue                /        |
+  //   |      . . .    |                  /         |
+  //   |               If                /          |
+  //   |               / \              /           |
+  //   |              /   \            /            |
+  //   |         IfFalse IfTrue       /             |
+  //   |           . . .   |         /              |
+  //   |                    \       /               |
+  //   |                     \     /                |
+  //   |             MemBarVolatile__(card mark)    |
+  //   |                ||   C |  M \  M \          |
+  //   |               LoadB   If    |    |         |
+  //   |                      / \    |    |         |
+  //   |                     . . .   |    |         |
+  //   |                          \  |    |        /
+  //   |                        StoreCM   |       /
+  //   |                          . . .   |      /
+  //   |                        _________/      /
+  //   |                       /  _____________/
+  //   |   . . .       . . .  |  /            /
+  //   |    |                 | /   _________/
+  //   |    |               Phi[M] /        /
+  //   |    |                 |   /        /
+  //   |    |                 |  /        /
+  //   |  Region  . . .     Phi[M]  _____/
+  //   |    /                 |    /
+  //   |                      |   /
+  //   | . . .   . . .        |  /
+  //   | /                    | /
+  // Region           |  |  Phi[M]
+  //   |              |  |  / Bot
+  //    \            MergeMem
+  //     \            /
+  //     MemBarVolatile
+  //
+  // As with CMS the initial MergeMem merges the AliasIdxBot Mem slice
+  // from the leading membar and the oopptr Mem slice from the Store
+  // into the card mark membar i.e. the memory flow to the card mark
+  // membar still looks like a normal graph.
+  //
+  // The trailing MergeMem merges an AliasIdxBot Mem slice with other
+  // Mem slices (from the StoreCM and other card mark queue stores).
+  // However in this case the AliasIdxBot Mem slice does not come
+  // direct from the card mark membar. It is merged through a series
+  // of Phi nodes. These are needed to merge the AliasIdxBot Mem flow
+  // from the leading membar with the Mem feed from the card mark
+  // membar. Each Phi corresponds to one of the Ifs which may skip
+  // around the card mark membar. So when the If implementing the NULL
+  // value check has been elided the total number of Phis is 2
+  // otherwise it is 3.
+  //
+  // The CAS graph when using G1GC also includes a pre-write subgraph
+  // and an optional post-write subgraph. Teh sam evarioations are
+  // introduced as for CMS with conditional card marking i.e. the
+  // StoreP/N is swapped for a CompareAndSwapP/N, the tariling
+  // MemBarVolatile for a MemBarCPUOrder + MemBarAcquire pair and the
+  // Mem feed from the CompareAndSwapP/N includes a precedence
+  // dependency feed to the StoreCM and a feed via an SCMemProj to the
+  // trailing membar. So, as before the configuration includes the
+  // normal CAS graph as a subgraph of the memory flow.
+  //
+  // So, the upshot is that in all cases the volatile put graph will
+  // include a *normal* memory subgraph betwen the leading membar and
+  // its child membar, either a volatile put graph (including a
+  // releasing StoreX) or a CAS graph (including a CompareAndSwapX).
+  // When that child is not a card mark membar then it marks the end
+  // of the volatile put or CAS subgraph. If the child is a card mark
+  // membar then the normal subgraph will form part of a volatile put
+  // subgraph if and only if the child feeds an AliasIdxBot Mem feed
+  // to a trailing barrier via a MergeMem. That feed is either direct
+  // (for CMS) or via 2 or 3 Phi nodes merging the leading barrier
+  // memory flow (for G1).
   //
   // The predicates controlling generation of instructions for store
   // and barrier nodes employ a few simple helper functions (described
@@ -1971,24 +1905,24 @@
   }
 
 
-  // leading_to_trailing
+  // leading_to_normal
   //
   //graph traversal helper which detects the normal case Mem feed from
   // a release membar (or, optionally, its cpuorder child) to a
   // dependent volatile membar i.e. it ensures that one or other of
   // the following Mem flow subgraph is present.
   //
-  //   MemBarRelease {leading}
-  //   {MemBarCPUOrder} {optional}
-  //     Bot |  \      . . .
-  //         |  StoreN/P[mo_release]  . . .
-  //         |   /
-  //        MergeMem
-  //         |
-  //   MemBarVolatile {not card mark}
-  //
-  //   MemBarRelease {leading}
-  //   {MemBarCPUOrder} {optional}
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
+  //          |  \      . . .
+  //          |  StoreN/P[mo_release]  . . .
+  //          |   /
+  //         MergeMem
+  //          |
+  //   MemBarVolatile {trailing or card mark}
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
   //      |       \      . . .
   //      |     CompareAndSwapX  . . .
   //               |
@@ -1999,23 +1933,6 @@
   //    MemBarCPUOrder
   //    MemBarAcquire {trailing}
   //
-  // the predicate needs to be capable of distinguishing the following
-  // volatile put graph which may arises when a GC post barrier
-  // inserts a card mark membar
-  //
-  //   MemBarRelease {leading}
-  //   {MemBarCPUOrder}__
-  //     Bot |   \       \
-  //         |   StoreN/P \
-  //         |    / \     |
-  //        MergeMem \    |
-  //         |        \   |
-  //   MemBarVolatile  \  |
-  //    {card mark}     \ |
-  //                  MergeMem
-  //                      |
-  // {not card mark} MemBarVolatile
-  //
   // if the correct configuration is present returns the trailing
   // membar otherwise NULL.
   //
@@ -2026,7 +1943,7 @@
   // the returned value may be a card mark or trailing membar
   //
 
-  MemBarNode *leading_to_trailing(MemBarNode *leading)
+  MemBarNode *leading_to_normal(MemBarNode *leading)
   {
     assert((leading->Opcode() == Op_MemBarRelease ||
 	    leading->Opcode() == Op_MemBarCPUOrder),
@@ -2043,21 +1960,15 @@
     StoreNode * st = NULL;
     LoadStoreNode *cas = NULL;
     MergeMemNode *mm = NULL;
-    MergeMemNode *mm2 = NULL;
 
     for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
       x = mem->fast_out(i);
       if (x->is_MergeMem()) {
 	if (mm != NULL) {
-	  if (mm2 != NULL) {
-	  // should not see more than 2 merge mems
-	    return NULL;
-	  } else {
-	    mm2 = x->as_MergeMem();
-	  }
-	} else {
-	  mm = x->as_MergeMem();
+	  return NULL;
 	}
+	// two merge mems is one too many
+	mm = x->as_MergeMem();
       } else if (x->is_Store() && x->as_Store()->is_release() && x->Opcode() != Op_StoreCM) {
 	// two releasing stores/CAS nodes is one too many
 	if (st != NULL || cas != NULL) {
@@ -2077,13 +1988,13 @@
       return NULL;
     }
 
-    // must have at least one merge if we also have st
+    // must have a merge if we also have st
     if (st && !mm) {
       return NULL;
     }
 
+    Node *y = NULL;
     if (cas) {
-      Node *y = NULL;
       // look for an SCMemProj
       for (DUIterator_Fast imax, i = cas->fast_outs(imax); i < imax; i++) {
 	x = cas->fast_out(i);
@@ -2103,29 +2014,10 @@
 	  break;
 	}
       }
-      if (mm == NULL) {
+      if (mm == NULL)
 	return NULL;
-      }
-      MemBarNode *mbar = NULL;
-      // ensure the merge feeds a trailing membar cpuorder + acquire pair
-      for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
-	x = mm->fast_out(i);
-	if (x->is_MemBar()) {
-	  int opcode = x->Opcode();
-	  if (opcode == Op_MemBarCPUOrder) {
-	    MemBarNode *z =  x->as_MemBar();
-	    z = child_membar(z);
-	    if (z != NULL && z->Opcode() == Op_MemBarAcquire) {
-	      mbar = z;
-	    }
-	  }
-	  break;
-	}
-      }
-      return mbar;
     } else {
-      Node *y = NULL;
-      // ensure the store feeds the first mergemem;
+      // ensure the store feeds the existing mergemem;
       for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
 	if (st->fast_out(i) == mm) {
 	  y = st;
@@ -2135,89 +2027,55 @@
       if (y == NULL) {
 	return NULL;
       }
-      if (mm2 != NULL) {
-	// ensure the store feeds the second mergemem;
-	y = NULL;
-	for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
-	  if (st->fast_out(i) == mm2) {
-	    y = st;
+    }
+
+    MemBarNode *mbar = NULL;
+    // ensure the merge feeds to the expected type of membar
+    for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
+      x = mm->fast_out(i);
+      if (x->is_MemBar()) {
+	int opcode = x->Opcode();
+	if (opcode == Op_MemBarVolatile && st) {
+	  mbar = x->as_MemBar();
+	} else if (cas && opcode == Op_MemBarCPUOrder) {
+	  MemBarNode *y =  x->as_MemBar();
+	  y = child_membar(y);
+	  if (y != NULL && y->Opcode() == Op_MemBarAcquire) {
+	    mbar = y;
 	  }
 	}
-	if (y == NULL) {
-	  return NULL;
-	}
-      }
-
-      MemBarNode *mbar = NULL;
-      // ensure the first mergemem feeds a volatile membar
-      for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
-	x = mm->fast_out(i);
-	if (x->is_MemBar()) {
-	  int opcode = x->Opcode();
-	  if (opcode == Op_MemBarVolatile) {
-	    mbar = x->as_MemBar();
-	  }
-	  break;
-	}
-      }
-      if (mm2 == NULL) {
-	// this is our only option for a trailing membar
-	return mbar;
+	break;
       }
-      // ensure the second mergemem feeds a volatile membar
-      MemBarNode *mbar2 = NULL;
-      for (DUIterator_Fast imax, i = mm2->fast_outs(imax); i < imax; i++) {
-	x = mm2->fast_out(i);
-	if (x->is_MemBar()) {
-	  int opcode = x->Opcode();
-	  if (opcode == Op_MemBarVolatile) {
-	    mbar2 = x->as_MemBar();
-	  }
-	  break;
-	}
-      }
-      // if we have two merge mems we must have two volatile membars
-      if (mbar == NULL || mbar2 == NULL) {
-	return NULL;
-      }
-      // return the trailing membar
-      if (is_card_mark_membar(mbar2)) {
-	return mbar;
-      } else {
-	if (is_card_mark_membar(mbar)) {
-	  return mbar2;
-	} else {
-	  return NULL;
-	}
-      }
-    }
-  }
-
-  // trailing_to_leading
+    }
+
+    return mbar;
+  }
+
+  // normal_to_leading
   //
   // graph traversal helper which detects the normal case Mem feed
-  // from a trailing membar to a preceding release membar (optionally
-  // its cpuorder child) i.e. it ensures that one or other of the
-  // following Mem flow subgraphs is present.
-  //
-  //   MemBarRelease {leading}
-  //   MemBarCPUOrder {optional}
-  //    | Bot |  \      . . .
-  //    |     |  StoreN/P[mo_release]  . . .
-  //    |     |   /
-  //    |    MergeMem
-  //    |     |
-  //   MemBarVolatile {not card mark}
-  //
-  //   MemBarRelease {leading}
-  //   MemBarCPUOrder {optional}
+  // from either a card mark or a trailing membar to a preceding
+  // release membar (optionally its cpuorder child) i.e. it ensures
+  // that one or other of the following Mem flow subgraphs is present.
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
+  //          |  \      . . .
+  //          |  StoreN/P[mo_release]  . . .
+  //          |   /
+  //         MergeMem
+  //          |
+  //   MemBarVolatile {card mark or trailing}
+  //
+  //   MemBarRelease
+  //   MemBarCPUOrder {leading}
   //      |       \      . . .
   //      |     CompareAndSwapX  . . .
   //               |
   //     . . .    SCMemProj
   //           \   |
   //      |    MergeMem
-  //      |       |
+  //      |        /
   //    MemBarCPUOrder
   //    MemBarAcquire {trailing}
   //
@@ -2227,20 +2085,15 @@
   // if the configuration is present returns the cpuorder member for
   // preference or when absent the release membar otherwise NULL.
   //
-  // n.b. the input membar is expected to be a MemBarVolatile or
-  // MemBarAcquire. if it is a MemBarVolatile it must *not* be a card
-  // mark membar.
-
-  MemBarNode *trailing_to_leading(const MemBarNode *barrier)
+  // n.b. the input membar is expected to be a MemBarVolatile but
+  // need not be a card mark membar.
+
+  MemBarNode *normal_to_leading(const MemBarNode *barrier)
   {
     // input must be a volatile membar
     assert((barrier->Opcode() == Op_MemBarVolatile ||
 	    barrier->Opcode() == Op_MemBarAcquire),
 	   "expecting a volatile or an acquire membar");
-
-    assert((barrier->Opcode() != Op_MemBarVolatile) ||
-	   !is_card_mark_membar(barrier),
-	   "not expecting a card mark membar");
     Node *x;
     bool is_cas = barrier->Opcode() == Op_MemBarAcquire;
 
@@ -2353,35 +2206,169 @@
     return NULL;
   }
 
-  // card_mark_to_leading
-  //
-  // graph traversal helper which traverses from a card mark volatile
-  // membar to a leading membar i.e. it ensures that the following Mem
-  // flow subgraph is present.
-  //
-  //    MemBarRelease {leading}
-  //   {MemBarCPUOrder} {optional}
-  //         |   . . .
+  // card_mark_to_trailing
+  //
+  // graph traversal helper which detects extra, non-normal Mem feed
+  // from a card mark volatile membar to a trailing membar i.e. it
+  // ensures that one of the following three GC post-write Mem flow
+  // subgraphs is present.
+  //
+  // 1)
+  //     . . .
+  //       |
+  //   MemBarVolatile (card mark)
+  //      |          |
+  //      |        StoreCM
+  //      |          |
+  //      |        . . .
+  //  Bot |  /
+  //   MergeMem
+  //      |
+  //      |
+  //    MemBarVolatile {trailing}
+  //
+  // 2)
+  //   MemBarRelease/CPUOrder (leading)
+  //    |
+  //    |
+  //    |\       . . .
+  //    | \        |
+  //    |  \  MemBarVolatile (card mark)
+  //    |   \   |     |
+  //     \   \  |   StoreCM    . . .
+  //      \   \ |
+  //       \  Phi
+  //        \ /
+  //        Phi  . . .
   //     Bot |   /
-  //      MergeMem
+  //       MergeMem
   //         |
-  //     MemBarVolatile (card mark)
-  //        |     \
-  //      . . .   StoreCM
-  //
-  // if the configuration is present returns the cpuorder member for
-  // preference or when absent the release membar otherwise NULL.
-  //
-  // n.b. the input membar is expected to be a MemBarVolatile amd must
-  // be a card mark membar.
-
-  MemBarNode *card_mark_to_leading(const MemBarNode *barrier)
+  //    MemBarVolatile {trailing}
+  //
+  //
+  // 3)
+  //   MemBarRelease/CPUOrder (leading)
+  //    |
+  //    |\
+  //    | \
+  //    |  \      . . .
+  //    |   \       |
+  //    |\   \  MemBarVolatile (card mark)
+  //    | \   \   |     |
+  //    |  \   \  |   StoreCM    . . .
+  //    |   \   \ |
+  //     \   \  Phi
+  //      \   \ /
+  //       \  Phi
+  //        \ /
+  //        Phi  . . .
+  //     Bot |   /
+  //       MergeMem
+  //         |
+  //         |
+  //    MemBarVolatile {trailing}
+  //
+  // configuration 1 is only valid if UseConcMarkSweepGC &&
+  // UseCondCardMark
+  //
+  // configurations 2 and 3 are only valid if UseG1GC.
+  //
+  // if a valid configuration is present returns the trailing membar
+  // otherwise NULL.
+  //
+  // n.b. the supplied membar is expected to be a card mark
+  // MemBarVolatile i.e. the caller must ensure the input node has the
+  // correct operand and feeds Mem to a StoreCM node
+
+  MemBarNode *card_mark_to_trailing(const MemBarNode *barrier)
   {
     // input must be a card mark volatile membar
     assert(is_card_mark_membar(barrier), "expecting a card mark membar");
 
+    Node *feed = barrier->proj_out(TypeFunc::Memory);
+    Node *x;
+    MergeMemNode *mm = NULL;
+
+    const int MAX_PHIS = 3;	// max phis we will search through
+    int phicount = 0; 		// current search count
+
+    bool retry_feed = true;
+    while (retry_feed) {
+      // see if we have a direct MergeMem feed
+      for (DUIterator_Fast imax, i = feed->fast_outs(imax); i < imax; i++) {
+	x = feed->fast_out(i);
+	// the correct Phi will be merging a Bot memory slice
+	if (x->is_MergeMem()) {
+	  mm = x->as_MergeMem();
+	  break;
+	}
+      }
+      if (mm) {
+	retry_feed = false;
+      } else if (UseG1GC & phicount++ < MAX_PHIS) {
+	// the barrier may feed indirectly via one or two Phi nodes
+	PhiNode *phi = NULL;
+	for (DUIterator_Fast imax, i = feed->fast_outs(imax); i < imax; i++) {
+	  x = feed->fast_out(i);
+	  // the correct Phi will be merging a Bot memory slice
+	  if (x->is_Phi() && x->adr_type() == TypePtr::BOTTOM) {
+	    phi = x->as_Phi();
+	    break;
+	  }
+	}
+	if (!phi) {
+	  return NULL;
+	}
+	// look for another merge below this phi
+	feed = phi;
+      } else {
+	// couldn't find a merge
+	return NULL;
+      }
+    }
+
+    // sanity check this feed turns up as the expected slice
+    assert(mm->as_MergeMem()->in(Compile::AliasIdxBot) == feed, "expecting membar to feed AliasIdxBot slice to Merge");
+
+    MemBarNode *trailing = NULL;
+    // be sure we have a trailing membar the merge
+    for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) {
+      x = mm->fast_out(i);
+      if (x->is_MemBar() && x->Opcode() == Op_MemBarVolatile) {
+	trailing = x->as_MemBar();
+	break;
+      }
+    }
+
+    return trailing;
+  }
+
+  // trailing_to_card_mark
+  //
+  // graph traversal helper which detects extra, non-normal Mem feed
+  // from a trailing volatile membar to a preceding card mark volatile
+  // membar i.e. it identifies whether one of the three possible extra
+  // GC post-write Mem flow subgraphs is present
+  //
+  // this predicate checks for the same flow as the previous predicate
+  // but starting from the bottom rather than the top.
+  //
+  // if the configuration is present returns the card mark membar
+  // otherwise NULL
+  //
+  // n.b. the supplied membar is expected to be a trailing
+  // MemBarVolatile i.e. the caller must ensure the input node has the
+  // correct opcode
+
+  MemBarNode *trailing_to_card_mark(const MemBarNode *trailing)
+  {
+    assert(trailing->Opcode() == Op_MemBarVolatile,
+	   "expecting a volatile membar");
+    assert(!is_card_mark_membar(trailing),
+	   "not expecting a card mark membar");
+
     // the Mem feed to the membar should be a merge
-    Node *x = barrier->in(TypeFunc::Memory);
+    Node *x = trailing->in(TypeFunc::Memory);
     if (!x->is_MergeMem()) {
       return NULL;
     }
@@ -2389,19 +2376,117 @@
     MergeMemNode *mm = x->as_MergeMem();
 
     x = mm->in(Compile::AliasIdxBot);
-
+    // with G1 we may possibly see a Phi or two before we see a Memory
+    // Proj from the card mark membar
+
+    const int MAX_PHIS = 3;	// max phis we will search through
+    int phicount = 0; 		// current search count
+
+    bool retry_feed = !x->is_Proj();
+
+    while (retry_feed) {
+      if (UseG1GC && x->is_Phi() && phicount++ < MAX_PHIS) {
+	PhiNode *phi = x->as_Phi();
+	ProjNode *proj = NULL;
+	PhiNode *nextphi = NULL;
+	bool found_leading = false;
+	for (uint i = 1; i < phi->req(); i++) {
+	  x = phi->in(i);
+	  if (x->is_Phi()) {
+	    nextphi = x->as_Phi();
+	  } else if (x->is_Proj()) {
+	    int opcode = x->in(0)->Opcode();
+	    if (opcode == Op_MemBarVolatile) {
+	      proj = x->as_Proj();
+	    } else if (opcode == Op_MemBarRelease ||
+		       opcode == Op_MemBarCPUOrder) {
+	      // probably a leading membar
+	      found_leading = true;
+	    }
+	  }
+	}
+	// if we found a correct looking proj then retry from there
+	// otherwise we must see a leading and a phi or this the
+	// wrong config
+	if (proj != NULL) {
+	  x = proj;
+	  retry_feed = false;
+	} else if (found_leading && nextphi != NULL) {
+	  // retry from this phi to check phi2
+	  x = nextphi;
+	} else {
+	  // not what we were looking for
+	  return NULL;
+	}
+      } else {
+	return NULL;
+      }
+    }
+    // the proj has to come from the card mark membar
+    x = x->in(0);
     if (!x->is_MemBar()) {
       return NULL;
     }
 
-    MemBarNode *leading = x->as_MemBar();
-
-    if (leading_membar(leading)) {
+    MemBarNode *card_mark_membar = x->as_MemBar();
+
+    if (!is_card_mark_membar(card_mark_membar)) {
+      return NULL;
+    }
+
+    return card_mark_membar;
+  }
+
+  // trailing_to_leading
+  //
+  // graph traversal helper which checks the Mem flow up the graph
+  // from a (non-card mark) trailing membar attempting to locate and
+  // return an associated leading membar. it first looks for a
+  // subgraph in the normal configuration (relying on helper
+  // normal_to_leading). failing that it then looks for one of the
+  // possible post-write card mark subgraphs linking the trailing node
+  // to a the card mark membar (relying on helper
+  // trailing_to_card_mark), and then checks that the card mark membar
+  // is fed by a leading membar (once again relying on auxiliary
+  // predicate normal_to_leading).
+  //
+  // if the configuration is valid returns the cpuorder member for
+  // preference or when absent the release membar otherwise NULL.
+  //
+  // n.b. the input membar is expected to be either a volatile or
+  // acquire membar but in the former case must *not* be a card mark
+  // membar.
+
+  MemBarNode *trailing_to_leading(const MemBarNode *trailing)
+  {
+    assert((trailing->Opcode() == Op_MemBarAcquire ||
+	    trailing->Opcode() == Op_MemBarVolatile),
+	   "expecting an acquire or volatile membar");
+    assert((trailing->Opcode() != Op_MemBarVolatile ||
+	    !is_card_mark_membar(trailing)),
+	   "not expecting a card mark membar");
+
+    MemBarNode *leading = normal_to_leading(trailing);
+
+    if (leading) {
       return leading;
     }
 
-    return NULL;
-  }
+    // nothing more to do if this is an acquire
+    if (trailing->Opcode() == Op_MemBarAcquire) {
+      return NULL;
+    }
+
+    MemBarNode *card_mark_membar = trailing_to_card_mark(trailing);
+
+    if (!card_mark_membar) {
+      return NULL;
+    }
+
+    return normal_to_leading(card_mark_membar);
+  }
+
+  // predicates controlling emit of ldr<x>/ldar<x> and associated dmb
 
 bool unnecessary_acquire(const Node *barrier)
 {
@@ -2617,8 +2702,19 @@
   }
 
   // must start with a normal feed
-  MemBarNode *trailing = leading_to_trailing(barrier);
-
+  MemBarNode *child_barrier = leading_to_normal(barrier);
+
+  if (!child_barrier) {
+    return false;
+  }
+
+  if (!is_card_mark_membar(child_barrier)) {
+    // this is the trailing membar and we are done
+    return true;
+  }
+
+  // must be sure this card mark feeds a trailing membar
+  MemBarNode *trailing = card_mark_to_trailing(child_barrier);
   return (trailing != NULL);
 }
 
@@ -2640,7 +2736,7 @@
   }
 
   // ok, if it's not a card mark then we still need to check if it is
-  // a trailing membar of a volatile put graph.
+  // a trailing membar of a volatile put hgraph.
 
   return (trailing_to_leading(mbvol) != NULL);
 }
@@ -2690,9 +2786,20 @@
   }
 
   // does this lead a normal subgraph?
-  MemBarNode *trailing = leading_to_trailing(barrier);
-
-  return (trailing != NULL);
+  MemBarNode *mbvol = leading_to_normal(barrier);
+
+  if (!mbvol) {
+    return false;
+  }
+
+  // all done unless this is a card mark
+  if (!is_card_mark_membar(mbvol)) {
+    return true;
+  }
+
+  // we found a card mark -- just make sure we have a trailing barrier
+
+  return (card_mark_to_trailing(mbvol) != NULL);
 }
 
 // predicate controlling translation of CAS
@@ -2734,7 +2841,7 @@
 	  "CAS not fed by cpuorder+release membar pair!");
 
   // does this lead a normal subgraph?
-  MemBarNode *mbar = leading_to_trailing(barrier);
+  MemBarNode *mbar = leading_to_normal(barrier);
 
   assert(mbar != NULL, "CAS not embedded in normal graph!");
 
@@ -2755,27 +2862,48 @@
 
   // we only ever need to generate a dmb ishst between an object put
   // and the associated card mark when we are using CMS without
-  // conditional card marking. Any other occurence will happen when
-  // performing a card mark using CMS with conditional card marking or
-  // G1. In those cases the preceding MamBarVolatile will be
-  // translated to a dmb ish which guarantes visibility of the
-  // preceding StoreN/P before this StoreCM
+  // conditional card marking
 
   if (!UseConcMarkSweepGC || UseCondCardMark) {
     return true;
   }
 
-  // if we are implementing volatile puts using barriers then we must
-  // insert the dmb ishst
+  // if we are implementing volatile puts using barriers then the
+  // object put as an str so we must insert the dmb ishst
 
   if (UseBarriersForVolatile) {
     return false;
   }
 
-  // we must be using CMS with conditional card marking so we ahve to
-  // generate the StoreStore
-
-  return false;
+  // we can omit the dmb ishst if this StoreCM is part of a volatile
+  // put because in thta case the put will be implemented by stlr
+  //
+  // we need to check for a normal subgraph feeding this StoreCM.
+  // that means the StoreCM must be fed Memory from a leading membar,
+  // either a MemBarRelease or its dependent MemBarCPUOrder, and the
+  // leading membar must be part of a normal subgraph
+
+  Node *x = storecm->in(StoreNode::Memory);
+
+  if (!x->is_Proj()) {
+    return false;
+  }
+
+  x = x->in(0);
+
+  if (!x->is_MemBar()) {
+    return false;
+  }
+
+  MemBarNode *leading = x->as_MemBar();
+
+  // reject invalid candidates
+  if (!leading_membar(leading)) {
+    return false;
+  }
+
+  // we can omit the StoreStore if it is the head of a normal subgraph
+  return (leading_to_normal(leading) != NULL);
 }
 
 
@@ -3008,6 +3136,10 @@
     __ notify(Assembler::method_reentry);
   }
 
+  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
+    __ reserved_stack_check();
+  }
+
   if (do_polling() && C->is_method_compilation()) {
     __ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type);
   }
@@ -9862,7 +9994,7 @@
 // END This section of the file is automatically generated. Do not edit --------------
 // ---------------------------------------------------------------------
 
-instruct get_and_setI(indirect mem, iRegINoSp newv, iRegI prev) %{
+instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
   match(Set prev (GetAndSetI mem newv));
   format %{ "atomic_xchgw  $prev, $newv, [$mem]" %}
   ins_encode %{
@@ -9871,7 +10003,7 @@
   ins_pipe(pipe_serial);
 %}
 
-instruct get_and_setL(indirect mem, iRegLNoSp newv, iRegL prev) %{
+instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
   match(Set prev (GetAndSetL mem newv));
   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
   ins_encode %{
@@ -9880,7 +10012,7 @@
   ins_pipe(pipe_serial);
 %}
 
-instruct get_and_setN(indirect mem, iRegNNoSp newv, iRegI prev) %{
+instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
   match(Set prev (GetAndSetN mem newv));
   format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
   ins_encode %{
@@ -9889,7 +10021,7 @@
   ins_pipe(pipe_serial);
 %}
 
-instruct get_and_setP(indirect mem, iRegPNoSp newv, iRegP prev) %{
+instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
   match(Set prev (GetAndSetP mem newv));
   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
   ins_encode %{
--- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -532,8 +532,14 @@
 
 void LIR_Assembler::return_op(LIR_Opr result) {
   assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == r0, "word returns are in r0,");
+
   // Pop the stack before the safepoint code
   __ remove_frame(initial_frame_size_in_bytes());
+
+  if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
+    __ reserved_stack_check();
+  }
+
   address polling_page(os::get_polling_page());
   __ read_polling_page(rscratch1, polling_page, relocInfo::poll_return_type);
   __ ret(lr);
--- a/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -1179,6 +1179,15 @@
         Label done;
         Label runtime;
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ ldrw(tmp, in_progress);
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ ldrb(tmp, in_progress);
+        }
+        __ cbzw(tmp, done);
+
         // Can we store original value in the thread's buffer?
         __ ldr(tmp, queue_index);
         __ cbz(tmp, runtime);
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -375,7 +375,8 @@
   fr._unextended_sp = unextended_sp;
 
   address original_pc = nm->get_original_pc(&fr);
-  assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
+  assert(nm->insts_contains_inclusive(original_pc),
+         "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
 }
 #endif
 
@@ -629,6 +630,7 @@
     DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_method);
     DESCRIBE_FP_OFFSET(interpreter_frame_mdp);
+    DESCRIBE_FP_OFFSET(interpreter_frame_mirror);
     DESCRIBE_FP_OFFSET(interpreter_frame_cache);
     DESCRIBE_FP_OFFSET(interpreter_frame_locals);
     DESCRIBE_FP_OFFSET(interpreter_frame_bcp);
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -46,6 +46,9 @@
 //    [pointer to locals     ]                   = locals()             locals_offset
 //    [constant pool cache   ]                   = cache()              cache_offset
 
+//    [klass of method       ]                   = mirror()             mirror_offset
+//    [padding               ]
+
 //    [methodData            ]                   = mdp()                mdx_offset
 //    [methodOop             ]                   = method()             method_offset
 
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.inline.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -82,7 +82,8 @@
   address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
-    assert(((CompiledMethod*)_cb)->insts_contains(_pc), "original PC must be in CompiledMethod");
+    assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
+           "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
     _deopt_state = is_deoptimized;
   } else {
     _deopt_state = not_deoptimized;
--- a/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/globalDefinitions_aarch64.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -53,4 +53,6 @@
 // evidence that it's worth doing.
 #define DEOPTIMIZE_WHEN_PATCHING
 
+#define SUPPORT_RESERVED_STACK_AREA
+
 #endif // CPU_AARCH64_VM_GLOBALDEFINITIONS_AARCH64_HPP
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -50,7 +50,7 @@
 // stack if compiled for unix and LP64. To pass stack overflow tests we need
 // 20 shadow pages.
 #define DEFAULT_STACK_SHADOW_PAGES (20 DEBUG_ONLY(+5))
-#define DEFAULT_STACK_RESERVED_PAGES (0)
+#define DEFAULT_STACK_RESERVED_PAGES (1)
 
 #define MIN_STACK_YELLOW_PAGES DEFAULT_STACK_YELLOW_PAGES
 #define MIN_STACK_RED_PAGES    DEFAULT_STACK_RED_PAGES
--- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -619,6 +619,22 @@
   // get sender esp
   ldr(esp,
       Address(rfp, frame::interpreter_frame_sender_sp_offset * wordSize));
+  if (StackReservedPages > 0) {
+    // testing if reserved zone needs to be re-enabled
+    Label no_reserved_zone_enabling;
+
+    ldr(rscratch1, Address(rthread, JavaThread::reserved_stack_activation_offset()));
+    cmp(esp, rscratch1);
+    br(Assembler::LS, no_reserved_zone_enabling);
+
+    call_VM_leaf(
+      CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), rthread);
+    call_VM(noreg, CAST_FROM_FN_PTR(address,
+                   InterpreterRuntime::throw_delayed_StackOverflowError));
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+  }
   // remove frame anchor
   leave();
   // If we're returning to interpreted code we will shortly be
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -402,6 +402,30 @@
   }
 }
 
+void MacroAssembler::reserved_stack_check() {
+    // testing if reserved zone needs to be enabled
+    Label no_reserved_zone_enabling;
+
+    ldr(rscratch1, Address(rthread, JavaThread::reserved_stack_activation_offset()));
+    cmp(sp, rscratch1);
+    br(Assembler::LO, no_reserved_zone_enabling);
+
+    enter();   // LR and FP are live.
+    lea(rscratch1, CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone));
+    mov(c_rarg0, rthread);
+    blr(rscratch1);
+    leave();
+
+    // We have already removed our own frame.
+    // throw_delayed_StackOverflowError will think that it's been
+    // called by our caller.
+    lea(rscratch1, RuntimeAddress(StubRoutines::throw_delayed_StackOverflowError_entry()));
+    br(rscratch1);
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+}
+
 int MacroAssembler::biased_locking_enter(Register lock_reg,
                                          Register obj_reg,
                                          Register swap_reg,
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -957,6 +957,9 @@
   // stack overflow + shadow pages.  Also, clobbers tmp
   void bang_stack_size(Register size, Register tmp);
 
+  // Check for reserved stack access in method being exited (for JIT)
+  void reserved_stack_check();
+
   virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
                                                 Register tmp,
                                                 int offset);
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -4676,8 +4676,11 @@
     StubRoutines::_throw_StackOverflowError_entry =
       generate_throw_exception("StackOverflowError throw_exception",
                                CAST_FROM_FN_PTR(address,
-                                                SharedRuntime::
-                                                throw_StackOverflowError));
+                                                SharedRuntime::throw_StackOverflowError));
+    StubRoutines::_throw_delayed_StackOverflowError_entry =
+      generate_throw_exception("delayed StackOverflowError throw_exception",
+                               CAST_FROM_FN_PTR(address,
+                                                SharedRuntime::throw_delayed_StackOverflowError));
     if (UseCRC32Intrinsics) {
       // set table address before stub generation which use it
       StubRoutines::_crc_table_adr = (address)StubRoutines::aarch64::_crc_table;
--- a/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/arm/vm/c1_Runtime1_arm.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -551,6 +551,8 @@
         const Register r_index_1    = R1;
         const Register r_buffer_2   = R2;
 
+        Address queue_active(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
+                                               SATBMarkQueue::byte_offset_of_active()));
         Address queue_index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
                                               SATBMarkQueue::byte_offset_of_index()));
         Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
@@ -559,6 +561,11 @@
         Label done;
         Label runtime;
 
+        // Is marking still active?
+        assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+        __ ldrb(R1, queue_active);
+        __ cbz(R1, done);
+
         __ ldr(r_index_1, queue_index);
         __ ldr(r_pre_val_0, Address(SP, nb_saved_regs*wordSize));
         __ ldr(r_buffer_2, buffer);
--- a/hotspot/src/cpu/arm/vm/frame_arm.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/arm/vm/frame_arm.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -364,7 +364,8 @@
   fr._unextended_sp = unextended_sp;
 
   address original_pc = nm->get_original_pc(&fr);
-  assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
+  assert(nm->insts_contains_inclusive(original_pc),
+         "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
   assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
 }
 #endif
--- a/hotspot/src/cpu/arm/vm/frame_arm.inline.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/arm/vm/frame_arm.inline.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -75,7 +75,8 @@
   address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
-    assert(_cb->as_compiled_method()->insts_contains(_pc), "original PC must be in CompiledMethod");
+    assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
+           "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
     _deopt_state = is_deoptimized;
   } else {
     _deopt_state = not_deoptimized;
--- a/hotspot/src/cpu/ppc/vm/c1_Runtime1_ppc.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/ppc/vm/c1_Runtime1_ppc.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -741,7 +741,10 @@
         Register tmp  = R14;
         Register tmp2 = R15;
 
-        Label refill, restart;
+        Label refill, restart, marking_not_active;
+        int satb_q_active_byte_offset =
+          in_bytes(JavaThread::satb_mark_queue_offset() +
+                   SATBMarkQueue::byte_offset_of_active());
         int satb_q_index_byte_offset =
           in_bytes(JavaThread::satb_mark_queue_offset() +
                    SATBMarkQueue::byte_offset_of_index());
@@ -753,6 +756,16 @@
         __ std(tmp, -16, R1_SP);
         __ std(tmp2, -24, R1_SP);
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ lwz(tmp, satb_q_active_byte_offset, R16_thread);
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ lbz(tmp, satb_q_active_byte_offset, R16_thread);
+        }
+        __ cmpdi(CCR0, tmp, 0);
+        __ beq(CCR0, marking_not_active);
+
         __ bind(restart);
         // Load the index into the SATB buffer. SATBMarkQueue::_index is a
         // size_t so ld_ptr is appropriate.
@@ -769,6 +782,7 @@
         __ std(tmp, satb_q_index_byte_offset, R16_thread);
         __ stdx(pre_val, tmp2, tmp); // [_buf + index] := <address_of_card>
 
+        __ bind(marking_not_active);
         // Restore temp registers and return-from-leaf.
         __ ld(tmp2, -24, R1_SP);
         __ ld(tmp, -16, R1_SP);
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -2569,7 +2569,7 @@
 }
 
 // Spin and retry if lock is busy.
-// inputs: box_Reg (monitor address)
+// inputs: owner_addr_Reg (monitor address)
 //       : retry_count_Reg
 // output: retry_count_Reg decremented by 1
 // CTR is killed
@@ -2577,15 +2577,22 @@
   Label SpinLoop, doneRetry;
   addic_(retry_count_Reg, retry_count_Reg, -1);
   blt(CCR0, doneRetry);
-  li(R0, RTMSpinLoopCount);
-  mtctr(R0);
+
+  if (RTMSpinLoopCount > 1) {
+    li(R0, RTMSpinLoopCount);
+    mtctr(R0);
+  }
 
   bind(SpinLoop);
   smt_yield(); // Can't use waitrsv(). No permission (SIGILL).
-  bdz(retryLabel);
-  ld(R0, 0, owner_addr_Reg);
-  cmpdi(CCR0, R0, 0);
-  bne(CCR0, SpinLoop);
+
+  if (RTMSpinLoopCount > 1) {
+    bdz(retryLabel);
+    ld(R0, 0, owner_addr_Reg);
+    cmpdi(CCR0, R0, 0);
+    bne(CCR0, SpinLoop);
+  }
+
   b(retryLabel);
 
   bind(doneRetry);
--- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -327,7 +327,10 @@
       warning("RTMAbortRatio must be in the range 0 to 100, resetting it to 50");
       FLAG_SET_DEFAULT(RTMAbortRatio, 50);
     }
-    guarantee(RTMSpinLoopCount > 0, "unsupported");
+    if (RTMSpinLoopCount < 0) {
+      warning("RTMSpinLoopCount must not be a negative value, resetting it to 0");
+      FLAG_SET_DEFAULT(RTMSpinLoopCount, 0);
+    }
 #else
     // Only C2 does RTM locking optimization.
     // Can't continue because UseRTMLocking affects UseBiasedLocking flag
--- a/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1105,16 +1105,16 @@
       }
     case T_FLOAT :
       if (short_disp) {
-                    __ z_ste(from->as_float_reg(),  disp_value, disp_reg, dest);
+        __ z_ste(from->as_float_reg(),  disp_value, disp_reg, dest);
       } else {
-                    __ z_stey(from->as_float_reg(), disp_value, disp_reg, dest);
+        __ z_stey(from->as_float_reg(), disp_value, disp_reg, dest);
       }
       break;
     case T_DOUBLE:
       if (short_disp) {
-                    __ z_std(from->as_double_reg(),  disp_value, disp_reg, dest);
+        __ z_std(from->as_double_reg(),  disp_value, disp_reg, dest);
       } else {
-                    __ z_stdy(from->as_double_reg(), disp_value, disp_reg, dest);
+        __ z_stdy(from->as_double_reg(), disp_value, disp_reg, dest);
       }
       break;
     default: ShouldNotReachHere();
@@ -1148,6 +1148,10 @@
     __ restore_return_pc();
   }
 
+  if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
+    __ reserved_stack_check(Z_R14);
+  }
+
   // We need to mark the code position where the load from the safepoint
   // polling page was emitted as relocInfo::poll_return_type here.
   __ relocate(relocInfo::poll_return_type);
--- a/hotspot/src/cpu/s390/vm/c1_Runtime1_s390.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/c1_Runtime1_s390.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017 Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2016 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -784,7 +784,10 @@
         Register tmp  = Z_R6; // Must be non-volatile because it is used to save pre_val.
         Register tmp2 = Z_R7;
 
-        Label refill, restart;
+        Label refill, restart, marking_not_active;
+        int satb_q_active_byte_offset =
+          in_bytes(JavaThread::satb_mark_queue_offset() +
+                   SATBMarkQueue::byte_offset_of_active());
         int satb_q_index_byte_offset =
           in_bytes(JavaThread::satb_mark_queue_offset() +
                    SATBMarkQueue::byte_offset_of_index());
@@ -796,6 +799,15 @@
         __ z_stg(tmp,  0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
         __ z_stg(tmp2, 1*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ load_and_test_int(tmp, Address(Z_thread, satb_q_active_byte_offset));
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ load_and_test_byte(tmp, Address(Z_thread, satb_q_active_byte_offset));
+        }
+        __ z_bre(marking_not_active); // Activity indicator is zero, so there is no marking going on currently.
+
         __ bind(restart);
         // Load the index into the SATB buffer. SATBMarkQueue::_index is a
         // size_t so ld_ptr is appropriate.
@@ -810,6 +822,7 @@
         __ z_stg(pre_val, 0, tmp, tmp2); // [_buf + index] := <address_of_card>
         __ z_stg(tmp, satb_q_index_byte_offset, Z_thread);
 
+        __ bind(marking_not_active);
         // Restore tmp registers (see assertion in G1PreBarrierStub::emit_code()).
         __ z_lg(tmp,  0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
         __ z_lg(tmp2, 1*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
--- a/hotspot/src/cpu/s390/vm/globalDefinitions_s390.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/globalDefinitions_s390.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -52,4 +52,6 @@
 // The expected size in bytes of a cache line, used to pad data structures.
 #define DEFAULT_CACHE_LINE_SIZE 256
 
+#define SUPPORT_RESERVED_STACK_AREA
+
 #endif // CPU_S390_VM_GLOBALDEFINITIONS_S390_HPP
--- a/hotspot/src/cpu/s390/vm/globals_s390.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/globals_s390.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -56,7 +56,7 @@
 // Java_java_net_SocketOutputStream_socketWrite0() uses a 64k buffer on the
 // stack. To pass stack overflow tests we need 20 shadow pages.
 #define DEFAULT_STACK_SHADOW_PAGES   (20 DEBUG_ONLY(+2))
-#define DEFAULT_STACK_RESERVED_PAGES (0)
+#define DEFAULT_STACK_RESERVED_PAGES (1)
 
 #define MIN_STACK_YELLOW_PAGES     DEFAULT_STACK_YELLOW_PAGES
 #define MIN_STACK_RED_PAGES        DEFAULT_STACK_RED_PAGES
--- a/hotspot/src/cpu/s390/vm/interp_masm_s390.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/interp_masm_s390.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -860,16 +860,39 @@
                                                   bool throw_monitor_exception,
                                                   bool install_monitor_exception,
                                                   bool notify_jvmti) {
-
+  BLOCK_COMMENT("remove_activation {");
   unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
 
   // Save result (push state before jvmti call and pop it afterwards) and notify jvmti.
   notify_method_exit(false, state, notify_jvmti ? NotifyJVMTI : SkipNotifyJVMTI);
 
+  if (StackReservedPages > 0) {
+    BLOCK_COMMENT("reserved_stack_check:");
+    // Test if reserved zone needs to be enabled.
+    Label no_reserved_zone_enabling;
+
+    // Compare frame pointers. There is no good stack pointer, as with stack
+    // frame compression we can get different SPs when we do calls. A subsequent
+    // call could have a smaller SP, so that this compare succeeds for an
+    // inner call of the method annotated with ReservedStack.
+    z_lg(Z_R0, Address(Z_SP, (intptr_t)_z_abi(callers_sp)));
+    z_clg(Z_R0, Address(Z_thread, JavaThread::reserved_stack_activation_offset())); // Compare with frame pointer in memory.
+    z_brl(no_reserved_zone_enabling);
+
+    // Enable reserved zone again, throw stack overflow exception.
+    call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), Z_thread);
+    call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_delayed_StackOverflowError));
+
+    should_not_reach_here();
+
+    bind(no_reserved_zone_enabling);
+  }
+
   verify_oop(Z_tos, state);
   verify_thread();
 
   pop_interpreter_frame(return_pc, Z_ARG2, Z_ARG3);
+  BLOCK_COMMENT("} remove_activation");
 }
 
 // lock object
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -2666,6 +2666,32 @@
   }
 }
 
+void MacroAssembler::reserved_stack_check(Register return_pc) {
+  // Test if reserved zone needs to be enabled.
+  Label no_reserved_zone_enabling;
+  assert(return_pc == Z_R14, "Return pc must be in R14 before z_br() to StackOverflow stub.");
+  BLOCK_COMMENT("reserved_stack_check {");
+
+  z_clg(Z_SP, Address(Z_thread, JavaThread::reserved_stack_activation_offset()));
+  z_brl(no_reserved_zone_enabling);
+
+  // Enable reserved zone again, throw stack overflow exception.
+  save_return_pc();
+  push_frame_abi160(0);
+  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), Z_thread);
+  pop_frame();
+  restore_return_pc();
+
+  load_const_optimized(Z_R1, StubRoutines::throw_delayed_StackOverflowError_entry());
+  // Don't use call() or z_basr(), they will invalidate Z_R14 which contains the return pc.
+  z_br(Z_R1);
+
+  should_not_reach_here();
+
+  bind(no_reserved_zone_enabling);
+  BLOCK_COMMENT("} reserved_stack_check");
+}
+
 // Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes.
 void MacroAssembler::tlab_allocate(Register obj,
                                    Register var_size_in_bytes,
--- a/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/macroAssembler_s390.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -627,6 +627,11 @@
   // Stack overflow checking
   void bang_stack_with_offset(int offset);
 
+  // Check for reserved stack access in method being exited. If the reserved
+  // stack area was accessed, protect it again and throw StackOverflowError.
+  // Uses Z_R1.
+  void reserved_stack_check(Register return_pc);
+
   // Atomics
   // -- none?
 
--- a/hotspot/src/cpu/s390/vm/s390.ad	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/s390.ad	Fri Feb 10 08:57:42 2017 -0800
@@ -909,15 +909,8 @@
   // If this does safepoint polling, then do it here.
   bool need_polling = do_polling() && C->is_method_compilation();
 
-  // Touch the polling page.
-  // Part 1: get the page's address.
-  if (need_polling) {
-    AddressLiteral pp(os::get_polling_page());
-    __ load_const_optimized(Z_R1_scratch, pp);
-  }
-
   // Pop frame, restore return_pc, and all stuff needed by interpreter.
-  // Pop frame by add insted of load (a penny saved is a penny got :-).
+  // Pop frame by add instead of load (a penny saved is a penny got :-).
   int frame_size_in_bytes = Assembler::align((C->frame_slots() << LogBytesPerInt), frame::alignment_in_bytes);
   int retPC_offset        = frame_size_in_bytes + _z_abi16(return_pc);
   if (Displacement::is_validDisp(retPC_offset)) {
@@ -928,9 +921,14 @@
     __ restore_return_pc();
   }
 
-  // Touch the polling page,
-  // part 2: touch the page now.
+  if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
+    __ reserved_stack_check(Z_R14);
+  }
+
+  // Touch the polling page.
   if (need_polling) {
+    AddressLiteral pp(os::get_polling_page());
+    __ load_const_optimized(Z_R1_scratch, pp);
     // We need to mark the code position where the load from the safepoint
     // polling page was emitted as relocInfo::poll_return_type here.
     __ relocate(relocInfo::poll_return_type);
@@ -939,7 +937,7 @@
 }
 
 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
-  // variable size. determine dynamically.
+  // Variable size. determine dynamically.
   return MachNode::size(ra_);
 }
 
--- a/hotspot/src/cpu/s390/vm/stubGenerator_s390.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/stubGenerator_s390.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -2433,13 +2433,12 @@
     StubRoutines::_throw_StackOverflowError_entry          =
       generate_throw_exception("StackOverflowError throw_exception",
                                CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
+    StubRoutines::_throw_delayed_StackOverflowError_entry  =
+      generate_throw_exception("delayed StackOverflowError throw_exception",
+                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_delayed_StackOverflowError), false);
 
     //----------------------------------------------------------------------
     // Entry points that are platform specific.
-    // Build this early so it's available for the interpreter.
-    StubRoutines::_throw_StackOverflowError_entry          =
-      generate_throw_exception("StackOverflowError throw_exception",
-                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError), false);
 
     if (UseCRC32Intrinsics) {
       // We have no CRC32 table on z/Architecture.
--- a/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1112,16 +1112,21 @@
   // top_frame_size = TOP_IJAVA_FRAME_ABI + max_stack + size of interpreter state
   __ add2reg(top_frame_size,
              frame::z_top_ijava_frame_abi_size +
-               frame::z_ijava_state_size +
-               frame::interpreter_frame_monitor_size() * wordSize,
+             frame::z_ijava_state_size +
+             frame::interpreter_frame_monitor_size() * wordSize,
              max_stack);
 
-  // Check if there's room for the new frame...
-  Register frame_size = max_stack; // Reuse the regiser for max_stack.
-  __ z_lgr(frame_size, Z_SP);
-  __ z_sgr(frame_size, sp_after_resize);
-  __ z_agr(frame_size, top_frame_size);
-  generate_stack_overflow_check(frame_size, fp/*tmp1*/);
+  if (!native_call) {
+    // Stack overflow check.
+    // Native calls don't need the stack size check since they have no
+    // expression stack and the arguments are already on the stack and
+    // we only add a handful of words to the stack.
+    Register frame_size = max_stack; // Reuse the regiser for max_stack.
+    __ z_lgr(frame_size, Z_SP);
+    __ z_sgr(frame_size, sp_after_resize);
+    __ z_agr(frame_size, top_frame_size);
+    generate_stack_overflow_check(frame_size, fp/*tmp1*/);
+  }
 
   DEBUG_ONLY(__ z_cg(Z_R14, _z_abi16(return_pc), Z_SP));
   __ asm_assert_eq("killed Z_R14", 0);
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -694,6 +694,7 @@
 int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) {
   int store_offset;
   if (!Assembler::is_simm13(offset + (type == T_LONG) ? wordSize : 0)) {
+    assert(base != O7, "destroying register");
     assert(!unaligned, "can't handle this");
     // for offsets larger than a simm13 we setup the offset in O7
     __ set(offset, O7);
@@ -712,9 +713,12 @@
       case T_LONG  :
 #ifdef _LP64
         if (unaligned || PatchALot) {
-          __ srax(from_reg->as_register_lo(), 32, O7);
+          // Don't use O7 here because it may be equal to 'base' (see LIR_Assembler::reg2mem)
+          assert(G3_scratch != base, "can't handle this");
+          assert(G3_scratch != from_reg->as_register_lo(), "can't handle this");
+          __ srax(from_reg->as_register_lo(), 32, G3_scratch);
           __ stw(from_reg->as_register_lo(), base, offset + lo_word_offset_in_bytes);
-          __ stw(O7,                         base, offset + hi_word_offset_in_bytes);
+          __ stw(G3_scratch,                 base, offset + hi_word_offset_in_bytes);
         } else {
           __ stx(from_reg->as_register_lo(), base, offset);
         }
@@ -821,7 +825,7 @@
       case T_SHORT : __ ldsh(base, offset, to_reg->as_register()); break;
       case T_INT   : __ ld(base, offset, to_reg->as_register()); break;
       case T_LONG  :
-        if (!unaligned) {
+        if (!unaligned && !PatchALot) {
 #ifdef _LP64
           __ ldx(base, offset, to_reg->as_register_lo());
 #else
@@ -1297,7 +1301,7 @@
       disp_reg = O7;
     }
   } else if (unaligned || PatchALot) {
-    __ add(src, addr->index()->as_register(), O7);
+    __ add(src, addr->index()->as_pointer_register(), O7);
     src = O7;
   } else {
     disp_reg = addr->index()->as_pointer_register();
@@ -1424,7 +1428,7 @@
       disp_reg = O7;
     }
   } else if (unaligned || PatchALot) {
-    __ add(src, addr->index()->as_register(), O7);
+    __ add(src, addr->index()->as_pointer_register(), O7);
     src = O7;
   } else {
     disp_reg = addr->index()->as_pointer_register();
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -856,7 +856,9 @@
         Register tmp2 = G3_scratch;
 
         Label refill, restart;
-        bool with_frame = false; // I don't know if we can do with-frame.
+        int satb_q_active_byte_offset =
+          in_bytes(JavaThread::satb_mark_queue_offset() +
+                   SATBMarkQueue::byte_offset_of_active());
         int satb_q_index_byte_offset =
           in_bytes(JavaThread::satb_mark_queue_offset() +
                    SATBMarkQueue::byte_offset_of_index());
@@ -864,6 +866,17 @@
           in_bytes(JavaThread::satb_mark_queue_offset() +
                    SATBMarkQueue::byte_offset_of_buf());
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ ld(G2_thread, satb_q_active_byte_offset, tmp);
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ ldsb(G2_thread, satb_q_active_byte_offset, tmp);
+        }
+        __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, restart);
+        __ retl();
+        __ delayed()->nop();
+
         __ bind(restart);
         // Load the index into the SATB buffer. SATBMarkQueue::_index is a
         // size_t so ld_ptr is appropriate
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -1623,6 +1623,8 @@
 
         NOT_LP64(__ get_thread(thread);)
 
+        Address queue_active(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
+                                              SATBMarkQueue::byte_offset_of_active()));
         Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
                                              SATBMarkQueue::byte_offset_of_index()));
         Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
@@ -1631,6 +1633,15 @@
         Label done;
         Label runtime;
 
+        // Is marking still active?
+        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
+          __ cmpl(queue_active, 0);
+        } else {
+          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
+          __ cmpb(queue_active, 0);
+        }
+        __ jcc(Assembler::equal, done);
+
         // Can we store original value in the thread's buffer?
 
         __ movptr(tmp, queue_index);
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -376,7 +376,8 @@
   fr._unextended_sp = unextended_sp;
 
   address original_pc = nm->get_original_pc(&fr);
-  assert(nm->insts_contains(original_pc), "original PC must be in CompiledMethod");
+  assert(nm->insts_contains_inclusive(original_pc),
+         "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
 }
 #endif
 
--- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -75,7 +75,8 @@
   address original_pc = CompiledMethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
     _pc = original_pc;
-    assert(((CompiledMethod*)_cb)->insts_contains(_pc), "original PC must be in CompiledMethod");
+    assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
+           "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
     _deopt_state = is_deoptimized;
   } else {
     if (_cb->is_deoptimization_stub()) {
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -3499,12 +3499,12 @@
   }
 }
 
-void MacroAssembler::movdqu(XMMRegister dst, AddressLiteral src) {
+void MacroAssembler::movdqu(XMMRegister dst, AddressLiteral src, Register scratchReg) {
   if (reachable(src)) {
     movdqu(dst, as_Address(src));
   } else {
-    lea(rscratch1, src);
-    movdqu(dst, Address(rscratch1, 0));
+    lea(scratchReg, src);
+    movdqu(dst, Address(scratchReg, 0));
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1085,7 +1085,7 @@
   void movdqu(Address     dst, XMMRegister src);
   void movdqu(XMMRegister dst, Address src);
   void movdqu(XMMRegister dst, XMMRegister src);
-  void movdqu(XMMRegister dst, AddressLiteral src);
+  void movdqu(XMMRegister dst, AddressLiteral src, Register scratchReg = rscratch1);
   // AVX Unaligned forms
   void vmovdqu(Address     dst, XMMRegister src);
   void vmovdqu(XMMRegister dst, Address src);
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86_sha.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -817,7 +817,7 @@
   movl(d, Address(CTX, 4*3));
   movl(e, Address(CTX, 4*4));
   movl(f, Address(CTX, 4*5));
-  movl(g, Address(CTX, 4*6));
+  // load g - r10 after it is used as scratch
   movl(h, Address(CTX, 4*7));
 
   pshuffle_byte_flip_mask_addr = pshuffle_byte_flip_mask;
@@ -825,6 +825,8 @@
   vmovdqu(SHUF_00BA, ExternalAddress(pshuffle_byte_flip_mask_addr + 32));     //[_SHUF_00BA wrt rip]
   vmovdqu(SHUF_DC00, ExternalAddress(pshuffle_byte_flip_mask_addr + 64));     //[_SHUF_DC00 wrt rip]
 
+  movl(g, Address(CTX, 4*6));
+
   movq(Address(rsp, _CTX), CTX);           // store
 
 bind(loop0);
@@ -977,7 +979,7 @@
   movl(d, Address(CTX, 4*3));   // 0xa54ff53a
   movl(e, Address(CTX, 4*4));   // 0x510e527f
   movl(f, Address(CTX, 4*5));   // 0x9b05688c
-  movl(g, Address(CTX, 4*6));   // 0x1f83d9ab
+  // load g - r10 after use as scratch
   movl(h, Address(CTX, 4*7));   // 0x5be0cd19
 
 
@@ -986,6 +988,8 @@
   vmovdqu(SHUF_00BA, ExternalAddress(pshuffle_byte_flip_mask_addr + 32));     //[_SHUF_00BA wrt rip]
   vmovdqu(SHUF_DC00, ExternalAddress(pshuffle_byte_flip_mask_addr + 64));     //[_SHUF_DC00 wrt rip]
 
+  movl(g, Address(CTX, 4*6));   // 0x1f83d9ab
+
   movq(Address(rsp, _CTX), CTX);
   jmpb(do_last_block);
 
@@ -1154,9 +1158,8 @@
       // Move to appropriate lanes for calculating w[16] and w[17]
       vperm2f128(xmm4, xmm0, xmm0, 0); //xmm4 = W[-16] + W[-7] + s0{ BABA }
 
-      address MASK_YMM_LO = StubRoutines::x86::pshuffle_byte_flip_mask_addr_sha512();
       //Move to appropriate lanes for calculating w[18] and w[19]
-      vpand(xmm0, xmm0, ExternalAddress(MASK_YMM_LO + 32), AVX_256bit); //xmm0 = W[-16] + W[-7] + s0{ DC00 }
+      vpand(xmm0, xmm0, xmm10, AVX_256bit); //xmm0 = W[-16] + W[-7] + s0{ DC00 }
       //Calculate w[16] and w[17] in both 128 bit lanes
       //Calculate sigma1 for w[16] and w[17] on both 128 bit lanes
       vperm2f128(xmm2, xmm7, xmm7, 17); //xmm2 = W[-2] {BABA}
@@ -1250,6 +1253,7 @@
 
     const XMMRegister& XFER = xmm0; // YTMP0
     const XMMRegister& BYTE_FLIP_MASK = xmm9; // ymm9
+    const XMMRegister& YMM_MASK_LO = xmm10; // ymm10
 #ifdef _WIN64
     const Register& INP = rcx; //1st arg
     const Register& CTX = rdx; //2nd arg
@@ -1368,11 +1372,14 @@
     movq(d, Address(CTX, 8 * 3));
     movq(e, Address(CTX, 8 * 4));
     movq(f, Address(CTX, 8 * 5));
-    movq(g, Address(CTX, 8 * 6));
+    // load g - r10 after it is used as scratch
     movq(h, Address(CTX, 8 * 7));
 
     pshuffle_byte_flip_mask_addr = pshuffle_byte_flip_mask_sha512;
     vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); //PSHUFFLE_BYTE_FLIP_MASK wrt rip
+    vmovdqu(YMM_MASK_LO, ExternalAddress(pshuffle_byte_flip_mask_addr + 32));
+
+    movq(g, Address(CTX, 8 * 6));
 
     bind(loop0);
     lea(TBL, ExternalAddress(K512_W));
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -3207,7 +3207,7 @@
     const Register len_reg     = c_rarg4;  // src len (must be multiple of blocksize 16)
 #else
     const Address  len_mem(rbp, 6 * wordSize);  // length is on stack on Win64
-    const Register len_reg     = r10;      // pick the first volatile windows register
+    const Register len_reg     = r11;      // pick the volatile windows register
 #endif
     const Register pos         = rax;
 
@@ -3404,7 +3404,7 @@
     const Register len_reg     = c_rarg4;  // src len (must be multiple of blocksize 16)
 #else
     const Address  len_mem(rbp, 6 * wordSize);  // length is on stack on Win64
-    const Register len_reg     = r10;      // pick the first volatile windows register
+    const Register len_reg     = r11;      // pick the volatile windows register
 #endif
     const Register pos         = rax;
 
@@ -3930,7 +3930,7 @@
 
     __ push(rbx); // Save RBX
     __ movdqu(xmm_curr_counter, Address(counter, 0x00)); // initialize counter with initial counter
-    __ movdqu(xmm_counter_shuf_mask, ExternalAddress(StubRoutines::x86::counter_shuffle_mask_addr()));
+    __ movdqu(xmm_counter_shuf_mask, ExternalAddress(StubRoutines::x86::counter_shuffle_mask_addr()), pos); // pos as scratch
     __ pshufb(xmm_curr_counter, xmm_counter_shuf_mask); //counter is shuffled
     __ movptr(pos, 0);
 
@@ -3953,7 +3953,7 @@
     __ movl(Address(used_addr, 0), used);
 
     // key length could be only {11, 13, 15} * 4 = {44, 52, 60}
-    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()), rbx); // rbx as scratch
     __ movl(rbx, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
     __ cmpl(rbx, 52);
     __ jcc(Assembler::equal, L_multiBlock_loopTop[1]);
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc.binformat/src/jdk/tools/jaotc/binformat/BinaryContainer.java	Fri Feb 10 08:57:42 2017 -0800
@@ -37,6 +37,7 @@
 import jdk.tools.jaotc.binformat.Symbol.Kind;
 import jdk.tools.jaotc.binformat.elf.JELFRelocObject;
 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
 
 /**
  * A format-agnostic container class that holds various components of a binary.
@@ -257,9 +258,9 @@
      * prefix {@code prefix}. It also initializes internal code container, symbol table and
      * relocation tables.
      */
-    public BinaryContainer(GraalHotSpotVMConfig config, String jvmVersion) {
-        this.codeSegmentSize = config.codeSegmentSize;
-        this.codeEntryAlignment = config.codeEntryAlignment;
+    public BinaryContainer(GraalHotSpotVMConfig graalHotSpotVMConfig, GraphBuilderConfiguration graphBuilderConfig, String jvmVersion) {
+        this.codeSegmentSize = graalHotSpotVMConfig.codeSegmentSize;
+        this.codeEntryAlignment = graalHotSpotVMConfig.codeEntryAlignment;
 
         // read only, code
         codeContainer = new CodeContainer(".text", this);
@@ -289,30 +290,31 @@
 
         addGlobalSymbols();
 
-        recordConfiguration(config);
+        recordConfiguration(graalHotSpotVMConfig, graphBuilderConfig);
     }
 
-    private void recordConfiguration(GraalHotSpotVMConfig config) {
+    private void recordConfiguration(GraalHotSpotVMConfig graalHotSpotVMConfig, GraphBuilderConfiguration graphBuilderConfig) {
         // @formatter:off
-        boolean[] booleanFlags = { config.cAssertions, // Debug VM
-                                   config.useCompressedOops,
-                                   config.useCompressedClassPointers,
-                                   config.compactFields,
-                                   config.useG1GC,
-                                   config.useCMSGC,
-                                   config.useTLAB,
-                                   config.useBiasedLocking,
+        boolean[] booleanFlags = { graalHotSpotVMConfig.cAssertions, // Debug VM
+                                   graalHotSpotVMConfig.useCompressedOops,
+                                   graalHotSpotVMConfig.useCompressedClassPointers,
+                                   graalHotSpotVMConfig.compactFields,
+                                   graalHotSpotVMConfig.useG1GC,
+                                   graalHotSpotVMConfig.useCMSGC,
+                                   graalHotSpotVMConfig.useTLAB,
+                                   graalHotSpotVMConfig.useBiasedLocking,
                                    TieredAOT.getValue(),
-                                   config.enableContended,
-                                   config.restrictContended,
+                                   graalHotSpotVMConfig.enableContended,
+                                   graalHotSpotVMConfig.restrictContended,
+                                   graphBuilderConfig.omitAssertions()
         };
 
-        int[] intFlags         = { config.narrowOopShift,
-                                   config.narrowKlassShift,
-                                   config.contendedPaddingWidth,
-                                   config.fieldsAllocationStyle,
-                                   config.objectAlignment,
-                                   config.codeSegmentSize,
+        int[] intFlags         = { graalHotSpotVMConfig.getOopEncoding().shift,
+                                   graalHotSpotVMConfig.getKlassEncoding().shift,
+                                   graalHotSpotVMConfig.contendedPaddingWidth,
+                                   graalHotSpotVMConfig.fieldsAllocationStyle,
+                                   1 << graalHotSpotVMConfig.getOopEncoding().alignment,
+                                   graalHotSpotVMConfig.codeSegmentSize,
         };
         // @formatter:on
 
@@ -395,6 +397,10 @@
         return "_aot_narrow_klass_base_address";
     }
 
+    public String getNarrowOopBaseAddressSymbolName() {
+        return "_aot_narrow_oop_base_address";
+    }
+
     public String getLogOfHeapRegionGrainBytesSymbolName() {
         return "_aot_log_of_heap_region_grain_bytes";
     }
@@ -445,6 +451,7 @@
         createGotSymbol(getHeapTopAddressSymbolName());
         createGotSymbol(getHeapEndAddressSymbolName());
         createGotSymbol(getNarrowKlassBaseAddressSymbolName());
+        createGotSymbol(getNarrowOopBaseAddressSymbolName());
         createGotSymbol(getPollingPageSymbolName());
         createGotSymbol(getLogOfHeapRegionGrainBytesSymbolName());
         createGotSymbol(getInlineContiguousAllocationSupportedSymbolName());
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTBackend.java	Fri Feb 10 08:57:42 2017 -0800
@@ -77,10 +77,14 @@
         this.filters = filters;
         providers = backend.getProviders();
         codeCache = providers.getCodeCache();
-        graphBuilderSuite = initGraphBuilderSuite(backend);
+        graphBuilderSuite = initGraphBuilderSuite(backend, main.options.compileWithAssertions);
         highTierContext = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.ALL);
     }
 
+    public PhaseSuite<HighTierContext> getGraphBuilderSuite() {
+        return graphBuilderSuite;
+    }
+
     private Suites getSuites() {
         // create suites every time, as we modify options for the compiler
         return backend.getSuites().getDefaultSuites();
@@ -146,14 +150,14 @@
         return backend.getRuntime().getVMConfig().cAssertions;
     }
 
-    private static PhaseSuite<HighTierContext> initGraphBuilderSuite(HotSpotBackend backend) {
+    private static PhaseSuite<HighTierContext> initGraphBuilderSuite(HotSpotBackend backend, boolean compileWithAssertions) {
         PhaseSuite<HighTierContext> graphBuilderSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
         ListIterator<BasePhase<? super HighTierContext>> iterator = graphBuilderSuite.findPhase(GraphBuilderPhase.class);
         GraphBuilderConfiguration baseConfig = ((GraphBuilderPhase) iterator.previous()).getGraphBuilderConfig();
 
         // Use all default plugins.
         Plugins plugins = baseConfig.getPlugins();
-        GraphBuilderConfiguration aotConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true);
+        GraphBuilderConfiguration aotConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withOmitAssertions(!compileWithAssertions);
 
         iterator.next();
         iterator.remove();
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/AOTCompiledClass.java	Fri Feb 10 08:57:42 2017 -0800
@@ -293,12 +293,18 @@
             // Record methods holder
             methodInfo.addDependentKlassData(binaryContainer, resolvedJavaType);
             // Record inlinee classes
-            for (ResolvedJavaMethod m : methodInfo.getCompilationResult().getMethods()) {
-                methodInfo.addDependentKlassData(binaryContainer, (HotSpotResolvedObjectType) m.getDeclaringClass());
+            ResolvedJavaMethod[] inlinees = methodInfo.getCompilationResult().getMethods();
+            if (inlinees != null) {
+                for (ResolvedJavaMethod m : inlinees) {
+                    methodInfo.addDependentKlassData(binaryContainer, (HotSpotResolvedObjectType) m.getDeclaringClass());
+                }
             }
             // Record classes of fields that were accessed
-            for (ResolvedJavaField f : methodInfo.getCompilationResult().getFields()) {
-                methodInfo.addDependentKlassData(binaryContainer, (HotSpotResolvedObjectType) f.getDeclaringClass());
+            ResolvedJavaField[] fields = methodInfo.getCompilationResult().getFields();
+            if (fields != null) {
+                for (ResolvedJavaField f : fields) {
+                    methodInfo.addDependentKlassData(binaryContainer, (HotSpotResolvedObjectType) f.getDeclaringClass());
+                }
             }
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/LoadedClass.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,64 @@
+package jdk.tools.jaotc;/*
+ * Copyright (c) 2015, 2017, 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.
+ */
+
+public class LoadedClass {
+    private final String name;
+    private final Class<?> clz;
+
+    public LoadedClass(String name, Class<?> clz) {
+        this.name = name;
+        this.clz = clz;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Class<?> getLoadedClass() {
+        return clz;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof LoadedClass)) return false;
+
+        LoadedClass that = (LoadedClass) o;
+
+        if (name != null ? !name.equals(that.name) : that.name != null) return false;
+        return clz != null ? clz.equals(that.clz) : that.clz == null;
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (clz != null ? clz.hashCode() : 0);
+        return result;
+    }
+}
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -43,19 +43,31 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Set;
 import java.util.stream.Stream;
 
 import jdk.tools.jaotc.binformat.BinaryContainer;
 import jdk.tools.jaotc.binformat.ByteContainer;
-import jdk.tools.jaotc.collect.ClassCollector;
+import jdk.tools.jaotc.collect.*;
+import jdk.tools.jaotc.collect.classname.ClassNameSourceProvider;
+import jdk.tools.jaotc.collect.directory.DirectorySourceProvider;
+import jdk.tools.jaotc.collect.jar.JarSourceProvider;
+import jdk.tools.jaotc.collect.module.ModuleSourceProvider;
 import jdk.tools.jaotc.utils.Timer;
 
 import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
+import org.graalvm.compiler.java.GraphBuilderPhase;
+import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
+import org.graalvm.compiler.phases.BasePhase;
+import org.graalvm.compiler.phases.PhaseSuite;
+import org.graalvm.compiler.phases.tiers.HighTierContext;
 import org.graalvm.compiler.runtime.RuntimeProvider;
 
 import jdk.vm.ci.meta.MetaAccessProvider;
@@ -120,17 +132,7 @@
         abstract void process(Main task, String opt, String arg) throws BadArgs;
     }
 
-    static Option[] recognizedOptions = {new Option("  --module <name>            Module to compile", true, "--module") {
-        @Override
-        void process(Main task, String opt, String arg) {
-            task.options.module = arg;
-        }
-    }, new Option("  --module-path <path>       Specify where to find module to compile", true, "--module-path") {
-        @Override
-        void process(Main task, String opt, String arg) {
-            task.options.modulepath = arg;
-        }
-    }, new Option("  --output <file>            Output file name", true, "--output") {
+    static Option[] recognizedOptions = { new Option("  --output <file>            Output file name", true, "--output") {
         @Override
         void process(Main task, String opt, String arg) {
             String name = arg;
@@ -139,22 +141,48 @@
             }
             task.options.outputName = name;
         }
+    }, new Option("  --class-name <class names> List of classes to compile", true, "--class-name", "--classname") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            task.options.files.addAll(ClassSearch.makeList(ClassNameSourceProvider.TYPE, arg));
+        }
+    }, new Option("  --jar <jarfiles>           List of jar files to compile", true, "--jar") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            task.options.files.addAll(ClassSearch.makeList(JarSourceProvider.TYPE, arg));
+        }
+    }, new Option("  --module <modules>         List of modules to compile", true, "--module") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            task.options.files.addAll(ClassSearch.makeList(ModuleSourceProvider.TYPE, arg));
+        }
+    }, new Option("  --directory <dirs>         List of directories where to search for files to compile", true, "--directory") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            task.options.files.addAll(ClassSearch.makeList(DirectorySourceProvider.TYPE, arg));
+        }
+    }, new Option("  --search-path <dirs>       List of directories where to search for specified files", true, "--search-path") {
+        @Override
+        void process(Main task, String opt, String arg) {
+            String[] elements = arg.split(":");
+            task.options.searchPath.add(elements);
+        }
     }, new Option("  --compile-commands <file>  Name of file with compile commands", true, "--compile-commands") {
         @Override
         void process(Main task, String opt, String arg) {
             task.options.methodList = arg;
         }
-    }, new Option("  --compile-for-tiered       Generated profiling code for tiered compilation", false, "--compile-for-tiered") {
+    }, new Option("  --compile-for-tiered       Generate profiling code for tiered compilation", false, "--compile-for-tiered") {
         @Override
         void process(Main task, String opt, String arg) {
             TieredAOT.setValue(true);
         }
-    }, new Option("  --classpath <path>         Specify where to find user class files", true, "--classpath", "--class-path") {
+    }, new Option("  --compile-with-assertions  Compile with java assertions", false, "--compile-with-assertions") {
         @Override
         void process(Main task, String opt, String arg) {
-            task.options.classpath = arg;
+            task.options.compileWithAssertions = true;
         }
-    }, new Option("  --threads <number>         Number of compilation threads to be used", true, "--threads") {
+    }, new Option("  --compile-threads <number> Number of compilation threads to be used", true, "--compile-threads", "--threads") {
         @Override
         void process(Main task, String opt, String arg) {
             int threads = Integer.parseInt(arg);
@@ -213,27 +241,27 @@
     }};
 
     public static class Options {
-        public List<String> files = new LinkedList<>();
-        public String module = null;
-        public String modulepath = "modules";
+        public List<SearchFor> files = new LinkedList<>();
         public String outputName = "unnamed";
         public String methodList;
-        public String classpath = ".";
+        public List<ClassSource> sources = new ArrayList<>();
+        public SearchPath searchPath = new SearchPath();
 
         /**
          * We don't see scaling beyond 16 threads.
          */
         private static final int COMPILER_THREADS = 16;
 
-        int threads = Integer.min(COMPILER_THREADS, Runtime.getRuntime().availableProcessors());
+        public int threads = Integer.min(COMPILER_THREADS, Runtime.getRuntime().availableProcessors());
 
         public boolean ignoreClassLoadingErrors;
         public boolean exitOnError;
-        boolean info;
-        boolean verbose;
-        boolean debug;
-        boolean help;
-        boolean version;
+        public boolean info;
+        public boolean verbose;
+        public boolean debug;
+        public boolean help;
+        public boolean version;
+        public boolean compileWithAssertions;
     }
 
     /* package */final Options options = new Options();
@@ -275,7 +303,9 @@
 
             printlnInfo("Compiling " + options.outputName + "...");
             final long start = System.currentTimeMillis();
-            run();
+            if (!run()) {
+              return EXIT_ABNORMAL;
+            }
             final long end = System.currentTimeMillis();
             printlnInfo("Total time: " + (end - start) + " ms");
 
@@ -318,17 +348,34 @@
     }
 
     @SuppressWarnings("try")
-    private void run() throws Exception {
+    private boolean run() throws Exception {
         openLog();
 
         try {
             CompilationSpec compilationRestrictions = collectSpecifiedMethods();
 
-            Set<Class<?>> classesToCompile;
+            Set<Class<?>> classesToCompile = new HashSet<>();
 
             try (Timer t = new Timer(this, "")) {
-                ClassCollector collector = new ClassCollector(this.options, this);
-                classesToCompile = collector.collectClassesToCompile();
+                FileSupport fileSupport = new FileSupport();
+                ClassSearch lookup = new ClassSearch();
+                lookup.addProvider(new ModuleSourceProvider());
+                lookup.addProvider(new ClassNameSourceProvider(fileSupport));
+                lookup.addProvider(new JarSourceProvider());
+                lookup.addProvider(new DirectorySourceProvider(fileSupport));
+
+                List<LoadedClass> found = null;
+                try {
+                    found = lookup.search(options.files, options.searchPath);
+                } catch (InternalError e) {
+                    reportError(e);
+                    return false;
+                }
+
+                for (LoadedClass loadedClass : found) {
+                    classesToCompile.add(loadedClass.getLoadedClass());
+                }
+
                 printInfo(classesToCompile.size() + " classes found");
             }
 
@@ -356,6 +403,11 @@
             AOTCompiler compiler = new AOTCompiler(this, aotBackend, options.threads);
             classes = compiler.compileClasses(classes);
 
+            GraalHotSpotVMConfig graalHotSpotVMConfig = runtime.getVMConfig();
+            PhaseSuite<HighTierContext> graphBuilderSuite = aotBackend.getGraphBuilderSuite();
+            ListIterator<BasePhase<? super HighTierContext>> iterator = graphBuilderSuite.findPhase(GraphBuilderPhase.class);
+            GraphBuilderConfiguration graphBuilderConfig = ((GraphBuilderPhase) iterator.previous()).getGraphBuilderConfig();
+
             // Free memory!
             try (Timer t = options.verbose ? new Timer(this, "Freeing memory") : null) {
                 printMemoryUsage();
@@ -364,7 +416,7 @@
                 System.gc();
             }
 
-            BinaryContainer binaryContainer = new BinaryContainer(runtime.getVMConfig(), JVM_VERSION);
+            BinaryContainer binaryContainer = new BinaryContainer(graalHotSpotVMConfig, graphBuilderConfig, JVM_VERSION);
             DataBuilder dataBuilder = new DataBuilder(this, backend, classes, binaryContainer);
             dataBuilder.prepareData();
 
@@ -446,6 +498,7 @@
         } finally {
             closeLog();
         }
+        return true;
     }
 
     private void addMethods(AOTCompiledClass aotClass, ResolvedJavaMethod[] methods, CompilationSpec compilationRestrictions, GraalFilters filters) {
@@ -509,7 +562,7 @@
                     break;
                 }
             } else {
-                options.files.add(arg);
+                options.files.add(new SearchFor(arg));
             }
         }
     }
@@ -570,6 +623,12 @@
         log.flush();
     }
 
+    private void reportError(Throwable e) {
+        log.println("Error: " + e.getMessage());
+        e.printStackTrace(log);
+        log.flush();
+    }
+
     private void reportError(String key, Object... args) {
         printError(MessageFormat.format(key, args));
     }
@@ -580,17 +639,17 @@
     }
 
     private void showUsage() {
-        log.println("Usage: " + PROGNAME + " <options> list...");
+        log.println("Usage: " + PROGNAME + " <options> list");
         log.println("use --help for a list of possible options");
     }
 
     private void showHelp() {
-        log.println("Usage: " + PROGNAME + " <options> <--module name> | <list...>");
+        log.println("Usage: " + PROGNAME + " <options> list");
         log.println();
-        log.println("  list       A list of class files, jar files or directories which");
-        log.println("             contains class files.");
+        log.println("  list       A : separated list of class names, modules, jar files");
+        log.println("             or directories which contain class files.");
         log.println();
-        log.println("where possible options include:");
+        log.println("where options include:");
         for (Option o : recognizedOptions) {
             String name = o.aliases[0].substring(1); // there must always be at least one name
             name = name.charAt(0) == '-' ? name.substring(1) : name;
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkId.java	Fri Feb 10 08:57:42 2017 -0800
@@ -48,6 +48,7 @@
     HEAP_TOP_ADDRESS("CodeInstaller::HEAP_TOP_ADDRESS"),
     HEAP_END_ADDRESS("CodeInstaller::HEAP_END_ADDRESS"),
     NARROW_KLASS_BASE_ADDRESS("CodeInstaller::NARROW_KLASS_BASE_ADDRESS"),
+    NARROW_OOP_BASE_ADDRESS("CodeInstaller::NARROW_OOP_BASE_ADDRESS"),
     CRC_TABLE_ADDRESS("CodeInstaller::CRC_TABLE_ADDRESS"),
     LOG_OF_HEAP_REGION_GRAIN_BYTES("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES"),
     INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED");
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/MarkProcessor.java	Fri Feb 10 08:57:42 2017 -0800
@@ -57,6 +57,7 @@
             case HEAP_TOP_ADDRESS:
             case HEAP_END_ADDRESS:
             case NARROW_KLASS_BASE_ADDRESS:
+            case NARROW_OOP_BASE_ADDRESS:
             case CRC_TABLE_ADDRESS:
             case LOG_OF_HEAP_REGION_GRAIN_BYTES:
             case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:
@@ -78,6 +79,9 @@
                     case NARROW_KLASS_BASE_ADDRESS:
                         vmSymbolName = binaryContainer.getNarrowKlassBaseAddressSymbolName();
                         break;
+                    case NARROW_OOP_BASE_ADDRESS:
+                        vmSymbolName = binaryContainer.getNarrowOopBaseAddressSymbolName();
+                        break;
                     case CRC_TABLE_ADDRESS:
                         vmSymbolName = binaryContainer.getCrcTableAddressSymbolName();
                         break;
--- a/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassCollector.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,332 +0,0 @@
-/*
- * 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 jdk.tools.jaotc.collect;
-
-import jdk.tools.jaotc.LogPrinter;
-import jdk.tools.jaotc.Main;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.*;
-import java.nio.file.*;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.*;
-
-import static java.nio.file.FileVisitResult.CONTINUE;
-
-public class ClassCollector {
-    private final Main.Options options;
-    private final LogPrinter log;
-
-    public ClassCollector(Main.Options options, LogPrinter log) {
-        this.options = options;
-        this.log = log;
-    }
-
-    /**
-     * Collect all class names passed by the user.
-     *
-     * @return array list of classes
-     */
-    public Set<Class<?>> collectClassesToCompile() {
-        Set<Class<?>> classes = new HashSet<>();
-        List<String> filesToScan = new LinkedList<>(options.files);
-
-        if (options.module != null) {
-            classes.addAll(scanModule(filesToScan));
-        }
-
-        classes.addAll(scanFiles(filesToScan));
-        return classes;
-    }
-
-    private Set<Class<?>> scanModule(List<String> filesToScan) {
-        String module = options.module;
-        // Search module in standard JDK installation.
-        Path dir = getModuleDirectory(options.modulepath, module);
-
-        if (Files.isDirectory(dir)) {
-            return loadFromModuleDirectory(dir);
-        } else {
-            findFilesToScan(filesToScan, module);
-            return new HashSet<>();
-        }
-    }
-
-    private Set<Class<?>> loadFromModuleDirectory(Path dir) {
-        log.printInfo("Scanning module: " + dir + " ...");
-        log.printlnVerbose(" "); // Break line
-
-        FileSystemFinder finder = new FileSystemFinder(dir, pathname -> entryIsClassFile(pathname.toString()));
-        Set<Class<?>> cls = loadWithClassLoader(() -> ClassLoader.getSystemClassLoader(), dir, finder);
-        log.printlnInfo(" " + cls.size() + " classes loaded.");
-        return cls;
-    }
-
-    private void findFilesToScan(List<String> filesToScan, String module) {
-        // Try to search regular directory, .jar or .class files
-        Path path = Paths.get(options.modulepath, module);
-
-        if (Files.isDirectory(path)) {
-            filesToScan.add(".");
-            options.classpath = path.toString();
-        } else if (path.endsWith(".jar") || path.endsWith(".class")) {
-            filesToScan.add(path.toString());
-        } else {
-            path = Paths.get(options.modulepath, module + ".jar");
-            if (Files.exists(path)) {
-                filesToScan.add(path.toString());
-            } else {
-                path = Paths.get(options.modulepath, module + ".class");
-                if (Files.exists(path)) {
-                    filesToScan.add(path.toString());
-                } else {
-                    throw new InternalError("Expecting a .class, .jar or directory: " + path);
-                }
-            }
-        }
-    }
-
-    private boolean entryIsClassFile(String entry) {
-        return entry.endsWith(".class") && !entry.endsWith("module-info.class");
-    }
-
-    private Set<Class<?>> scanFiles(List<String> filesToScan) {
-        Set<Class<?>> classes = new HashSet<>();
-        for (String fileName : filesToScan) {
-            Set<Class<?>> loaded = scanFile(fileName);
-            log.printlnInfo(" " + loaded.size() + " classes loaded.");
-            classes.addAll(loaded);
-        }
-        return classes;
-    }
-
-    interface ClassLoaderFactory {
-        ClassLoader create() throws IOException;
-    }
-
-    private Set<Class<?>> loadWithClassLoader(ClassLoaderFactory factory, Path root, FileSystemFinder finder) {
-        ClassLoader loader = null;
-        try {
-            loader = factory.create();
-            return loadClassFiles(root, finder, loader);
-        } catch (IOException e) {
-            throw new InternalError(e);
-        } finally {
-            if (loader instanceof AutoCloseable) {
-                try {
-                    ((AutoCloseable) loader).close();
-                } catch (Exception e) {
-                    throw new InternalError(e);
-                }
-            }
-        }
-    }
-
-    private Set<Class<?>> scanFile(String fileName) {
-        log.printInfo("Scanning: " + fileName + " ...");
-        log.printlnVerbose(" "); // Break line
-
-        if (fileName.endsWith(".jar")) {
-            return loadFromJarFile(fileName);
-        } else if (fileName.endsWith(".class")) {
-            Set<Class<?>> classes = new HashSet<>();
-            loadFromClassFile(fileName, classes);
-            return classes;
-        } else {
-            return scanClassPath(fileName);
-        }
-    }
-
-    private Set<Class<?>> loadFromJarFile(String fileName) {
-        FileSystem fs = makeFileSystem(fileName);
-        FileSystemFinder finder = new FileSystemFinder(fs.getPath("/"), pathname -> entryIsClassFile(pathname.toString()));
-        return loadWithClassLoader(() -> URLClassLoader.newInstance(buildUrls(fileName)), fs.getPath("/"), finder);
-    }
-
-    private void loadFromClassFile(String fileName, Set<Class<?>> classes) {
-        Class<?> result;
-        File file = new File(options.classpath);
-        try (URLClassLoader loader = URLClassLoader.newInstance(buildUrls(file))) {
-            result = loadClassFile(loader, fileName);
-        } catch (IOException e) {
-            throw new InternalError(e);
-        }
-        Class<?> c = result;
-        addClass(classes, fileName, c);
-    }
-
-    private Set<Class<?>> scanClassPath(String fileName) {
-        Path classPath = Paths.get(options.classpath);
-        if (!Files.exists(classPath)) {
-            throw new InternalError("Path does not exist: " + classPath);
-        }
-        if (!Files.isDirectory(classPath)) {
-            throw new InternalError("Path must be a directory: " + classPath);
-        }
-
-        // Combine class path and file name and see what it is.
-        Path combinedPath = Paths.get(options.classpath + File.separator + fileName);
-        if (combinedPath.endsWith(".class")) {
-            throw new InternalError("unimplemented");
-        } else if (Files.isDirectory(combinedPath)) {
-            return scanDirectory(classPath, combinedPath);
-        } else {
-            throw new InternalError("Expecting a .class, .jar or directory: " + fileName);
-        }
-    }
-
-    private FileSystem makeFileSystem(String fileName) {
-        try {
-            return FileSystems.newFileSystem(makeJarFileURI(fileName), new HashMap<>());
-        } catch (IOException e) {
-            throw new InternalError(e);
-        }
-    }
-
-    private URI makeJarFileURI(String fileName) {
-        try {
-            return new URI("jar:file:" + Paths.get(fileName).toAbsolutePath() + "!/");
-        } catch (URISyntaxException e) {
-            throw new InternalError(e);
-        }
-    }
-
-    private PathMatcher combine(PathMatcher m1, PathMatcher m2) {
-        return path -> m1.matches(path) && m2.matches(path);
-    }
-
-    private Set<Class<?>> scanDirectory(Path classPath, Path combinedPath) {
-        String dir = options.classpath;
-
-        FileSystem fileSystem = FileSystems.getDefault();
-        PathMatcher matcher = fileSystem.getPathMatcher("glob:" + "*.class");
-        FileSystemFinder finder = new FileSystemFinder(combinedPath,
-            combine(matcher, pathname -> entryIsClassFile(pathname.toString())));
-
-        File file = new File(dir);
-        try (URLClassLoader loader = URLClassLoader.newInstance(buildUrls(file))) {
-            return loadClassFiles(classPath, finder, loader);
-        } catch (IOException e) {
-            throw new InternalError(e);
-        }
-    }
-
-    private Set<Class<?>> loadClassFiles(Path root, FileSystemFinder finder, ClassLoader loader) {
-        Set<Class<?>> classes = new HashSet<>();
-        for (Path name : finder.done()) {
-            // Now relativize to the class path so we get the actual class names.
-            String entry = root.relativize(name).normalize().toString();
-            Class<?> c = loadClassFile(loader, entry);
-            addClass(classes, entry, c);
-        }
-        return classes;
-    }
-
-    private void addClass(Set<Class<?>> classes, String name, Class<?> c) {
-        if (c != null) {
-            classes.add(c);
-            log.printlnVerbose(" loaded " + name);
-        }
-    }
-
-    private URL[] buildUrls(String fileName) throws MalformedURLException {
-        return new URL[]{ new URL("jar:file:" + Paths.get(fileName).toAbsolutePath() + "!/") };
-    }
-
-    private URL[] buildUrls(File file) throws MalformedURLException {
-        return new URL[] {file.toURI().toURL() };
-    }
-
-    private Path getModuleDirectory(String modulepath, String module) {
-        FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
-        return fs.getPath(modulepath, module);
-    }
-
-    /**
-     * Loads a class with the given file name from the specified {@link URLClassLoader}.
-     */
-    private Class<?> loadClassFile(final ClassLoader loader, final String fileName) {
-        int start = 0;
-        if (fileName.startsWith("/")) {
-            start = 1;
-        }
-        String className = fileName.substring(start, fileName.length() - ".class".length());
-        className = className.replace('/', '.');
-        try {
-            return loader.loadClass(className);
-        } catch (Throwable e) {
-            // If we are running in JCK mode we ignore all exceptions.
-            if (options.ignoreClassLoadingErrors) {
-                log.printError(className + ": " + e);
-                return null;
-            }
-            throw new InternalError(e);
-        }
-    }
-
-    /**
-     * {@link FileVisitor} implementation to find class files recursively.
-     */
-    private static class FileSystemFinder extends SimpleFileVisitor<Path> {
-        private final ArrayList<Path> fileNames = new ArrayList<>();
-        private final PathMatcher filter;
-
-        FileSystemFinder(Path combinedPath, PathMatcher filter) {
-            this.filter = filter;
-            try {
-                Files.walkFileTree(combinedPath, this);
-            } catch (IOException e) {
-                throw new InternalError(e);
-            }
-        }
-
-        /**
-         * Compares the glob pattern against the file name.
-         */
-        void find(Path file) {
-            Path name = file.getFileName();
-            if (name != null && filter.matches(name)) {
-                fileNames.add(file);
-            }
-        }
-
-        List<Path> done() {
-            return fileNames;
-        }
-
-        @Override
-        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
-            find(file);
-            return CONTINUE;
-        }
-
-        @Override
-        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
-            find(dir);
-            return CONTINUE;
-        }
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect;
+
+import jdk.tools.jaotc.LoadedClass;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ClassSearch {
+    private List<SourceProvider> providers = new ArrayList<>();
+
+    public void addProvider(SourceProvider provider) {
+        providers.add(provider);
+    }
+
+    public List<LoadedClass> search(List<SearchFor> search, SearchPath searchPath) {
+        List<LoadedClass> loaded = new ArrayList<>();
+
+        List<ClassSource> sources = new ArrayList<>();
+
+        for (SearchFor entry : search) {
+            sources.add(findSource(entry, searchPath));
+        }
+
+        for (ClassSource source : sources) {
+            source.eachClass((name, loader) -> loaded.add(loadClass(name, loader)));
+        }
+
+        return loaded;
+    }
+
+    private LoadedClass loadClass(String name, ClassLoader loader) {
+        try {
+            Class<?> clzz = loader.loadClass(name);
+            return new LoadedClass(name, clzz);
+        } catch (ClassNotFoundException e) {
+            throw new InternalError("Failed to load with: " + loader, e);
+        }
+    }
+
+    private ClassSource findSource(SearchFor searchFor, SearchPath searchPath) {
+        ClassSource found = null;
+
+        for (SourceProvider provider : providers) {
+            if (!searchFor.isUnknown() && !provider.supports(searchFor.getType())) {
+                continue;
+            }
+
+            ClassSource source = provider.findSource(searchFor.getName(), searchPath);
+            if (source != null) {
+                if (found != null) {
+                    throw new InternalError("Multiple possible sources: " + source + " and: " + found);
+                }
+                found = source;
+            }
+        }
+
+        if (found == null) {
+            throw new InternalError("Failed to find: " + searchFor.toString());
+        }
+        return found;
+    }
+
+    public static List<SearchFor> makeList(String type, String argument) {
+        List<SearchFor> list = new ArrayList<>();
+        String[] elements = argument.split(":");
+        for (String element : elements) {
+            list.add(new SearchFor(element, type));
+        }
+        return list;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSource.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect;
+
+import java.nio.file.Path;
+import java.util.function.BiConsumer;
+
+public interface ClassSource {
+    static boolean pathIsClassFile(Path entry) {
+        String fileName = entry.getFileName().toString();
+        return fileName.endsWith(".class") && !fileName.endsWith("module-info.class");
+    }
+
+    static String makeClassName(Path path) {
+        String fileName = path.toString();
+
+        if (!fileName.endsWith(".class")) {
+            throw new IllegalArgumentException("File doesn't end with .class: '" + fileName + "'");
+        }
+
+        int start = 0;
+        if (fileName.startsWith("/")) {
+            start = 1;
+        }
+
+        String className = fileName.substring(start, fileName.length() - ".class".length());
+        className = className.replace('/', '.');
+        return className;
+    }
+
+    void eachClass(BiConsumer<String, ClassLoader> consumer);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect;
+
+import java.io.IOException;
+import java.net.*;
+import java.nio.file.*;
+import java.util.HashMap;
+
+public class FileSupport {
+    public boolean exists(Path path)  {
+        return Files.exists(path);
+    }
+
+    public boolean isDirectory(Path path) {
+        return Files.isDirectory(path);
+    }
+
+    private FileSystem makeJarFileSystem(Path path) {
+        try {
+            return FileSystems.newFileSystem(makeJarFileURI(path), new HashMap<>());
+        } catch (IOException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    private URI makeJarFileURI(Path path) {
+        try {
+            return new URI("jar:file:" + path.toAbsolutePath() + "!/");
+        } catch (URISyntaxException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    public ClassLoader createClassLoader(Path path, ClassLoader parent) {
+        try {
+            return URLClassLoader.newInstance(buildUrls(path), parent);
+        } catch (MalformedURLException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    public ClassLoader createClassLoader(Path path) throws MalformedURLException {
+        return URLClassLoader.newInstance(buildUrls(path));
+    }
+
+    private URL[] buildUrls(Path path) throws MalformedURLException {
+        return new URL[] { path.toUri().toURL() };
+    }
+
+    public Path getJarFileSystemRoot(Path jarFile) {
+        FileSystem fileSystem = makeJarFileSystem(jarFile);
+        return fileSystem.getPath("/");
+    }
+
+    public boolean isAbsolute(Path entry) {
+        return entry.isAbsolute();
+    }
+
+    public Path getSubDirectory(FileSystem fileSystem, Path root, Path path) throws IOException {
+        DirectoryStream<Path> paths = fileSystem.provider().newDirectoryStream(root,null);
+        for (Path entry : paths) {
+            Path relative = root.relativize(entry);
+            if (relative.equals(path)) {
+                return entry;
+            }
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSystemFinder.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect;
+
+import java.io.IOException;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import static java.nio.file.FileVisitResult.CONTINUE;
+
+/**
+ * {@link FileVisitor} implementation to find class files recursively.
+ */
+public class FileSystemFinder extends SimpleFileVisitor<Path> implements Iterable<Path> {
+    private final ArrayList<Path> fileNames = new ArrayList<>();
+    private final PathMatcher filter;
+
+    public FileSystemFinder(Path combinedPath, PathMatcher filter) {
+        this.filter = filter;
+        try {
+            Files.walkFileTree(combinedPath, this);
+        } catch (IOException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    /**
+     * Compares the glob pattern against the file name.
+     */
+    private void find(Path file) {
+        Path name = file.getFileName();
+        if (name != null && filter.matches(name)) {
+            fileNames.add(file);
+        }
+    }
+
+    @Override
+    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+        find(file);
+        return CONTINUE;
+    }
+
+    @Override
+    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+        find(dir);
+        return CONTINUE;
+    }
+
+
+    @Override
+    public Iterator<Path> iterator() {
+        return fileNames.iterator();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect;
+
+public class SearchFor {
+    private final String name;
+    private final String type;
+
+    public SearchFor(String name) {
+        this(name, "unknown");
+    }
+
+    public SearchFor(String name, String type) {
+        this.name = name;
+        this.type = type;
+    }
+
+    public boolean isUnknown() {
+        return "unknown".equals(type);
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public String toString() {
+        return type + ":" + name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchPath.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect;
+
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+public class SearchPath {
+    private final List<Path> searchPaths = new ArrayList<>();
+    private final FileSupport fileSupport;
+
+    public SearchPath() {
+        this(new FileSupport());
+    }
+
+    public SearchPath(FileSupport fileSupport) {
+        this.fileSupport = fileSupport;
+    }
+
+    public Path find(FileSystem fileSystem, Path entry, String... defaults) {
+        if (isAbsolute(entry)) {
+            if (exists(entry)) {
+                return entry;
+            }
+            return null;
+        }
+
+        if (exists(entry)) {
+            return entry;
+        }
+
+        for (String searchPath : defaults) {
+            Path newPath = fileSystem.getPath(searchPath, entry.toString());
+            if (exists(newPath)) {
+                return newPath;
+            }
+        }
+
+        for (Path searchPath : searchPaths) {
+            Path newPath = fileSystem.getPath(searchPath.toString(), entry.toString());
+            if (exists(newPath)) {
+                return newPath;
+            }
+        }
+
+        return null;
+    }
+
+    private boolean isAbsolute(Path entry) {
+        return fileSupport.isAbsolute(entry);
+    }
+
+    private boolean exists(Path entry) {
+        return fileSupport.exists(entry);
+    }
+
+    public void add(String... paths) {
+        for (String name : paths) {
+            Path path = Paths.get(name);
+            searchPaths.add(path);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SourceProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect;
+
+public interface SourceProvider {
+    ClassSource findSource(String name, SearchPath searchPath);
+
+    boolean supports(String type);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSource.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect.classname;
+
+import jdk.tools.jaotc.collect.ClassSource;
+
+import java.util.function.BiConsumer;
+
+public class ClassNameSource implements ClassSource {
+    private final String name;
+    private final ClassLoader classLoader;
+
+    public ClassNameSource(String name, ClassLoader classLoader) {
+        this.name = name;
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        consumer.accept(name, classLoader);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect.classname;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSupport;
+import jdk.tools.jaotc.collect.SearchPath;
+import jdk.tools.jaotc.collect.SourceProvider;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class ClassNameSourceProvider implements SourceProvider {
+    public final static String TYPE = "classname";
+    private final ClassLoader classLoader;
+
+    public ClassNameSourceProvider(FileSupport fileSupport) {
+        String classPath = System.getProperty("java.class.path");
+        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+        if (classPath != null && !classPath.isEmpty()) {
+            classLoader = systemClassLoader;
+        } else {
+            Path path = Paths.get(".").toAbsolutePath();
+            classLoader = fileSupport.createClassLoader(path, systemClassLoader);
+        }
+    }
+
+    @Override
+    public ClassSource findSource(String name, SearchPath searchPath) {
+        try {
+            classLoader.loadClass(name);
+            return new ClassNameSource(name, classLoader);
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean supports(String type) {
+        return TYPE.equals(type);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySource.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect.directory;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSystemFinder;
+
+import java.nio.file.Path;
+import java.util.function.BiConsumer;
+
+public class DirectorySource implements ClassSource {
+    private final Path directoryPath;
+    private final ClassLoader classLoader;
+
+    public DirectorySource(Path directoryPath, ClassLoader classLoader) {
+        this.directoryPath = directoryPath;
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        FileSystemFinder finder = new FileSystemFinder(directoryPath, ClassSource::pathIsClassFile);
+
+        for (Path path : finder) {
+            consumer.accept(ClassSource.makeClassName(directoryPath.relativize(path).normalize()), classLoader);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "directory:" + directoryPath.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/directory/DirectorySourceProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect.directory;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSupport;
+import jdk.tools.jaotc.collect.SearchPath;
+import jdk.tools.jaotc.collect.SourceProvider;
+
+import java.net.MalformedURLException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+
+public class DirectorySourceProvider implements SourceProvider {
+    private final FileSupport fileSupport;
+    private final FileSystem fileSystem;
+    public final static String TYPE = "directory";
+
+    public DirectorySourceProvider(FileSupport fileSupport) {
+        this.fileSupport = fileSupport;
+        fileSystem = FileSystems.getDefault();
+    }
+
+    @Override
+    public ClassSource findSource(String name, SearchPath searchPath) {
+        Path directoryPath = fileSystem.getPath(name);
+
+        if (!fileSupport.exists(directoryPath)) {
+            return null;
+        }
+        if (!fileSupport.isDirectory(directoryPath)) {
+            return null;
+        }
+
+        try {
+            ClassLoader classLoader = fileSupport.createClassLoader(directoryPath);
+            return new DirectorySource(directoryPath, classLoader);
+        } catch (MalformedURLException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public boolean supports(String type) {
+        return TYPE.equals(type);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarFileSource.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect.jar;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSystemFinder;
+
+import java.nio.file.Path;
+import java.util.function.BiConsumer;
+
+public class JarFileSource implements ClassSource {
+    private final Path jarFile;
+    private final Path jarRootPath;
+    private final ClassLoader classLoader;
+
+
+    public JarFileSource(Path jarFile, Path jarRootPath, ClassLoader classLoader) {
+        this.jarFile = jarFile;
+        this.jarRootPath = jarRootPath;
+        this.classLoader = classLoader;
+    }
+
+    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        FileSystemFinder finder = new FileSystemFinder(jarRootPath, ClassSource::pathIsClassFile);
+
+        for (Path path : finder) {
+            consumer.accept(ClassSource.makeClassName(jarRootPath.relativize(path).normalize()), classLoader);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "jar:" + jarFile.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/jar/JarSourceProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect.jar;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSupport;
+import jdk.tools.jaotc.collect.SearchPath;
+import jdk.tools.jaotc.collect.SourceProvider;
+
+import java.net.MalformedURLException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.ProviderNotFoundException;
+
+public class JarSourceProvider implements SourceProvider {
+    private final FileSystem fileSystem;
+    private final FileSupport fileSupport;
+    public final static String TYPE = "jar";
+
+    public JarSourceProvider() {
+        this(new FileSupport());
+    }
+
+    public JarSourceProvider(FileSupport fileSupport) {
+        this.fileSupport = fileSupport;
+        fileSystem = FileSystems.getDefault();
+    }
+
+    @Override
+    public ClassSource findSource(String name, SearchPath searchPath) {
+        Path fileName = fileSystem.getPath(name);
+        Path jarFile = searchPath.find(fileSystem, fileName);
+
+        if (!validPath(jarFile)) {
+            return null;
+        }
+
+        return createSource(jarFile);
+    }
+
+    private ClassSource createSource(Path jarFile) {
+        try {
+            Path jarRootPath = fileSupport.getJarFileSystemRoot(jarFile);
+            if (jarRootPath == null) {
+                return null;
+            }
+            ClassLoader classLoader = fileSupport.createClassLoader(jarFile);
+            return new JarFileSource(jarFile, jarRootPath, classLoader);
+        } catch (ProviderNotFoundException | MalformedURLException e) {
+        }
+        return null;
+    }
+
+    @Override
+    public boolean supports(String type) {
+        return TYPE.equals(type);
+    }
+
+    private boolean validPath(Path jarFile) {
+        return jarFile != null && !fileSupport.isDirectory(jarFile);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSource.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect.module;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSystemFinder;
+
+import java.nio.file.Path;
+import java.util.function.BiConsumer;
+
+public class ModuleSource implements ClassSource {
+    private final Path modulePath;
+    private final ClassLoader classLoader;
+
+    public ModuleSource(Path modulePath, ClassLoader classLoader) {
+        this.modulePath = modulePath;
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        FileSystemFinder finder = new FileSystemFinder(modulePath, ClassSource::pathIsClassFile);
+
+        for (Path path : finder) {
+            consumer.accept(ClassSource.makeClassName(modulePath.relativize(path).normalize()), classLoader);
+        }
+    }
+
+    public Path getModulePath() {
+        return modulePath;
+    }
+
+    @Override
+    public String toString() {
+        return "module:" + modulePath.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/module/ModuleSourceProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.collect.module;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.collect.FileSupport;
+import jdk.tools.jaotc.collect.SearchPath;
+import jdk.tools.jaotc.collect.SourceProvider;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+
+public class ModuleSourceProvider implements SourceProvider {
+    private final FileSystem fileSystem;
+    private final ClassLoader classLoader;
+    private final FileSupport fileSupport;
+    public final static String TYPE = "module";
+
+    public ModuleSourceProvider() {
+        this(FileSystems.getFileSystem(URI.create("jrt:/")), ClassLoader.getSystemClassLoader(), new FileSupport());
+    }
+
+    public ModuleSourceProvider(FileSystem fileSystem, ClassLoader classLoader, FileSupport fileSupport) {
+        this.fileSystem = fileSystem;
+        this.classLoader = classLoader;
+        this.fileSupport = fileSupport;
+    }
+
+    @Override
+    public ClassSource findSource(String name, SearchPath searchPath) {
+        Path path = fileSystem.getPath(name);
+        Path dir = fileSystem.getPath("modules");
+
+        if (dir == null || !fileSupport.isDirectory(dir)) {
+            return null;
+        }
+
+        Path found = findModuleDirectory(dir, path);
+
+        if (found == null) {
+            return null;
+        }
+
+        return new ModuleSource(found, classLoader);
+    }
+
+    private Path findModuleDirectory(Path root, Path path) {
+        try {
+            return fileSupport.getSubDirectory(fileSystem, root, path);
+        } catch (IOException e) {
+            throw new InternalError(e);
+        }
+    }
+
+    @Override
+    public boolean supports(String type) {
+        return TYPE.equals(type);
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Fri Feb 10 08:57:42 2017 -0800
@@ -100,15 +100,19 @@
     native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Determines if {@code method} can be inlined. A method may not be inlinable for a number of
-     * reasons such as:
-     * <ul>
-     * <li>a CompileOracle directive may prevent inlining or compilation of methods</li>
-     * <li>the method may have a bytecode breakpoint set</li>
-     * <li>the method may have other bytecode features that require special handling by the VM</li>
-     * </ul>
+     * Determines whether {@code method} is currently compilable by the JVMCI compiler being used by
+     * the VM. This can return false if JVMCI compilation failed earlier for {@code method}, a
+     * breakpoint is currently set in {@code method} or {@code method} contains other bytecode
+     * features that require special handling by the VM.
      */
-    native boolean canInlineMethod(HotSpotResolvedJavaMethodImpl method);
+    native boolean isCompilable(HotSpotResolvedJavaMethodImpl method);
+
+    /**
+     * Determines if {@code method} is targeted by a VM directive (e.g.,
+     * {@code -XX:CompileCommand=dontinline,<pattern>}) or annotation (e.g.,
+     * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined.
+     */
+    native boolean hasNeverInlineDirective(HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Determines if {@code method} should be inlined at any cost. This could be because:
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java	Fri Feb 10 08:57:42 2017 -0800
@@ -50,13 +50,6 @@
     boolean isForceInline();
 
     /**
-     * Returns true if this method has a {@code DontInline} annotation.
-     *
-     * @return true if DontInline annotation present, false otherwise
-     */
-    boolean isDontInline();
-
-    /**
      * Returns true if this method has a {@code ReservedStackAccess} annotation.
      *
      * @return true if ReservedStackAccess annotation present, false otherwise
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -299,15 +299,6 @@
     }
 
     /**
-     * Returns true if this method has a {@code DontInline} annotation.
-     *
-     * @return true if DontInline annotation present, false otherwise
-     */
-    public boolean isDontInline() {
-        return (getFlags() & config().methodFlagsDontInline) != 0;
-    }
-
-    /**
      * Returns true if this method has a {@code ReservedStackAccess} annotation.
      *
      * @return true if ReservedStackAccess annotation present, false otherwise
@@ -582,10 +573,15 @@
 
     @Override
     public boolean canBeInlined() {
-        if (isDontInline()) {
+        if (hasNeverInlineDirective()) {
             return false;
         }
-        return compilerToVM().canInlineMethod(this);
+        return compilerToVM().isCompilable(this);
+    }
+
+    @Override
+    public boolean hasNeverInlineDirective() {
+        return compilerToVM().hasNeverInlineDirective(this);
     }
 
     @Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Fri Feb 10 08:57:42 2017 -0800
@@ -347,6 +347,13 @@
     boolean canBeInlined();
 
     /**
+     * Determines if this method is targeted by a VM directive (e.g.,
+     * {@code -XX:CompileCommand=dontinline,<pattern>}) or VM recognized annotation (e.g.,
+     * {@code jdk.internal.vm.annotation.DontInline}) that specifies it should not be inlined.
+     */
+    boolean hasNeverInlineDirective();
+
+    /**
      * Returns {@code true} if the inlining of this method should be forced.
      */
     boolean shouldBeInlined();
--- a/hotspot/src/jdk.vm.compiler/.mx.graal/suite.py	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/.mx.graal/suite.py	Fri Feb 10 08:57:42 2017 -0800
@@ -638,6 +638,7 @@
       "annotationProcessors" : [
         "GRAAL_NODEINFO_PROCESSOR",
         "GRAAL_REPLACEMENTS_VERIFIER",
+        "GRAAL_OPTIONS_PROCESSOR",
       ],
       "workingSets" : "Graal,Graph",
     },
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Debug.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.debug/src/org/graalvm/compiler/debug/Debug.java	Fri Feb 10 08:57:42 2017 -0800
@@ -116,6 +116,7 @@
     public static final int INFO_LOG_LEVEL = 2;
     public static final int VERBOSE_LOG_LEVEL = 3;
     public static final int DETAILED_LOG_LEVEL = 4;
+    public static final int VERY_DETAILED_LOG_LEVEL = 5;
 
     public static boolean isDumpEnabled(int dumpLevel) {
         return ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel);
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotBackend.java	Fri Feb 10 08:57:42 2017 -0800
@@ -267,10 +267,15 @@
 
             if (config.useCompressedClassPointers) {
                 Register register = r10;
-                AMD64HotSpotMove.decodeKlassPointer(asm, register, providers.getRegisters().getHeapBaseRegister(), src, config.getKlassEncoding());
-                if (config.narrowKlassBase != 0) {
-                    // The heap base register was destroyed above, so restore it
-                    asm.movq(providers.getRegisters().getHeapBaseRegister(), config.narrowOopBase);
+                AMD64HotSpotMove.decodeKlassPointer(crb, asm, register, providers.getRegisters().getHeapBaseRegister(), src, config);
+                if (GeneratePIC.getValue()) {
+                    asm.movq(providers.getRegisters().getHeapBaseRegister(), asm.getPlaceholder(-1));
+                    crb.recordMark(config.MARKID_NARROW_OOP_BASE_ADDRESS);
+                } else {
+                    if (config.narrowKlassBase != 0) {
+                        // The heap base register was destroyed above, so restore it
+                        asm.movq(providers.getRegisters().getHeapBaseRegister(), config.narrowOopBase);
+                    }
                 }
                 asm.cmpq(inlineCacheKlass, register);
             } else {
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotMove.java	Fri Feb 10 08:57:42 2017 -0800
@@ -265,14 +265,21 @@
         }
     }
 
-    public static void decodeKlassPointer(AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, CompressEncoding encoding) {
+    public static void decodeKlassPointer(CompilationResultBuilder crb, AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, GraalHotSpotVMConfig config) {
+        CompressEncoding encoding = config.getKlassEncoding();
         masm.movl(register, address);
         if (encoding.shift != 0) {
             assert encoding.alignment == encoding.shift : "Decode algorithm is wrong";
             masm.shlq(register, encoding.alignment);
         }
-        if (encoding.base != 0) {
-            masm.movq(scratch, encoding.base);
+        if (GeneratePIC.getValue() || encoding.base != 0) {
+            if (GeneratePIC.getValue()) {
+                masm.movq(scratch, masm.getPlaceholder(-1));
+                crb.recordMark(config.MARKID_NARROW_KLASS_BASE_ADDRESS);
+            } else {
+                assert encoding.base != 0;
+                masm.movq(scratch, encoding.base);
+            }
             masm.addq(register, scratch);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/AOTGraalHotSpotVMConfig.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.graalvm.compiler.hotspot;
+
+import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
+
+public class AOTGraalHotSpotVMConfig extends GraalHotSpotVMConfig {
+    private final CompressEncoding aotOopEncoding;
+    private final CompressEncoding aotKlassEncoding;
+
+    public AOTGraalHotSpotVMConfig(HotSpotVMConfigStore store) {
+        super(store);
+        // In AOT, force the shift to be always equal to alignment therefore avoiding zero-shift.
+        CompressEncoding vmOopEncoding = super.getOopEncoding();
+        aotOopEncoding = new CompressEncoding(vmOopEncoding.base, vmOopEncoding.alignment, vmOopEncoding.alignment);
+        CompressEncoding vmKlassEncoding = super.getKlassEncoding();
+        aotKlassEncoding = new CompressEncoding(vmKlassEncoding.base, vmKlassEncoding.alignment, vmKlassEncoding.alignment);
+        assert check();
+    }
+
+    @Override
+    public CompressEncoding getOopEncoding() {
+        return aotOopEncoding;
+    }
+
+    @Override
+    public CompressEncoding getKlassEncoding() {
+        return aotKlassEncoding;
+    }
+}
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Fri Feb 10 08:57:42 2017 -0800
@@ -479,7 +479,6 @@
     public final int methodCompiledEntryOffset = getFieldOffset("Method::_from_compiled_entry", Integer.class, "address");
     public final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, isJDK8 ? "nmethod*" : "CompiledMethod*");
 
-    public final int methodFlagsJfrTowrite = getConstant("Method::_jfr_towrite", Integer.class);
     public final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class);
     public final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class);
     public final int methodFlagsDontInline = getConstant("Method::_dont_inline", Integer.class);
@@ -773,13 +772,14 @@
     public final int MARKID_HEAP_TOP_ADDRESS = getConstant("CodeInstaller::HEAP_TOP_ADDRESS", Integer.class, 17);
     public final int MARKID_HEAP_END_ADDRESS = getConstant("CodeInstaller::HEAP_END_ADDRESS", Integer.class, 18);
     public final int MARKID_NARROW_KLASS_BASE_ADDRESS = getConstant("CodeInstaller::NARROW_KLASS_BASE_ADDRESS", Integer.class, 19);
-    public final int MARKID_CRC_TABLE_ADDRESS = getConstant("CodeInstaller::CRC_TABLE_ADDRESS", Integer.class, 20);
-    public final int MARKID_LOG_OF_HEAP_REGION_GRAIN_BYTES = getConstant("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES", Integer.class, 21);
-    public final int MARKID_INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED = getConstant("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED", Integer.class, 22);
+    public final int MARKID_NARROW_OOP_BASE_ADDRESS = getConstant("CodeInstaller::NARROW_OOP_BASE_ADDRESS", Integer.class, 20);
+    public final int MARKID_CRC_TABLE_ADDRESS = getConstant("CodeInstaller::CRC_TABLE_ADDRESS", Integer.class, 21);
+    public final int MARKID_LOG_OF_HEAP_REGION_GRAIN_BYTES = getConstant("CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES", Integer.class, 22);
+    public final int MARKID_INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED = getConstant("CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED", Integer.class, 23);
 
     // Checkstyle: resume
 
-    private boolean check() {
+    protected boolean check() {
         for (Field f : getClass().getDeclaredFields()) {
             int modifiers = f.getModifiers();
             if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Fri Feb 10 08:57:42 2017 -0800
@@ -22,6 +22,7 @@
  */
 package org.graalvm.compiler.hotspot;
 
+import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.debug.GraalDebugConfig.areScopedGlobalMetricsEnabled;
 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.DebugValueSummary;
 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.Dump;
@@ -99,7 +100,7 @@
     HotSpotGraalRuntime(HotSpotJVMCIRuntime jvmciRuntime, CompilerConfigurationFactory compilerConfigurationFactory) {
 
         HotSpotVMConfigStore store = jvmciRuntime.getConfigStore();
-        config = new GraalHotSpotVMConfig(store);
+        config = GeneratePIC.getValue() ? new AOTGraalHotSpotVMConfig(store) : new GraalHotSpotVMConfig(store);
         CompileTheWorldOptions.overrideWithNativeOptions(config);
 
         // Only set HotSpotPrintInlining if it still has its default value (false).
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotNodePlugin.java	Fri Feb 10 08:57:42 2017 -0800
@@ -22,7 +22,6 @@
  */
 package org.graalvm.compiler.hotspot.meta;
 
-import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
 import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
 import static org.graalvm.compiler.hotspot.meta.HotSpotGraalConstantFieldProvider.FieldReadEnabledInImmutableCode;
 
@@ -112,11 +111,6 @@
                 return true;
             }
         }
-        if (GeneratePIC.getValue()) {
-            if (field.isSynthetic() && field.getName().startsWith("$assertionsDisabled")) {
-                return tryReadField(b, field, null);
-            }
-        }
         if (b.parsingIntrinsic() && wordOperationPlugin.handleLoadStaticField(b, field)) {
             return true;
         }
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1738,9 +1738,8 @@
             } else {
                 // Intrinsic was not applied: remove intrinsic guard
                 // and restore the original receiver node in the arguments array
-                for (Node node : graph.getNewNodes(intrinsicGuard.mark)) {
-                    GraphUtil.killCFG(node);
-                }
+                intrinsicGuard.lastInstr.setNext(null);
+                GraphUtil.removeNewNodes(graph, intrinsicGuard.mark);
                 lastInstr = intrinsicGuard.lastInstr;
                 args[0] = intrinsicGuard.receiver;
             }
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/SimplifyingGraphDecoder.java	Fri Feb 10 08:57:42 2017 -0800
@@ -153,9 +153,7 @@
         }
 
         for (Node node : methodScope.graph.getNewNodes(methodScope.methodStartMark)) {
-            if (!(node instanceof FixedNode) && node.hasNoUsages()) {
-                GraphUtil.killCFG(node);
-            }
+            GraphUtil.tryKillUnused(node);
         }
     }
 
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/StructuredGraph.java	Fri Feb 10 08:57:42 2017 -0800
@@ -506,7 +506,7 @@
         for (Node successor : snapshot) {
             if (successor != null && successor.isAlive()) {
                 if (successor != survivingSuccessor) {
-                    GraphUtil.killCFG(successor, tool);
+                    GraphUtil.killCFG((FixedNode) successor, tool);
                 }
             }
         }
@@ -566,6 +566,9 @@
             reduceTrivialMerge(begin);
         } else { // convert to merge
             AbstractMergeNode merge = this.add(new MergeNode());
+            for (EndNode end : begin.forwardEnds()) {
+                merge.addForwardEnd(end);
+            }
             this.replaceFixedWithFixed(begin, merge);
         }
     }
@@ -576,7 +579,14 @@
         for (PhiNode phi : merge.phis().snapshot()) {
             assert phi.valueCount() == 1;
             ValueNode singleValue = phi.valueAt(0);
-            phi.replaceAtUsagesAndDelete(singleValue);
+            if (phi.hasUsages()) {
+                phi.replaceAtUsagesAndDelete(singleValue);
+            } else {
+                phi.safeDelete();
+                if (singleValue != null) {
+                    GraphUtil.tryKillUnused(singleValue);
+                }
+            }
         }
         // remove loop exits
         if (merge instanceof LoopBeginNode) {
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -22,18 +22,30 @@
  */
 package org.graalvm.compiler.nodes.util;
 
+import static org.graalvm.compiler.graph.Graph.Options.VerifyGraalGraphEdges;
+import static org.graalvm.compiler.nodes.util.GraphUtil.Options.VerifyKillCFGUnusedNodes;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.Set;
 
 import org.graalvm.compiler.bytecode.Bytecode;
 import org.graalvm.compiler.code.SourceStackTraceBailoutException;
+import org.graalvm.compiler.core.common.CollectionsFactory;
 import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.debug.Debug;
+import org.graalvm.compiler.graph.Graph;
 import org.graalvm.compiler.graph.Node;
+import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.NodeWorkList;
+import org.graalvm.compiler.graph.Position;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
 import org.graalvm.compiler.graph.spi.SimplifierTool;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.AbstractBeginNode;
 import org.graalvm.compiler.nodes.AbstractEndNode;
 import org.graalvm.compiler.nodes.AbstractMergeNode;
@@ -48,11 +60,15 @@
 import org.graalvm.compiler.nodes.StateSplit;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.calc.FloatingNode;
 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
 import org.graalvm.compiler.nodes.spi.ArrayLengthProvider;
 import org.graalvm.compiler.nodes.spi.LimitedValueProxy;
 import org.graalvm.compiler.nodes.spi.LoweringProvider;
 import org.graalvm.compiler.nodes.spi.ValueProxy;
+import org.graalvm.compiler.options.Option;
+import org.graalvm.compiler.options.OptionType;
+import org.graalvm.compiler.options.OptionValue;
 
 import jdk.vm.ci.code.BailoutException;
 import jdk.vm.ci.code.BytecodePosition;
@@ -64,22 +80,78 @@
 
 public class GraphUtil {
 
-    public static void killCFG(Node node, SimplifierTool tool) {
-        NodeWorkList worklist = killCFG(node, tool, null);
-        if (worklist != null) {
-            for (Node successor : worklist) {
-                killCFG(successor, tool, worklist);
+    public static class Options {
+        @Option(help = "Verify that there are no new unused nodes when performing killCFG", type = OptionType.Debug)//
+        public static final OptionValue<Boolean> VerifyKillCFGUnusedNodes = new OptionValue<>(false);
+    }
+
+    @SuppressWarnings("try")
+    public static void killCFG(FixedNode node, SimplifierTool tool) {
+        try (Debug.Scope scope = Debug.scope("KillCFG", node)) {
+            Set<Node> unusedNodes = null;
+            Set<Node> unsafeNodes = null;
+            Graph.NodeEventScope nodeEventScope = null;
+            if (VerifyGraalGraphEdges.getValue()) {
+                unsafeNodes = collectUnsafeNodes(node.graph());
+            }
+            if (VerifyKillCFGUnusedNodes.getValue()) {
+                Set<Node> collectedUnusedNodes = unusedNodes = CollectionsFactory.newSet();
+                nodeEventScope = node.graph().trackNodeEvents(new Graph.NodeEventListener() {
+                    @Override
+                    public void event(Graph.NodeEvent e, Node n) {
+                        if (e == Graph.NodeEvent.ZERO_USAGES && isFloatingNode(n)) {
+                            collectedUnusedNodes.add(n);
+                        }
+                    }
+                });
+            }
+            Debug.dump(Debug.VERY_DETAILED_LOG_LEVEL, node.graph(), "Before killCFG %s", node);
+            NodeWorkList worklist = killCFG(node, tool, null);
+            if (worklist != null) {
+                for (Node n : worklist) {
+                    killCFG(n, tool, worklist);
+                }
+            }
+            if (VerifyGraalGraphEdges.getValue()) {
+                Set<Node> newUnsafeNodes = collectUnsafeNodes(node.graph());
+                newUnsafeNodes.removeAll(unsafeNodes);
+                assert newUnsafeNodes.isEmpty() : "New unsafe nodes: " + newUnsafeNodes;
+            }
+            if (VerifyKillCFGUnusedNodes.getValue()) {
+                nodeEventScope.close();
+                unusedNodes.removeIf(n -> n.isDeleted());
+                assert unusedNodes.isEmpty() : "New unused nodes: " + unusedNodes;
+            }
+        } catch (Throwable t) {
+            throw Debug.handle(t);
+        }
+    }
+
+    /**
+     * Collects all node in the graph which have non-optional inputs that are null.
+     */
+    private static Set<Node> collectUnsafeNodes(Graph graph) {
+        Set<Node> unsafeNodes = CollectionsFactory.newSet();
+        for (Node n : graph.getNodes()) {
+            for (Position pos : n.inputPositions()) {
+                Node input = pos.get(n);
+                if (input == null) {
+                    if (!pos.isInputOptional()) {
+                        unsafeNodes.add(n);
+                    }
+                }
             }
         }
+        return unsafeNodes;
     }
 
     private static NodeWorkList killCFG(Node node, SimplifierTool tool, NodeWorkList worklist) {
         NodeWorkList newWorklist = worklist;
-        // DebugScope.forceDump(node.graph(), "kill CFG %s", node);
         if (node instanceof FixedNode) {
             newWorklist = killCFGLinear((FixedNode) node, newWorklist, tool);
         } else {
-            propagateKill(node);
+            newWorklist = propagateKill(node, newWorklist);
+            Debug.dump(Debug.VERY_DETAILED_LOG_LEVEL, node.graph(), "killCFG (Floating) %s", node);
         }
         return newWorklist;
     }
@@ -93,19 +165,20 @@
             if (current instanceof AbstractEndNode) {
                 // We reached a control flow end.
                 AbstractEndNode end = (AbstractEndNode) current;
-                killEnd(end, tool);
+                newWorklist = killEnd(end, newWorklist, tool);
             } else if (current instanceof FixedWithNextNode) {
-                next = ((FixedWithNextNode) current).next();
+                // Node guaranteed to have a single successor
+                FixedWithNextNode fixedWithNext = (FixedWithNextNode) current;
+                assert fixedWithNext.successors().count() == 1 || fixedWithNext.successors().count() == 0;
+                assert fixedWithNext.successors().first() == fixedWithNext.next();
+                next = fixedWithNext.next();
             } else {
-                // Normal control flow node.
                 /*
                  * We do not take a successor snapshot because this iterator supports concurrent
                  * modifications as long as they do not change the size of the successor list. Not
                  * taking a snapshot allows us to see modifications to other branches that may
                  * happen while processing one branch.
                  */
-                // assert node.successors().count() > 1 || node.successors().count() == 0 :
-                // node.getClass();
                 Iterator<Node> successors = current.successors().iterator();
                 if (successors.hasNext()) {
                     Node first = successors.next();
@@ -126,100 +199,158 @@
                 }
             }
             current.replaceAtPredecessor(null);
-            propagateKill(current);
+            newWorklist = propagateKill(current, newWorklist);
+            Debug.dump(Debug.VERY_DETAILED_LOG_LEVEL, current.graph(), "killCFGLinear %s", current);
             current = next;
         }
+        Debug.dump(Debug.DETAILED_LOG_LEVEL, in.graph(), "killCFGLinear %s", in);
         return newWorklist;
     }
 
-    public static void killCFG(Node node) {
+    public static void killCFG(FixedNode node) {
         killCFG(node, null);
     }
 
-    private static void killEnd(AbstractEndNode end, SimplifierTool tool) {
+    /**
+     * Node type used temporarily while deleting loops.
+     *
+     * It is used as replacement for the loop {@link PhiNode PhiNodes} in order to break data-flow
+     * cycles before deleting the loop. The control-flow of the whole loop is killed before killing
+     * the poison node if they are still alive.
+     */
+    @NodeInfo(allowedUsageTypes = InputType.Unchecked)
+    private static final class PoisonNode extends FloatingNode {
+        public static final NodeClass<PoisonNode> TYPE = NodeClass.create(PoisonNode.class);
+
+        protected PoisonNode() {
+            super(TYPE, StampFactory.forVoid());
+        }
+    }
+
+    private static NodeWorkList killEnd(AbstractEndNode end, NodeWorkList worklist, SimplifierTool tool) {
+        NodeWorkList newWorklist = worklist;
         AbstractMergeNode merge = end.merge();
         if (merge != null) {
             merge.removeEnd(end);
             StructuredGraph graph = end.graph();
             if (merge instanceof LoopBeginNode && merge.forwardEndCount() == 0) {
                 // dead loop
-                for (PhiNode phi : merge.phis().snapshot()) {
-                    propagateKill(phi);
-                }
                 LoopBeginNode begin = (LoopBeginNode) merge;
                 // disconnect and delete loop ends & loop exits
                 for (LoopEndNode loopend : begin.loopEnds().snapshot()) {
                     loopend.predecessor().replaceFirstSuccessor(loopend, null);
                     loopend.safeDelete();
                 }
+                // clean unused proxies to avoid creating new unused nodes
+                for (LoopExitNode exit : begin.loopExits()) {
+                    for (ProxyNode vpn : exit.proxies().snapshot()) {
+                        tryKillUnused(vpn);
+                    }
+                }
                 begin.removeExits();
+                PoisonNode poison = null;
+                if (merge.phis().isNotEmpty()) {
+                    poison = graph.unique(new PoisonNode());
+                    for (PhiNode phi : merge.phis()) {
+                        phi.replaceAtUsages(poison);
+                    }
+                    for (PhiNode phi : merge.phis().snapshot()) {
+                        killWithUnusedFloatingInputs(phi);
+                    }
+                }
                 FixedNode loopBody = begin.next();
-                if (loopBody != null) { // for small infinite loops, the body may be killed while
-                                        // killing the loop ends
-                    killCFG(loopBody);
+                Debug.dump(Debug.VERY_DETAILED_LOG_LEVEL, end.graph(), "killEnd (Loop) %s after initial loop cleanup", end);
+                if (loopBody != null) {
+                    // for small infinite loops, the body may already be killed while killing the
+                    // LoopEnds
+                    newWorklist = killCFG(loopBody, tool, worklist);
+                }
+                FrameState frameState = begin.stateAfter();
+                begin.safeDelete();
+                if (frameState != null) {
+                    tryKillUnused(frameState);
                 }
-                begin.safeDelete();
+                if (poison != null && poison.isAlive()) {
+                    if (newWorklist == null) {
+                        newWorklist = graph.createNodeWorkList();
+                    }
+                    // drain the worklist to finish the loop before adding the poison
+                    for (Node n : newWorklist) {
+                        killCFG(n, tool, newWorklist);
+                    }
+                    if (poison.isAlive()) {
+                        newWorklist.add(poison);
+                    }
+                }
             } else if (merge instanceof LoopBeginNode && ((LoopBeginNode) merge).loopEnds().isEmpty()) {
                 // not a loop anymore
                 if (tool != null) {
-                    merge.phis().forEach(phi -> tool.addToWorkList(phi.usages()));
+                    for (PhiNode phi : merge.phis()) {
+                        tool.addToWorkList(phi.usages());
+                    }
                 }
                 graph.reduceDegenerateLoopBegin((LoopBeginNode) merge);
             } else if (merge.phiPredecessorCount() == 1) {
                 // not a merge anymore
                 if (tool != null) {
-                    merge.phis().forEach(phi -> tool.addToWorkList(phi.usages()));
+                    for (PhiNode phi : merge.phis()) {
+                        tool.addToWorkList(phi.usages());
+                    }
                 }
                 graph.reduceTrivialMerge(merge);
             }
         }
+        return newWorklist;
     }
 
     public static boolean isFloatingNode(Node n) {
         return !(n instanceof FixedNode);
     }
 
-    private static void propagateKill(Node node) {
+    private static NodeWorkList propagateKill(Node node, NodeWorkList workList) {
+        NodeWorkList newWorkList = workList;
         if (node != null && node.isAlive()) {
-            node.markDeleted();
-
-            for (Node in : node.inputs()) {
-                if (in.isAlive()) {
-                    in.removeUsage(node);
-                    if (in.hasNoUsages() && !(in instanceof FixedNode)) {
-                        killWithUnusedFloatingInputs(in);
+            for (Node usage : node.usages().snapshot()) {
+                assert usage.isAlive();
+                if (isFloatingNode(usage)) {
+                    boolean addUsage = false;
+                    if (usage instanceof PhiNode) {
+                        PhiNode phi = (PhiNode) usage;
+                        assert phi.merge() != null;
+                        if (phi.merge() == node) {
+                            // we reach the phi directly through he merge, queue it.
+                            addUsage = true;
+                        } else {
+                            // we reach it though a value
+                            assert phi.values().contains(node);
+                            // let that be handled when we reach the corresponding End node
+                        }
+                    } else {
+                        addUsage = true;
+                    }
+                    if (addUsage) {
+                        if (newWorkList == null) {
+                            newWorkList = node.graph().createNodeWorkList();
+                        }
+                        newWorkList.add(usage);
                     }
                 }
-            }
-
-            ArrayList<Node> usageToKill = null;
-            for (Node usage : node.usages()) {
-                if (usage.isAlive() && !(usage instanceof FixedNode)) {
-                    if (usageToKill == null) {
-                        usageToKill = new ArrayList<>();
-                    }
-                    usageToKill.add(usage);
-                }
+                usage.replaceFirstInput(node, null);
             }
-            if (usageToKill != null) {
-                for (Node usage : usageToKill) {
-                    if (usage.isAlive()) {
-                        if (usage instanceof PhiNode) {
-                            PhiNode phiNode = (PhiNode) usage;
-                            usage.replaceFirstInput(node, null);
-                            if (phiNode.merge() == null || !phiNode.hasValidInput()) {
-                                propagateKill(usage);
-                            }
-                        } else {
-                            propagateKill(usage);
-                        }
-                    }
-                }
-            }
+            killWithUnusedFloatingInputs(node);
         }
+        return newWorkList;
+    }
+
+    private static boolean checkKill(Node node) {
+        node.assertTrue(node.isAlive(), "must be alive");
+        node.assertTrue(node.hasNoUsages(), "cannot kill node %s because of usages: %s", node, node.usages());
+        node.assertTrue(node.predecessor() == null, "cannot kill node %s because of predecessor: %s", node, node.predecessor());
+        return true;
     }
 
     public static void killWithUnusedFloatingInputs(Node node) {
+        assert checkKill(node);
         node.markDeleted();
         outer: for (Node in : node.inputs()) {
             if (in.isAlive()) {
@@ -227,7 +358,7 @@
                 if (in.hasNoUsages()) {
                     node.maybeNotifyZeroUsages(in);
                 }
-                if (!(in instanceof FixedNode)) {
+                if (isFloatingNode(in)) {
                     if (in.hasNoUsages()) {
                         killWithUnusedFloatingInputs(in);
                     } else if (in instanceof PhiNode) {
@@ -244,6 +375,35 @@
         }
     }
 
+    /**
+     * Removes all nodes created after the {@code mark}, assuming no "old" nodes point to "new"
+     * nodes.
+     */
+    public static void removeNewNodes(Graph graph, Graph.Mark mark) {
+        assert checkNoOldToNewEdges(graph, mark);
+        for (Node n : graph.getNewNodes(mark)) {
+            n.markDeleted();
+            for (Node in : n.inputs()) {
+                in.removeUsage(n);
+            }
+        }
+    }
+
+    private static boolean checkNoOldToNewEdges(Graph graph, Graph.Mark mark) {
+        for (Node old : graph.getNodes()) {
+            if (graph.isNew(mark, old)) {
+                break;
+            }
+            for (Node n : old.successors()) {
+                assert !graph.isNew(mark, n) : old + " -> " + n;
+            }
+            for (Node n : old.inputs()) {
+                assert !graph.isNew(mark, n) : old + " -> " + n;
+            }
+        }
+        return true;
+    }
+
     public static void removeFixedWithUnusedInputs(FixedWithNextNode fixed) {
         if (fixed instanceof StateSplit) {
             FrameState stateAfter = ((StateSplit) fixed).stateAfter();
@@ -688,8 +848,9 @@
 
         @Override
         public void deleteBranch(Node branch) {
-            branch.predecessor().replaceFirstSuccessor(branch, null);
-            GraphUtil.killCFG(branch, this);
+            FixedNode fixedBranch = (FixedNode) branch;
+            fixedBranch.predecessor().replaceFirstSuccessor(fixedBranch, null);
+            GraphUtil.killCFG(fixedBranch, this);
         }
 
         @Override
--- a/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/jdk.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/CanonicalizerPhase.java	Fri Feb 10 08:57:42 2017 -0800
@@ -444,8 +444,9 @@
 
             @Override
             public void deleteBranch(Node branch) {
-                branch.predecessor().replaceFirstSuccessor(branch, null);
-                GraphUtil.killCFG(branch, this);
+                FixedNode fixedBranch = (FixedNode) branch;
+                fixedBranch.predecessor().replaceFirstSuccessor(fixedBranch, null);
+                GraphUtil.killCFG(fixedBranch, this);
             }
 
             @Override
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. 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
@@ -632,7 +632,6 @@
   sigaddset(&unblocked_sigs, SIGBUS);
   sigaddset(&unblocked_sigs, SIGFPE);
   sigaddset(&unblocked_sigs, SIGTRAP);
-  sigaddset(&unblocked_sigs, SIGDANGER);
   sigaddset(&unblocked_sigs, SR_signum);
 
   if (!ReduceSignalUsage) {
@@ -1553,6 +1552,8 @@
   print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
   print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
   print_signal_handler(st, SIGTRAP, buf, buflen);
+  // We also want to know if someone else adds a SIGDANGER handler because
+  // that will interfere with OOM killling.
   print_signal_handler(st, SIGDANGER, buf, buflen);
 }
 
@@ -3156,7 +3157,6 @@
     set_signal_handler(SIGFPE, true);
     set_signal_handler(SIGTRAP, true);
     set_signal_handler(SIGXFSZ, true);
-    set_signal_handler(SIGDANGER, true);
 
     if (libjsig_is_loaded) {
       // Tell libjsig jvm finishes setting signal handlers.
@@ -3273,7 +3273,6 @@
   if (UseSIGTRAP) {
     DO_SIGNAL_CHECK(SIGTRAP);
   }
-  DO_SIGNAL_CHECK(SIGDANGER);
 
   // ReduceSignalUsage allows the user to override these handlers
   // see comments at the very top and jvm_solaris.h
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -778,6 +778,11 @@
   // is already attached to a debugger; debugger must observe
   // the exception below to show the correct name.
 
+  // If there is no debugger attached skip raising the exception
+  if (!IsDebuggerPresent()) {
+    return;
+  }
+
   const DWORD MS_VC_EXCEPTION = 0x406D1388;
   struct {
     DWORD dwType;     // must be 0x1000
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017 SAP SE. 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
@@ -258,13 +258,6 @@
     }
   }
 
-  // Handle SIGDANGER right away. AIX would raise SIGDANGER whenever available swap
-  // space falls below 30%. This is only a chance for the process to gracefully abort.
-  // We can't hope to proceed after SIGDANGER since SIGKILL tailgates.
-  if (sig == SIGDANGER) {
-    goto report_and_die;
-  }
-
   if (info == NULL || uc == NULL || thread == NULL && vmthread == NULL) {
     goto run_chained_handler;
   }
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -87,6 +87,7 @@
 #define SPELL_REG_FP "rbp"
 #else
 #define REG_FP 29
+#define REG_LR 30
 
 #define SPELL_REG_SP "sp"
 #define SPELL_REG_FP "x29"
@@ -182,6 +183,46 @@
   return frame(sp, fp, epc.pc());
 }
 
+bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Linux::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_context(uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // more complex code with compiled code
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling
+      return false;
+    } else {
+      // In compiled code, the stack banging is performed before LR
+      // has been saved in the frame.  LR is live, and SP and FP
+      // belong to the caller.
+      intptr_t* fp = os::Linux::ucontext_get_fp(uc);
+      intptr_t* sp = os::Linux::ucontext_get_sp(uc);
+      address pc = (address)(uc->uc_mcontext.regs[REG_LR]
+                         - NativeInstruction::instruction_size);
+      *fr = frame(sp, fp, pc);
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        assert(!fr->is_first_frame(), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 // By default, gcc always saves frame pointer rfp on this stack. This
 // may get turned off by -fomit-frame-pointer.
 frame os::get_sender_for_C_frame(frame* fr) {
@@ -313,6 +354,24 @@
         if (thread->in_stack_yellow_reserved_zone(addr)) {
           thread->disable_stack_yellow_reserved_zone();
           if (thread->thread_state() == _thread_in_Java) {
+            if (thread->in_stack_reserved_zone(addr)) {
+              frame fr;
+              if (os::Linux::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+                assert(fr.is_java_frame(), "Must be a Java frame");
+                frame activation =
+                  SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+                if (activation.sp() != NULL) {
+                  thread->disable_stack_reserved_zone();
+                  if (activation.is_interpreted_frame()) {
+                    thread->set_reserved_stack_activation((address)(
+                      activation.fp() + frame::interpreter_frame_initial_sp_offset));
+                  } else {
+                    thread->set_reserved_stack_activation((address)activation.unextended_sp());
+                  }
+                  return 1;
+                }
+              }
+            }
             // Throw a stack overflow exception.  Guard pages will be reenabled
             // while unwinding the stack.
             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
--- a/hotspot/src/os_cpu/linux_s390/vm/os_linux_s390.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/os_cpu/linux_s390/vm/os_linux_s390.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -144,6 +144,42 @@
   return frame(sp, epc.pc());
 }
 
+bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
+  address pc = (address) os::Linux::ucontext_get_pc(uc);
+  if (Interpreter::contains(pc)) {
+    // Interpreter performs stack banging after the fixed frame header has
+    // been generated while the compilers perform it before. To maintain
+    // semantic consistency between interpreted and compiled frames, the
+    // method returns the Java sender of the current frame.
+    *fr = os::fetch_frame_from_context(uc);
+    if (!fr->is_first_java_frame()) {
+      assert(fr->safe_for_sender(thread), "Safety check");
+      *fr = fr->java_sender();
+    }
+  } else {
+    // More complex code with compiled code.
+    assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
+    CodeBlob* cb = CodeCache::find_blob(pc);
+    if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
+      // Not sure where the pc points to, fallback to default
+      // stack overflow handling. In compiled code, we bang before
+      // the frame is complete.
+      return false;
+    } else {
+      intptr_t* fp = os::Linux::ucontext_get_fp(uc);
+      intptr_t* sp = os::Linux::ucontext_get_sp(uc);
+      *fr = frame(sp, (address)*sp);
+      if (!fr->is_java_frame()) {
+        assert(fr->safe_for_sender(thread), "Safety check");
+        assert(!fr->is_first_frame(), "Safety check");
+        *fr = fr->java_sender();
+      }
+    }
+  }
+  assert(fr->is_java_frame(), "Safety check");
+  return true;
+}
+
 frame os::get_sender_for_C_frame(frame* fr) {
   if (*fr->sp() == 0) {
     // fr is the last C frame.
@@ -279,13 +315,31 @@
       if (thread->on_local_stack(addr)) {
         // stack overflow
         if (thread->in_stack_yellow_reserved_zone(addr)) {
-          thread->disable_stack_yellow_reserved_zone();
           if (thread->thread_state() == _thread_in_Java) {
+            if (thread->in_stack_reserved_zone(addr)) {
+              frame fr;
+              if (os::Linux::get_frame_at_stack_banging_point(thread, uc, &fr)) {
+                assert(fr.is_java_frame(), "Must be a Javac frame");
+                frame activation =
+                  SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
+                if (activation.sp() != NULL) {
+                  thread->disable_stack_reserved_zone();
+                  if (activation.is_interpreted_frame()) {
+                    thread->set_reserved_stack_activation((address)activation.fp());
+                  } else {
+                    thread->set_reserved_stack_activation((address)activation.unextended_sp());
+                  }
+                  return 1;
+                }
+              }
+            }
             // Throw a stack overflow exception.
             // Guard pages will be reenabled while unwinding the stack.
+            thread->disable_stack_yellow_reserved_zone();
             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
           } else {
             // Thread was in the vm or native code. Return and try to finish.
+            thread->disable_stack_yellow_reserved_zone();
             return 1;
           }
         } else if (thread->in_stack_red_zone(addr)) {
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -89,7 +89,10 @@
 // Minimum usable stack sizes required to get to user code. Space for
 // HotSpot guard pages is added later.
 #ifdef _LP64
-size_t os::Posix::_compiler_thread_min_stack_allowed = 202 * K;
+// The adlc generated method 'State::MachNodeGenerator(int)' used by the C2 compiler
+// threads requires a large stack with the Solaris Studio C++ compiler version 5.13
+// and product VM builds (debug builds require significantly less stack space).
+size_t os::Posix::_compiler_thread_min_stack_allowed = 325 * K;
 size_t os::Posix::_java_thread_min_stack_allowed = 48 * K;
 size_t os::Posix::_vm_internal_thread_min_stack_allowed = 224 * K;
 #else
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -650,6 +650,7 @@
   if( strcmp(_matrule->_opType,"MemBarReleaseLock") == 0 ) return true;
   if( strcmp(_matrule->_opType,"MemBarAcquireLock") == 0 ) return true;
   if( strcmp(_matrule->_opType,"MemBarStoreStore") == 0 ) return true;
+  if( strcmp(_matrule->_opType,"MemBarVolatile") == 0 ) return true;
   if( strcmp(_matrule->_opType,"StoreFence") == 0 ) return true;
   if( strcmp(_matrule->_opType,"LoadFence") == 0 ) return true;
 
--- a/hotspot/src/share/vm/aot/aotCodeHeap.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/aot/aotCodeHeap.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,7 @@
 
 #include "aot/aotCodeHeap.hpp"
 #include "aot/aotLoader.hpp"
+#include "classfile/javaAssertions.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "gc/shared/gcLocker.hpp"
 #include "interpreter/abstractInterpreter.hpp"
@@ -294,6 +295,8 @@
     // When the AOT compiler compiles something big we fail to generate metadata
     // in CodeInstaller::gather_metadata. In that case the scopes_pcs_begin == scopes_pcs_end.
     // In all successful cases we always have 2 entries of scope pcs.
+    log_info(aot, class, resolve)("Failed to load %s (no metadata available)", mh->name_and_sig_as_C_string());
+    _code_to_aot[code_id]._state = invalid;
     return;
   }
 
@@ -536,6 +539,7 @@
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_heap_end_address", address, (heap->supports_inline_contig_alloc() ? heap->end_addr() : NULL));
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_polling_page", address, os::get_polling_page());
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_narrow_klass_base_address", address, Universe::narrow_klass_base());
+    SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_narrow_oop_base_address", address, Universe::narrow_oop_base());
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_log_of_heap_region_grain_bytes", int, HeapRegion::LogOfHRGrainBytes);
     SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_inline_contiguous_allocation_supported", bool, heap->supports_inline_contig_alloc());
     link_shared_runtime_symbols();
@@ -706,6 +710,12 @@
     return false;
   }
 
+  if (_lib->config()->_omitAssertions && JavaAssertions::enabled(kh->name()->as_C_string(), kh->class_loader() == NULL)) {
+    log_trace(aot, class, load)("class  %s  in  %s does not have java assertions in compiled code, but assertions are enabled for this execution.", kh->internal_name(), _lib->name());
+    sweep_dependent_methods(klass_data);
+    return false;
+  }
+
   NOT_PRODUCT( aot_klasses_found++; )
 
   log_trace(aot, class, load)("found  %s  in  %s for classloader %p tid=" INTPTR_FORMAT, kh->internal_name(), _lib->name(), kh->class_loader_data(), p2i(thread));
@@ -714,7 +724,7 @@
   // Set klass's Resolve (second) got cell.
   _metaspace_got[klass_data->_got_index] = kh();
 
-  // Initialize global symbols of the DSO to the correspondingVM symbol values.
+  // Initialize global symbols of the DSO to the corresponding VM symbol values.
   link_global_lib_symbols();
 
   int methods_offset = klass_data->_compiled_methods_offset;
--- a/hotspot/src/share/vm/aot/aotCodeHeap.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/aot/aotCodeHeap.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -88,7 +88,7 @@
 } AOTHeader;
 
 typedef struct {
-  enum { CONFIG_SIZE = 11 + 7 * 4 };
+  enum { CONFIG_SIZE = 12 + 7 * 4 };
   int _config_size;
   int _narrowOopShift;
   int _narrowKlassShift;
@@ -108,6 +108,7 @@
   bool _tieredAOT;
   bool _enableContended;
   bool _restrictContended;
+  bool _omitAssertions;
 } AOTConfiguration;
 
 class AOTLib : public CHeapObj<mtCode> {
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -3298,7 +3298,9 @@
   // for osr compile, bailout if some requirements are not fulfilled
   if (osr_bci != -1) {
     BlockBegin* osr_block = blm.bci2block()->at(osr_bci);
-    assert(osr_block->is_set(BlockBegin::was_visited_flag),"osr entry must have been visited for osr compile");
+    if (!osr_block->is_set(BlockBegin::was_visited_flag)) {
+      BAILOUT("osr entry must have been visited for osr compile");
+    }
 
     // check if osr entry point has empty stack - we cannot handle non-empty stacks at osr entry points
     if (!osr_block->state()->stack_is_empty()) {
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -895,8 +895,32 @@
           ciMethod* target = s.get_method(ignored_will_link, &declared_signature);
           ciKlass*  holder = s.get_declared_method_holder();
           assert(declared_signature != NULL, "cannot be null");
-          // Push appendix argument, if one.
-          if (s.has_appendix()) {
+          // If the current bytecode has an attached appendix argument,
+          // push an unknown object to represent that argument. (Analysis
+          // of dynamic call sites, especially invokehandle calls, needs
+          // the appendix argument on the stack, in addition to "regular" arguments
+          // pushed onto the stack by bytecode instructions preceding the call.)
+          //
+          // The escape analyzer does _not_ use the ciBytecodeStream::has_appendix(s)
+          // method to determine whether the current bytecode has an appendix argument.
+          // The has_appendix() method obtains the appendix from the
+          // ConstantPoolCacheEntry::_f1 field, which can happen concurrently with
+          // resolution of dynamic call sites. Callees in the
+          // ciBytecodeStream::get_method() call above also access the _f1 field;
+          // interleaving the get_method() and has_appendix() calls in the current
+          // method with call site resolution can lead to an inconsistent view of
+          // the current method's argument count. In particular, some interleaving(s)
+          // can cause the method's argument count to not include the appendix, which
+          // then leads to stack over-/underflow in the escape analyzer.
+          //
+          // Instead of pushing the argument if has_appendix() is true, the escape analyzer
+          // pushes an appendix for all call sites targeted by invokedynamic and invokehandle
+          // instructions, except if the call site is the _invokeBasic intrinsic
+          // (that intrinsic is always targeted by an invokehandle instruction but does
+          // not have an appendix argument).
+          if (target->is_loaded() &&
+              Bytecodes::has_optional_appendix(s.cur_bc_raw()) &&
+              target->intrinsic_id() != vmIntrinsics::_invokeBasic) {
             state.apush(unknown_obj);
           }
           // Pass in raw bytecode because we need to see invokehandle instructions.
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -136,15 +136,19 @@
     check_is_loaded();
     return _signature->size() + (_flags.is_static() ? 0 : 1);
   }
-  // Report the number of elements on stack when invoking this method.
-  // This is different than the regular arg_size because invokedynamic
-  // has an implicit receiver.
+  // Report the number of elements on stack when invoking the current method.
+  // If the method is loaded, arg_size() gives precise information about the
+  // number of stack elements (using the method's signature and its flags).
+  // However, if the method is not loaded, the number of stack elements must
+  // be determined differently, as the method's flags are not yet available.
+  // The invoke_arg_size() method assumes in that case that all bytecodes except
+  // invokestatic and invokedynamic have a receiver that is also pushed onto the
+  // stack by the caller of the current method.
   int invoke_arg_size(Bytecodes::Code code) const {
     if (is_loaded()) {
       return arg_size();
     } else {
       int arg_size = _signature->size();
-      // Add a receiver argument, maybe:
       if (code != Bytecodes::_invokestatic &&
           code != Bytecodes::_invokedynamic) {
         arg_size++;
--- a/hotspot/src/share/vm/classfile/classLoader.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -364,7 +364,12 @@
     if (verstr != NULL) {
       version = atoi(verstr);
       if (version < base_version || version > cur_ver) {
-        is_multi_ver = false;
+        // If the specified version is lower than the base version, the base
+        // entry will be used; if the version is higher than the current
+        // jdk version, the highest versioned entry will be used.
+        if (version < base_version) {
+          is_multi_ver = false;
+        }
         // print out warning, do not use assertion here since it will continue to look
         // for proper version.
         warning("JDK%d is not supported in multiple version jars", version);
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -94,7 +94,7 @@
   _metaspace(NULL), _unloading(false), _klasses(NULL),
   _modules(NULL), _packages(NULL),
   _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL),
-  _next(NULL), _dependencies(dependencies), _shared_class_loader_id(-1),
+  _next(NULL), _dependencies(dependencies),
   _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true,
                             Monitor::_safepoint_check_never)) {
   TRACE_INIT_ID(this);
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -204,9 +204,6 @@
   // Support for walking class loader data objects
   ClassLoaderData* _next; /// Next loader_datas created
 
-  // CDS
-  int _shared_class_loader_id;
-
   // ReadOnly and ReadWrite metaspaces (static because only on the null
   // class loader for now).
   static Metaspace* _ro_metaspace;
@@ -338,15 +335,6 @@
   Metaspace* rw_metaspace();
   void initialize_shared_metaspaces();
 
-  int shared_class_loader_id() const {
-    return _shared_class_loader_id;
-  }
-  void set_shared_class_loader_id(int id) {
-    assert(id >= 0, "sanity");
-    assert(_shared_class_loader_id <0, "cannot be assigned more than once");
-    _shared_class_loader_id = id;
-  }
-
   TRACE_DEFINE_TRACE_ID_METHODS;
 };
 
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -163,8 +163,8 @@
 
   Klass* k = SystemDictionary::String_klass();
   compute_offset(value_offset,           k, vmSymbols::value_name(),  vmSymbols::byte_array_signature());
-  compute_optional_offset(hash_offset,   k, vmSymbols::hash_name(),   vmSymbols::int_signature());
-  compute_optional_offset(coder_offset,  k, vmSymbols::coder_name(),  vmSymbols::byte_signature());
+  compute_offset(hash_offset,            k, vmSymbols::hash_name(),   vmSymbols::int_signature());
+  compute_offset(coder_offset,           k, vmSymbols::coder_name(),  vmSymbols::byte_signature());
 
   initialized = true;
 }
@@ -3977,12 +3977,8 @@
   // java.lang.String
 
   CHECK_OFFSET("java/lang/String", java_lang_String, value, "[B");
-  if (java_lang_String::has_hash_field()) {
-    CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I");
-  }
-  if (java_lang_String::has_coder_field()) {
-    CHECK_OFFSET("java/lang/String", java_lang_String, coder, "B");
-  }
+  CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I");
+  CHECK_OFFSET("java/lang/String", java_lang_String, coder, "B");
 
   // java.lang.Class
 
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -81,15 +81,6 @@
   static Handle create_from_platform_dependent_str(const char* str, TRAPS);
   static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS);
 
-  static bool has_hash_field()  {
-    assert(initialized, "Must be initialized");
-    return (hash_offset > 0);
-  }
-  static bool has_coder_field()  {
-    assert(initialized, "Must be initialized");
-    return (coder_offset > 0);
-  }
-
   static void set_compact_strings(bool value);
 
   static int value_offset_in_bytes()  {
--- a/hotspot/src/share/vm/classfile/javaClasses.inline.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/javaClasses.inline.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -30,10 +30,8 @@
 #include "oops/oopsHierarchy.hpp"
 
 void java_lang_String::set_coder(oop string, jbyte coder) {
-  assert(initialized, "Must be initialized");
-  if (coder_offset > 0) {
-    string->byte_field_put(coder_offset, coder);
-  }
+  assert(initialized && (coder_offset > 0), "Must be initialized");
+  string->byte_field_put(coder_offset, coder);
 }
 
 void java_lang_String::set_value_raw(oop string, typeArrayOop buffer) {
@@ -61,15 +59,11 @@
   return java_string->int_field(hash_offset);
 }
 bool java_lang_String::is_latin1(oop java_string) {
-  assert(initialized, "Must be initialized");
+  assert(initialized && (coder_offset > 0), "Must be initialized");
   assert(is_instance(java_string), "must be java_string");
-  if (coder_offset > 0) {
-    jbyte coder = java_string->byte_field(coder_offset);
-    assert(CompactStrings || coder == CODER_UTF16, "Must be UTF16 without CompactStrings");
-    return coder == CODER_LATIN1;
-  } else {
-    return false;
-  }
+  jbyte coder = java_string->byte_field(coder_offset);
+  assert(CompactStrings || coder == CODER_UTF16, "Must be UTF16 without CompactStrings");
+  return coder == CODER_LATIN1;
 }
 int java_lang_String::length(oop java_string) {
   assert(initialized, "Must be initialized");
--- a/hotspot/src/share/vm/classfile/modules.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/modules.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2016, 2017, 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
@@ -39,8 +39,6 @@
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/instanceKlass.hpp"
-#include "oops/objArrayKlass.hpp"
-#include "oops/objArrayOop.inline.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
@@ -48,17 +46,17 @@
 #include "utilities/stringUtils.hpp"
 #include "utilities/utf8.hpp"
 
-static bool verify_module_name(char *module_name) {
+static bool verify_module_name(const char *module_name) {
   if (module_name == NULL) return false;
   int len = (int)strlen(module_name);
   return (len > 0 && len <= Symbol::max_length());
 }
 
-bool Modules::verify_package_name(char *package_name) {
+bool Modules::verify_package_name(const char* package_name) {
   if (package_name == NULL) return false;
   int len = (int)strlen(package_name);
   return (len > 0 && len <= Symbol::max_length() &&
-    UTF8::is_legal_utf8((unsigned char *)package_name, len, false) &&
+    UTF8::is_legal_utf8((const unsigned char *)package_name, len, false) &&
     ClassFileParser::verify_unqualified_name(package_name, len,
     ClassFileParser::LegalClass));
 }
@@ -107,10 +105,8 @@
   return java_lang_reflect_Module::module_entry(module_h(), CHECK_NULL);
 }
 
-static PackageEntry* get_package_entry(ModuleEntry* module_entry, jstring package, TRAPS) {
+static PackageEntry* get_package_entry(ModuleEntry* module_entry, const char* package_name, TRAPS) {
   ResourceMark rm(THREAD);
-  if (package == NULL) return NULL;
-  const char *package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
   if (package_name == NULL) return NULL;
   TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK_NULL);
   PackageEntryTable* package_entry_table = module_entry->loader_data()->packages();
@@ -139,7 +135,8 @@
 }
 
 static void define_javabase_module(jobject module, jstring version,
-                                   jstring location, jobjectArray packages, TRAPS) {
+                                   jstring location, const char* const* packages,
+                                   jsize num_packages, TRAPS) {
   ResourceMark rm(THREAD);
 
   Handle module_handle(THREAD, JNIHandles::resolve(module));
@@ -164,21 +161,12 @@
     }
   }
 
-  objArrayOop packages_oop = objArrayOop(JNIHandles::resolve(packages));
-  objArrayHandle packages_h(THREAD, packages_oop);
-  int num_packages = (packages_h == NULL ? 0 : packages_h->length());
 
   // Check that the list of packages has no duplicates and that the
   // packages are syntactically ok.
   GrowableArray<Symbol*>* pkg_list = new GrowableArray<Symbol*>(num_packages);
   for (int x = 0; x < num_packages; x++) {
-    oop string_obj = packages_h->obj_at(x);
-
-    if (string_obj == NULL || !string_obj->is_a(SystemDictionary::String_klass())) {
-      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-                "Bad package name for module: " JAVA_BASE_NAME);
-    }
-    char *package_name = java_lang_String::as_utf8_string(string_obj);
+    const char *package_name = packages[x];
     if (!Modules::verify_package_name(package_name)) {
       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
                 err_msg("Invalid package name: %s for module: " JAVA_BASE_NAME, package_name));
@@ -239,7 +227,7 @@
     }
   }
   if (duplicate_javabase) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+    THROW_MSG(vmSymbols::java_lang_InternalError(),
               "Module " JAVA_BASE_NAME " is already defined");
   }
 
@@ -262,13 +250,39 @@
   }
 }
 
+// Caller needs ResourceMark.
+void throw_dup_pkg_exception(const char* module_name, PackageEntry* package, TRAPS) {
+  const char* package_name = package->name()->as_C_string();
+  if (package->module()->is_named()) {
+    THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
+      err_msg("Package %s for module %s is already in another module, %s, defined to the class loader",
+              package_name, module_name, package->module()->name()->as_C_string()));
+  } else {
+    THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
+      err_msg("Package %s for module %s is already in the unnamed module defined to the class loader",
+              package_name, module_name));
+  }
+}
+
 void Modules::define_module(jobject module, jstring version,
-                            jstring location, jobjectArray packages, TRAPS) {
+                            jstring location, const char* const* packages,
+                            jsize num_packages, TRAPS) {
   ResourceMark rm(THREAD);
 
   if (module == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Null module object");
   }
+
+  if (num_packages < 0) {
+    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+              "num_packages must be >= 0");
+  }
+
+  if (packages == NULL && num_packages > 0) {
+    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+              "num_packages should be zero if packages is null");
+  }
+
   Handle module_handle(THREAD, JNIHandles::resolve(module));
   if (!java_lang_reflect_Module::is_instance(module_handle())) {
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
@@ -283,7 +297,7 @@
 
   // Special handling of java.base definition
   if (strcmp(module_name, JAVA_BASE_NAME) == 0) {
-    define_javabase_module(module, version, location, packages, CHECK);
+    define_javabase_module(module, version, location, packages, num_packages, CHECK);
     return;
   }
 
@@ -297,21 +311,11 @@
   }
   Handle h_loader = Handle(THREAD, loader);
 
-  objArrayOop packages_oop = objArrayOop(JNIHandles::resolve(packages));
-  objArrayHandle packages_h(THREAD, packages_oop);
-  int num_packages = (packages_h == NULL ? 0 : packages_h->length());
-
   // Check that the list of packages has no duplicates and that the
   // packages are syntactically ok.
   GrowableArray<Symbol*>* pkg_list = new GrowableArray<Symbol*>(num_packages);
   for (int x = 0; x < num_packages; x++) {
-    oop string_obj = packages_h->obj_at(x);
-
-    if (string_obj == NULL || !string_obj->is_a(SystemDictionary::String_klass())) {
-      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-                err_msg("Bad package name for module: %s", module_name));
-    }
-    char *package_name = java_lang_String::as_utf8_string(string_obj);
+    const char* package_name = packages[x];
     if (!verify_package_name(package_name)) {
       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
                 err_msg("Invalid package name: %s for module: %s",
@@ -323,12 +327,15 @@
         !SystemDictionary::is_platform_class_loader(h_loader) &&
         strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0) {
       const char* class_loader_name = SystemDictionary::loader_name(h_loader());
-      StringUtils::replace_no_expand(package_name, "/", ".");
+      size_t pkg_len = strlen(package_name);
+      char* pkg_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, pkg_len);
+      strncpy(pkg_name, package_name, pkg_len);
+      StringUtils::replace_no_expand(pkg_name, "/", ".");
       const char* msg_text1 = "Class loader (instance of): ";
       const char* msg_text2 = " tried to define prohibited package name: ";
-      size_t len = strlen(msg_text1) + strlen(class_loader_name) + strlen(msg_text2) + strlen(package_name) + 1;
+      size_t len = strlen(msg_text1) + strlen(class_loader_name) + strlen(msg_text2) + pkg_len + 1;
       char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
-      jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, package_name);
+      jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, pkg_name);
       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message);
     }
 
@@ -347,7 +354,6 @@
   // Create symbol* entry for module name.
   TempNewSymbol module_symbol = SymbolTable::new_symbol(module_name, CHECK);
 
-  int dupl_pkg_index = -1;
   bool dupl_modules = false;
 
   // Create symbol* entry for module version.
@@ -373,6 +379,7 @@
   assert(loader_data != NULL, "class loader data shouldn't be null");
 
   PackageEntryTable* package_table = NULL;
+  PackageEntry* existing_pkg = NULL;
   {
     MutexLocker ml(Module_lock, THREAD);
 
@@ -382,13 +389,12 @@
 
       // Check that none of the packages exist in the class loader's package table.
       for (int x = 0; x < pkg_list->length(); x++) {
-        if (package_table->lookup_only(pkg_list->at(x)) != NULL) {
+        existing_pkg = package_table->lookup_only(pkg_list->at(x));
+        if (existing_pkg != NULL) {
           // This could be because the module was already defined.  If so,
           // report that error instead of the package error.
           if (module_table->lookup_only(module_symbol) != NULL) {
             dupl_modules = true;
-          } else {
-            dupl_pkg_index = x;
           }
           break;
         }
@@ -396,9 +402,8 @@
     }  // if (num_packages > 0)...
 
     // Add the module and its packages.
-    if (!dupl_modules && dupl_pkg_index == -1) {
+    if (!dupl_modules && existing_pkg == NULL) {
       // Create the entry for this module in the class loader's module entry table.
-
       ModuleEntry* module_entry = module_table->locked_create_entry_or_null(module_handle, module_symbol,
                                     version_symbol, location_symbol, loader_data);
 
@@ -426,13 +431,10 @@
 
   // any errors ?
   if (dupl_modules) {
-     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+     THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
                err_msg("Module %s is already defined", module_name));
-  }
-  if (dupl_pkg_index != -1) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-              err_msg("Package %s for module %s already exists for class loader",
-                      pkg_list->at(dupl_pkg_index)->as_C_string(), module_name));
+  } else if (existing_pkg != NULL) {
+      throw_dup_pkg_exception(module_name, existing_pkg, CHECK);
   }
 
   if (log_is_enabled(Debug, modules)) {
@@ -497,8 +499,8 @@
   java_lang_reflect_Module::set_module_entry(module_handle(), unnamed_module);
 }
 
-void Modules::add_module_exports(jobject from_module, jstring package, jobject to_module, TRAPS) {
-  if (package == NULL) {
+void Modules::add_module_exports(jobject from_module, const char* package_name, jobject to_module, TRAPS) {
+  if (package_name == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
               "package is null");
   }
@@ -526,10 +528,9 @@
     }
   }
 
-  PackageEntry *package_entry = get_package_entry(from_module_entry, package, CHECK);
+  PackageEntry *package_entry = get_package_entry(from_module_entry, package_name, CHECK);
   ResourceMark rm(THREAD);
   if (package_entry == NULL) {
-    const char *package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               err_msg("Package %s not found in from_module %s",
                       package_name != NULL ? package_name : "",
@@ -557,7 +558,7 @@
 }
 
 
-void Modules::add_module_exports_qualified(jobject from_module, jstring package,
+void Modules::add_module_exports_qualified(jobject from_module, const char* package,
                                            jobject to_module, TRAPS) {
   if (to_module == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
@@ -649,21 +650,15 @@
 }
 
 
-jobject Modules::get_module_by_package_name(jobject loader, jstring package, TRAPS) {
+jobject Modules::get_module_by_package_name(jobject loader, const char* package_name, TRAPS) {
   ResourceMark rm(THREAD);
   assert(ModuleEntryTable::javabase_defined(),
          "Attempt to call get_module_from_pkg before " JAVA_BASE_NAME " is defined");
 
-  if (NULL == package) {
+  if (package_name == NULL) {
     THROW_MSG_(vmSymbols::java_lang_NullPointerException(),
                "package is null", JNI_FALSE);
   }
-  const char* package_str =
-    java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
-  if (NULL == package_str) {
-    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
-               "Invalid package", JNI_FALSE);
-  }
 
   Handle h_loader (THREAD, JNIHandles::resolve(loader));
   // Check that loader is a subclass of java.lang.ClassLoader.
@@ -672,7 +667,7 @@
                "Class loader is not a subclass of java.lang.ClassLoader", JNI_FALSE);
   }
 
-  if (strlen(package_str) == 0) {
+  if (strlen(package_name) == 0) {
     // Return the unnamed module
     ModuleEntryTable* module_table = get_module_entry_table(h_loader, CHECK_NULL);
     if (NULL == module_table) return NULL;
@@ -680,24 +675,24 @@
     return JNIHandles::make_local(THREAD, JNIHandles::resolve(unnamed_module->module()));
 
   } else {
-    TempNewSymbol package_sym = SymbolTable::new_symbol(package_str, CHECK_NULL);
+    TempNewSymbol package_sym = SymbolTable::new_symbol(package_name, CHECK_NULL);
     return get_module(package_sym, h_loader, CHECK_NULL);
   }
   return NULL;
 }
 
 
-jobject Modules::get_named_module(Handle h_loader, const char* package_str, TRAPS) {
+jobject Modules::get_named_module(Handle h_loader, const char* package_name, TRAPS) {
   assert(ModuleEntryTable::javabase_defined(),
          "Attempt to call get_named_module before " JAVA_BASE_NAME " is defined");
   assert(h_loader.is_null() || java_lang_ClassLoader::is_subclass(h_loader->klass()),
          "Class loader is not a subclass of java.lang.ClassLoader");
-  assert(package_str != NULL, "the package_str should not be NULL");
+  assert(package_name != NULL, "the package_name should not be NULL");
 
-  if (strlen(package_str) == 0) {
+  if (strlen(package_name) == 0) {
     return NULL;
   }
-  TempNewSymbol package_sym = SymbolTable::new_symbol(package_str, CHECK_NULL);
+  TempNewSymbol package_sym = SymbolTable::new_symbol(package_name, CHECK_NULL);
   const PackageEntry* const pkg_entry =
     get_package_entry_by_name(package_sym, h_loader, THREAD);
   const ModuleEntry* const module_entry = (pkg_entry != NULL ? pkg_entry->module() : NULL);
@@ -723,14 +718,14 @@
   return NULL;
 }
 
-void Modules::add_module_package(jobject module, jstring package, TRAPS) {
+void Modules::add_module_package(jobject module, const char* package_name, TRAPS) {
   ResourceMark rm(THREAD);
 
   if (module == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
               "module is null");
   }
-  if (package == NULL) {
+  if (package_name == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
               "package is null");
   }
@@ -743,11 +738,6 @@
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "module cannot be an unnamed module");
   }
-  char *package_name = java_lang_String::as_utf8_string(
-    JNIHandles::resolve_non_null(package));
-  if (package_name == NULL) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Bad package");
-  }
   if (!verify_package_name(package_name)) {
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               err_msg("Invalid package name: %s", package_name));
@@ -760,12 +750,15 @@
       !loader_data->is_platform_class_loader_data() &&
       strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0) {
     const char* class_loader_name = SystemDictionary::loader_name(loader_data);
-    StringUtils::replace_no_expand(package_name, "/", ".");
+    size_t pkg_len = strlen(package_name);
+    char* pkg_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, pkg_len);
+    strncpy(pkg_name, package_name, pkg_len);
+    StringUtils::replace_no_expand(pkg_name, "/", ".");
     const char* msg_text1 = "Class loader (instance of): ";
     const char* msg_text2 = " tried to define prohibited package name: ";
-    size_t len = strlen(msg_text1) + strlen(class_loader_name) + strlen(msg_text2) + strlen(package_name) + 1;
+    size_t len = strlen(msg_text1) + strlen(class_loader_name) + strlen(msg_text2) + pkg_len + 1;
     char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
-    jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, package_name);
+    jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, pkg_name);
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message);
   }
 
@@ -776,31 +769,29 @@
   PackageEntryTable* package_table = loader_data->packages();
   assert(package_table != NULL, "Missing package_table");
 
-  bool pkg_exists = false;
+  PackageEntry* existing_pkg = NULL;
   {
     MutexLocker ml(Module_lock, THREAD);
 
     // Check that the package does not exist in the class loader's package table.
-    if (!package_table->lookup_only(pkg_symbol)) {
+    existing_pkg = package_table->lookup_only(pkg_symbol);
+    if (existing_pkg == NULL) {
       PackageEntry* pkg = package_table->locked_create_entry_or_null(pkg_symbol, module_entry);
       assert(pkg != NULL, "Unable to create a module's package entry");
-    } else {
-      pkg_exists = true;
     }
   }
-  if (pkg_exists) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-              err_msg("Package %s already exists for class loader", package_name));
+  if (existing_pkg != NULL) {
+    throw_dup_pkg_exception(module_entry->name()->as_C_string(), existing_pkg, CHECK);
   }
 }
 
 // Export package in module to all unnamed modules.
-void Modules::add_module_exports_to_all_unnamed(jobject module, jstring package, TRAPS) {
+void Modules::add_module_exports_to_all_unnamed(jobject module, const char* package_name, TRAPS) {
   if (module == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
               "module is null");
   }
-  if (package == NULL) {
+  if (package_name == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
               "package is null");
   }
@@ -811,10 +802,9 @@
   }
 
   if (module_entry->is_named()) { // No-op for unnamed module.
-    PackageEntry *package_entry = get_package_entry(module_entry, package, CHECK);
+    PackageEntry *package_entry = get_package_entry(module_entry, package_name, CHECK);
     ResourceMark rm(THREAD);
     if (package_entry == NULL) {
-      const char *package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
                 err_msg("Package %s not found in module %s",
                         package_name != NULL ? package_name : "",
@@ -833,10 +823,7 @@
                        package_entry->name()->as_C_string(),
                        module_entry->name()->as_C_string());
 
-    // Mark package as exported to all unnamed modules, unless already
-    // unqualifiedly exported.
-    if (!package_entry->is_unqual_exported()) {
-      package_entry->set_is_exported_allUnnamed();
-    }
+    // Mark package as exported to all unnamed modules.
+    package_entry->set_is_exported_allUnnamed();
   }
 }
--- a/hotspot/src/share/vm/classfile/modules.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/modules.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -48,9 +48,12 @@
   // * Packages contains a duplicate package name
   // * A package already exists in another module for this class loader
   // * Module is an unnamed module
+  // * num_packages is negative
+  // * num_packages is non-zero when packages is null
   //  NullPointerExceptions are thrown if module is null.
   static void define_module(jobject module, jstring version,
-                            jstring location, jobjectArray packages, TRAPS);
+                            jstring location, const char* const* packages,
+                            jsize num_packages, TRAPS);
 
   // Provides the java.lang.reflect.Module for the unnamed module defined
   // to the boot loader.
@@ -72,7 +75,7 @@
   // * Package is not syntactically correct
   // * Package is not defined for from_module's class loader
   // * Package is not in module from_module.
-  static void add_module_exports(jobject from_module, jstring package, jobject to_module, TRAPS);
+  static void add_module_exports(jobject from_module, const char* package, jobject to_module, TRAPS);
 
   // This does a qualified export of package in module from_module to module
   // to_module.  The format for the package name must use "/' not ".".
@@ -83,7 +86,7 @@
   // * Package is not syntactically correct
   // * Package is not defined for from_module's class loader
   // * Package is not in module from_module.
-  static void add_module_exports_qualified(jobject from_module, jstring package, jobject to_module, TRAPS);
+  static void add_module_exports_qualified(jobject from_module, const char* package, jobject to_module, TRAPS);
 
   // add_reads_module adds module to_module to the list of modules that from_module
   // can read.  If from_module is the same as to_module then this is a no-op.
@@ -102,7 +105,7 @@
   // NullPointerException is thrown if package is null.
   // IllegalArgumentException is thrown if loader is neither null nor a subtype of
   // java/lang/ClassLoader.
-  static jobject get_module_by_package_name(jobject loader, jstring package, TRAPS);
+  static jobject get_module_by_package_name(jobject loader, const char* package, TRAPS);
   static jobject get_named_module(Handle h_loader, const char* package, TRAPS);
 
   // If package is defined by loader, return the
@@ -116,16 +119,16 @@
   // * Module is unnamed
   // * Package is not syntactically correct
   // * Package is already defined for module's class loader.
-  static void add_module_package(jobject module, jstring package, TRAPS);
+  static void add_module_package(jobject module, const char* package, TRAPS);
 
   // Marks the specified package as exported to all unnamed modules.
   // If either module or package is null then NullPointerException is thrown.
   // If module or package is bad, or module is unnamed, or package is not in
   // module then IllegalArgumentException is thrown.
-  static void add_module_exports_to_all_unnamed(jobject module, jstring package, TRAPS);
+  static void add_module_exports_to_all_unnamed(jobject module, const char* package, TRAPS);
 
   // Return TRUE if package_name is syntactically valid, false otherwise.
-  static bool verify_package_name(char *package_name);
+  static bool verify_package_name(const char *package_name);
 
   // Return TRUE iff package is defined by loader
   static bool is_package_defined(Symbol* package_name, Handle h_loader, TRAPS);
--- a/hotspot/src/share/vm/classfile/packageEntry.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/packageEntry.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -37,8 +37,8 @@
 
 // Returns true if this package specifies m as a qualified export, including through an unnamed export
 bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
+  assert(Module_lock->owned_by_self(), "should have the Module_lock");
   assert(m != NULL, "No module to lookup in this package's qualified exports list");
-  MutexLocker m1(Module_lock);
   if (is_exported_allUnnamed() && !m->is_named()) {
     return true;
   } else if (!has_qual_exports_list()) {
@@ -98,15 +98,8 @@
   }
 
   if (m == NULL) {
-    // NULL indicates the package is being unqualifiedly exported
-    if (has_qual_exports_list()) {
-      // Legit to transition a package from being qualifiedly exported
-      // to unqualified.  Clean up the qualified lists at the next
-      // safepoint.
-      _exported_pending_delete = _qualified_exports;
-    }
-
-    // Mark package as unqualifiedly exported
+    // NULL indicates the package is being unqualifiedly exported.  Clean up
+    // the qualified list at the next safepoint.
     set_unqual_exported();
 
   } else {
@@ -115,14 +108,19 @@
   }
 }
 
+// Set the package as exported to all unnamed modules unless the package is
+// already unqualifiedly exported.
 void PackageEntry::set_is_exported_allUnnamed() {
   MutexLocker m1(Module_lock);
   if (!is_unqual_exported()) {
-   _is_exported_allUnnamed = true;
+   _export_flags = PKG_EXP_ALLUNNAMED;
   }
 }
 
-// Remove dead module entries within the package's exported list.
+// Remove dead module entries within the package's exported list.  Note that
+// if all of the modules on the _qualified_exports get purged the list does not
+// get deleted.  This prevents the package from illegally transitioning from
+// exported to non-exported.
 void PackageEntry::purge_qualified_exports() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   if (_must_walk_exports &&
@@ -160,18 +158,9 @@
 
 void PackageEntry::delete_qualified_exports() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
-  if (_exported_pending_delete != NULL) {
-    // If a transition occurred from qualified to unqualified, the _qualified_exports
-    // field should have been NULL'ed out.
-    assert(_qualified_exports == NULL, "Package's exported pending delete, exported list should not be active");
-    delete _exported_pending_delete;
-  }
-
   if (_qualified_exports != NULL) {
     delete _qualified_exports;
   }
-
-  _exported_pending_delete = NULL;
   _qualified_exports = NULL;
 }
 
@@ -314,6 +303,11 @@
   }
 }
 
+bool PackageEntry::exported_pending_delete() const {
+  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+  return (is_unqual_exported() && _qualified_exports != NULL);
+}
+
 // Remove dead entries from all packages' exported list
 void PackageEntryTable::purge_all_package_exports() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
@@ -344,13 +338,17 @@
   }
 }
 
+// This function may be called from debuggers so access private fields directly
+// to prevent triggering locking-related asserts that could result from calling
+// getter methods.
 void PackageEntry::print(outputStream* st) {
   ResourceMark rm;
   st->print_cr("package entry " PTR_FORMAT " name %s module %s classpath_index "
                INT32_FORMAT " is_exported_unqualified %d is_exported_allUnnamed %d " "next " PTR_FORMAT,
                p2i(this), name()->as_C_string(),
                (module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
-               _classpath_index, _is_exported_unqualified, _is_exported_allUnnamed, p2i(next()));
+               _classpath_index, _export_flags == PKG_EXP_UNQUALIFIED,
+               _export_flags == PKG_EXP_ALLUNNAMED, p2i(next()));
 }
 
 void PackageEntryTable::verify() {
--- a/hotspot/src/share/vm/classfile/packageEntry.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/packageEntry.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -34,8 +34,8 @@
 // A PackageEntry basically represents a Java package.  It contains:
 //   - Symbol* containing the package's name.
 //   - ModuleEntry* for this package's containing module.
-//   - a flag indicating if package is exported unqualifiedly
-//   - a flag indicating if this package is exported to all unnamed modules.
+//   - a field indicating if the package is exported unqualifiedly or to all
+//     unnamed modules.
 //   - a growable array containing other module entries that this
 //     package is exported to.
 //
@@ -44,9 +44,9 @@
 //   - qualified exports:   the package has been explicitly qualified to at least
 //                            one particular module or has been qualifiedly exported
 //                            to all unnamed modules.
-//                            Note: _is_exported_allUnnamed is a form of a qualified
-//                            export. It is equivalent to the package being
-//                            explicitly exported to all current and future unnamed modules.
+//                            Note: being exported to all unnamed is a form of a qualified
+//                            export. It is equivalent to the package being explicitly
+//                            exported to all current and future unnamed modules.
 //   - unqualified exports: the package is exported to all modules.
 //
 // A package can transition from:
@@ -56,21 +56,53 @@
 // A package cannot transition from:
 //   - being unqualifiedly exported, to exported qualifiedly to a specific module.
 //       This transition attempt is silently ignored in set_exported.
+//   - being qualifiedly exported to not exported.
+//       Because transitions are only allowed from less exposure to greater exposure,
+//       the transition from qualifiedly exported to not exported would be considered
+//       a backward direction.  Therefore the implementation considers a package as
+//       qualifiedly exported even if its export-list exists but is empty.
 //
 // The Mutex Module_lock is shared between ModuleEntry and PackageEntry, to lock either
 // data structure.
+
+// PKG_EXP_UNQUALIFIED and PKG_EXP_ALLUNNAMED indicate whether the package is
+// exported unqualifiedly or exported to all unnamed modules.  They are used to
+// set the value of _export_flags.  Field _export_flags and the _qualified_exports
+// list are used to determine a package's export state.
+// Valid states are:
+//
+//   1. Package is not exported
+//      _export_flags is zero and _qualified_exports is null
+//   2. Package is unqualifiedly exported
+//      _export_flags is set to PKG_EXP_UNQUALIFIED
+//      _qualified_exports may or may not be null depending on whether the package
+//        transitioned from qualifiedly exported to unqualifiedly exported.
+//   3. Package is qualifiedly exported
+//      _export_flags may be set to PKG_EXP_ALLUNNAMED if the package is also
+//        exported to all unnamed modules
+//      _qualified_exports will be non-null
+//   4. Package is exported to all unnamed modules
+//      _export_flags is set to PKG_EXP_ALLUNNAMED
+//      _qualified_exports may or may not be null depending on whether the package
+//        is also qualifiedly exported to one or more named modules.
+#define PKG_EXP_UNQUALIFIED  0x0001
+#define PKG_EXP_ALLUNNAMED   0x0002
+#define PKG_EXP_UNQUALIFIED_OR_ALL_UNAMED (PKG_EXP_UNQUALIFIED | PKG_EXP_ALLUNNAMED)
+
 class PackageEntry : public HashtableEntry<Symbol*, mtModule> {
 private:
   ModuleEntry* _module;
+  // Indicates if package is exported unqualifiedly or to all unnamed. Access to
+  // this field is protected by the Module_lock.
+  int _export_flags;
   // Used to indicate for packages with classes loaded by the boot loader that
   // a class in that package has been loaded.  And, for packages with classes
   // loaded by the boot loader from -Xbootclasspath/a in an unnamed module, it
   // indicates from which class path entry.
   s2 _classpath_index;
-  bool _is_exported_unqualified;
-  bool _is_exported_allUnnamed;
   bool _must_walk_exports;
-  GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint
+  // Contains list of modules this package is qualifiedly exported to.  Access
+  // to this list is protected by the Module_lock.
   GrowableArray<ModuleEntry*>* _qualified_exports;
   TRACE_DEFINE_TRACE_ID_FIELD;
 
@@ -80,17 +112,14 @@
 public:
   void init() {
     _module = NULL;
+    _export_flags = 0;
     _classpath_index = -1;
-    _is_exported_unqualified = false;
-    _is_exported_allUnnamed = false;
     _must_walk_exports = false;
-    _exported_pending_delete = NULL;
     _qualified_exports = NULL;
   }
 
   // package name
   Symbol*            name() const               { return literal(); }
-  void               set_name(Symbol* n)        { set_literal(n); }
 
   // the module containing the package definition
   ModuleEntry*       module() const             { return _module; }
@@ -98,37 +127,39 @@
 
   // package's export state
   bool is_exported() const { // qualifiedly or unqualifiedly exported
-      return (is_unqual_exported() || has_qual_exports_list() || is_exported_allUnnamed());
+    assert_locked_or_safepoint(Module_lock);
+    return ((_export_flags & PKG_EXP_UNQUALIFIED_OR_ALL_UNAMED) != 0) || has_qual_exports_list();
   }
   // Returns true if the package has any explicit qualified exports or is exported to all unnamed
   bool is_qual_exported() const {
+    assert_locked_or_safepoint(Module_lock);
     return (has_qual_exports_list() || is_exported_allUnnamed());
   }
-  // Returns true if there are any explicit qualified exports
+  // Returns true if there are any explicit qualified exports.  Note that even
+  // if the _qualified_exports list is now empty (because the modules that were
+  // on the list got gc-ed and deleted from the list) this method may still
+  // return true.
   bool has_qual_exports_list() const {
-    assert(!(_qualified_exports != NULL && _is_exported_unqualified),
-           "_qualified_exports set at same time as _is_exported_unqualified");
-    return (_qualified_exports != NULL);
+    assert_locked_or_safepoint(Module_lock);
+    return (!is_unqual_exported() && _qualified_exports != NULL);
   }
   bool is_exported_allUnnamed() const {
-    assert(!(_is_exported_allUnnamed && _is_exported_unqualified),
-           "_is_exported_allUnnamed set at same time as _is_exported_unqualified");
-    return _is_exported_allUnnamed;
+    assert_locked_or_safepoint(Module_lock);
+    return (_export_flags == PKG_EXP_ALLUNNAMED);
   }
   bool is_unqual_exported() const {
-    assert(!(_qualified_exports != NULL && _is_exported_unqualified),
-           "_qualified_exports set at same time as _is_exported_unqualified");
-    assert(!(_is_exported_allUnnamed && _is_exported_unqualified),
-           "_is_exported_allUnnamed set at same time as _is_exported_unqualified");
-    return _is_exported_unqualified;
+    assert_locked_or_safepoint(Module_lock);
+    return (_export_flags == PKG_EXP_UNQUALIFIED);
   }
+
+  // Explicitly set _export_flags to PKG_EXP_UNQUALIFIED and clear
+  // PKG_EXP_ALLUNNAMED, if it was set.
   void set_unqual_exported() {
     assert(Module_lock->owned_by_self(), "should have the Module_lock");
-    _is_exported_unqualified = true;
-    _is_exported_allUnnamed = false;
-    _qualified_exports = NULL;
+    _export_flags = PKG_EXP_UNQUALIFIED;
   }
-  bool exported_pending_delete() const     { return (_exported_pending_delete != NULL); }
+
+  bool exported_pending_delete() const;
 
   void set_exported(ModuleEntry* m);
 
--- a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -29,7 +29,6 @@
 #include "classfile/dictionary.hpp"
 
 class ClassFileStream;
-class SerializeClosure;
 
 class SystemDictionaryShared: public SystemDictionary {
 public:
@@ -79,8 +78,6 @@
     return NULL;
   }
 
-  static void serialize(SerializeClosure* soc) {}
-
   // The (non-application) CDS implementation supports only classes in the boot
   // class loader, which ensures that the verification constraints are the same
   // during archive creation time and runtime. Thus we can do the constraint checks
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -590,11 +590,11 @@
   template(java_lang_management_ThreadState,           "java/lang/management/ThreadState")                        \
   template(java_lang_management_MemoryUsage,           "java/lang/management/MemoryUsage")                        \
   template(java_lang_management_ThreadInfo,            "java/lang/management/ThreadInfo")                         \
+  template(jdk_internal_agent_Agent,                   "jdk/internal/agent/Agent")                                \
   template(sun_management_Sensor,                      "sun/management/Sensor")                                   \
-  template(sun_management_Agent,                       "sun/management/Agent")                                    \
+  template(sun_management_ManagementFactoryHelper,     "sun/management/ManagementFactoryHelper")                  \
   template(com_sun_management_internal_DiagnosticCommandImpl,  "com/sun/management/internal/DiagnosticCommandImpl")     \
   template(com_sun_management_internal_GarbageCollectorExtImpl,"com/sun/management/internal/GarbageCollectorExtImpl")   \
-  template(sun_management_ManagementFactoryHelper,     "sun/management/ManagementFactoryHelper")                  \
   template(getDiagnosticCommandMBean_name,             "getDiagnosticCommandMBean")                               \
   template(getDiagnosticCommandMBean_signature,        "()Lcom/sun/management/DiagnosticCommandMBean;")           \
   template(getGcInfoBuilder_name,                      "getGcInfoBuilder")                                        \
--- a/hotspot/src/share/vm/code/codeCache.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -149,16 +149,17 @@
   size_t total_size = non_nmethod_size + profiled_size + non_profiled_size;
   // Prepare error message
   const char* error = "Invalid code heap sizes";
-  err_msg message("NonNMethodCodeHeapSize (%zuK) + ProfiledCodeHeapSize (%zuK) + NonProfiledCodeHeapSize (%zuK) = %zuK",
+  err_msg message("NonNMethodCodeHeapSize (" SIZE_FORMAT "K) + ProfiledCodeHeapSize (" SIZE_FORMAT "K)"
+                  " + NonProfiledCodeHeapSize (" SIZE_FORMAT "K) = " SIZE_FORMAT "K",
           non_nmethod_size/K, profiled_size/K, non_profiled_size/K, total_size/K);
 
   if (total_size > cache_size) {
     // Some code heap sizes were explicitly set: total_size must be <= cache_size
-    message.append(" is greater than ReservedCodeCacheSize (%zuK).", cache_size/K);
+    message.append(" is greater than ReservedCodeCacheSize (" SIZE_FORMAT "K).", cache_size/K);
     vm_exit_during_initialization(error, message);
   } else if (all_set && total_size != cache_size) {
     // All code heap sizes were explicitly set: total_size must equal cache_size
-    message.append(" is not equal to ReservedCodeCacheSize (%zuK).", cache_size/K);
+    message.append(" is not equal to ReservedCodeCacheSize (" SIZE_FORMAT "K).", cache_size/K);
     vm_exit_during_initialization(error, message);
   }
 }
@@ -267,7 +268,7 @@
   uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3);
   if (non_nmethod_size < (min_code_cache_size + code_buffers_size)) {
     vm_exit_during_initialization(err_msg(
-        "Not enough space in non-nmethod code heap to run VM: %zuK < %zuK",
+        "Not enough space in non-nmethod code heap to run VM: " SIZE_FORMAT "K < " SIZE_FORMAT "K",
         non_nmethod_size/K, (min_code_cache_size + code_buffers_size)/K));
   }
 
--- a/hotspot/src/share/vm/code/compiledMethod.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/code/compiledMethod.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -250,7 +250,11 @@
 
   address insts_begin() const { return code_begin(); }
   address insts_end() const { return stub_begin(); }
+  // Returns true if a given address is in the 'insts' section. The method
+  // insts_contains_inclusive() is end-inclusive.
   bool insts_contains(address addr) const { return insts_begin() <= addr && addr < insts_end(); }
+  bool insts_contains_inclusive(address addr) const { return insts_begin() <= addr && addr <= insts_end(); }
+
   int insts_size() const { return insts_end() - insts_begin(); }
 
   virtual address consts_begin() const = 0;
--- a/hotspot/src/share/vm/compiler/compilerDefinitions.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/compiler/compilerDefinitions.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -23,6 +23,8 @@
  */
 
 #include "precompiled.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "compiler/compilerDefinitions.hpp"
 
 const char* compilertype2name_tab[compiler_number_of_types] = {
@@ -32,3 +34,82 @@
   "jvmci",
   "shark"
 };
+
+#if defined(COMPILER2) || defined(SHARK)
+CompLevel  CompLevel_highest_tier      = CompLevel_full_optimization;  // pure C2 and tiered or JVMCI and tiered
+#elif defined(COMPILER1)
+CompLevel  CompLevel_highest_tier      = CompLevel_simple;             // pure C1 or JVMCI
+#else
+CompLevel  CompLevel_highest_tier      = CompLevel_none;
+#endif
+
+#if defined(TIERED)
+CompLevel  CompLevel_initial_compile   = CompLevel_full_profile;        // tiered
+#elif defined(COMPILER1) || INCLUDE_JVMCI
+CompLevel  CompLevel_initial_compile   = CompLevel_simple;              // pure C1 or JVMCI
+#elif defined(COMPILER2) || defined(SHARK)
+CompLevel  CompLevel_initial_compile   = CompLevel_full_optimization;   // pure C2
+#else
+CompLevel  CompLevel_initial_compile   = CompLevel_none;
+#endif
+
+#if defined(COMPILER2)
+CompMode  Compilation_mode             = CompMode_server;
+#elif defined(COMPILER1)
+CompMode  Compilation_mode             = CompMode_client;
+#else
+CompMode  Compilation_mode             = CompMode_none;
+#endif
+
+#ifdef TIERED
+void set_client_compilation_mode() {
+  Compilation_mode = CompMode_client;
+  CompLevel_highest_tier = CompLevel_simple;
+  CompLevel_initial_compile = CompLevel_simple;
+  FLAG_SET_ERGO(bool, TieredCompilation, false);
+  FLAG_SET_ERGO(bool, ProfileInterpreter, false);
+#if INCLUDE_JVMCI
+  FLAG_SET_ERGO(bool, EnableJVMCI, false);
+  FLAG_SET_ERGO(bool, UseJVMCICompiler, false);
+#endif
+#if INCLUDE_AOT
+  FLAG_SET_ERGO(bool, UseAOT, false);
+#endif
+  if (FLAG_IS_DEFAULT(NeverActAsServerClassMachine)) {
+    FLAG_SET_ERGO(bool, NeverActAsServerClassMachine, true);
+  }
+  if (FLAG_IS_DEFAULT(InitialCodeCacheSize)) {
+    FLAG_SET_ERGO(uintx, InitialCodeCacheSize, 160*K);
+  }
+  if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
+    FLAG_SET_ERGO(uintx, ReservedCodeCacheSize, 32*M);
+  }
+  if (FLAG_IS_DEFAULT(NonProfiledCodeHeapSize)) {
+    FLAG_SET_ERGO(uintx, NonProfiledCodeHeapSize, 27*M);
+  }
+  if (FLAG_IS_DEFAULT(ProfiledCodeHeapSize)) {
+    FLAG_SET_ERGO(uintx, ProfiledCodeHeapSize, 0);
+  }
+  if (FLAG_IS_DEFAULT(NonNMethodCodeHeapSize)) {
+    FLAG_SET_ERGO(uintx, NonNMethodCodeHeapSize, 5*M);
+  }
+  if (FLAG_IS_DEFAULT(CodeCacheExpansionSize)) {
+    FLAG_SET_ERGO(uintx, CodeCacheExpansionSize, 32*K);
+  }
+  if (FLAG_IS_DEFAULT(MetaspaceSize)) {
+    FLAG_SET_ERGO(size_t, MetaspaceSize, 12*M);
+  }
+  if (FLAG_IS_DEFAULT(MaxRAM)) {
+    FLAG_SET_ERGO(uint64_t, MaxRAM, 1ULL*G);
+  }
+  if (FLAG_IS_DEFAULT(CompileThreshold)) {
+    FLAG_SET_ERGO(intx, CompileThreshold, 1500);
+  }
+  if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) {
+    FLAG_SET_ERGO(intx, OnStackReplacePercentage, 933);
+  }
+  if (FLAG_IS_DEFAULT(CICompilerCount)) {
+    FLAG_SET_ERGO(intx, CICompilerCount, 1);
+  }
+}
+#endif // TIERED
--- a/hotspot/src/share/vm/compiler/compilerDefinitions.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/compiler/compilerDefinitions.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -54,26 +54,29 @@
   CompLevel_simple            = 1,         // C1
   CompLevel_limited_profile   = 2,         // C1, invocation & backedge counters
   CompLevel_full_profile      = 3,         // C1, invocation & backedge counters + mdo
-  CompLevel_full_optimization = 4,         // C2, Shark or JVMCI
+  CompLevel_full_optimization = 4          // C2, Shark or JVMCI
+};
+
+extern CompLevel CompLevel_highest_tier;
+extern CompLevel CompLevel_initial_compile;
 
-#if defined(COMPILER2) || defined(SHARK)
-  CompLevel_highest_tier      = CompLevel_full_optimization,  // pure C2 and tiered or JVMCI and tiered
-#elif defined(COMPILER1)
-  CompLevel_highest_tier      = CompLevel_simple,             // pure C1 or JVMCI
-#else
-  CompLevel_highest_tier      = CompLevel_none,
-#endif
+enum CompMode {
+  CompMode_none = 0,
+  CompMode_client = 1,
+  CompMode_server = 2
+};
 
-#if defined(TIERED)
-  CompLevel_initial_compile   = CompLevel_full_profile        // tiered
-#elif defined(COMPILER1) || INCLUDE_JVMCI
-  CompLevel_initial_compile   = CompLevel_simple              // pure C1 or JVMCI
-#elif defined(COMPILER2) || defined(SHARK)
-  CompLevel_initial_compile   = CompLevel_full_optimization   // pure C2
-#else
-  CompLevel_initial_compile   = CompLevel_none
-#endif
-};
+extern CompMode Compilation_mode;
+
+inline bool is_server_compilation_mode_vm() {
+  return Compilation_mode == CompMode_server;
+}
+
+inline bool is_client_compilation_mode_vm() {
+  return Compilation_mode == CompMode_client;
+}
+
+extern void set_client_compilation_mode();
 
 inline bool is_c1_compile(int comp_level) {
   return comp_level > CompLevel_none && comp_level < CompLevel_full_optimization;
--- a/hotspot/src/share/vm/compiler/compilerDirectives.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/compiler/compilerDirectives.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -445,7 +445,9 @@
   _default_directives->_c1_store->EnableOption = true;
 #endif
 #ifdef COMPILER2
-  _default_directives->_c2_store->EnableOption = true;
+  if (is_server_compilation_mode_vm()) {
+    _default_directives->_c2_store->EnableOption = true;
+  }
 #endif
   assert(error_msg == NULL, "Must succeed.");
   push(_default_directives);
--- a/hotspot/src/share/vm/compiler/compilerDirectives.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/compiler/compilerDirectives.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -60,13 +60,12 @@
     cflags(BlockLayoutByFrequency,  bool, BlockLayoutByFrequency,  BlockLayoutByFrequency) \
     cflags(PrintOptoAssembly,       bool, PrintOptoAssembly, PrintOptoAssembly) \
     cflags(PrintIntrinsics,         bool, PrintIntrinsics, PrintIntrinsics) \
-    cflags(TraceOptoPipelining,     bool, false, TraceOptoPipelining) \
-    cflags(TraceOptoOutput,         bool, false, TraceOptoOutput) \
+NOT_PRODUCT(cflags(TraceOptoPipelining, bool, TraceOptoPipelining, TraceOptoPipelining)) \
+NOT_PRODUCT(cflags(TraceOptoOutput,     bool, TraceOptoOutput, TraceOptoOutput)) \
     cflags(TraceSpilling,           bool, TraceSpilling, TraceSpilling) \
     cflags(Vectorize,               bool, false, Vectorize) \
     cflags(VectorizeDebug,         uintx, 0, VectorizeDebug) \
     cflags(CloneMapDebug,           bool, false, CloneMapDebug) \
-    cflags(DoReserveCopyInSuperWordDebug, bool, false, DoReserveCopyInSuperWordDebug) \
     cflags(IGVPrintLevel,           intx, PrintIdealGraphLevel, IGVPrintLevel) \
     cflags(MaxNodeLimit,            intx, MaxNodeLimit, MaxNodeLimit)
 #else
--- a/hotspot/src/share/vm/gc/g1/g1BiasedArray.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/gc/g1/g1BiasedArray.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -69,12 +69,12 @@
   void initialize(HeapWord* bottom, HeapWord* end, size_t target_elem_size_in_bytes, size_t mapping_granularity_in_bytes) {
     assert(mapping_granularity_in_bytes > 0, "just checking");
     assert(is_power_of_2(mapping_granularity_in_bytes),
-           "mapping granularity must be power of 2, is %zd", mapping_granularity_in_bytes);
+           "mapping granularity must be power of 2, is " SIZE_FORMAT, mapping_granularity_in_bytes);
     assert((uintptr_t)bottom % mapping_granularity_in_bytes == 0,
-           "bottom mapping area address must be a multiple of mapping granularity %zd, is  " PTR_FORMAT,
+           "bottom mapping area address must be a multiple of mapping granularity " SIZE_FORMAT ", is  " PTR_FORMAT,
            mapping_granularity_in_bytes, p2i(bottom));
     assert((uintptr_t)end % mapping_granularity_in_bytes == 0,
-           "end mapping area address must be a multiple of mapping granularity %zd, is " PTR_FORMAT,
+           "end mapping area address must be a multiple of mapping granularity " SIZE_FORMAT ", is " PTR_FORMAT,
            mapping_granularity_in_bytes, p2i(end));
     size_t num_target_elems = pointer_delta(end, bottom, mapping_granularity_in_bytes);
     idx_t bias = (uintptr_t)bottom / mapping_granularity_in_bytes;
--- a/hotspot/src/share/vm/gc/shared/collectedHeap.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/gc/shared/collectedHeap.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -233,7 +233,7 @@
   // Used for ReduceInitialCardMarks (when COMPILER2 is used);
   // otherwise remains unused.
 #if defined(COMPILER2) || INCLUDE_JVMCI
-  _defer_initial_card_mark =    ReduceInitialCardMarks && can_elide_tlab_store_barriers()
+  _defer_initial_card_mark = is_server_compilation_mode_vm() &&  ReduceInitialCardMarks && can_elide_tlab_store_barriers()
                              && (DeferInitialCardMark || card_mark_must_follow_store());
 #else
   assert(_defer_initial_card_mark == false, "Who would set it?");
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1209,7 +1209,7 @@
 #if defined(COMPILER2) || INCLUDE_JVMCI
   assert(DerivedPointerTable::is_empty(), "derived pointer present");
   size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr()));
-  guarantee(actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
+  guarantee(is_client_compilation_mode_vm() || actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
 #endif /* COMPILER2 || INCLUDE_JVMCI */
 
   resize_all_tlabs();
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -57,11 +57,11 @@
   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
 
   _always_clear_soft_ref_policy = new AlwaysClearPolicy();
-#if defined(COMPILER2) || INCLUDE_JVMCI
-  _default_soft_ref_policy      = new LRUMaxHeapPolicy();
-#else
-  _default_soft_ref_policy      = new LRUCurrentHeapPolicy();
-#endif
+  if (is_server_compilation_mode_vm()) {
+    _default_soft_ref_policy = new LRUMaxHeapPolicy();
+  } else {
+    _default_soft_ref_policy = new LRUCurrentHeapPolicy();
+  }
   if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
     vm_exit_during_initialization("Could not allocate reference policy object");
   }
--- a/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/gc/shared/threadLocalAllocBuffer.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -233,9 +233,11 @@
   // If the C2 compiler is not present, no space is reserved.
 
   // +1 for rounding up to next cache line, +1 to be safe
-  int lines =  MAX2(AllocatePrefetchLines, AllocateInstancePrefetchLines) + 2;
-  _reserve_for_allocation_prefetch = (AllocatePrefetchDistance + AllocatePrefetchStepSize * lines) /
-                                     (int)HeapWordSize;
+  if (is_server_compilation_mode_vm()) {
+    int lines =  MAX2(AllocatePrefetchLines, AllocateInstancePrefetchLines) + 2;
+    _reserve_for_allocation_prefetch = (AllocatePrefetchDistance + AllocatePrefetchStepSize * lines) /
+                                       (int)HeapWordSize;
+  }
 #endif
 
   // During jvm startup, the main (primordial) thread is initialized
--- a/hotspot/src/share/vm/interpreter/bytecode.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/interpreter/bytecode.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -112,7 +112,7 @@
 // Implementation of Bytecode_tableupswitch
 
 int Bytecode_tableswitch::dest_offset_at(int i) const {
-  return get_Java_u4_at(aligned_offset(1 + (3 + i)*jintSize));
+  return get_aligned_Java_u4_at(1 + (3 + i)*jintSize);
 }
 
 
--- a/hotspot/src/share/vm/interpreter/bytecode.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/interpreter/bytecode.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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,11 +45,11 @@
   address addr_at            (int offset)        const     { return (address)_bcp + offset; }
   u_char byte_at(int offset) const               { return *addr_at(offset); }
   address aligned_addr_at    (int offset)        const     { return (address)round_to((intptr_t)addr_at(offset), jintSize); }
-  int     aligned_offset     (int offset)        const     { return aligned_addr_at(offset) - addr_at(0); }
 
   // Word access:
   int     get_Java_u2_at     (int offset)        const     { return Bytes::get_Java_u2(addr_at(offset)); }
   int     get_Java_u4_at     (int offset)        const     { return Bytes::get_Java_u4(addr_at(offset)); }
+  int     get_aligned_Java_u4_at(int offset)     const     { return Bytes::get_Java_u4(aligned_addr_at(offset)); }
   int     get_native_u2_at   (int offset)        const     { return Bytes::get_native_u2(addr_at(offset)); }
   int     get_native_u4_at   (int offset)        const     { return Bytes::get_native_u4(addr_at(offset)); }
 
@@ -150,8 +150,8 @@
   void verify() const PRODUCT_RETURN;
 
   // Attributes
-  int  default_offset() const                    { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
-  int  number_of_pairs() const                   { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
+  int  default_offset() const                    { return get_aligned_Java_u4_at(1 + 0*jintSize); }
+  int  number_of_pairs() const                   { return get_aligned_Java_u4_at(1 + 1*jintSize); }
   LookupswitchPair pair_at(int i) const          {
     assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
     return LookupswitchPair(aligned_addr_at(1 + (1 + i)*2*jintSize));
@@ -166,9 +166,9 @@
   void verify() const PRODUCT_RETURN;
 
   // Attributes
-  int  default_offset() const                    { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
-  int  low_key() const                           { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
-  int  high_key() const                          { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); }
+  int  default_offset() const                    { return get_aligned_Java_u4_at(1 + 0*jintSize); }
+  int  low_key() const                           { return get_aligned_Java_u4_at(1 + 1*jintSize); }
+  int  high_key() const                          { return get_aligned_Java_u4_at(1 + 2*jintSize); }
   int  dest_offset_at(int i) const;
   int  length()                                  { return high_key()-low_key()+1; }
 };
--- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -554,7 +554,7 @@
   _constants = buffer.consts();
 
   initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK);
-  JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, CHECK_OK);
+  JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, false, CHECK_OK);
   if (result != JVMCIEnv::ok) {
     return result;
   }
@@ -587,7 +587,7 @@
   _constants = buffer.consts();
 
   initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK);
-  JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, CHECK_OK);
+  JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, true, CHECK_OK);
   if (result != JVMCIEnv::ok) {
     return result;
   }
@@ -726,7 +726,7 @@
 }
 
 // perform data and call relocation on the CodeBuffer
-JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, TRAPS) {
+JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, bool check_size, TRAPS) {
   HandleMark hm;
   objArrayHandle sites = this->sites();
   int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo));
@@ -738,7 +738,7 @@
   int stubs_size = estimate_stubs_size(CHECK_OK);
   int total_size = round_to(_code_size, buffer.insts()->alignment()) + round_to(_constants_size, buffer.consts()->alignment()) + round_to(stubs_size, buffer.stubs()->alignment());
 
-  if (total_size > JVMCINMethodSizeLimit) {
+  if (check_size && total_size > JVMCINMethodSizeLimit) {
     return JVMCIEnv::code_too_large;
   }
 
@@ -1258,6 +1258,7 @@
       case HEAP_TOP_ADDRESS:
       case HEAP_END_ADDRESS:
       case NARROW_KLASS_BASE_ADDRESS:
+      case NARROW_OOP_BASE_ADDRESS:
       case CRC_TABLE_ADDRESS:
       case LOG_OF_HEAP_REGION_GRAIN_BYTES:
       case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:
--- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -133,9 +133,10 @@
     HEAP_TOP_ADDRESS                       = 17,
     HEAP_END_ADDRESS                       = 18,
     NARROW_KLASS_BASE_ADDRESS              = 19,
-    CRC_TABLE_ADDRESS                      = 20,
-    LOG_OF_HEAP_REGION_GRAIN_BYTES         = 21,
-    INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED = 22,
+    NARROW_OOP_BASE_ADDRESS                = 20,
+    CRC_TABLE_ADDRESS                      = 21,
+    LOG_OF_HEAP_REGION_GRAIN_BYTES         = 22,
+    INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED = 23,
     INVOKE_INVALID                         = -1
   };
 
@@ -227,7 +228,7 @@
   int estimate_stubs_size(TRAPS);
 
   // perform data and call relocation on the CodeBuffer
-  JVMCIEnv::CodeInstallResult initialize_buffer(CodeBuffer& buffer, TRAPS);
+  JVMCIEnv::CodeInstallResult initialize_buffer(CodeBuffer& buffer, bool check_size, TRAPS);
 
   void assumption_NoFinalizableSubclass(Handle assumption);
   void assumption_ConcreteSubtype(Handle assumption);
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -591,12 +591,16 @@
   return method->is_ignored_by_security_stack_walk();
 C2V_END
 
-C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
+C2V_VMENTRY(jboolean, isCompilable,(JNIEnv *, jobject, jobject jvmci_method))
   methodHandle method = CompilerToVM::asMethod(jvmci_method);
-  // In hosted mode ignore the not_compilable flags since they are never set by
+  // Ignore the not_compilable flags in hosted mode since they are never set by
   // the JVMCI compiler.
-  bool is_compilable = UseJVMCICompiler ? !method->is_not_compilable(CompLevel_full_optimization) : true;
-  return is_compilable && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
+  return UseJVMCICompiler || !method->is_not_compilable(CompLevel_full_optimization);
+C2V_END
+
+C2V_VMENTRY(jboolean, hasNeverInlineDirective,(JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  return CompilerOracle::should_not_inline(method) || method->dont_inline();
 C2V_END
 
 C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
@@ -1591,7 +1595,8 @@
   {CC "getStackTraceElement",                         CC "(" HS_RESOLVED_METHOD "I)" STACK_TRACE_ELEMENT,                                   FN_PTR(getStackTraceElement)},
   {CC "methodIsIgnoredBySecurityStackWalk",           CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(methodIsIgnoredBySecurityStackWalk)},
   {CC "doNotInlineOrCompile",                         CC "(" HS_RESOLVED_METHOD ")V",                                                       FN_PTR(doNotInlineOrCompile)},
-  {CC "canInlineMethod",                              CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(canInlineMethod)},
+  {CC "isCompilable",                                 CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(isCompilable)},
+  {CC "hasNeverInlineDirective",                      CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(hasNeverInlineDirective)},
   {CC "shouldInlineMethod",                           CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(shouldInlineMethod)},
   {CC "lookupType",                                   CC "(" STRING CLASS "Z)" HS_RESOLVED_KLASS,                                           FN_PTR(lookupType)},
   {CC "lookupNameInPool",                             CC "(" HS_CONSTANT_POOL "I)" STRING,                                                  FN_PTR(lookupNameInPool)},
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -429,6 +429,7 @@
   declare_constant(CodeInstaller::HEAP_TOP_ADDRESS)                       \
   declare_constant(CodeInstaller::HEAP_END_ADDRESS)                       \
   declare_constant(CodeInstaller::NARROW_KLASS_BASE_ADDRESS)              \
+  declare_constant(CodeInstaller::NARROW_OOP_BASE_ADDRESS)                \
   declare_constant(CodeInstaller::CRC_TABLE_ADDRESS)                      \
   declare_constant(CodeInstaller::LOG_OF_HEAP_REGION_GRAIN_BYTES)         \
   declare_constant(CodeInstaller::INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED) \
@@ -534,7 +535,6 @@
                                                                           \
   declare_constant(markOopDesc::no_hash)                                  \
                                                                           \
-  declare_constant(Method::_jfr_towrite)                                  \
   declare_constant(Method::_caller_sensitive)                             \
   declare_constant(Method::_force_inline)                                 \
   declare_constant(Method::_dont_inline)                                  \
--- a/hotspot/src/share/vm/logging/logConfiguration.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/logging/logConfiguration.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -478,7 +478,7 @@
 
 void LogConfiguration::print_command_line_help(FILE* out) {
   jio_fprintf(out, "-Xlog Usage: -Xlog[:[what][:[output][:[decorators][:output-options]]]]\n"
-              "\t where 'what' is a combination of tags and levels on the form tag1[+tag2...][*][=level][,...]\n"
+              "\t where 'what' is a combination of tags and levels of the form tag1[+tag2...][*][=level][,...]\n"
               "\t Unless wildcard (*) is specified, only log messages tagged with exactly the tags specified will be matched.\n\n");
 
   jio_fprintf(out, "Available log levels:\n");
@@ -514,6 +514,14 @@
               " -Xlog:gc\n"
               "\t Log messages tagged with 'gc' tag using 'info' level to stdout, with default decorations.\n\n"
 
+              " -Xlog:gc,safepoint\n"
+              "\t Log messages tagged either with 'gc' or 'safepoint' tags, both using 'info' level, to stdout, with default decorations.\n"
+              "\t (Messages tagged with both 'gc' and 'safepoint' will not be logged.)\n\n"
+
+              " -Xlog:gc+ref=debug\n"
+              "\t Log messages tagged with both 'gc' and 'ref' tags, using 'debug' level, to stdout, with default decorations.\n"
+              "\t (Messages tagged only with one of the two tags will not be logged.)\n\n"
+
               " -Xlog:gc=debug:file=gc.txt:none\n"
               "\t Log messages tagged with 'gc' tag using 'debug' level to file 'gc.txt' with no decorations.\n\n"
 
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -145,10 +145,6 @@
   StringTable::serialize(soc, string_space, space_size);
   soc->do_tag(--tag);
 
-  // Dump/restore the misc information for system dictionary
-  SystemDictionaryShared::serialize(soc);
-  soc->do_tag(--tag);
-
   soc->do_tag(666);
 }
 
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -2139,8 +2139,6 @@
 }
 
 void InstanceKlass::release_C_heap_structures() {
-  assert(!this->is_shared(), "should not be called for a shared class");
-
   // Can't release the constant pool here because the constant pool can be
   // deallocated separately from the InstanceKlass for default methods and
   // redefine classes.
@@ -2191,7 +2189,7 @@
   }
 
   // deallocate the cached class file
-  if (_cached_class_file != NULL) {
+  if (_cached_class_file != NULL && !MetaspaceShared::is_in_shared_space(_cached_class_file)) {
     os::free(_cached_class_file);
     _cached_class_file = NULL;
   }
--- a/hotspot/src/share/vm/oops/method.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/oops/method.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -85,7 +85,6 @@
   set_constMethod(xconst);
   set_access_flags(access_flags);
   set_intrinsic_id(vmIntrinsics::_none);
-  set_jfr_towrite(false);
   set_force_inline(false);
   set_hidden(false);
   set_dont_inline(false);
--- a/hotspot/src/share/vm/oops/method.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/oops/method.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -75,18 +75,19 @@
 
   // Flags
   enum Flags {
-    _jfr_towrite           = 1 << 0,
-    _caller_sensitive      = 1 << 1,
-    _force_inline          = 1 << 2,
-    _dont_inline           = 1 << 3,
-    _hidden                = 1 << 4,
-    _has_injected_profile  = 1 << 5,
-    _running_emcp          = 1 << 6,
-    _intrinsic_candidate   = 1 << 7,
-    _reserved_stack_access = 1 << 8
+    _caller_sensitive      = 1 << 0,
+    _force_inline          = 1 << 1,
+    _dont_inline           = 1 << 2,
+    _hidden                = 1 << 3,
+    _has_injected_profile  = 1 << 4,
+    _running_emcp          = 1 << 5,
+    _intrinsic_candidate   = 1 << 6,
+    _reserved_stack_access = 1 << 7
   };
   mutable u2 _flags;
 
+  TRACE_DEFINE_FLAG;
+
 #ifndef PRODUCT
   int               _compiled_invocation_count;  // Number of nmethod invocations so far (for perf. debugging)
 #endif
@@ -833,13 +834,6 @@
   void init_intrinsic_id();     // updates from _none if a match
   static vmSymbols::SID klass_id_for_intrinsics(const Klass* holder);
 
-  bool jfr_towrite() const {
-    return (_flags & _jfr_towrite) != 0;
-  }
-  void set_jfr_towrite(bool x) const {
-    _flags = x ? (_flags | _jfr_towrite) : (_flags & ~_jfr_towrite);
-  }
-
   bool caller_sensitive() {
     return (_flags & _caller_sensitive) != 0;
   }
@@ -890,6 +884,8 @@
     _flags = x ? (_flags | _reserved_stack_access) : (_flags & ~_reserved_stack_access);
   }
 
+  TRACE_DEFINE_FLAG_ACCESSOR;
+
   ConstMethod::MethodType method_type() const {
       return _constMethod->method_type();
   }
--- a/hotspot/src/share/vm/oops/methodData.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/oops/methodData.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -717,9 +717,9 @@
 }
 
 int MethodData::bytecode_cell_count(Bytecodes::Code code) {
-#if defined(COMPILER1) && !(defined(COMPILER2) || INCLUDE_JVMCI)
-  return no_profile_data;
-#else
+  if (is_client_compilation_mode_vm()) {
+    return no_profile_data;
+  }
   switch (code) {
   case Bytecodes::_checkcast:
   case Bytecodes::_instanceof:
@@ -778,7 +778,6 @@
     return variable_cell_count;
   }
   return no_profile_data;
-#endif
 }
 
 // Compute the size of the profiling information corresponding to
@@ -840,7 +839,9 @@
   case Bytecodes::_ifnonnull:
   case Bytecodes::_invokestatic:
 #ifdef COMPILER2
-    return UseTypeSpeculation;
+    if (is_server_compilation_mode_vm()) {
+      return UseTypeSpeculation;
+    }
 #endif
   default:
     return false;
@@ -942,9 +943,9 @@
 // the segment in bytes.
 int MethodData::initialize_data(BytecodeStream* stream,
                                        int data_index) {
-#if defined(COMPILER1) && !(defined(COMPILER2) || INCLUDE_JVMCI)
-  return 0;
-#else
+  if (is_client_compilation_mode_vm()) {
+    return 0;
+  }
   int cell_count = -1;
   int tag = DataLayout::no_tag;
   DataLayout* data_layout = data_layout_at(data_index);
@@ -1061,7 +1062,6 @@
     assert(!bytecode_has_profile(c), "agree w/ !BHP");
     return 0;
   }
-#endif
 }
 
 // Get the data at an arbitrary (sort of) data index.
--- a/hotspot/src/share/vm/oops/methodData.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/oops/methodData.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -2183,7 +2183,7 @@
   uint _nof_overflow_traps;         // trap count, excluding _trap_hist
   union {
     intptr_t _align;
-    u1 _array[_trap_hist_limit];
+    u1 _array[JVMCI_ONLY(2 *) _trap_hist_limit];
   } _trap_hist;
 
   // Support for interprocedural escape analysis, from Thomas Kotzmann.
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -2097,6 +2097,7 @@
   uint ideal_reg = _type->ideal_reg();
   assert( ideal_reg != Node::NotAMachineReg, "invalid type at Phi" );
   if( ideal_reg == 0 ) return RegMask::Empty;
+  assert(ideal_reg != Op_RegFlags, "flags register is not spillable");
   return *(Compile::current()->matcher()->idealreg2spillmask[ideal_reg]);
 }
 
--- a/hotspot/src/share/vm/opto/coalesce.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/coalesce.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -292,7 +292,14 @@
               // Copy any flags as well
               _phc.clone_projs(pred, pred->end_idx(), m, copy, _phc._lrg_map);
             } else {
-              const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
+              int ireg = m->ideal_reg();
+              if (ireg == 0 || ireg == Op_RegFlags) {
+                assert(false, "attempted to spill a non-spillable item: %d: %s, ireg = %d, spill_type: %s",
+                       m->_idx, m->Name(), ireg, MachSpillCopyNode::spill_type(MachSpillCopyNode::PhiInput));
+                C->record_method_not_compilable("attempted to spill a non-spillable item");
+                return;
+              }
+              const RegMask *rm = C->matcher()->idealreg2spillmask[ireg];
               copy = new MachSpillCopyNode(MachSpillCopyNode::PhiInput, m, *rm, *rm);
               // Find a good place to insert.  Kinda tricky, use a subroutine
               insert_copy_with_overlap(pred,copy,phi_name,src_name);
@@ -326,7 +333,14 @@
               b->insert_node(copy, l++);
               l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map);
             } else {
-              const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
+              int ireg = m->ideal_reg();
+              if (ireg == 0 || ireg == Op_RegFlags) {
+                assert(false, "attempted to spill a non-spillable item: %d: %s, ireg = %d, spill_type: %s",
+                       m->_idx, m->Name(), ireg, MachSpillCopyNode::spill_type(MachSpillCopyNode::TwoAddress));
+                C->record_method_not_compilable("attempted to spill a non-spillable item");
+                return;
+              }
+              const RegMask *rm = C->matcher()->idealreg2spillmask[ireg];
               copy = new MachSpillCopyNode(MachSpillCopyNode::TwoAddress, m, *rm, *rm);
               // Insert the copy in the basic block, just before us
               b->insert_node(copy, l++);
@@ -373,7 +387,14 @@
               if( k < b->_num_succs )
                 continue;     // Live out; do not pre-split
               // Split the lrg at this use
-              const RegMask *rm = C->matcher()->idealreg2spillmask[inp->ideal_reg()];
+              int ireg = inp->ideal_reg();
+              if (ireg == 0 || ireg == Op_RegFlags) {
+                assert(false, "attempted to spill a non-spillable item: %d: %s, ireg = %d, spill_type: %s",
+                       inp->_idx, inp->Name(), ireg, MachSpillCopyNode::spill_type(MachSpillCopyNode::DebugUse));
+                C->record_method_not_compilable("attempted to spill a non-spillable item");
+                return;
+              }
+              const RegMask *rm = C->matcher()->idealreg2spillmask[ireg];
               Node* copy = new MachSpillCopyNode(MachSpillCopyNode::DebugUse, inp, *rm, *rm);
               // Insert the copy in the use-def chain
               n->set_req(inpidx, copy );
--- a/hotspot/src/share/vm/opto/compile.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/compile.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -971,7 +971,7 @@
     _java_calls(0),
     _inner_loops(0),
 #ifndef PRODUCT
-    _trace_opto_output(TraceOptoOutput),
+    _trace_opto_output(directive->TraceOptoOutputOption),
     _in_dump_cnt(0),
     _printer(NULL),
 #endif
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -3152,19 +3152,6 @@
   return membar;
 }
 
-void GraphKit::insert_store_load_for_barrier() {
-  Node* mem = reset_memory();
-  MemBarNode* mb = MemBarNode::make(C, Op_MemBarVolatile, Compile::AliasIdxBot);
-  mb->init_req(TypeFunc::Control, control());
-  mb->init_req(TypeFunc::Memory, mem);
-  Node* membar = _gvn.transform(mb);
-  set_control(_gvn.transform(new ProjNode(membar, TypeFunc::Control)));
-  Node* newmem = _gvn.transform(new ProjNode(membar, TypeFunc::Memory));
-  set_all_memory(mem);
-  set_memory(newmem, Compile::AliasIdxRaw);
-}
-
-
 //------------------------------shared_lock------------------------------------
 // Emit locking code.
 FastLockNode* GraphKit::shared_lock(Node* obj) {
@@ -3854,7 +3841,7 @@
   BasicType bt = T_BYTE;
 
   if (UseConcMarkSweepGC && UseCondCardMark) {
-    insert_store_load_for_barrier();
+    insert_mem_bar(Op_MemBarVolatile);   // StoreLoad barrier
     __ sync_kit(this);
   }
 
@@ -4294,7 +4281,8 @@
 
         __ if_then(card_val, BoolTest::ne, young_card); {
           sync_kit(ideal);
-          insert_store_load_for_barrier();
+          // Use Op_MemBarVolatile to achieve the effect of a StoreLoad barrier.
+          insert_mem_bar(Op_MemBarVolatile, oop_store);
           __ sync_kit(this);
 
           Node* card_val_reload = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
@@ -4348,20 +4336,16 @@
 }
 
 Node* GraphKit::load_String_coder(Node* ctrl, Node* str) {
-  if (java_lang_String::has_coder_field()) {
-    if (!CompactStrings) {
-      return intcon(java_lang_String::CODER_UTF16);
-    }
-    int coder_offset = java_lang_String::coder_offset_in_bytes();
-    const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
-                                                       false, NULL, 0);
-    const TypePtr* coder_field_type = string_type->add_offset(coder_offset);
-    int coder_field_idx = C->get_alias_index(coder_field_type);
-    return make_load(ctrl, basic_plus_adr(str, str, coder_offset),
-                     TypeInt::BYTE, T_BYTE, coder_field_idx, MemNode::unordered);
-  } else {
-    return intcon(0); // false
+  if (!CompactStrings) {
+    return intcon(java_lang_String::CODER_UTF16);
   }
+  int coder_offset = java_lang_String::coder_offset_in_bytes();
+  const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+                                                     false, NULL, 0);
+  const TypePtr* coder_field_type = string_type->add_offset(coder_offset);
+  int coder_field_idx = C->get_alias_index(coder_field_type);
+  return make_load(ctrl, basic_plus_adr(str, str, coder_offset),
+                   TypeInt::BYTE, T_BYTE, coder_field_idx, MemNode::unordered);
 }
 
 void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
--- a/hotspot/src/share/vm/opto/graphKit.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/graphKit.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -837,7 +837,6 @@
   int next_monitor();
   Node* insert_mem_bar(int opcode, Node* precedent = NULL);
   Node* insert_mem_bar_volatile(int opcode, int alias_idx, Node* precedent = NULL);
-  void insert_store_load_for_barrier();
   // Optional 'precedent' is appended as an extra edge, to force ordering.
   FastLockNode* shared_lock(Node* obj);
   void shared_unlock(Node* box, Node* obj);
--- a/hotspot/src/share/vm/opto/library_call.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -6335,7 +6335,7 @@
 
 //------------------------------get_key_start_from_aescrypt_object-----------------------
 Node * LibraryCallKit::get_key_start_from_aescrypt_object(Node *aescrypt_object) {
-#ifdef PPC64
+#if defined(PPC64) || defined(S390)
   // MixColumns for decryption can be reduced by preprocessing MixColumns with round keys.
   // Intel's extention is based on this optimization and AESCrypt generates round keys by preprocessing MixColumns.
   // However, ppc64 vncipher processes MixColumns and requires the same round keys with encryption.
--- a/hotspot/src/share/vm/opto/machnode.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/machnode.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -643,6 +643,7 @@
   }
 
   // Values outside the domain represent debug info
+  assert(in(idx)->ideal_reg() != Op_RegFlags, "flags register is not spillable");
   return *Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()];
 }
 
--- a/hotspot/src/share/vm/opto/macro.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/macro.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -426,7 +426,7 @@
 
 // Generate loads from source of the arraycopy for fields of
 // destination needed at a deoptimization point
-Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, BasicType ft, const Type *ftype, AllocateNode *alloc) {
+Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, Node* mem, BasicType ft, const Type *ftype, AllocateNode *alloc) {
   BasicType bt = ft;
   const Type *type = ftype;
   if (ft == T_NARROWOOP) {
@@ -438,8 +438,7 @@
     Node* base = ac->in(ArrayCopyNode::Src)->in(AddPNode::Base);
     Node* adr = _igvn.transform(new AddPNode(base, base, MakeConX(offset)));
     const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset);
-    Node* m = ac->in(TypeFunc::Memory);
-    res = LoadNode::make(_igvn, ctl, m, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
+    res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
   } else {
     if (ac->modifies(offset, offset, &_igvn, true)) {
       assert(ac->in(ArrayCopyNode::Dest) == alloc->result_cast(), "arraycopy destination should be allocation's result");
@@ -454,8 +453,7 @@
       Node* base = ac->in(ArrayCopyNode::Src);
       Node* adr = _igvn.transform(new AddPNode(base, base, off));
       const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset);
-      Node* m = ac->in(TypeFunc::Memory);
-      res = LoadNode::make(_igvn, ctl, m, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
+      res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned);
     }
   }
   if (res != NULL) {
@@ -544,7 +542,7 @@
         assert(false, "Object is not scalar replaceable if a LoadStore node accesses its field");
         return NULL;
       } else if (val->is_ArrayCopy()) {
-        Node* res = make_arraycopy_load(val->as_ArrayCopy(), offset, val->in(0), ft, phi_type, alloc);
+        Node* res = make_arraycopy_load(val->as_ArrayCopy(), offset, val->in(0), val->in(TypeFunc::Memory), ft, phi_type, alloc);
         if (res == NULL) {
           return NULL;
         }
@@ -657,11 +655,13 @@
       }
     } else if (mem->is_ArrayCopy()) {
       Node* ctl = mem->in(0);
+      Node* m = mem->in(TypeFunc::Memory);
       if (sfpt_ctl->is_Proj() && sfpt_ctl->as_Proj()->is_uncommon_trap_proj(Deoptimization::Reason_none)) {
         // pin the loads in the uncommon trap path
         ctl = sfpt_ctl;
+        m = sfpt_mem;
       }
-      return make_arraycopy_load(mem->as_ArrayCopy(), offset, ctl, ft, ftype, alloc);
+      return make_arraycopy_load(mem->as_ArrayCopy(), offset, ctl, m, ft, ftype, alloc);
     }
   }
   // Something go wrong.
--- a/hotspot/src/share/vm/opto/macro.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/macro.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -200,7 +200,7 @@
                             Node* old_eden_top, Node* new_eden_top,
                             Node* length);
 
-  Node* make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, BasicType ft, const Type *ftype, AllocateNode *alloc);
+  Node* make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, Node* mem, BasicType ft, const Type *ftype, AllocateNode *alloc);
 
 public:
   PhaseMacroExpand(PhaseIterGVN &igvn) : Phase(Macro_Expand), _igvn(igvn), _has_locks(false) {
--- a/hotspot/src/share/vm/opto/matcher.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -85,6 +85,7 @@
   idealreg2spillmask  [Op_VecX] = NULL;
   idealreg2spillmask  [Op_VecY] = NULL;
   idealreg2spillmask  [Op_VecZ] = NULL;
+  idealreg2spillmask  [Op_RegFlags] = NULL;
 
   idealreg2debugmask  [Op_RegI] = NULL;
   idealreg2debugmask  [Op_RegN] = NULL;
@@ -97,6 +98,7 @@
   idealreg2debugmask  [Op_VecX] = NULL;
   idealreg2debugmask  [Op_VecY] = NULL;
   idealreg2debugmask  [Op_VecZ] = NULL;
+  idealreg2debugmask  [Op_RegFlags] = NULL;
 
   idealreg2mhdebugmask[Op_RegI] = NULL;
   idealreg2mhdebugmask[Op_RegN] = NULL;
@@ -109,6 +111,7 @@
   idealreg2mhdebugmask[Op_VecX] = NULL;
   idealreg2mhdebugmask[Op_VecY] = NULL;
   idealreg2mhdebugmask[Op_VecZ] = NULL;
+  idealreg2mhdebugmask[Op_RegFlags] = NULL;
 
   debug_only(_mem_node = NULL;)   // Ideal memory node consumed by mach node
 }
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -23,7 +23,7 @@
  */
 
 // Precompiled headers are turned off for Sun Studion,
-// or if the user passes USE_PRECOMPILED_HEADER=0 to the makefiles.
+// or if the user passes --disable-precompiled-headers to configure.
 
 #ifndef DONT_USE_PRECOMPILED_HEADER
 # include "asm/assembler.hpp"
--- a/hotspot/src/share/vm/prims/jniCheck.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -238,8 +238,8 @@
   size_t live_handles = handles->get_number_of_live_handles();
   if (live_handles > planned_capacity) {
     IN_VM(
-      tty->print_cr("WARNING: JNI local refs: %zu, exceeds capacity: %zu",
-          live_handles, planned_capacity);
+      tty->print_cr("WARNING: JNI local refs: " SIZE_FORMAT ", exceeds capacity: " SIZE_FORMAT,
+                    live_handles, planned_capacity);
       thr->print_stack();
     )
     // Complain just the once, reset to current + warn threshold
--- a/hotspot/src/share/vm/prims/jvm.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1009,9 +1009,9 @@
 // Module support //////////////////////////////////////////////////////////////////////////////
 
 JVM_ENTRY(void, JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version,
-                                 jstring location, jobjectArray packages))
+                                 jstring location, const char* const* packages, jsize num_packages))
   JVMWrapper("JVM_DefineModule");
-  Modules::define_module(module, version, location, packages, CHECK);
+  Modules::define_module(module, version, location, packages, num_packages, CHECK);
 JVM_END
 
 JVM_ENTRY(void, JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module))
@@ -1019,17 +1019,17 @@
   Modules::set_bootloader_unnamed_module(module, CHECK);
 JVM_END
 
-JVM_ENTRY(void, JVM_AddModuleExports(JNIEnv *env, jobject from_module, jstring package, jobject to_module))
+JVM_ENTRY(void, JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module))
   JVMWrapper("JVM_AddModuleExports");
   Modules::add_module_exports_qualified(from_module, package, to_module, CHECK);
 JVM_END
 
-JVM_ENTRY(void, JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, jstring package))
+JVM_ENTRY(void, JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package))
   JVMWrapper("JVM_AddModuleExportsToAllUnnamed");
   Modules::add_module_exports_to_all_unnamed(from_module, package, CHECK);
 JVM_END
 
-JVM_ENTRY(void, JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, jstring package))
+JVM_ENTRY(void, JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package))
   JVMWrapper("JVM_AddModuleExportsToAll");
   Modules::add_module_exports(from_module, package, NULL, CHECK);
 JVM_END
@@ -1039,16 +1039,11 @@
   Modules::add_reads_module(from_module, source_module, CHECK);
 JVM_END
 
-JVM_ENTRY (void, JVM_AddModulePackage(JNIEnv *env, jobject module, jstring package))
+JVM_ENTRY (void, JVM_AddModulePackage(JNIEnv *env, jobject module, const char* package))
   JVMWrapper("JVM_AddModulePackage");
   Modules::add_module_package(module, package, CHECK);
 JVM_END
 
-JVM_ENTRY (jobject, JVM_GetModuleByPackageName(JNIEnv *env, jobject loader, jstring package))
-  JVMWrapper("JVM_GetModuleByPackageName");
-  return Modules::get_module_by_package_name(loader, package, THREAD);
-JVM_END
-
 // Reflection support //////////////////////////////////////////////////////////////////////////////
 
 JVM_ENTRY(jstring, JVM_GetClassName(JNIEnv *env, jclass cls))
--- a/hotspot/src/share/vm/prims/jvm.h	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/prims/jvm.h	Fri Feb 10 08:57:42 2017 -0800
@@ -412,30 +412,67 @@
  * Module support funcions
  */
 
+/*
+ * Define a module with the specified packages and bind the module to the
+ * given class loader.
+ *  module:       module to define
+ *  is_open:      specifies if module is open (currently ignored)
+ *  version:      the module version
+ *  location:     the module location
+ *  packages:     list of packages in the module
+ *  num_packages: number of packages in the module
+ */
 JNIEXPORT void JNICALL
 JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version,
-                 jstring location, jobjectArray packages);
+                 jstring location, const char* const* packages, jsize num_packages);
 
+/*
+ * Set the boot loader's unnamed module.
+ *  module: boot loader's unnamed module
+ */
 JNIEXPORT void JNICALL
 JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module);
 
+/*
+ * Do a qualified export of a package.
+ *  from_module: module containing the package to export
+ *  package:     name of the package to export
+ *  to_module:   module to export the package to
+ */
 JNIEXPORT void JNICALL
-JVM_AddModuleExports(JNIEnv *env, jobject from_module, jstring package, jobject to_module);
+JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module);
 
+/*
+ * Do an export of a package to all unnamed modules.
+ *  from_module: module containing the package to export
+ *  package:     name of the package to export to all unnamed modules
+ */
 JNIEXPORT void JNICALL
-JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, jstring package);
+JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package);
 
+/*
+ * Do an unqualified export of a package.
+ *  from_module: module containing the package to export
+ *  package:     name of the package to export
+ */
 JNIEXPORT void JNICALL
-JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, jstring package);
+JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package);
 
+/*
+ * Add a module to the list of modules that a given module can read.
+ *  from_module:   module requesting read access
+ *  source_module: module that from_module wants to read
+ */
 JNIEXPORT void JNICALL
 JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module);
 
+/*
+ * Add a package to a module.
+ *  module:  module that will contain the package
+ *  package: package to add to the module
+ */
 JNIEXPORT void JNICALL
-JVM_AddModulePackage(JNIEnv* env,  jobject module, jstring package);
-
-JNIEXPORT jobject JNICALL
-JVM_GetModuleByPackageName(JNIEnv* env, jobject loader, jstring package);
+JVM_AddModulePackage(JNIEnv* env,  jobject module, const char* package);
 
 /*
  * Reflection support functions
--- a/hotspot/src/share/vm/prims/jvmti.xml	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/prims/jvmti.xml	Fri Feb 10 08:57:42 2017 -0800
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <?xml-stylesheet type="text/xsl" href="jvmti.xsl"?>
 <!--
- Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2017, 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
@@ -12864,11 +12864,13 @@
       If the capability has been added then the VM posts the event as early
       as possible. The VM is capable of executing bytecode but it may not have
       initialized to the point where it can load classes in modules other than
-      <code>java.base</code>. Agents that do load-time instrumentation in this
+      <code>java.base</code>, or even arbitrary classes in <code>java.base</code>.
+      Agents that do load-time instrumentation in this
       phase must take great care when instrumenting code that potentially
-      executes in this phase. Care should also be taken with JNI
-      <code>FindClass</code> as it may not be possible to load classes that are
-      not in the <code>java.base</code> module.
+      executes in this phase. Extreme care should also be taken with JNI
+      <code>FindClass</code> as it may not be possible to load classes and attempts
+      to do so may result in unpredictable behavior, maybe even stability issues
+      on some VM implementations.
       If the capability has not been added then the VM delays posting this
       event until it is capable of loading classes in modules other than
       <code>java.base</code> or the VM has completed its initialization.
--- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl	Fri Feb 10 08:57:42 2017 -0800
@@ -1246,7 +1246,7 @@
   <xsl:param name="name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="$name"/>
-  <xsl:text>=0x%zx</xsl:text>
+  <xsl:text>=" SIZE_FORMAT_HEX "</xsl:text>
 </xsl:template>
 
 <xsl:template match="jfloat|jdouble" mode="traceInFormat">
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -40,6 +40,8 @@
 #include "memory/universe.hpp"
 #include "memory/oopFactory.hpp"
 #include "oops/constantPool.hpp"
+#include "oops/objArrayKlass.hpp"
+#include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/wbtestmethods/parserTests.hpp"
 #include "prims/whitebox.hpp"
@@ -659,6 +661,9 @@
 WB_END
 
 WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
+  if (method == NULL || comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier)) {
+    return false;
+  }
   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
   MutexLockerEx mu(Compile_lock);
@@ -760,7 +765,7 @@
 
 bool WhiteBox::compile_method(Method* method, int comp_level, int bci, Thread* THREAD) {
   // Screen for unavailable/bad comp level or null method
-  if (method == NULL || comp_level > TieredStopAtLevel ||
+  if (method == NULL || comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier) ||
       CompileBroker::compiler(comp_level) == NULL) {
     return false;
   }
@@ -1400,19 +1405,52 @@
 
 WB_ENTRY(void, WB_DefineModule(JNIEnv* env, jobject o, jobject module, jstring version, jstring location,
                                 jobjectArray packages))
-  Modules::define_module(module, version, location, packages, CHECK);
+  ResourceMark rm(THREAD);
+
+  objArrayOop packages_oop = objArrayOop(JNIHandles::resolve(packages));
+  objArrayHandle packages_h(THREAD, packages_oop);
+  int num_packages = (packages_h == NULL ? 0 : packages_h->length());
+
+  char** pkgs = NULL;
+  if (num_packages > 0) {
+    pkgs = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char*, num_packages);
+    for (int x = 0; x < num_packages; x++) {
+      oop pkg_str = packages_h->obj_at(x);
+      if (pkg_str == NULL || !pkg_str->is_a(SystemDictionary::String_klass())) {
+        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+                  err_msg("Bad package name"));
+      }
+      pkgs[x] = java_lang_String::as_utf8_string(pkg_str);
+    }
+  }
+  Modules::define_module(module, version, location, (const char* const*)pkgs, num_packages, CHECK);
 WB_END
 
 WB_ENTRY(void, WB_AddModuleExports(JNIEnv* env, jobject o, jobject from_module, jstring package, jobject to_module))
-  Modules::add_module_exports_qualified(from_module, package, to_module, CHECK);
+  ResourceMark rm(THREAD);
+  char* package_name = NULL;
+  if (package != NULL) {
+      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
+  }
+  Modules::add_module_exports_qualified(from_module, package_name, to_module, CHECK);
 WB_END
 
 WB_ENTRY(void, WB_AddModuleExportsToAllUnnamed(JNIEnv* env, jobject o, jclass module, jstring package))
-  Modules::add_module_exports_to_all_unnamed(module, package, CHECK);
+  ResourceMark rm(THREAD);
+  char* package_name = NULL;
+  if (package != NULL) {
+      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
+  }
+  Modules::add_module_exports_to_all_unnamed(module, package_name, CHECK);
 WB_END
 
 WB_ENTRY(void, WB_AddModuleExportsToAll(JNIEnv* env, jobject o, jclass module, jstring package))
-  Modules::add_module_exports(module, package, NULL, CHECK);
+  ResourceMark rm(THREAD);
+  char* package_name = NULL;
+  if (package != NULL) {
+      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
+  }
+  Modules::add_module_exports(module, package_name, NULL, CHECK);
 WB_END
 
 WB_ENTRY(void, WB_AddReadsModule(JNIEnv* env, jobject o, jobject from_module, jobject source_module))
@@ -1420,11 +1458,21 @@
 WB_END
 
 WB_ENTRY(void, WB_AddModulePackage(JNIEnv* env, jobject o, jclass module, jstring package))
-  Modules::add_module_package(module, package, CHECK);
+  ResourceMark rm(THREAD);
+  char* package_name = NULL;
+  if (package != NULL) {
+      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
+  }
+  Modules::add_module_package(module, package_name, CHECK);
 WB_END
 
 WB_ENTRY(jobject, WB_GetModuleByPackageName(JNIEnv* env, jobject o, jobject loader, jstring package))
-  return Modules::get_module_by_package_name(loader, package, THREAD);
+  ResourceMark rm(THREAD);
+  char* package_name = NULL;
+  if (package != NULL) {
+      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
+  }
+  return Modules::get_module_by_package_name(loader, package_name, THREAD);
 WB_END
 
 WB_ENTRY(jlong, WB_IncMetaspaceCapacityUntilGC(JNIEnv* env, jobject wb, jlong inc))
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -1819,6 +1819,25 @@
 #endif // INCLUDE_ALL_GCS
 }
 
+#ifdef TIERED
+bool Arguments::compilation_mode_selected() {
+ return !FLAG_IS_DEFAULT(TieredCompilation) || !FLAG_IS_DEFAULT(TieredStopAtLevel) ||
+        !FLAG_IS_DEFAULT(UseAOT) JVMCI_ONLY(|| !FLAG_IS_DEFAULT(EnableJVMCI) || !FLAG_IS_DEFAULT(UseJVMCICompiler));
+
+}
+
+void Arguments::select_compilation_mode_ergonomically() {
+#if defined(_WINDOWS) && !defined(_LP64)
+  if (FLAG_IS_DEFAULT(NeverActAsServerClassMachine)) {
+    FLAG_SET_ERGO(bool, NeverActAsServerClassMachine, true);
+  }
+#endif
+  if (NeverActAsServerClassMachine) {
+    set_client_compilation_mode();
+  }
+}
+#endif //TIERED
+
 void Arguments::select_gc_ergonomically() {
 #if INCLUDE_ALL_GCS
   if (os::is_server_class_machine()) {
@@ -1854,7 +1873,40 @@
   }
 }
 
+#if INCLUDE_JVMCI
+void Arguments::set_jvmci_specific_flags() {
+  if (UseJVMCICompiler) {
+    if (FLAG_IS_DEFAULT(TypeProfileWidth)) {
+      FLAG_SET_DEFAULT(TypeProfileWidth, 8);
+    }
+    if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) {
+      FLAG_SET_DEFAULT(OnStackReplacePercentage, 933);
+    }
+    if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
+      FLAG_SET_DEFAULT(ReservedCodeCacheSize, 64*M);
+    }
+    if (FLAG_IS_DEFAULT(InitialCodeCacheSize)) {
+      FLAG_SET_DEFAULT(InitialCodeCacheSize, 16*M);
+    }
+    if (FLAG_IS_DEFAULT(MetaspaceSize)) {
+      FLAG_SET_DEFAULT(MetaspaceSize, 12*M);
+    }
+    if (FLAG_IS_DEFAULT(NewSizeThreadIncrease)) {
+      FLAG_SET_DEFAULT(NewSizeThreadIncrease, 4*K);
+    }
+    if (FLAG_IS_DEFAULT(TypeProfileLevel)) {
+      FLAG_SET_DEFAULT(TypeProfileLevel, 0);
+    }
+  }
+}
+#endif
+
 void Arguments::set_ergonomics_flags() {
+#ifdef TIERED
+  if (!compilation_mode_selected()) {
+    select_compilation_mode_ergonomically();
+  }
+#endif
   select_gc();
 
 #if defined(COMPILER2) || INCLUDE_JVMCI
@@ -1863,7 +1915,7 @@
   // server performance.  When -server is specified, keep the default off
   // unless it is asked for.  Future work: either add bytecode rewriting
   // at link time, or rewrite bytecodes in non-shared methods.
-  if (!DumpSharedSpaces && !RequireSharedSpaces &&
+  if (is_server_compilation_mode_vm() && !DumpSharedSpaces && !RequireSharedSpaces &&
       (FLAG_IS_DEFAULT(UseSharedSpaces) || !UseSharedSpaces)) {
     no_shared_spaces("COMPILER2 default: -Xshare:auto | off, have to manually setup to on.");
   }
@@ -2463,14 +2515,6 @@
       warning("forcing ScavengeRootsInCode non-zero because JVMCI is enabled");
       ScavengeRootsInCode = 1;
     }
-    if (FLAG_IS_DEFAULT(TypeProfileLevel)) {
-      TypeProfileLevel = 0;
-    }
-    if (UseJVMCICompiler) {
-      if (FLAG_IS_DEFAULT(TypeProfileWidth)) {
-        TypeProfileWidth = 8;
-      }
-    }
   }
 #endif
 
@@ -3195,8 +3239,8 @@
         if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != Flag::SUCCESS) {
           return JNI_EINVAL;
         }
-        // management agent in module java.management
-        if (!create_numbered_property("jdk.module.addmods", "java.management", addmods_count++)) {
+        // management agent in module jdk.management.agent
+        if (!create_numbered_property("jdk.module.addmods", "jdk.management.agent", addmods_count++)) {
           return JNI_ENOMEM;
         }
 #else
@@ -3691,6 +3735,12 @@
     return JNI_ERR;
   }
 
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler) {
+    Compilation_mode = CompMode_server;
+  }
+#endif
+
   return JNI_OK;
 }
 
@@ -3820,6 +3870,9 @@
     return JNI_ENOMEM;
   }
 
+  jio_fprintf(defaultStream::error_stream(),
+              "Picked up %s: %s\n", name, buffer);
+
   int retcode = parse_options_buffer(name, buffer, strlen(buffer), vm_args);
 
   os::free(buffer);
@@ -4420,6 +4473,10 @@
   // Set flags based on ergonomics.
   set_ergonomics_flags();
 
+#if INCLUDE_JVMCI
+  set_jvmci_specific_flags();
+#endif
+
   set_shared_spaces_flags();
 
   // Check the GC selections again.
@@ -4432,7 +4489,9 @@
   } else {
     int max_compilation_policy_choice = 1;
 #ifdef COMPILER2
-    max_compilation_policy_choice = 2;
+    if (is_server_compilation_mode_vm()) {
+      max_compilation_policy_choice = 2;
+    }
 #endif
     // Check if the policy is valid.
     if (CompilationPolicyChoice >= max_compilation_policy_choice) {
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -455,6 +455,10 @@
   static intx _Tier3InvokeNotifyFreqLog;
   static intx _Tier4InvocationThreshold;
 
+  // Compilation mode.
+  static bool compilation_mode_selected();
+  static void select_compilation_mode_ergonomically();
+
   // Tiered
   static void set_tiered_flags();
   // CMS/ParNew garbage collectors
@@ -638,6 +642,7 @@
 #if INCLUDE_JVMCI
   // Check consistency of jvmci vm argument settings.
   static bool check_jvmci_args_consistency();
+  static void set_jvmci_specific_flags();
 #endif
   // Check for consistency in the selection of the garbage collector.
   static bool check_gc_consistency();        // Check user-selected gc
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -238,31 +238,17 @@
 // Note: this policy is used ONLY if TieredCompilation is off.
 // compiler_count() behaves the following way:
 // - with TIERED build (with both COMPILER1 and COMPILER2 defined) it should return
-//   zero for the c1 compilation levels, hence the particular ordering of the
-//   statements.
-// - the same should happen when COMPILER2 is defined and COMPILER1 is not
-//   (server build without TIERED defined).
-// - if only COMPILER1 is defined (client build), zero should be returned for
-//   the c2 level.
+//   zero for the c1 compilation levels in server compilation mode runs
+//   and c2 compilation levels in client compilation mode runs.
+// - with COMPILER2 not defined it should return zero for c2 compilation levels.
+// - with COMPILER1 not defined it should return zero for c1 compilation levels.
 // - if neither is defined - always return zero.
 int NonTieredCompPolicy::compiler_count(CompLevel comp_level) {
   assert(!TieredCompilation, "This policy should not be used with TieredCompilation");
-#ifdef COMPILER2
-  if (is_c2_compile(comp_level)) {
+  if (COMPILER2_PRESENT(is_server_compilation_mode_vm() && is_c2_compile(comp_level) ||)
+      is_client_compilation_mode_vm() && is_c1_compile(comp_level)) {
     return _compiler_count;
-  } else {
-    return 0;
   }
-#endif
-
-#ifdef COMPILER1
-  if (is_c1_compile(comp_level)) {
-    return _compiler_count;
-  } else {
-    return 0;
-  }
-#endif
-
   return 0;
 }
 
--- a/hotspot/src/share/vm/runtime/globals.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -469,14 +469,18 @@
   }
 
   if (!printRanges) {
+    // Use some named constants to make code more readable.
+    const unsigned int nSpaces    = 10;
+    const unsigned int maxFlagLen = 40 + nSpaces;
+
     // The print below assumes that the flag name is 40 characters or less.
     // This works for most flags, but there are exceptions. Our longest flag
     // name right now is UseAdaptiveGenerationSizePolicyAtMajorCollection and
     // its minor collection buddy. These are 48 characters. We use a buffer of
-    // 10 spaces below to adjust the space between the flag value and the
+    // nSpaces spaces below to adjust the space between the flag value and the
     // column of flag type and origin that is printed in the end of the line.
-    char spaces[10 + 1] = "          ";
-    st->print("%9s %-40s = ", _type, _name);
+    char spaces[nSpaces + 1] = "          ";
+    st->print("%9s %-*s = ", _type, maxFlagLen-nSpaces, _name);
 
     if (is_bool()) {
       st->print("%-20s", get_bool() ? "true" : "false");
@@ -509,9 +513,12 @@
       }
       else st->print("%-20s", "");
     }
-    assert(strlen(_name) < 50, "Flag name is longer than expected");
-    spaces[50 - MAX2((size_t)40, strlen(_name))] = '\0';
-    st->print("%s", spaces);
+    // Make sure we do not punch a '\0' at a negative char array index.
+    unsigned int nameLen = (unsigned int)strlen(_name);
+    if (nameLen <= maxFlagLen) {
+      spaces[maxFlagLen - MAX2(maxFlagLen-nSpaces, nameLen)] = '\0';
+      st->print("%s", spaces);
+    }
     print_kind_and_origin(st);
 
 #ifndef PRODUCT
--- a/hotspot/src/share/vm/runtime/os.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/os.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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 "classfile/classLoader.hpp"
 #include "classfile/javaClasses.hpp"
+#include "classfile/moduleEntry.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
@@ -1229,7 +1230,7 @@
   FREE_C_HEAP_ARRAY(char, jimage);
 
   // check if developer build with exploded modules
-  char* base_classes = format_boot_path("%/modules/java.base", home, home_len, fileSep, pathSep);
+  char* base_classes = format_boot_path("%/modules/" JAVA_BASE_NAME, home, home_len, fileSep, pathSep);
   if (base_classes == NULL) return false;
   if (os::stat(base_classes, &st) == 0) {
     Arguments::set_sysclasspath(base_classes, false);
--- a/hotspot/src/share/vm/runtime/reflection.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/reflection.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -534,22 +534,26 @@
     PackageEntry* package_to = new_class->package();
     assert(package_to != NULL, "can not obtain new_class' package");
 
-    // Once readability is established, if module_to exports T unqualifiedly,
-    // (to all modules), than whether module_from is in the unnamed module
-    // or not does not matter, access is allowed.
-    if (package_to->is_unqual_exported()) {
-      return ACCESS_OK;
-    }
+    {
+      MutexLocker m1(Module_lock);
+
+      // Once readability is established, if module_to exports T unqualifiedly,
+      // (to all modules), than whether module_from is in the unnamed module
+      // or not does not matter, access is allowed.
+      if (package_to->is_unqual_exported()) {
+        return ACCESS_OK;
+      }
 
-    // Access is allowed if both 1 & 2 hold:
-    //   1. Readability, module_from can read module_to (established above).
-    //   2. Either module_to exports T to module_from qualifiedly.
-    //      or
-    //      module_to exports T to all unnamed modules and module_from is unnamed.
-    //      or
-    //      module_to exports T unqualifiedly to all modules (checked above).
-    if (!package_to->is_qexported_to(module_from)) {
-      return TYPE_NOT_EXPORTED;
+      // Access is allowed if both 1 & 2 hold:
+      //   1. Readability, module_from can read module_to (established above).
+      //   2. Either module_to exports T to module_from qualifiedly.
+      //      or
+      //      module_to exports T to all unnamed modules and module_from is unnamed.
+      //      or
+      //      module_to exports T unqualifiedly to all modules (checked above).
+      if (!package_to->is_qexported_to(module_from)) {
+        return TYPE_NOT_EXPORTED;
+      }
     }
     return ACCESS_OK;
   }
--- a/hotspot/src/share/vm/runtime/vframe_hp.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/vframe_hp.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -158,7 +158,7 @@
     deferred =  new(ResourceObj::C_HEAP, mtCompiler) GrowableArray<jvmtiDeferredLocalVariableSet*> (1, true);
     thread()->set_deferred_locals(deferred);
   }
-  deferred->push(new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id()));
+  deferred->push(new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id(), vframe_id()));
   assert(deferred->top()->id() == fr().id(), "Huh? Must match");
   deferred->top()->set_local_at(index, type, value);
 }
@@ -243,6 +243,7 @@
 compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, CompiledMethod* nm)
 : javaVFrame(fr, reg_map, thread) {
   _scope  = NULL;
+  _vframe_id = 0;
   // Compiled method (native stub or Java code)
   // native wrappers have no scope data, it is implied
   if (!nm->is_compiled() || !nm->as_compiled_method()->is_native_method()) {
@@ -250,9 +251,10 @@
   }
 }
 
-compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope)
+compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope, int vframe_id)
 : javaVFrame(fr, reg_map, thread) {
   _scope  = scope;
+  _vframe_id = vframe_id;
   guarantee(_scope != NULL, "scope must be present");
 }
 
@@ -316,14 +318,15 @@
   } else {
     return scope()->is_top()
       ? vframe::sender()
-      : new compiledVFrame(&f, register_map(), thread(), scope()->sender());
+      : new compiledVFrame(&f, register_map(), thread(), scope()->sender(), vframe_id() + 1);
   }
 }
 
-jvmtiDeferredLocalVariableSet::jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id) {
+jvmtiDeferredLocalVariableSet::jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id, int vframe_id) {
   _method = method;
   _bci = bci;
   _id = id;
+  _vframe_id = vframe_id;
   // Alway will need at least one, must be on C heap
   _locals = new(ResourceObj::C_HEAP, mtCompiler) GrowableArray<jvmtiDeferredLocalVariable*> (1, true);
 }
@@ -339,7 +342,11 @@
 bool jvmtiDeferredLocalVariableSet::matches(vframe* vf) {
   if (!vf->is_compiled_frame()) return false;
   compiledVFrame* cvf = (compiledVFrame*)vf;
-  return cvf->fr().id() == id() && cvf->method() == method() && cvf->bci() == bci();
+  if (cvf->fr().id() == id() && cvf->vframe_id() == vframe_id()) {
+    assert(cvf->method() == method() && cvf->bci() == bci(), "must agree");
+    return true;
+  }
+  return false;
 }
 
 void jvmtiDeferredLocalVariableSet::set_local_at(int idx, BasicType type, jvalue val) {
--- a/hotspot/src/share/vm/runtime/vframe_hp.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/vframe_hp.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -36,6 +36,7 @@
   StackValueCollection*        locals()             const;
   StackValueCollection*        expressions()        const;
   GrowableArray<MonitorInfo*>* monitors()           const;
+  int                          vframe_id()          const { return _vframe_id; }
 
   void set_locals(StackValueCollection* values) const;
 
@@ -68,14 +69,14 @@
 
  protected:
   ScopeDesc* _scope;
-
+  int _vframe_id;
 
   //StackValue resolve(ScopeValue* sv) const;
   BasicLock* resolve_monitor_lock(Location location) const;
   StackValue *create_stack_value(ScopeValue *sv) const;
 
  private:
-  compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope);
+  compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope, int vframe_id);
 
 #ifndef PRODUCT
  public:
@@ -95,6 +96,7 @@
   Method* _method;
   int       _bci;
   intptr_t* _id;
+  int _vframe_id;
   GrowableArray<jvmtiDeferredLocalVariable*>* _locals;
 
  public:
@@ -102,6 +104,7 @@
   Method*                           method()         const  { return _method; }
   int                               bci()            const  { return _bci; }
   intptr_t*                         id()             const  { return _id; }
+  int                               vframe_id()      const  { return _vframe_id; }
   GrowableArray<jvmtiDeferredLocalVariable*>* locals()         const  { return _locals; }
   void                              set_local_at(int idx, BasicType typ, jvalue val);
 
@@ -111,7 +114,7 @@
   void                              oops_do(OopClosure* f);
 
   // constructor
-  jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id);
+  jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id, int vframe_id);
 
   // destructor
   ~jvmtiDeferredLocalVariableSet();
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -2453,7 +2453,6 @@
   /* ConstMethod anon-enum */                                             \
   /********************************/                                      \
                                                                           \
-  declare_constant(Method::_jfr_towrite)                                  \
   declare_constant(Method::_caller_sensitive)                             \
   declare_constant(Method::_force_inline)                                 \
   declare_constant(Method::_dont_inline)                                  \
--- a/hotspot/src/share/vm/runtime/vm_version.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -131,19 +131,32 @@
       return UseSharedSpaces ? "interpreted mode, sharing" : "interpreted mode";
     case Arguments::_mixed:
       if (UseSharedSpaces) {
-          if (UseAOT) {
-            return "mixed mode, aot, sharing";
-          } else {
-            return "mixed mode, sharing";
-          }
+        if (UseAOT) {
+          return "mixed mode, aot, sharing";
+#ifdef TIERED
+        } else if(is_client_compilation_mode_vm()) {
+          return "mixed mode, emulated-client, sharing";
+#endif
+        } else {
+          return "mixed mode, sharing";
+         }
       } else {
         if (UseAOT) {
           return "mixed mode, aot";
+#ifdef TIERED
+        } else if(is_client_compilation_mode_vm()) {
+          return "mixed mode, emulated-client";
+#endif
         } else {
           return "mixed mode";
         }
       }
     case Arguments::_comp:
+#ifdef TIERED
+      if (is_client_compilation_mode_vm()) {
+         return UseSharedSpaces ? "compiled mode, emulated-client, sharing" : "compiled mode, emulated-client";
+      }
+#endif
       return UseSharedSpaces ? "compiled mode, sharing"    : "compiled mode";
   };
   ShouldNotReachHere();
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -292,7 +292,7 @@
       char *opt = (char *)os::malloc(opt_len, mtInternal);
       if (opt == NULL) {
         output()->print_cr("JVMTI agent attach failed: "
-                           "Could not allocate %zu bytes for argument.",
+                           "Could not allocate " SIZE_FORMAT " bytes for argument.",
                            opt_len);
         return;
       }
@@ -748,13 +748,13 @@
     ResourceMark rm(THREAD);
     HandleMark hm(THREAD);
 
-    // Load and initialize the sun.management.Agent class
+    // Load and initialize the jdk.internal.agent.Agent class
     // invoke startRemoteManagementAgent(string) method to start
     // the remote management server.
     // throw java.lang.NoSuchMethodError if the method doesn't exist
 
     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
-    Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK);
+    Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK);
     instanceKlassHandle ik (THREAD, k);
 
     JavaValue result(T_VOID);
@@ -821,13 +821,13 @@
     ResourceMark rm(THREAD);
     HandleMark hm(THREAD);
 
-    // Load and initialize the sun.management.Agent class
+    // Load and initialize the jdk.internal.agent.Agent class
     // invoke startLocalManagementAgent(void) method to start
     // the local management server
     // throw java.lang.NoSuchMethodError if method doesn't exist
 
     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
-    Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK);
+    Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK);
     instanceKlassHandle ik (THREAD, k);
 
     JavaValue result(T_VOID);
@@ -838,13 +838,13 @@
     ResourceMark rm(THREAD);
     HandleMark hm(THREAD);
 
-    // Load and initialize the sun.management.Agent class
+    // Load and initialize the jdk.internal.agent.Agent class
     // invoke stopRemoteManagementAgent method to stop the
     // management server
     // throw java.lang.NoSuchMethodError if method doesn't exist
 
     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
-    Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK);
+    Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK);
     instanceKlassHandle ik (THREAD, k);
 
     JavaValue result(T_VOID);
@@ -860,12 +860,12 @@
   ResourceMark rm(THREAD);
   HandleMark hm(THREAD);
 
-  // Load and initialize the sun.management.Agent class
+  // Load and initialize the jdk.internal.agent.Agent class
   // invoke getManagementAgentStatus() method to generate the status info
   // throw java.lang.NoSuchMethodError if method doesn't exist
 
   Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
-  Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK);
+  Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK);
   instanceKlassHandle ik (THREAD, k);
 
   JavaValue result(T_OBJECT);
--- a/hotspot/src/share/vm/services/management.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/services/management.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -145,16 +145,16 @@
     ResourceMark rm(THREAD);
     HandleMark hm(THREAD);
 
-    // Load and initialize the sun.management.Agent class
+    // Load and initialize the jdk.internal.agent.Agent class
     // invoke startAgent method to start the management server
     Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
-    Klass* k = SystemDictionary::resolve_or_null(vmSymbols::sun_management_Agent(),
+    Klass* k = SystemDictionary::resolve_or_null(vmSymbols::jdk_internal_agent_Agent(),
                                                    loader,
                                                    Handle(),
                                                    THREAD);
     if (k == NULL) {
       vm_exit_during_initialization("Management agent initialization failure: "
-          "class sun.management.Agent not found.");
+          "class jdk.internal.agent.Agent not found.");
     }
     instanceKlassHandle ik (THREAD, k);
 
--- a/hotspot/src/share/vm/trace/traceMacros.hpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp	Fri Feb 10 08:57:42 2017 -0800
@@ -55,6 +55,8 @@
 #define TRACE_DEFINE_THREAD_ID_SIZE typedef int ___IGNORED_hs_trace_type6
 #define TRACE_DEFINE_THREAD_DATA_WRITER_OFFSET typedef int ___IGNORED_hs_trace_type7
 #define TRACE_THREAD_DATA_WRITER_OFFSET in_ByteSize(0); ShouldNotReachHere()
+#define TRACE_DEFINE_FLAG typedef int ___IGNORED_hs_trace_type8
+#define TRACE_DEFINE_FLAG_ACCESSOR typedef int ___IGNORED_hs_trace_type9
 #define TRACE_TEMPLATES(template)
 #define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)
 
--- a/hotspot/src/share/vm/utilities/copy.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/src/share/vm/utilities/copy.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -214,7 +214,7 @@
     case 2: do_conjoint_swap<uint16_t,D>(src, dst, byte_count); break;
     case 4: do_conjoint_swap<uint32_t,D>(src, dst, byte_count); break;
     case 8: do_conjoint_swap<uint64_t,D>(src, dst, byte_count); break;
-    default: guarantee(false, "do_conjoint_swap: Invalid elem_size %zd\n", elem_size);
+    default: guarantee(false, "do_conjoint_swap: Invalid elem_size " SIZE_FORMAT "\n", elem_size);
     }
   }
 };
--- a/hotspot/test/ProblemList.txt	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/ProblemList.txt	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2016, 2017, 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
@@ -55,7 +55,7 @@
 
 gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all
 gc/survivorAlignment/TestPromotionToSurvivor.java 8129886 generic-all
-gc/stress/TestStressG1Humongous.java 8171045 generic-all
+gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
 
 #############################################################################
 
@@ -78,5 +78,7 @@
 
 # :hotspot_misc
 
+testlibrary_tests/ctw/JarDirTest.java 8172457 windows-all
+
 #############################################################################
 
--- a/hotspot/test/TEST.ROOT	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/TEST.ROOT	Fri Feb 10 08:57:42 2017 -0800
@@ -46,6 +46,8 @@
     vm.gc.Parallel \
     vm.gc.ConcMarkSweep \
     vm.jvmci \
+    vm.emulatedClient \
+    vm.cpu.features \
     vm.debug
 
 # Tests using jtreg 4.2 b04 features
--- a/hotspot/test/compiler/aot/AotCompiler.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/AotCompiler.java	Fri Feb 10 08:57:42 2017 -0800
@@ -69,7 +69,7 @@
         extraopts.add("-classpath");
         extraopts.add(Utils.TEST_CLASS_PATH + File.pathSeparator + Utils.TEST_SRC);
         if (className != null && libName != null) {
-            OutputAnalyzer oa = launchCompiler(libName, className + ".class", extraopts, compileList);
+            OutputAnalyzer oa = launchCompiler(libName, className, extraopts, compileList);
             oa.shouldHaveExitValue(0);
         } else {
             printUsage();
@@ -93,12 +93,14 @@
             }
         }
         List<String> args = new ArrayList<>();
+        args.add("--compile-with-assertions");
         args.add("--output");
         args.add(libName);
         if (file != null) {
             args.add("--compile-commands");
             args.add(file.toString());
         }
+        args.add("--class-name");
         args.add(item);
         return launchJaotc(args, extraopts);
     }
--- a/hotspot/test/compiler/aot/RecompilationTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/RecompilationTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -33,6 +33,7 @@
  * @run main compiler.aot.AotCompiler -libname libRecompilationTest1.so
  *     -class compiler.whitebox.SimpleTestCaseHelper
  *     -extraopt -Dgraal.TieredAOT=true -extraopt -Dgraal.ProfileSimpleMethods=true
+ *     -extraopt -Dgraal.ProbabilisticProfiling=false
  *     -extraopt -XX:+UnlockDiagnosticVMOptions -extraopt -XX:+WhiteBoxAPI -extraopt -Xbootclasspath/a:.
  *     -extraopt -XX:-UseCompressedOops
  *     -extraopt -XX:CompileCommand=dontinline,compiler.whitebox.SimpleTestCaseHelper::*
--- a/hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * 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
- * @library / /test/lib /testlibrary
- * @modules java.base/jdk.internal.misc
- * @requires vm.bits == "64" & os.arch == "amd64" & os.family == "linux"
- * @build compiler.aot.cli.jaotc.ClasspathOptionTest
- * @run driver ClassFileInstaller compiler.aot.cli.jaotc.data.HelloWorldOne
- * @run driver compiler.aot.cli.jaotc.ClasspathOptionTest
- * @summary check jaotc can compile class from classpath
- */
-
-package compiler.aot.cli.jaotc;
-
-import compiler.aot.cli.jaotc.data.HelloWorldOne;
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import jdk.test.lib.Asserts;
-import jdk.test.lib.process.OutputAnalyzer;
-
-public class ClasspathOptionTest {
-    public static void main(String[] args) {
-        Path cp = Paths.get("testClasspath");
-        try {
-            Files.createDirectory(cp);
-            Files.move(Paths.get("compiler"), cp.resolve("compiler"));
-        } catch (IOException e) {
-            throw new Error("TESTBUG: can't create test data " + e, e);
-        }
-        OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--classpath", cp.toString(),
-                JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class));
-        oa.shouldHaveExitValue(0);
-        File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
-        Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing");
-        Asserts.assertGT(compiledLibrary.length(), 0L, "Unexpected compiled library size");
-        JaotcTestHelper.checkLibraryUsage(HelloWorldOne.class.getName());
-    }
-}
--- a/hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionUnknownClassTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/cli/jaotc/ClasspathOptionUnknownClassTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -39,7 +39,7 @@
 
 public class ClasspathOptionUnknownClassTest {
     public static void main(String[] args) {
-        OutputAnalyzer oa = JaotcTestHelper.compileLibrary("HelloWorldOne.class");
+        OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--class-name", "HelloWorldOne");
         Asserts.assertNE(oa.getExitValue(), 0, "Unexpected compilation exit code");
         File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
         Asserts.assertFalse(compiledLibrary.exists(), "Compiler library unexpectedly exists");
--- a/hotspot/test/compiler/aot/cli/jaotc/CompileClassTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/cli/jaotc/CompileClassTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -41,7 +41,7 @@
 
 public class CompileClassTest {
     public static void main(String[] args) {
-        OutputAnalyzer oa = JaotcTestHelper.compileLibrary(JaotcTestHelper
+        OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--class-name", JaotcTestHelper
                 .getClassAotCompilationName(HelloWorldOne.class));
         oa.shouldHaveExitValue(0);
         File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
--- a/hotspot/test/compiler/aot/cli/jaotc/CompileDirectoryTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/cli/jaotc/CompileDirectoryTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -42,7 +42,7 @@
 
 public class CompileDirectoryTest {
     public static void main(String[] args) {
-        OutputAnalyzer oa =JaotcTestHelper.compileLibrary(".");
+        OutputAnalyzer oa =JaotcTestHelper.compileLibrary("--directory", ".");
         oa.shouldHaveExitValue(0);
         File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
         Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing");
--- a/hotspot/test/compiler/aot/cli/jaotc/CompileJarTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/cli/jaotc/CompileJarTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -48,7 +48,7 @@
 
     public static void main(String[] args) {
         createJar();
-        OutputAnalyzer oa = JaotcTestHelper.compileLibrary(JAR_NAME);
+        OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--jar", JAR_NAME);
         oa.shouldHaveExitValue(0);
         File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
         Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing");
--- a/hotspot/test/compiler/aot/cli/jaotc/JaotcTestHelper.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/cli/jaotc/JaotcTestHelper.java	Fri Feb 10 08:57:42 2017 -0800
@@ -44,6 +44,7 @@
         for (String vmOpt : Utils.getTestJavaOpts()) {
             launcher.addVMArg(vmOpt);
         }
+        launcher.addToolArg("--compile-with-assertions");
         for (String arg : args) {
             launcher.addToolArg(arg);
         }
@@ -70,7 +71,11 @@
         }
     }
 
-    public static String getClassAotCompilationName(Class<?> classToCompile) {
+    public static String getClassAotCompilationFilename(Class<?> classToCompile) {
         return classToCompile.getName().replaceAll("\\.", File.separator) + ".class";
     }
+
+    public static String getClassAotCompilationName(Class<?> classToCompile) {
+        return classToCompile.getName();
+    }
 }
--- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionNotExistingTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionNotExistingTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -45,7 +45,7 @@
 
     public static void main(String[] args) {
         OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--compile-commands", "./notExisting.list",
-                COMPILE_ITEM);
+                "--class-name", COMPILE_ITEM);
         int exitCode = oa.getExitValue();
         Asserts.assertNE(exitCode, 0, "Unexpected compilation exit code");
         File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
--- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -66,7 +66,7 @@
             throw new Error("TESTBUG: can't write list file " + e, e);
         }
         OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--compile-commands", COMPILE_COMMAND_FILE.toString(),
-                JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class));
+                "--class-name", JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class));
         oa.shouldHaveExitValue(0);
         File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
         Asserts.assertTrue(compiledLibrary.exists(), "Compiled library file missing");
--- a/hotspot/test/compiler/aot/cli/jaotc/ListOptionWrongFileTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/cli/jaotc/ListOptionWrongFileTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -49,12 +49,15 @@
     private static final String COMPILE_ITEM
             = JaotcTestHelper.getClassAotCompilationName(HelloWorldOne.class);
 
+    private static final String COMPILE_FILE
+            = JaotcTestHelper.getClassAotCompilationFilename(HelloWorldOne.class);
+
     public static void main(String[] args) {
         // expecting wrong file to be read but no compilation directive recognized, so, all compiled
-        OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--compile-commands", COMPILE_ITEM, COMPILE_ITEM);
+        OutputAnalyzer oa = JaotcTestHelper.compileLibrary("--compile-commands", COMPILE_FILE, "--class-name", COMPILE_ITEM);
         oa.shouldHaveExitValue(0);
         File compiledLibrary = new File(JaotcTestHelper.DEFAULT_LIB_PATH);
-        Asserts.assertTrue(compiledLibrary.exists(), "Expecte compiler library to exist");
+        Asserts.assertTrue(compiledLibrary.exists(), "Expected compiler library to exist");
         JaotcTestHelper.checkLibraryUsage(HelloWorldOne.class.getName(), EXPECTED, null);
     }
 }
--- a/hotspot/test/compiler/aot/fingerprint/CDSDumper.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * 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 compiler.aot.fingerprint;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.PrintStream;
-
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
-
-// Usage:
-// java CDSDumper <classpath> <classlist> <archive> <class1> <class2> ...
-public class CDSDumper {
-    public static void main(String[] args) throws Exception {
-        String classpath = args[0];
-        String classlist = args[1];
-        String archive = args[2];
-
-        // Prepare the classlist
-        FileOutputStream fos = new FileOutputStream(classlist);
-        PrintStream ps = new PrintStream(fos);
-
-        for (int i=3; i<args.length; i++) {
-            ps.println(args[i].replace('.', '/'));
-        }
-        ps.close();
-        fos.close();
-
-        // Dump the archive
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-            "-XX:+UnlockCommercialFeatures",
-            "-XX:+UseAppCDS",
-            "-XX:+UnlockDiagnosticVMOptions",
-            "-cp", classpath,
-            "-XX:ExtraSharedClassListFile=" + classlist,
-            "-XX:SharedArchiveFile=" + archive,
-            "-Xshare:dump",
-            "-XX:+PrintSharedSpaces");
-
-        OutputAnalyzer output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Loading classes to share");
-        output.shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/compiler/aot/fingerprint/CDSRunner.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * 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 compiler.aot.fingerprint;
-
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
-
-// Usage:
-// java CDSRunner <vmargs> <class> <args> ...
-public class CDSRunner {
-    public static void main(String[] args) throws Exception {
-        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
-        OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
-        System.out.println("[stdout = " + output.getStdout() + "]");
-        System.out.println("[stderr = " + output.getStderr() + "]");
-
-        output.shouldContain("PASSED");
-        output.shouldHaveExitValue(0);
-    }
-}
--- a/hotspot/test/compiler/aot/fingerprint/SelfChanged.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * 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 AOT methods should be swept if a super class has changed.
- * @library /test/lib /
- * @modules java.base/jdk.internal.misc
- *          java.management
- * @requires vm.bits == "64" & os.arch == "amd64" & os.family == "linux"
- * @build compiler.aot.fingerprint.SelfChanged
- *        compiler.aot.AotCompiler
- *
- * @run main
- *      compiler.aot.fingerprint.SelfChanged WRITE-UNMODIFIED-CLASS
- * @run main/othervm compiler.aot.AotCompiler -libname libSelfChanged.so
- *      -class compiler.aot.fingerprint.Blah
- *
- * @run main/othervm
- *      compiler.aot.fingerprint.SelfChanged TEST-UNMODIFIED
- * @run main/othervm -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSelfChanged.so
- *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
- *      compiler.aot.fingerprint.SelfChanged TEST-UNMODIFIED
- *
- * @run main
- *      compiler.aot.fingerprint.SelfChanged WRITE-MODIFIED-CLASS
- * @run main
- *      compiler.aot.fingerprint.SelfChanged TEST-MODIFIED
- * @run main/othervm -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSelfChanged.so
- *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
- *      compiler.aot.fingerprint.SelfChanged TEST-MODIFIED
- */
-
-package compiler.aot.fingerprint;
-
-import jdk.test.lib.Asserts;
-import jdk.test.lib.InMemoryJavaCompiler;
-
-import java.io.*;
-
-class Blah {
-    volatile int z;
-    int getX() {
-        for (z = 0; z < 10000; z++) {
-            if (z % 7 == 1) {
-                z += 2;
-            }
-        }
-        return 0;
-    }
-}
-
-public class SelfChanged {
-    public static void main(String args[]) throws Throwable {
-        Blah f = new Blah();
-        System.out.println("f.getX = " + f.getX());
-        switch (args[0]) {
-        case "WRITE-UNMODIFIED-CLASS":
-            compileClass(false);
-            break;
-        case "WRITE-MODIFIED-CLASS":
-            compileClass(true);
-            break;
-        case "TEST-UNMODIFIED":
-            Asserts.assertTrue(f.getX() == 0, "getX from unmodified Blah class should return 0");
-            break;
-        case "TEST-MODIFIED":
-            Asserts.assertTrue(f.getX() == 1, "getX from modified Blah class should return 1");
-            break;
-        default:
-            throw new RuntimeException("unexpected option: " + args[0]);
-        }
-    }
-
-    static void compileClass(boolean isModified) throws Throwable {
-        String src =
-               "package compiler.aot.fingerprint;"
-             + "public class Blah {"
-             + "    volatile int z;"
-             + "    int getX() {"
-             + "        for (z = 0; z < 10000; z++) {"
-             + "            if (z % 7 == 1) {"
-             + "                z += 2;"
-             + "            }"
-             + "        }"
-             + "        return " + ((isModified) ? "1" : "0") + ";"
-             + "    }"
-             + "    int getY() {return 255;}"
-
-            // The following is for the SelfChangedCDS.java test case. We always load an unmodified
-            // version of Blah from the CDS archive. However, we would load an AOT library that
-            // was compiled using a modified version of Blah. The getX method in this AOT library should
-            // not be used.
-
-            + "    public static void main(String args[]) {"
-             + "        Blah b = new Blah();"
-             + "        int n = b.getX();"
-             + "        if (n != 0) {"
-             + "            throw new RuntimeException(args[0] +  \" : \" + n);"
-             + "        }"
-             + "        System.out.println(\"PASSED\");"
-             + "    }"
-             + "}";
-
-        String filename = System.getProperty("test.classes") + "/compiler/aot/fingerprint/Blah.class";
-        FileOutputStream fos = new FileOutputStream(filename);
-        fos.write(InMemoryJavaCompiler.compile("compiler.aot.fingerprint.Blah", src));
-        fos.close();
-    }
-}
--- a/hotspot/test/compiler/aot/fingerprint/SelfChangedCDS.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * 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 AOT methods should be swept if a super class has changed (with CDS).
- * @library /test/lib /
- * @modules java.base/jdk.internal.misc
- *          java.management
- * @requires vm.bits == "64" & os.arch == "amd64" & os.family == "linux"
- * @build compiler.aot.fingerprint.SelfChanged
- *        compiler.aot.AotCompiler
- *
- * @run main compiler.aot.fingerprint.SelfChanged WRITE-UNMODIFIED-CLASS
- * @run main/othervm compiler.aot.AotCompiler -libname libSelfChanged.so
- *      -class compiler.aot.fingerprint.Blah
- *
- * @run main ClassFileInstaller -jar SelfChangedCDS.jar compiler.aot.fingerprint.Blah
- * @run main compiler.aot.fingerprint.CDSDumper SelfChangedCDS.jar SelfChangedCDS.classlist SelfChangedCDS.jsa
- *      compiler.aot.fingerprint.Blah
- *
- * @run main compiler.aot.fingerprint.CDSRunner -cp SelfChangedCDS.jar
- *      compiler.aot.fingerprint.Blah TEST-UNMODIFIED
- * @run main compiler.aot.fingerprint.CDSRunner -cp SelfChangedCDS.jar
- *      -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSelfChanged.so
- *      -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=SelfChangedCDS.jsa
- *      -Xshare:auto -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -showversion
- *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
- *      compiler.aot.fingerprint.Blah TEST-UNMODIFIED
- *
- * @run main
- *      compiler.aot.fingerprint.SelfChanged WRITE-MODIFIED-CLASS
- * @run main/othervm compiler.aot.AotCompiler -libname libSelfChanged.so
- *      -class compiler.aot.fingerprint.Blah
- *
- * @run main compiler.aot.fingerprint.CDSRunner -cp SelfChangedCDS.jar
- *      compiler.aot.fingerprint.Blah TEST-MODIFIED
- * @run main compiler.aot.fingerprint.CDSRunner -cp SelfChangedCDS.jar
- *      -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSelfChanged.so
- *      -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=SelfChangedCDS.jsa
- *      -Xshare:auto -XX:+UnlockCommercialFeatures -XX:+UseAppCDS -showversion
- *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
- *      compiler.aot.fingerprint.Blah TEST-MODIFIED
- */
--- a/hotspot/test/compiler/aot/fingerprint/SuperChanged.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * 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 AOT methods should be swept if a super class has changed.
- * @library /test/lib /
- * @modules java.base/jdk.internal.misc
- *          java.management
- * @requires vm.bits == "64" & os.arch == "amd64" & os.family == "linux"
- * @build compiler.aot.fingerprint.SuperChanged
- *        compiler.aot.AotCompiler
- *
- * @run main
- *      compiler.aot.fingerprint.SuperChanged WRITE-UNMODIFIED-CLASS
- * @run main/othervm compiler.aot.AotCompiler -libname libSuperChanged.so
- *      -class compiler.aot.fingerprint.Foo
- *
- * @run main
- *      compiler.aot.fingerprint.SuperChanged TEST-UNMODIFIED
- * @run main/othervm -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSuperChanged.so
- *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
- *      compiler.aot.fingerprint.SuperChanged TEST-UNMODIFIED
-  *
- * @run main
- *      compiler.aot.fingerprint.SuperChanged WRITE-MODIFIED-CLASS
- * @run main
- *      compiler.aot.fingerprint.SuperChanged TEST-MODIFIED
- * @run main/othervm -XX:+UseAOT -XX:+PrintAOT -XX:AOTLibrary=./libSuperChanged.so
- *      -Xlog:aot+class+fingerprint=trace -Xlog:aot+class+load=trace
- *      compiler.aot.fingerprint.SuperChanged TEST-MODIFIED
- */
-
-package compiler.aot.fingerprint;
-
-import jdk.test.lib.Asserts;
-import jdk.test.lib.InMemoryJavaCompiler;
-
-import java.io.*;
-
-class Bar {
-    volatile int x = 0;
-    volatile int y = 1;
-}
-
-class Foo extends Bar {
-
-    volatile int z;
-    int getX() {
-        for (z = 0; z < 10000; z++) {
-            if (z % 7 == 1) {
-                z += 2;
-            }
-        }
-        return x;
-    }
-}
-
-public class SuperChanged {
-    public static void main(String args[]) throws Throwable {
-        Foo f = new Foo();
-        System.out.println("f.getX = " + f.getX());
-        switch (args[0]) {
-        case "WRITE-UNMODIFIED-CLASS":
-            compileClass(false);
-            break;
-        case "WRITE-MODIFIED-CLASS":
-            compileClass(true);
-            break;
-        case "TEST-UNMODIFIED":
-            Asserts.assertTrue(f.getX() == 0, "getX from unmodified Foo class should return 0");
-            break;
-        case "TEST-MODIFIED":
-            Asserts.assertTrue(f.getX() == 1, "getX from modified Foo class should return 1");
-            break;
-        default:
-            throw new RuntimeException("unexpected option: " + args[0]);
-        }
-    }
-
-    static void compileClass(boolean isModified) throws Throwable {
-        String class_src_0 = "package compiler.aot.fingerprint; class Bar {volatile int x = 0;  volatile int y = 1;}";
-        String class_src_1 = "package compiler.aot.fingerprint; class Bar {volatile int y = 0;  volatile int x = 1;}";
-        String src = (isModified) ? class_src_1 : class_src_0;
-
-        String filename = System.getProperty("test.classes") + "/compiler/aot/fingerprint/Bar.class";
-        FileOutputStream fos = new FileOutputStream(filename);
-        fos.write(InMemoryJavaCompiler.compile("compiler.aot.fingerprint.Bar", src));
-        fos.close();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSearchTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect;
+
+
+import jdk.tools.jaotc.LoadedClass;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.BiConsumer;
+
+public class ClassSearchTest {
+    @Test(expected = InternalError.class)
+    public void itShouldThrowExceptionIfNoProvidersAvailable() {
+        ClassSearch target = new ClassSearch();
+        SearchPath searchPath = new SearchPath();
+        target.search(list("foo"), searchPath);
+    }
+
+    @Test
+    public void itShouldFindAProviderForEachEntry() {
+        Set<String> searched = new HashSet<>();
+        ClassSearch target = new ClassSearch();
+        target.addProvider(new SourceProvider() {
+            @Override
+            public ClassSource findSource(String name, SearchPath searchPath) {
+                searched.add(name);
+                return new NoopSource();
+            }
+        });
+        target.search(list("foo", "bar", "foobar"), null);
+        Assert.assertEquals(hashset("foo", "bar", "foobar"), searched);
+    }
+
+    @Test
+    public void itShouldSearchAllProviders() {
+        Set<String> visited = new HashSet<>();
+        ClassSearch target = new ClassSearch();
+        target.addProvider((name, searchPath) -> {
+            visited.add("1");
+            return null;
+        });
+        target.addProvider((name, searchPath) -> {
+            visited.add("2");
+            return null;
+        });
+
+        try {
+            target.search(list("foo"), null);
+        } catch (InternalError e) {
+            // throws because no provider gives a source
+        }
+
+        Assert.assertEquals(hashset("1", "2"), visited);
+    }
+
+    @Test
+    public void itShouldTryToLoadSaidClassFromClassLoader() {
+        Set<String> loaded = new HashSet<>();
+
+        ClassSearch target = new ClassSearch();
+        target.addProvider(new SourceProvider() {
+            @Override
+            public ClassSource findSource(String name, SearchPath searchPath) {
+                return new ClassSource() {
+                    @Override
+                    public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+                        consumer.accept("foo.Bar", new ClassLoader() {
+                            @Override
+                            public Class<?> loadClass(String name) throws ClassNotFoundException {
+                                loaded.add(name);
+                                return null;
+                            }
+                        });
+                    }
+                };
+            }
+        });
+
+        java.util.List<LoadedClass> search = target.search(list("/tmp/something"), null);
+        Assert.assertEquals(list(new LoadedClass("foo.Bar", null)), search);
+    }
+
+    @Test(expected = InternalError.class)
+    public void itShouldThrowInternalErrorWhenClassLoaderFails() {
+        ClassLoader classLoader = new ClassLoader() {
+            @Override
+            public Class<?> loadClass(String name1) throws ClassNotFoundException {
+                throw new ClassNotFoundException("failed to find " + name1);
+            }
+        };
+
+        ClassSearch target = new ClassSearch();
+        target.addProvider((name, searchPath) -> consumer -> consumer.accept("foo.Bar", classLoader));
+        target.search(list("foobar"), null);
+    }
+
+    private <T> List<T> list(T... entries) {
+        List<T> list = new ArrayList<T>();
+        for (T entry : entries) {
+            list.add(entry);
+        }
+        return list;
+    }
+
+    private <T> Set<T> hashset(T... entries) {
+        Set<T> set = new HashSet<T>();
+        for (T entry : entries) {
+            set.add(entry);
+        }
+        return set;
+    }
+
+    private static class NoopSource implements ClassSource {
+        @Override
+        public void eachClass(BiConsumer<String, ClassLoader> consumer) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/ClassSourceTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.nio.file.Paths;
+
+import static jdk.tools.jaotc.collect.ClassSource.makeClassName;
+
+public class ClassSourceTest {
+    @Test(expected=IllegalArgumentException.class)
+    public void itShouldThrowExceptionIfPathDoesntEndWithClass() {
+        makeClassName(Paths.get("Bar.clazz"));
+    }
+
+    @Test
+    public void itShouldReplaceSlashesWithDots() {
+        Assert.assertEquals("foo.Bar", makeClassName(Paths.get("foo/Bar.class")));
+    }
+
+    @Test
+    public void itShouldStripLeadingSlash() {
+        Assert.assertEquals("Hello", makeClassName(Paths.get("/Hello.class")));
+    }
+
+    @Test
+    public void itShouldReplaceMultipleDots() {
+        Assert.assertEquals("some.foo.bar.FooBar", makeClassName(Paths.get("/some/foo/bar/FooBar.class")));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeFileSupport.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect;
+
+import java.net.MalformedURLException;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Set;
+
+public class FakeFileSupport extends FileSupport {
+    private final Set<String> exists = new HashSet<>();
+    private final Set<String> directories = new HashSet<>();
+
+    private final Set<String> checkedExists = new HashSet<>();
+    private final Set<String> checkedDirectory = new HashSet<>();
+    private final Set<String> checkedJarFileSystemRoots = new HashSet<>();
+    private final Set<String> classloaderPaths = new HashSet<>();
+
+    private Path jarFileSystemRoot = null;
+    private final ClassLoader classLoader;
+
+    public FakeFileSupport(Set<String> existing, Set<String> directories) {
+        this.exists.addAll(existing);
+        this.directories.addAll(directories);
+
+        classLoader = new ClassLoader() {
+            @Override
+            public Class<?> loadClass(String name) throws ClassNotFoundException {
+                return null;
+            }
+        };
+    }
+
+    public void setJarFileSystemRoot(Path path) {
+        jarFileSystemRoot = path;
+    }
+
+    @Override
+    public boolean exists(Path path) {
+        checkedExists.add(path.toString());
+        return exists.contains(path.toString());
+    }
+
+    @Override
+    public boolean isDirectory(Path path) {
+        checkedDirectory.add(path.toString());
+        return directories.contains(path.toString());
+    }
+
+    @Override
+    public ClassLoader createClassLoader(Path path) throws MalformedURLException {
+        classloaderPaths.add(path.toString());
+        return classLoader;
+    }
+
+    @Override
+    public Path getJarFileSystemRoot(Path jarFile) {
+        checkedJarFileSystemRoots.add(jarFile.toString());
+        return jarFileSystemRoot;
+    }
+
+    @Override
+    public boolean isAbsolute(Path entry) {
+        return entry.toString().startsWith("/");
+    }
+
+    public void addExist(String name) {
+        exists.add(name);
+    }
+
+    public void addDirectory(String name) {
+        directories.add(name);
+    }
+
+    public Set<String> getCheckedExists() {
+        return checkedExists;
+    }
+
+    public Set<String> getCheckedDirectory() {
+        return checkedDirectory;
+    }
+
+    public Set<String> getCheckedJarFileSystemRoots() {
+        return checkedJarFileSystemRoots;
+    }
+
+    public Set<String> getClassloaderPaths() {
+        return classloaderPaths;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/FakeSearchPath.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect;
+
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Set;
+
+import static jdk.tools.jaotc.test.collect.Utils.set;
+
+public class FakeSearchPath extends SearchPath {
+    private Path path = null;
+    public Set<String> entries = set();
+
+    public FakeSearchPath(String name) {
+        if (name != null) {
+            path = Paths.get(name);
+        }
+    }
+
+    @Override
+    public Path find(FileSystem fileSystem, Path entry, String... defaults) {
+        entries.add(entry.toString());
+        return path;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/SearchPathTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static jdk.tools.jaotc.test.collect.Utils.set;
+import static org.junit.Assert.*;
+
+public class SearchPathTest {
+    private FakeFileSupport fileSupport;
+    private FileSystem fs;
+
+    @Before
+    public void setUp() throws Exception {
+        fs = FileSystems.getDefault();
+    }
+
+    @Test
+    public void itShouldUsePathIfPathIsAbsoluteAndExisting() {
+        fileSupport = new FakeFileSupport(set("/foo"), set());
+        SearchPath target = new SearchPath(fileSupport);
+        Path foo = Paths.get("/foo");
+        Path result = target.find(fs, foo);
+        assertSame(result, foo);
+    }
+
+    @Test
+    public void itShouldReturnNullIfPathIsAbsoluteAndNonExisting() {
+        fileSupport = new FakeFileSupport(set(), set());
+        SearchPath target = new SearchPath(fileSupport);
+        Path result = target.find(fs, Paths.get("/bar"));
+        assertNull(result);
+    }
+
+    @Test
+    public void itShouldUseRelativeExisting() {
+        fileSupport = new FakeFileSupport(set("hello", "tmp/hello", "search/hello"), set());
+        SearchPath target = new SearchPath(fileSupport);
+        target.add("search");
+        Path hello = Paths.get("hello");
+        Path result = target.find(fs, hello, "tmp");
+        assertSame(result, hello);
+    }
+
+    @Test
+    public void itShouldSearchDefaultsBeforeSearchPaths() {
+        fileSupport = new FakeFileSupport(set("bar/foobar"), set());
+        SearchPath target = new SearchPath(fileSupport);
+        Path result = target.find(fs, Paths.get("foobar"), "default1", "bar");
+        assertEquals("bar/foobar", result.toString());
+        assertEquals(set("foobar", "default1/foobar", "bar/foobar"), fileSupport.getCheckedExists());
+    }
+
+    @Test
+    public void itShouldUseSearchPathsIfNotInDefaults() {
+        fileSupport = new FakeFileSupport(set("bar/tmp/foobar"), set());
+        SearchPath target = new SearchPath(fileSupport);
+        target.add("foo/tmp", "bar/tmp");
+
+        Path result = target.find(fs, Paths.get("foobar"), "foo", "bar");
+        assertEquals("bar/tmp/foobar", result.toString());
+        assertEquals(set("foobar", "foo/foobar", "bar/foobar", "bar/tmp/foobar", "foo/tmp/foobar"), fileSupport.getCheckedExists());
+    }
+
+    @Test
+    public void itShouldReturnNullIfNoExistingPathIsFound() {
+        fileSupport = new FakeFileSupport(set(), set());
+        SearchPath target = new SearchPath(fileSupport);
+        target.add("dir1", "dir2");
+
+        Path result = target.find(fs, Paths.get("entry"), "dir3", "dir4");
+        assertNull(result);
+        assertEquals(set("entry", "dir1/entry", "dir2/entry", "dir3/entry", "dir4/entry"), fileSupport.getCheckedExists());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/Utils.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class Utils {
+    public static <T> Set<T> set(T... entries) {
+        Set<T> set = new HashSet<T>();
+        for (T entry : entries) {
+            set.add(entry);
+        }
+        return set;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/directory/DirectorySourceProviderTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect.directory;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.test.collect.FakeFileSupport;
+import jdk.tools.jaotc.test.collect.FileSupport;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.MalformedURLException;
+import java.nio.file.Path;
+import java.util.Set;
+
+import static jdk.tools.jaotc.test.collect.Utils.set;
+
+public class DirectorySourceProviderTest {
+    @Test
+    public void itShouldReturnNullForNonExistantPath() {
+        DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set(), set()));
+        ClassSource result = target.findSource("hello", null);
+        Assert.assertNull(result);
+    }
+
+    @Test
+    public void itShouldReturnNullForNonDirectory() {
+        DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set("foobar"), set()));
+        ClassSource result = target.findSource("foobar", null);
+        Assert.assertNull(result);
+    }
+
+    @Test
+    public void itShouldReturnNullForMalformedURI() {
+        Set<String> visited = set();
+        DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set("foobar"), set("foobar")) {
+            @Override
+            public ClassLoader createClassLoader(Path path) throws MalformedURLException {
+                visited.add("1");
+                throw new MalformedURLException("...");
+            }
+        });
+        ClassSource result = target.findSource("foobar", null);
+        Assert.assertNull(result);
+        Assert.assertEquals(set("1"), visited);
+    }
+
+    @Test
+    public void itShouldCreateSourceIfNameExistsAndIsADirectory() {
+        FileSupport fileSupport = new FakeFileSupport(set("foo"), set("foo"));
+        DirectorySourceProvider target = new DirectorySourceProvider(fileSupport);
+        ClassSource foo = target.findSource("foo", null);
+        Assert.assertNotNull(foo);
+        Assert.assertEquals("directory:foo", foo.toString());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/jar/JarSourceProviderTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect.jar;
+
+import jdk.tools.jaotc.collect.ClassSource;
+import jdk.tools.jaotc.test.collect.FakeFileSupport;
+import jdk.tools.jaotc.test.collect.FakeSearchPath;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.ProviderNotFoundException;
+import java.util.Set;
+
+import static jdk.tools.jaotc.test.collect.Utils.set;
+
+public class JarSourceProviderTest {
+
+    private FakeFileSupport fileSupport;
+    private JarSourceProvider target;
+
+    @Before
+    public void setUp() throws Exception {
+        fileSupport = new FakeFileSupport(set(), set());
+        target = new JarSourceProvider(fileSupport);
+    }
+
+    @Test
+    public void itShouldUseSearchPathToFindPath() {
+        Set<String> visited = set();
+        JarSourceProvider target = new JarSourceProvider(fileSupport);
+        FakeSearchPath searchPath = new FakeSearchPath(null);
+        ClassSource source = target.findSource("hello", searchPath);
+
+        Assert.assertEquals(set("hello"), searchPath.entries);
+    }
+
+    @Test
+    public void itShouldReturnNullIfPathIsNull() {
+        JarSourceProvider target = new JarSourceProvider(fileSupport);
+        ClassSource source = target.findSource("foobar", new FakeSearchPath(null));
+        Assert.assertNull(source);
+    }
+
+    @Test
+    public void itShouldReturnNullIfPathIsDirectory() {
+        fileSupport.addDirectory("hello/foobar");
+        ClassSource source = target.findSource("foobar", new FakeSearchPath("hello/foobar"));
+
+        Assert.assertNull(source);
+        Assert.assertEquals(set("hello/foobar"), fileSupport.getCheckedDirectory());
+    }
+
+    @Test
+    public void itShouldReturnNullIfUnableToMakeJarFileSystem() {
+        fileSupport.setJarFileSystemRoot(null);
+        ClassSource result = target.findSource("foobar", new FakeSearchPath("foo/bar"));
+
+        Assert.assertEquals(set("foo/bar"), fileSupport.getCheckedJarFileSystemRoots());
+        Assert.assertNull(result);
+    }
+
+    @Test
+    public void itShouldReturnNullIfNotValidJarProvider() {
+        fileSupport = new FakeFileSupport(set(), set()) {
+
+            @Override
+            public Path getJarFileSystemRoot(Path jarFile) {
+                super.getJarFileSystemRoot(jarFile);
+                throw new ProviderNotFoundException();
+            }
+        };
+        fileSupport.setJarFileSystemRoot(null);
+        target = new JarSourceProvider(fileSupport);
+
+        ClassSource result = target.findSource("foobar", new FakeSearchPath("foo/bar"));
+
+        Assert.assertEquals(set("foo/bar"), fileSupport.getCheckedJarFileSystemRoots());
+        Assert.assertNull(result);
+    }
+
+    @Test
+    public void itShouldReturnSourceWhenAllIsValid() {
+        fileSupport.setJarFileSystemRoot(Paths.get("some/bar"));
+        ClassSource result = target.findSource("foobar", new FakeSearchPath("this/bar"));
+
+        Assert.assertEquals(set("this/bar"), fileSupport.getClassloaderPaths());
+        Assert.assertEquals("jar:this/bar", result.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/aot/jdk.tools.jaotc.test/src/jdk/tools/jaotc/test/collect/module/ModuleSourceProviderTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017, 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 jdk.tools.jaotc.test.collect.module;
+
+import jdk.tools.jaotc.*;
+import jdk.tools.jaotc.test.collect.FakeSearchPath;
+import jdk.tools.jaotc.test.collect.Utils;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.file.FileSystems;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class ModuleSourceProviderTest {
+    private ClassLoader classLoader;
+    private ModuleSourceProvider target;
+
+    @Before
+    public void setUp() {
+        classLoader = new FakeClassLoader();
+        target = new ModuleSourceProvider(FileSystems.getDefault(), classLoader);
+    }
+
+    @Test
+    public void itShouldUseSearchPath() {
+        FakeSearchPath searchPath = new FakeSearchPath("blah/java.base");
+        ModuleSource source = (ModuleSource) target.findSource("java.base", searchPath);
+        assertEquals(Utils.set("java.base"), searchPath.entries);
+        assertEquals("blah/java.base", source.getModulePath().toString());
+        assertEquals("module:blah/java.base", source.toString());
+    }
+
+    @Test
+    public void itShouldReturnNullIfSearchPathReturnsNull() {
+        FakeSearchPath searchPath = new FakeSearchPath(null);
+        ModuleSource source = (ModuleSource) target.findSource("jdk.base", searchPath);
+        assertEquals(Utils.set("jdk.base"), searchPath.entries);
+        assertNull(source);
+    }
+
+    private static class FakeClassLoader extends ClassLoader {
+        @Override
+        public Class<?> loadClass(String name) throws ClassNotFoundException {
+            return null;
+        }
+    }
+}
--- a/hotspot/test/compiler/aot/verification/ClassAndLibraryNotMatchTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/verification/ClassAndLibraryNotMatchTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -85,9 +85,8 @@
     }
 
     private void compileAotLibrary() {
-        AotCompiler.launchCompiler(LIB_NAME, HELLO_WORLD_CLASS_NAME + ".class",
-                Arrays.asList("-classpath", Utils.TEST_CLASS_PATH + File.pathSeparator
-                        + Utils.TEST_SRC), null);
+        AotCompiler.launchCompiler(LIB_NAME, HELLO_WORLD_CLASS_NAME,
+                Arrays.asList("-classpath", Utils.TEST_CLASS_PATH + ":."), null);
     }
 
     private void runAndCheckHelloWorld(String checkString) {
--- a/hotspot/test/compiler/aot/verification/vmflags/BasicFlagsChange.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/aot/verification/vmflags/BasicFlagsChange.java	Fri Feb 10 08:57:42 2017 -0800
@@ -76,7 +76,7 @@
         extraOpts.add(option);
         extraOpts.add("-classpath");
         extraOpts.add(Utils.TEST_CLASS_PATH + File.pathSeparator + Utils.TEST_SRC);
-        AotCompiler.launchCompiler(libName, className + ".class", extraOpts, null);
+        AotCompiler.launchCompiler(libName, className, extraOpts, null);
     }
 
     private static void runAndCheck(String option, String libName,
--- a/hotspot/test/compiler/arraycopy/TestArrayCopyNoInitDeopt.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/arraycopy/TestArrayCopyNoInitDeopt.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,7 +25,7 @@
  * @test
  * @bug 8072016
  * @summary Infinite deoptimization/recompilation cycles in case of arraycopy with tightly coupled allocation
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -86,8 +86,8 @@
     }
 
     static public void main(String[] args) throws Exception {
-        if (!Platform.isServer()) {
-            throw new Error("TESTBUG: Not server VM");
+        if (!Platform.isServer() || Platform.isEmulatedClient()) {
+            throw new Error("TESTBUG: Not server mode");
         }
         // Only execute if C2 is available
         if (TIERED_STOP_AT_LEVEL == CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestArrayCopyUNCBadMem.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, Red Hat, Inc. 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 8173147
+ * @summary Loads generated at uncommon trap from eliminated arraycopy have incorrect memory state
+ * @run main/othervm -XX:CompileOnly=TestArrayCopyUNCBadMem::test -Xcomp TestArrayCopyUNCBadMem
+ *
+ */
+
+
+public class TestArrayCopyUNCBadMem {
+
+    volatile static int field;
+
+    static class unloaded {
+        static int dummy;
+    }
+
+    static int test(int[] input) {
+        int[] alloc = new int[10];
+        System.arraycopy(input, 0, alloc, 0, 10);
+
+        // membars to have anti-dependence edges and make scheduling
+        // fail
+        field = 0x42;
+
+        // uncommon trap
+        unloaded.dummy = 0x42;
+
+        return alloc[0] + alloc[1];
+    }
+
+    public static void main(String[] args) {
+        int[] array = new int[10];
+        System.arraycopy(array, 0, array, 0, 0); // load System class
+        test(array);
+    }
+}
--- a/hotspot/test/compiler/c1/CanonicalizeArrayLength.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/c1/CanonicalizeArrayLength.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8150102 8150514 8150534
+ * @bug 8150102 8150514 8150534 8171435
  * @summary C1 crashes in Canonicalizer::do_ArrayLength() after fix for JDK-8150102
  *
  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
@@ -31,7 +31,7 @@
  *                   -XX:-BackgroundCompilation
  *                   compiler.c1.CanonicalizeArrayLength
  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
- *                   -XX:CompileThreshold=100 -XX:+TieredCompilation -XX:TieredStopAtLevel=1
+ *                   -XX:CompileThreshold=100 -XX:+TieredCompilation -XX:TieredStopAtLevel=3
  *                   -XX:-BackgroundCompilation
  *                   -XX:+PatchALot
  *                   compiler.c1.CanonicalizeArrayLength
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c1/Test8172751.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, 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 8172751
+ * @summary OSR compilation at unreachable bci causes C1 crash
+ *
+ * @run main/othervm -XX:-BackgroundCompilation compiler.c1.Test8172751
+ */
+
+package compiler.c1;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MutableCallSite;
+
+public class Test8172751 {
+    private static final MethodHandle CONSTANT_TRUE = MethodHandles.constant(boolean.class, true);
+    private static final MethodHandle CONSTANT_FALSE = MethodHandles.constant(boolean.class, false);
+    private static final MutableCallSite CALL_SITE = new MutableCallSite(CONSTANT_FALSE);
+    private static final int LIMIT = 1_000_000;
+    private static volatile int counter;
+
+    private static boolean doSomething() {
+        return counter++ < LIMIT;
+    }
+
+    private static void executeLoop() {
+        /*
+         * Start off with executing the first loop, then change the call site
+         * target so as to switch over to the second loop but continue running
+         * in the first loop. Eventually, an OSR compilation of the first loop
+         * is triggered. Yet C1 will not find the OSR entry, since it will
+         * have optimized out the first loop already during parsing.
+         */
+        if (CALL_SITE.getTarget() == CONSTANT_FALSE) {
+            int count = 0;
+            while (doSomething()) {
+                if (count++ == 1) {
+                    flipSwitch();
+                }
+            }
+        } else {
+            while (doSomething()) {
+            }
+        }
+    }
+
+    private static void flipSwitch() {
+        CALL_SITE.setTarget(CONSTANT_TRUE);
+    }
+
+    public static void main(String[] args) {
+        executeLoop();
+    }
+}
--- a/hotspot/test/compiler/c2/cr6589834/Test_ia32.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/c2/cr6589834/Test_ia32.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -30,7 +30,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  *
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
--- a/hotspot/test/compiler/c2/cr7200264/Test7200264.sh	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-#!/bin/sh
-# 
-# Copyright (c) 2012, 2015, 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.
-# 
-# 
-
-## some tests require path to find test source dir
-if [ "${TESTSRC}" = "" ]
-then
-  TESTSRC=${PWD}
-  echo "TESTSRC not set.  Using "${TESTSRC}" as default"
-fi
-echo "TESTSRC=${TESTSRC}"
-## Adding common setup Variables for running shell tests.
-. ${TESTSRC}/../../../test_env.sh
-
-${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -Xinternalversion | sed 's/amd64/x86/' | grep "x86" | grep "Server VM" | grep "debug"
-
-# Only test fastdebug Server VM on x86
-if [ $? != 0 ]
-then
-    echo "Test Passed"
-    exit 0
-fi
-
-# grep for support integer multiply vectors (cpu with SSE4.1)
-${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -XX:+PrintMiscellaneous -XX:+Verbose -version | grep "cores per cpu" | grep "sse4.1"
-
-if [ $? != 0 ]
-then
-    SSE=2
-else
-    SSE=4
-fi
-
-cp ${TESTSRC}${FS}TestIntVect.java .
-${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} -d . TestIntVect.java
-
-# CICompilerCount must be at least 2 with -TieredCompilation
-${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -Xbatch -XX:-TieredCompilation  \
-        -XX:CICompilerCount=2 -XX:+PrintCompilation -XX:+TraceNewVectors \
-        compiler.c2.cr7200264.TestIntVect > test.out 2>&1
-
-COUNT=`grep AddVI test.out | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 4 ]
-then
-    echo "Test Failed: AddVI $COUNT < 4"
-    exit 1
-fi
-
-# AddVI is generated for test_subc
-COUNT=`grep SubVI test.out | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 4 ]
-then
-    echo "Test Failed: SubVI $COUNT < 4"
-    exit 1
-fi
-
-# MulVI is only supported with SSE4.1.
-if [ $SSE -gt 3 ]
-then
-# LShiftVI+SubVI is generated for test_mulc
-COUNT=`grep MulVI test.out | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 2 ]
-then
-    echo "Test Failed: MulVI $COUNT < 2"
-    exit 1
-fi
-fi
-
-COUNT=`grep AndV test.out | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 3 ]
-then
-    echo "Test Failed: AndV $COUNT < 3"
-    exit 1
-fi
-
-COUNT=`grep OrV test.out | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 3 ]
-then
-    echo "Test Failed: OrV $COUNT < 3"
-    exit 1
-fi
-
-COUNT=`grep XorV test.out | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 3 ]
-then
-    echo "Test Failed: XorV $COUNT < 3"
-    exit 1
-fi
-
-# LShiftVI+SubVI is generated for test_mulc
-COUNT=`grep LShiftVI test.out | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 5 ]
-then
-    echo "Test Failed: LShiftVI $COUNT < 5"
-    exit 1
-fi
-
-COUNT=`grep RShiftVI test.out | sed '/URShiftVI/d' | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 3 ]
-then
-    echo "Test Failed: RShiftVI $COUNT < 3"
-    exit 1
-fi
-
-COUNT=`grep URShiftVI test.out | wc -l | awk '{print $1}'`
-if [ $COUNT -lt 3 ]
-then
-    echo "Test Failed: URShiftVI $COUNT < 3"
-    exit 1
-fi
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c2/cr7200264/TestDriver.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,68 @@
+/*
+ * 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 compiler.c2.cr7200264;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestDriver {
+    private final Map<String, Long> expectedVectorizationNumbers
+            = new HashMap<>();
+
+    public void addExpectedVectorization(String v, long num) {
+        expectedVectorizationNumbers.put(v, num);
+    }
+
+    public void run() throws Throwable {
+        verifyVectorizationNumber(executeApplication());
+    }
+
+    private List<String> executeApplication() throws Throwable {
+        OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJvmAllArgs(
+            "-Xbatch",
+            "-XX:-TieredCompilation",
+            "-XX:+PrintCompilation",
+            "-XX:+TraceNewVectors",
+            TestIntVect.class.getName());
+        outputAnalyzer.shouldHaveExitValue(0);
+        return outputAnalyzer.asLines();
+    }
+
+    private void verifyVectorizationNumber(List<String> vectorizationLog) {
+        for (Map.Entry<String, Long> entry : expectedVectorizationNumbers.entrySet()) {
+            String v = "\t" + entry.getKey();
+            long actualNum = vectorizationLog.stream()
+                    .filter(s -> s.contains(v)).count();
+            long expectedNum = entry.getValue();
+            Asserts.assertGTE(actualNum, expectedNum,
+                              "Unexpected " + entry.getKey() + " number");
+        }
+    }
+}
--- a/hotspot/test/compiler/c2/cr7200264/TestIntVect.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/c2/cr7200264/TestIntVect.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -21,14 +21,6 @@
  * questions.
  */
 
-/**
- * @test
- * @bug 7200264
- * @summary 7192963 changes disabled shift vectors
- *
- * @run shell Test7200264.sh
- */
-
 package compiler.c2.cr7200264;
 /*
  * Copy of test/compiler/6340864/TestIntVect.java without performance tests.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c2/cr7200264/TestSSE2IntVect.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,49 @@
+/*
+ * 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 7200264
+ * @summary 7192963 changes disabled shift vectors
+ * @requires vm.cpu.features ~= ".*sse2.*" & vm.debug & vm.flavor == "server"
+ * @requires !vm.emulatedClient
+ * @library /test/lib /
+ * @run driver compiler.c2.cr7200264.TestSSE2IntVect
+ */
+
+package compiler.c2.cr7200264;
+
+public class TestSSE2IntVect {
+    public static void main(String[] args) throws Throwable {
+        TestDriver test = new TestDriver();
+        test.addExpectedVectorization("AddVI", 4);
+        test.addExpectedVectorization("SubVI", 4);
+        test.addExpectedVectorization("AndV", 3);
+        test.addExpectedVectorization("OrV", 3);
+        test.addExpectedVectorization("XorV", 3);
+        test.addExpectedVectorization("LShiftVI", 5);
+        test.addExpectedVectorization("RShiftVI", 3);
+        test.addExpectedVectorization("URShiftVI", 3);
+        test.run();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c2/cr7200264/TestSSE4IntVect.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,42 @@
+/*
+ * 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 7200264
+ * @summary 7192963 changes disabled shift vectors
+ * @requires vm.cpu.features ~= ".*sse4\\.1.*" & vm.debug & vm.flavor == "server"
+ * @requires !vm.emulatedClient
+ * @library /test/lib /
+ * @run driver compiler.c2.cr7200264.TestSSE4IntVect
+ */
+
+package compiler.c2.cr7200264;
+
+public class TestSSE4IntVect {
+    public static void main(String[] args) throws Throwable {
+        TestDriver test = new TestDriver();
+        test.addExpectedVectorization("MulVI", 2);
+        test.run();
+    }
+}
--- a/hotspot/test/compiler/ciReplay/TestVMNoCompLevel.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/ciReplay/TestVMNoCompLevel.java	Fri Feb 10 08:57:42 2017 -0800
@@ -65,7 +65,11 @@
             throw new Error("Failed to read/write replay data: " + ioe, ioe);
         }
         if (CLIENT_VM_AVAILABLE) {
-            negativeTest(CLIENT_VM_OPTION);
+            if (SERVER_VM_AVAILABLE) {
+                negativeTest(CLIENT_VM_OPTION);
+            } else {
+                positiveTest(CLIENT_VM_OPTION);
+            }
         }
         if (SERVER_VM_AVAILABLE) {
             positiveTest(TIERED_DISABLED_VM_OPTION, SERVER_VM_OPTION);
--- a/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/codecache/cli/TestSegmentedCodeCacheOption.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -29,7 +29,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  *
  * @run driver compiler.codecache.cli.TestSegmentedCodeCacheOption
  */
--- a/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/codecache/cli/codeheapsize/TestCodeHeapSizeOptions.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -29,7 +29,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  *
  * @run driver/timeout=240 compiler.codecache.cli.codeheapsize.TestCodeHeapSizeOptions
  */
--- a/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/codecache/cli/printcodecache/TestPrintCodeCacheOption.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -29,7 +29,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  *
  * @run main/timeout=240 compiler.codecache.cli.printcodecache.TestPrintCodeCacheOption
  */
--- a/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/codecache/stress/OverloadCompileQueueTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -65,9 +65,9 @@
             AVAILABLE_LEVELS = IntStream
                     .rangeClosed(LEVEL_SIMPLE, TIERED_STOP_AT_LEVEL)
                     .toArray();
-        } else if (Platform.isServer()) {
+        } else if (Platform.isServer() && !Platform.isEmulatedClient()) {
             AVAILABLE_LEVELS = new int[] { LEVEL_FULL_OPTIMIZATION };
-        } else if (Platform.isClient() || Platform.isMinimal()) {
+        } else if (Platform.isClient() || Platform.isMinimal() || Platform.isEmulatedClient()) {
             AVAILABLE_LEVELS = new int[] { LEVEL_SIMPLE };
         } else {
             throw new Error("TESTBUG: unknown VM: " + Platform.vmName);
--- a/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java	Fri Feb 10 08:57:42 2017 -0800
@@ -75,7 +75,7 @@
                 prepareArguments(prepareBooleanFlag(AESIntrinsicsBase
                         .USE_AES, true)));
         final String errorMessage = "Case testUseAES failed";
-        if (Platform.isServer()) {
+        if (Platform.isServer() && !Platform.isEmulatedClient()) {
             verifyOutput(new String[]{AESIntrinsicsBase.CIPHER_INTRINSIC,
                     AESIntrinsicsBase.AES_INTRINSIC}, null, errorMessage,
                     outputAnalyzer);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/gcbarriers/TestMembarDependencies.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, 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 TestMembarDependencies
+ * @bug 8172850
+ * @summary Tests correct scheduling of memory loads around MembarVolatile emitted by GC barriers.
+ * @library /test/lib /
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run driver compiler.membars.TestMembarDependencies
+ */
+
+package compiler.membars;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestMembarDependencies {
+    private static TestMembarDependencies f1;
+    private static TestMembarDependencies f2;
+
+    public static void main(String args[]) throws Exception {
+        if (args.length == 0) {
+            // For debugging, add "-XX:+TraceOptoPipelining"
+            OutputAnalyzer oa = ProcessTools.executeTestJvm("-XX:+IgnoreUnrecognizedVMOptions",
+                "-XX:-TieredCompilation", "-XX:-BackgroundCompilation", "-XX:+PrintOpto",
+                "-XX:CompileCommand=compileonly,compiler.membars.TestMembarDependencies::test*",
+                "-XX:CompileCommand=dontinline,compiler.membars.TestMembarDependencies::test_m1",
+                TestMembarDependencies.class.getName(), "run");
+            // C2 should not crash or bail out from compilation
+            oa.shouldHaveExitValue(0);
+            oa.shouldNotMatch("Bailout: Recompile without subsuming loads");
+            System.out.println(oa.getOutput());
+        } else {
+            f2 = new TestMembarDependencies();
+            // Trigger compilation of test1 and test2
+            for (int i = 0; i < 10_000; ++i) {
+              f2.test1(f2);
+              f2.test2(f2);
+            }
+        }
+    }
+
+    public void test_m1() { }
+    public void test_m2() { }
+
+    public void test1(TestMembarDependencies obj) {
+        // Try/catch/finally is used to create a CFG block without a test + jmpCon
+        // allowing GCM to schedule the testN_mem_reg0 instruction into that block.
+        try {
+            // Method call defines memory state that is then
+            // used by subsequent instructions/blocks (see below).
+            test_m1();
+        } catch (Exception e) {
+
+        } finally {
+            // Oop write to field emits a GC post-barrier with a MembarVolatile
+            // which has a wide memory effect (kills all memory). This creates an
+            // anti-dependency on all surrounding memory loads.
+            f1 = obj;
+        }
+        // The empty method m2 is inlined but the null check of f2 remains. It is encoded
+        // as CmpN(LoadN(MEM), NULL) where MEM is the memory after the call to test_m1().
+        // This is matched to testN_mem_reg0 on x86 which is scheduled before the barrier
+        // in the try/catch block due to the anti-dependency on the MembarVolatile.
+        // C2 crashes in the register allocator when trying to spill the flag register
+        // to keep the result of the testN instruction live from the try/catch block
+        // until it is here.
+        f2.test_m2();
+    }
+
+    public void test2(TestMembarDependencies obj) {
+        // Same as test1 but without try/catch/finally.
+        // This causes C2 to bail out in block local scheduling because testN_mem_reg0 is
+        // scheduled into a block that already contains another test + jmpCon instruction.
+        test_m1();
+        f1 = obj;
+        f2.test_m2();
+    }
+}
--- a/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/IntrinsicAvailableTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -114,7 +114,7 @@
 
     public void test() throws Exception {
         Executable intrinsicMethod = testCase.getExecutable();
-        if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) {
+        if (Platform.isServer() && !Platform.isEmulatedClient() && (TIERED_STOP_AT_LEVEL == COMP_LEVEL_FULL_OPTIMIZATION)) {
             if (TIERED_COMPILATION) {
                 checkIntrinsicForCompilationLevel(intrinsicMethod, COMP_LEVEL_SIMPLE);
             }
--- a/hotspot/test/compiler/intrinsics/IntrinsicDisabledTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/IntrinsicDisabledTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -197,7 +197,8 @@
     }
 
     public static void main(String args[]) {
-        if (Platform.isServer() && (TIERED_STOP_AT_LEVEL == CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION)) {
+        if (Platform.isServer() && !Platform.isEmulatedClient() &&
+                                   (TIERED_STOP_AT_LEVEL == CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION)) {
             if (TIERED_COMPILATION) {
                 test(CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE);
             }
--- a/hotspot/test/compiler/intrinsics/bigInteger/MontgomeryMultiplyTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bigInteger/MontgomeryMultiplyTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -26,7 +26,7 @@
  * @test
  * @bug 8130150 8131779 8139907
  * @summary Verify that the Montgomery multiply and square intrinsic works and correctly checks their arguments.
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @modules java.base/jdk.internal.misc:open
  * @modules java.base/java.math:open
  * @library /test/lib /
@@ -314,8 +314,8 @@
     }
 
     public static void main(String args[]) {
-        if (!Platform.isServer()) {
-            throw new Error("TESTBUG: Not server VM");
+        if (!Platform.isServer() || Platform.isEmulatedClient()) {
+            throw new Error("TESTBUG: Not server mode");
         }
         if (wb.isIntrinsicAvailable(getExecutable(true), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) &&
                 wb.isIntrinsicAvailable(getExecutable(false), CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION)) {
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestI.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AndnTestL.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BmiIntrinsicBase.java	Fri Feb 10 08:57:42 2017 -0800
@@ -78,7 +78,7 @@
 
         System.out.println(testCase.name());
 
-        if (TIERED_COMPILATION && TIERED_STOP_AT_LEVEL != CompilerWhiteBoxTest.COMP_LEVEL_MAX) {
+        if (TIERED_COMPILATION && TIERED_STOP_AT_LEVEL != CompilerWhiteBoxTest.COMP_LEVEL_MAX || Platform.isEmulatedClient()) {
             System.out.println("TieredStopAtLevel value (" + TIERED_STOP_AT_LEVEL + ") is too low, test SKIPPED");
             return;
         }
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8031321
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
--- a/hotspot/test/compiler/intrinsics/klass/CastNullCheckDroppingsTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/klass/CastNullCheckDroppingsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,7 +25,7 @@
  * @test NullCheckDroppingsTest
  * @bug 8054492
  * @summary Casting can result in redundant null checks in generated code
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -84,8 +84,8 @@
     int[]   asink;
 
     public static void main(String[] args) throws Exception {
-        if (!Platform.isServer()) {
-            throw new Error("TESTBUG: Not server VM");
+        if (!Platform.isServer() || Platform.isEmulatedClient()) {
+            throw new Error("TESTBUG: Not server mode");
         }
         // Make sure background compilation is disabled
         if (WHITE_BOX.getBooleanVMFlag("BackgroundCompilation")) {
--- a/hotspot/test/compiler/intrinsics/mathexact/sanity/IntrinsicBase.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/IntrinsicBase.java	Fri Feb 10 08:57:42 2017 -0800
@@ -50,7 +50,7 @@
 
         int expectedIntrinsicCount = 0;
 
-        if (Platform.isServer()) {
+        if (Platform.isServer() && !Platform.isEmulatedClient()) {
             if (TIERED_COMPILATION) {
                 int max_level = TIERED_STOP_AT_LEVEL;
                 expectedIntrinsicCount = (max_level == COMP_LEVEL_MAX) ? 1 : 0;
--- a/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	Fri Feb 10 08:57:42 2017 -0800
@@ -48,8 +48,12 @@
         return CTVM.getExceptionTableStart((HotSpotResolvedJavaMethodImpl)method);
     }
 
-    public static boolean canInlineMethod(HotSpotResolvedJavaMethod method) {
-        return CTVM.canInlineMethod((HotSpotResolvedJavaMethodImpl)method);
+    public static boolean isCompilable(HotSpotResolvedJavaMethod method) {
+        return CTVM.isCompilable((HotSpotResolvedJavaMethodImpl)method);
+    }
+
+    public static boolean hasNeverInlineDirective(HotSpotResolvedJavaMethod method) {
+        return CTVM.hasNeverInlineDirective((HotSpotResolvedJavaMethodImpl)method);
     }
 
     public static boolean shouldInlineMethod(HotSpotResolvedJavaMethod method) {
--- a/hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2015, 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 8136421
- * @requires vm.jvmci
- * @library /test/lib /
- * @library ../common/patches
- * @modules java.base/jdk.internal.misc
- * @modules java.base/jdk.internal.org.objectweb.asm
- *          java.base/jdk.internal.org.objectweb.asm.tree
- *          jdk.vm.ci/jdk.vm.ci.hotspot
- *          jdk.vm.ci/jdk.vm.ci.code
- *
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
- * @run driver ClassFileInstaller sun.hotspot.WhiteBox
- *                                sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:.
- *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- *                   compiler.jvmci.compilerToVM.CanInlineMethodTest
- */
-
-package compiler.jvmci.compilerToVM;
-
-import compiler.jvmci.common.CTVMUtilities;
-import jdk.test.lib.Asserts;
-import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import sun.hotspot.WhiteBox;
-
-import java.lang.reflect.Executable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class CanInlineMethodTest {
-
-    private static final WhiteBox WB = WhiteBox.getWhiteBox();
-
-    public static void main(String[] args) {
-        List<Executable> testCases = createTestCases();
-        testCases.forEach(CanInlineMethodTest::runSanityTest);
-    }
-
-    private static void runSanityTest(Executable aMethod) {
-        HotSpotResolvedJavaMethod method = CTVMUtilities
-                .getResolvedMethod(aMethod);
-        boolean canInline = CompilerToVMHelper.canInlineMethod(method);
-        boolean expectedCanInline = !WB.testSetDontInlineMethod(aMethod,
-                true);
-        Asserts.assertEQ(canInline, expectedCanInline, "Unexpected initial " +
-                "value of property 'can inline'");
-
-        canInline = CompilerToVMHelper.canInlineMethod(method);
-        Asserts.assertFalse(canInline, aMethod + "Unexpected value of " +
-                "property 'can inline' after setting 'do not inline' to true");
-        WB.testSetDontInlineMethod(aMethod, false);
-        canInline = CompilerToVMHelper.canInlineMethod(method);
-        Asserts.assertTrue(canInline, "Unexpected value of " +
-                "property 'can inline' after setting 'do not inline' to false");
-    }
-
-    private static List<Executable> createTestCases() {
-        List<Executable> testCases = new ArrayList<>();
-
-        Class<?> aClass = DummyClass.class;
-        testCases.addAll(Arrays.asList(aClass.getDeclaredMethods()));
-        testCases.addAll(Arrays.asList(aClass.getDeclaredConstructors()));
-        return testCases;
-    }
-}
--- a/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -67,13 +67,13 @@
     private static void runSanityTest(Executable aMethod) {
         HotSpotResolvedJavaMethod method = CTVMUtilities
                 .getResolvedMethod(aMethod);
-        boolean canInline = CompilerToVMHelper.canInlineMethod(method);
-        Asserts.assertTrue(canInline, "Unexpected initial " +
-                "value of property 'can inline'");
+        boolean hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
+        Asserts.assertFalse(hasNeverInlineDirective, "Unexpected initial " +
+                "value of property 'hasNeverInlineDirective'");
         CompilerToVMHelper.doNotInlineOrCompile(method);
-        canInline = CompilerToVMHelper.canInlineMethod(method);
-        Asserts.assertFalse(canInline, aMethod
-                + " : can be inlined even after doNotInlineOrCompile'");
+        hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
+        Asserts.assertTrue(hasNeverInlineDirective, aMethod
+                + " : hasNeverInlineDirective is false even after doNotInlineOrCompile'");
     }
 
     private static List<Executable> createTestCases() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/HasNeverInlineDirectiveTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires vm.jvmci
+ * @library /test/lib /
+ * @library ../common/patches
+ * @modules java.base/jdk.internal.misc
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.org.objectweb.asm.tree
+ *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.code
+ *
+ * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:.
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *                   compiler.jvmci.compilerToVM.HasNeverInlineDirectiveTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import jdk.test.lib.Asserts;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import sun.hotspot.WhiteBox;
+
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class HasNeverInlineDirectiveTest {
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    public static void main(String[] args) {
+        List<Executable> testCases = createTestCases();
+        testCases.forEach(HasNeverInlineDirectiveTest::runSanityTest);
+    }
+
+    private static void runSanityTest(Executable aMethod) {
+        HotSpotResolvedJavaMethod method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        boolean hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
+        boolean expected = WB.testSetDontInlineMethod(aMethod, true);
+        Asserts.assertEQ(hasNeverInlineDirective, expected, "Unexpected initial " +
+                "value of property 'hasNeverInlineDirective'");
+
+        hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
+        Asserts.assertTrue(hasNeverInlineDirective, aMethod + "Unexpected value of " +
+                "property 'hasNeverInlineDirective' after setting 'do not inline' to true");
+        WB.testSetDontInlineMethod(aMethod, false);
+        hasNeverInlineDirective = CompilerToVMHelper.hasNeverInlineDirective(method);
+        Asserts.assertFalse(hasNeverInlineDirective, "Unexpected value of " +
+                "property 'hasNeverInlineDirective' after setting 'do not inline' to false");
+    }
+
+    private static List<Executable> createTestCases() {
+        List<Executable> testCases = new ArrayList<>();
+
+        Class<?> aClass = DummyClass.class;
+        testCases.addAll(Arrays.asList(aClass.getDeclaredMethods()));
+        testCases.addAll(Arrays.asList(aClass.getDeclaredConstructors()));
+        return testCases;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/compilerToVM/IsCompilableTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015, 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 8136421
+ * @requires vm.jvmci
+ * @library /test/lib /
+ * @library ../common/patches
+ * @modules java.base/jdk.internal.misc
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.org.objectweb.asm.tree
+ *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          jdk.vm.ci/jdk.vm.ci.code
+ *
+ * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:.
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler
+ *                   compiler.jvmci.compilerToVM.IsCompilableTest
+ * @run main/othervm -Xbootclasspath/a:.
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
+ *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *                   compiler.jvmci.compilerToVM.IsCompilableTest
+ */
+
+package compiler.jvmci.compilerToVM;
+
+import compiler.jvmci.common.CTVMUtilities;
+import jdk.test.lib.Asserts;
+import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import sun.hotspot.WhiteBox;
+
+import java.lang.reflect.Executable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class IsCompilableTest {
+
+    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+    public static void main(String[] args) {
+        List<Executable> testCases = createTestCases();
+        testCases.forEach(IsCompilableTest::runSanityTest);
+    }
+
+    private static void runSanityTest(Executable aMethod) {
+        boolean UseJVMCICompiler = (Boolean) WB.getVMFlag("UseJVMCICompiler");
+        HotSpotResolvedJavaMethod method = CTVMUtilities
+                .getResolvedMethod(aMethod);
+        boolean isCompilable = CompilerToVMHelper.isCompilable(method);
+        boolean expected = UseJVMCICompiler || WB.isMethodCompilable(aMethod);
+        Asserts.assertEQ(isCompilable, expected, "Unexpected initial " +
+                "value of property 'compilable'");
+
+        if (!UseJVMCICompiler) {
+            WB.makeMethodNotCompilable(aMethod);
+            isCompilable = CompilerToVMHelper.isCompilable(method);
+            Asserts.assertFalse(isCompilable, aMethod + "Unexpected value of " +
+                "property 'isCompilable' after setting 'compilable' to false");
+        }
+    }
+
+    private static List<Executable> createTestCases() {
+        List<Executable> testCases = new ArrayList<>();
+
+        Class<?> aClass = DummyClass.class;
+        testCases.addAll(Arrays.asList(aClass.getDeclaredMethods()));
+        testCases.addAll(Arrays.asList(aClass.getDeclaredConstructors()));
+        return testCases;
+    }
+}
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DebugInfoTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DebugInfoTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.code.DebugInfo;
 import jdk.vm.ci.code.Location;
+import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.VirtualObject;
 import jdk.vm.ci.hotspot.HotSpotReferenceMap;
 import jdk.vm.ci.meta.JavaKind;
@@ -32,6 +34,9 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Test code installation with debug information.
@@ -54,11 +59,43 @@
         int numStack = slotKinds.length - numLocals;
         JavaValue[] values = new JavaValue[slotKinds.length];
         test(asm -> {
+            /*
+             * Ensure that any objects mentioned in the VirtualObjects are also in the OopMap.
+             */
+            List<Location> newLocations = new ArrayList<Location>(Arrays.asList(objects));
+            List<Location> newDerived = new ArrayList<Location>(Arrays.asList(derivedBase));
+            int[] newSizeInBytes = sizeInBytes;
             VirtualObject[] vobjs = compiler.compile(asm, values);
+            if (vobjs != null) {
+                for (VirtualObject obj : vobjs) {
+                    JavaValue[] objValues = obj.getValues();
+                    for (int i = 0; i < objValues.length; i++) {
+                            if (obj.getSlotKind(i) == JavaKind.Object) {
+                                    Location oopLocation = null;
+                                    int bytes = -1;
+                                    if (objValues[i] instanceof RegisterValue) {
+                                            RegisterValue reg = (RegisterValue) objValues[i];
+                                            oopLocation = Location.register(reg.getRegister());
+                                            bytes = reg.getValueKind().getPlatformKind().getSizeInBytes();
+                                    } else if (objValues[i] instanceof StackSlot) {
+                                            StackSlot slot = (StackSlot) objValues[i];
+                                            oopLocation = Location.stack(asm.getOffset(slot));
+                                            bytes = slot.getValueKind().getPlatformKind().getSizeInBytes();
+                                    }
+                                    if (oopLocation != null && !newLocations.contains(oopLocation)) {
+                                            newLocations.add(oopLocation);
+                                            newDerived.add(null);
+                                            newSizeInBytes = Arrays.copyOf(newSizeInBytes, newSizeInBytes.length + 1);
+                                        newSizeInBytes[newSizeInBytes.length - 1] = bytes;
+                                }
+                        }
+                    }
+                }
+            }
 
             BytecodeFrame frame = new BytecodeFrame(null, resolvedMethod, bci, false, false, values, slotKinds, numLocals, numStack, 0);
             DebugInfo info = new DebugInfo(frame, vobjs);
-            info.setReferenceMap(new HotSpotReferenceMap(objects, derivedBase, sizeInBytes, 8));
+            info.setReferenceMap(new HotSpotReferenceMap(newLocations.toArray(new Location[0]), newDerived.toArray(new Location[0]), newSizeInBytes, 8));
 
             asm.emitTrap(info);
         }, method);
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java	Fri Feb 10 08:57:42 2017 -0800
@@ -256,6 +256,10 @@
         return StackSlot.get(new TestValueKind(kind), -curStackSlot, true);
     }
 
+    public int getOffset(StackSlot slot) {
+        return slot.getOffset(frameSize);
+    }
+
     protected void growFrame(int sizeInBytes) {
         curStackSlot += sizeInBytes;
         if (curStackSlot > frameSize) {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -103,6 +103,12 @@
         return new TestClass();
     }
 
+    public static TestClass buildObjectStack() {
+        return new TestClass();
+    }
+
+    boolean storeToStack;
+
     private VirtualObject[] compileBuildObject(TestAssembler asm, JavaValue[] values) {
         TestClass template = new TestClass();
         ArrayList<VirtualObject> vobjs = new ArrayList<>();
@@ -135,7 +141,11 @@
             } else if (template.arrayField[i] instanceof String) {
                 String value = (String) template.arrayField[i];
                 Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.forString(value));
-                arrayContent[i] = reg.asValue(asm.getValueKind(JavaKind.Object));
+                if (storeToStack) {
+                    arrayContent[i] = asm.emitPointerToStack(reg);
+                } else {
+                    arrayContent[i] = reg.asValue(asm.getValueKind(JavaKind.Object));
+                }
             } else {
                 Assert.fail("unexpected value");
             }
@@ -174,6 +184,13 @@
 
     @Test
     public void testBuildObject() {
+        storeToStack = false;
         test(this::compileBuildObject, getMethod("buildObject"), 7, JavaKind.Object);
     }
+
+    @Test
+    public void testBuildObjectStack() {
+        storeToStack = true;
+        test(this::compileBuildObject, getMethod("buildObjectStack"), 7, JavaKind.Object);
+    }
 }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java	Fri Feb 10 08:57:42 2017 -0800
@@ -466,6 +466,7 @@
         "getProfilingInfo",
         "reprofile",
         "getCompilerStorage",
+        "hasNeverInlineDirective",
         "canBeInlined",
         "shouldBeInlined",
         "getLineNumberTable",
--- a/hotspot/test/compiler/loopopts/TestCountedLoopSafepointBackedge.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/loopopts/TestCountedLoopSafepointBackedge.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /**
  * @test
  * @bug 8161147
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @summary Safepoint on backedge breaks UseCountedLoopSafepoints
  * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:+UseCountedLoopSafepoints TestCountedLoopSafepointBackedge
  *
--- a/hotspot/test/compiler/loopopts/UseCountedLoopSafepointsTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/loopopts/UseCountedLoopSafepointsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -27,7 +27,8 @@
  * @bug 6869327
  * @summary Test that C2 flag UseCountedLoopSafepoints ensures a safepoint is kept in a CountedLoop
  * @library /test/lib /
- * @requires vm.compMode != "Xint" & vm.flavor == "server" & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4)
+ * @requires vm.compMode != "Xint" & vm.flavor == "server" & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4) & vm.debug == true
+ * @requires !vm.emulatedClient
  * @modules java.base/jdk.internal.misc
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
@@ -37,6 +38,7 @@
 
 package compiler.loopopts;
 
+import jdk.test.lib.Platform;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import java.util.List;
--- a/hotspot/test/compiler/rangechecks/TestExplicitRangeChecks.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/rangechecks/TestExplicitRangeChecks.java	Fri Feb 10 08:57:42 2017 -0800
@@ -445,7 +445,7 @@
                 success = false;
             }
             // Only perform these additional checks if C2 is available
-            if (Platform.isServer() &&
+            if (Platform.isServer() && !Platform.isEmulatedClient() &&
                 TIERED_STOP_AT_LEVEL == CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) {
                 if (deoptimize && WHITE_BOX.isMethodCompiled(m)) {
                     System.out.println(name + " not deoptimized on invalid access");
--- a/hotspot/test/compiler/testlibrary/CompilerUtils.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/testlibrary/CompilerUtils.java	Fri Feb 10 08:57:42 2017 -0800
@@ -53,10 +53,10 @@
                     "TieredStopAtLevel has value out of int capacity");
             return IntStream.rangeClosed(1, maxLevel).toArray();
         } else {
-            if (Platform.isServer()) {
+            if (Platform.isServer() && !Platform.isEmulatedClient()) {
                 return new int[]{4};
             }
-            if (Platform.isClient() || Platform.isMinimal()) {
+            if (Platform.isClient() || Platform.isMinimal() || Platform.isEmulatedClient()) {
                 return new int[]{1};
             }
         }
--- a/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/testlibrary/sha/predicate/IntrinsicPredicates.java	Fri Feb 10 08:57:42 2017 -0800
@@ -55,7 +55,7 @@
                 "TieredStopAtLevel");
         boolean maxLevelIsReachable = (tieredMaxLevel
                 == IntrinsicPredicates.TIERED_MAX_LEVEL);
-        return Platform.isServer() && (!isTiered || maxLevelIsReachable);
+        return Platform.isServer() && !Platform.isEmulatedClient() && (!isTiered || maxLevelIsReachable);
     };
 
     public static final BooleanSupplier SHA1_INSTRUCTION_AVAILABLE
--- a/hotspot/test/compiler/tiered/NonTieredLevelsTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/tiered/NonTieredLevelsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -47,13 +47,12 @@
     private static final int AVAILABLE_COMP_LEVEL;
     private static final IntPredicate IS_AVAILABLE_COMPLEVEL;
     static {
-        if (Platform.isServer()) {
+        if (Platform.isServer() && !Platform.isEmulatedClient()) {
             AVAILABLE_COMP_LEVEL = COMP_LEVEL_FULL_OPTIMIZATION;
             IS_AVAILABLE_COMPLEVEL = x -> x == COMP_LEVEL_FULL_OPTIMIZATION;
-        } else if (Platform.isClient() || Platform.isMinimal()) {
+        } else if (Platform.isClient() || Platform.isMinimal() || Platform.isEmulatedClient()) {
             AVAILABLE_COMP_LEVEL = COMP_LEVEL_SIMPLE;
-            IS_AVAILABLE_COMPLEVEL = x -> x >= COMP_LEVEL_SIMPLE
-                    && x <= COMP_LEVEL_FULL_PROFILE;
+            IS_AVAILABLE_COMPLEVEL = x -> x == COMP_LEVEL_SIMPLE;
         } else {
             throw new Error("TESTBUG: unknown VM: " + Platform.vmName);
         }
--- a/hotspot/test/compiler/types/correctness/CorrectnessTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/types/correctness/CorrectnessTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,7 +25,7 @@
  * @test CorrectnessTest
  * @bug 8038418
  * @summary Tests correctness of type usage with type profiling and speculations
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -88,8 +88,8 @@
     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
 
     public static void main(String[] args) {
-        if (!Platform.isServer()) {
-            throw new Error("TESTBUG: Not server VM");
+        if (!Platform.isServer() || Platform.isEmulatedClient()) {
+            throw new Error("TESTBUG: Not server mode");
         }
         Asserts.assertGTE(args.length, 1);
         ProfilingType profilingType = ProfilingType.valueOf(args[0]);
--- a/hotspot/test/compiler/uncommontrap/TestUnstableIfTrap.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/uncommontrap/TestUnstableIfTrap.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -29,7 +29,7 @@
  *          java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  *
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
@@ -206,7 +206,7 @@
         boolean isMethodCompiledAtMaxTier
                 = WB.getMethodCompilationLevel(m) == MAX_TIER;
 
-        return Platform.isServer() && isMethodCompiled
+        return Platform.isServer() && !Platform.isEmulatedClient() && isMethodCompiled
                 && (!isTiered || isMethodCompiledAtMaxTier);
     }
 
--- a/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,7 +28,7 @@
  * @summary tests on constant folding of unsafe get operations
  * @library /test/lib
  *
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  *
  * @modules java.base/jdk.internal.org.objectweb.asm
  *          java.base/jdk.internal.vm.annotation
@@ -93,8 +93,8 @@
     static final Unsafe U = Unsafe.getUnsafe();
 
     public static void main(String[] args) {
-        if (!Platform.isServer()) {
-            throw new Error("TESTBUG: Not server VM");
+        if (!Platform.isServer() || Platform.isEmulatedClient()) {
+            throw new Error("TESTBUG: Not server mode");
         }
         testUnsafeGetAddress();
         testUnsafeGetField();
--- a/hotspot/test/compiler/unsafe/UnsafeGetStableArrayElement.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/unsafe/UnsafeGetStableArrayElement.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,7 +28,7 @@
  * @summary tests on constant folding of unsafe get operations from stable arrays
  * @library /test/lib
  *
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  *
  * @modules java.base/jdk.internal.vm.annotation
  *          java.base/jdk.internal.misc
@@ -332,8 +332,8 @@
     }
 
     public static void main(String[] args) throws Exception {
-        if (!Platform.isServer()) {
-            throw new Error("TESTBUG: Not server VM");
+        if (!Platform.isServer() || Platform.isEmulatedClient()) {
+            throw new Error("TESTBUG: Not server mode");
         }
         testUnsafeAccess();
         System.out.println("TEST PASSED");
--- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,7 +25,8 @@
  * @test IsMethodCompilableTest
  * @bug 8007270 8006683 8007288 8022832
  * @summary testing of WB::isMethodCompilable()
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4)
+ * @requires !vm.emulatedClient
  * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management
@@ -82,8 +83,8 @@
     protected void test() throws Exception {
 
         // Only c2 compilations can be disabled through PerMethodRecompilationCutoff
-        if (!Platform.isServer()) {
-            throw new Error("TESTBUG: Not server VM");
+        if (!Platform.isServer() || Platform.isEmulatedClient()) {
+            throw new Error("TESTBUG: Not server mode");
         }
 
         if (skipXcompOSR()) {
--- a/hotspot/test/gc/g1/TestHumongousShrinkHeap.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/g1/TestHumongousShrinkHeap.java	Fri Feb 10 08:57:42 2017 -0800
@@ -27,7 +27,7 @@
  * @requires vm.gc.G1
  * @summary Verify that heap shrinks after GC in the presence of fragmentation
  * due to humongous objects
- * @library /test/lib
+ * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  * @modules java.management/sun.management
  * @run main/othervm -XX:-ExplicitGCInvokesConcurrent -XX:MinHeapFreeRatio=10
@@ -40,6 +40,8 @@
 import java.lang.management.MemoryUsage;
 import java.util.ArrayList;
 import java.util.List;
+import java.text.NumberFormat;
+import gc.testlibrary.Helpers;
 import static jdk.test.lib.Asserts.*;
 
 public class TestHumongousShrinkHeap {
@@ -70,9 +72,9 @@
 
         System.out.format("Running with %s initial heap size of %s maximum heap size. "
                           + "Will allocate humongous object of %s size %d times.%n",
-                          MemoryUsagePrinter.humanReadableByteCount(TOTAL_MEMORY, false),
-                          MemoryUsagePrinter.humanReadableByteCount(MAX_MEMORY, false),
-                          MemoryUsagePrinter.humanReadableByteCount(HUMON_SIZE, false),
+                          MemoryUsagePrinter.NF.format(TOTAL_MEMORY),
+                          MemoryUsagePrinter.NF.format(MAX_MEMORY),
+                          MemoryUsagePrinter.NF.format(HUMON_SIZE),
                           HUMON_COUNT
         );
         new TestHumongousShrinkHeap().test();
@@ -134,24 +136,16 @@
  */
 class MemoryUsagePrinter {
 
-    public static String humanReadableByteCount(long bytes, boolean si) {
-        int unit = si ? 1000 : 1024;
-        if (bytes < unit) {
-            return bytes + " B";
-        }
-        int exp = (int) (Math.log(bytes) / Math.log(unit));
-        String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
-        return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
-    }
+    public static final NumberFormat NF = Helpers.numberFormatter();
 
     public static void printMemoryUsage(String label) {
         MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
         float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
         System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n",
                 label,
-                humanReadableByteCount(memusage.getInit(), false),
-                humanReadableByteCount(memusage.getUsed(), false),
-                humanReadableByteCount(memusage.getCommitted(), false),
+                NF.format(memusage.getInit()),
+                NF.format(memusage.getUsed()),
+                NF.format(memusage.getCommitted()),
                 freeratio * 100
         );
     }
--- a/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/g1/TestShrinkDefragmentedHeap.java	Fri Feb 10 08:57:42 2017 -0800
@@ -31,7 +31,7 @@
  *        "..................................H"
  *     3. invoke gc and check that memory returned to the system (amount of committed memory got down)
  *
- * @library /test/lib
+ * @library /test/lib /
  * @modules java.base/jdk.internal.misc
  *          java.management/sun.management
  */
@@ -39,10 +39,12 @@
 import java.lang.management.MemoryUsage;
 import java.util.ArrayList;
 import java.util.List;
+import java.text.NumberFormat;
 import static jdk.test.lib.Asserts.*;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 import com.sun.management.HotSpotDiagnosticMXBean;
+import gc.testlibrary.Helpers;
 
 public class TestShrinkDefragmentedHeap {
     // Since we store all the small objects, they become old and old regions are also allocated at the bottom of the heap
@@ -114,8 +116,8 @@
 
         private void allocate() {
             System.out.format("Will allocate objects of small size = %s and humongous size = %s",
-                    MemoryUsagePrinter.humanReadableByteCount(SMALL_OBJS_SIZE, false),
-                    MemoryUsagePrinter.humanReadableByteCount(HUMONG_OBJS_SIZE, false)
+                    MemoryUsagePrinter.NF.format(SMALL_OBJS_SIZE),
+                    MemoryUsagePrinter.NF.format(HUMONG_OBJS_SIZE)
             );
 
             for (int i = 0; i < ALLOCATE_COUNT; i++) {
@@ -170,24 +172,16 @@
      */
     static class MemoryUsagePrinter {
 
-        public static String humanReadableByteCount(long bytes, boolean si) {
-            int unit = si ? 1000 : 1024;
-            if (bytes < unit) {
-                return bytes + " B";
-            }
-            int exp = (int) (Math.log(bytes) / Math.log(unit));
-            String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
-            return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
-        }
+        public static final NumberFormat NF = Helpers.numberFormatter();
 
         public static void printMemoryUsage(String label) {
             MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
             float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
             System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n",
                     label,
-                    humanReadableByteCount(memusage.getInit(), false),
-                    humanReadableByteCount(memusage.getUsed(), false),
-                    humanReadableByteCount(memusage.getCommitted(), false),
+                    NF.format(memusage.getInit()),
+                    NF.format(memusage.getUsed()),
+                    NF.format(memusage.getCommitted()),
                     freeratio * 100
             );
         }
--- a/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/metaspace/TestMetaspacePerfCounters.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -42,7 +42,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management/sun.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseSerialGC TestMetaspacePerfCounters
  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseParallelGC -XX:+UseParallelOldGC TestMetaspacePerfCounters
  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UsePerfData -XX:+UseG1GC TestMetaspacePerfCounters
--- a/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/metaspace/TestPerfCountersAndMemoryPools.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -35,7 +35,7 @@
  *          report the same data.
  * @modules java.base/jdk.internal.misc
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedClassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools
  * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers -XX:+UseSerialGC -XX:+UsePerfData -Xint TestPerfCountersAndMemoryPools
  */
--- a/hotspot/test/gc/parallel/TestDynShrinkHeap.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/parallel/TestDynShrinkHeap.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,15 +28,17 @@
  * @summary Verify that the heap shrinks after full GC according to the current values of the Min/MaxHeapFreeRatio flags
  * @modules java.base/jdk.internal.misc
  * @modules jdk.management
- * @library /test/lib
+ * @library /test/lib /
  * @run main/othervm -XX:+UseAdaptiveSizePolicyWithSystemGC -XX:+UseParallelGC -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -Xmx1g -verbose:gc TestDynShrinkHeap
  */
 import jdk.test.lib.DynamicVMOption;
 import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryUsage;
 import java.util.ArrayList;
+import java.text.NumberFormat;
 import static jdk.test.lib.Asserts.assertLessThan;
 import com.sun.management.HotSpotDiagnosticMXBean;
+import gc.testlibrary.Helpers;
 
 public class TestDynShrinkHeap {
 
@@ -101,24 +103,16 @@
  */
 class MemoryUsagePrinter {
 
-    public static String humanReadableByteCount(long bytes, boolean si) {
-        int unit = si ? 1000 : 1024;
-        if (bytes < unit) {
-            return bytes + " B";
-        }
-        int exp = (int) (Math.log(bytes) / Math.log(unit));
-        String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i");
-        return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
-    }
+    public static final NumberFormat NF = Helpers.numberFormatter();
 
     public static void printMemoryUsage(String label) {
         MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
         float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
         System.out.format("[%-24s] init: %-7s, used: %-7s, comm: %-7s, freeRatio ~= %.1f%%%n",
                 label,
-                humanReadableByteCount(memusage.getInit(), true),
-                humanReadableByteCount(memusage.getUsed(), true),
-                humanReadableByteCount(memusage.getCommitted(), true),
+                NF.format(memusage.getInit()),
+                NF.format(memusage.getUsed()),
+                NF.format(memusage.getCommitted()),
                 freeratio * 100
         );
     }
--- a/hotspot/test/gc/stress/TestStressG1Humongous.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/stress/TestStressG1Humongous.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,14 +28,9 @@
  * @summary Stress G1 by humongous allocations in situation near OOM
  * @requires vm.gc.G1
  * @requires !vm.flightRecorder
- * @run main/othervm/timeout=200 -Xlog:gc=debug -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=4m
- *              -Dtimeout=120 -Dthreads=3 -Dhumongoussize=1.1 -Dregionsize=4 TestStressG1Humongous
- * @run main/othervm/timeout=200 -Xlog:gc=debug -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=16m
- *              -Dtimeout=120 -Dthreads=5 -Dhumongoussize=2.1 -Dregionsize=16 TestStressG1Humongous
- * @run main/othervm/timeout=200 -Xlog:gc=debug -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=32m
- *              -Dtimeout=120 -Dthreads=4 -Dhumongoussize=0.6 -Dregionsize=32 TestStressG1Humongous
- * @run main/othervm/timeout=700 -Xlog:gc=debug -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=1m
- *              -Dtimeout=600 -Dthreads=7 -Dhumongoussize=0.6 -Dregionsize=1 TestStressG1Humongous
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @run driver/timeout=1300 TestStressG1Humongous
  */
 
 import java.util.ArrayList;
@@ -44,8 +39,45 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 
-public class TestStressG1Humongous {
+import jdk.test.lib.Platform;
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TestStressG1Humongous{
+
+    public static void main(String[] args) throws Exception {
+        // Limit heap size on 32-bit platforms
+        int heapSize = Platform.is32bit() ? 512 : 1024;
+        // Heap size, region size, threads, humongous size, timeout
+        run(heapSize, 4, 3, 1.1, 120);
+        run(heapSize, 16, 5, 2.1, 120);
+        run(heapSize, 32, 4, 0.6, 120);
+        run(heapSize, 1, 7, 0.6, 600);
+    }
 
+    private static void run(int heapSize, int regionSize, int threads, double humongousSize, int timeout)
+            throws Exception {
+        ArrayList<String> options = new ArrayList<>();
+        Collections.addAll(options, Utils.getTestJavaOpts());
+        Collections.addAll(options,
+                "-Xlog:gc=debug",
+                "-Xmx" + heapSize + "m",
+                "-XX:+UseG1GC",
+                "-XX:G1HeapRegionSize=" + regionSize + "m",
+                "-Dtimeout=" + timeout,
+                "-Dthreads=" + threads,
+                "-Dhumongoussize=" + humongousSize,
+                "-Dregionsize=" + regionSize,
+                TestStressG1HumongousImpl.class.getName()
+        );
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(options.toArray(new String[options.size()]));
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+    }
+}
+
+class TestStressG1HumongousImpl {
     // Timeout in seconds
     private static final int TIMEOUT = Integer.getInteger("timeout", 60);
     private static final int THREAD_COUNT = Integer.getInteger("threads", 2);
@@ -60,10 +92,10 @@
     public static final List<Object> GARBAGE = Collections.synchronizedList(new ArrayList<>());
 
     public static void main(String[] args) throws InterruptedException {
-        new TestStressG1Humongous().run();
+        new TestStressG1HumongousImpl().run();
     }
 
-    public TestStressG1Humongous() {
+    public TestStressG1HumongousImpl() {
         isRunning = true;
         threads = new Thread[THREAD_COUNT];
         alocatedObjectsCount = new AtomicInteger(0);
--- a/hotspot/test/gc/stress/gcbasher/TestGCBasherWithCMS.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithCMS.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -29,9 +29,9 @@
  * @key gc
  * @key stress
  * @requires vm.gc.ConcMarkSweep
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @summary Stress the CMS GC by trying to make old objects more likely to be garbage than young objects.
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseConcMarkSweepGC TestGCBasherWithCMS 120000
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx256m -server -XX:+UseConcMarkSweepGC TestGCBasherWithCMS 120000
  */
 public class TestGCBasherWithCMS {
     public static void main(String[] args) throws IOException {
--- a/hotspot/test/gc/stress/gcbasher/TestGCBasherWithG1.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithG1.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -29,9 +29,9 @@
  * @key gc
  * @key stress
  * @requires vm.gc.G1
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @summary Stress the G1 GC by trying to make old objects more likely to be garbage than young objects.
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseG1GC TestGCBasherWithG1 120000
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx256m -server -XX:+UseG1GC TestGCBasherWithG1 120000
  */
 public class TestGCBasherWithG1 {
     public static void main(String[] args) throws IOException {
--- a/hotspot/test/gc/stress/gcbasher/TestGCBasherWithParallel.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithParallel.java	Fri Feb 10 08:57:42 2017 -0800
@@ -29,7 +29,7 @@
  * @key gc
  * @key stress
  * @requires vm.gc.Parallel
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @summary Stress the Parallel GC by trying to make old objects more likely to be garbage than young objects.
  * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx256m -server -XX:+UseParallelGC -XX:-UseGCOverheadLimit TestGCBasherWithParallel 120000
  */
--- a/hotspot/test/gc/stress/gcbasher/TestGCBasherWithSerial.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/stress/gcbasher/TestGCBasherWithSerial.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -29,9 +29,9 @@
  * @key gc
  * @key stress
  * @requires vm.gc.Serial
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @summary Stress the Serial GC by trying to make old objects more likely to be garbage than young objects.
- * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx128m -server -XX:+UseSerialGC TestGCBasherWithSerial 120000
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx256m -server -XX:+UseSerialGC TestGCBasherWithSerial 120000
  */
 public class TestGCBasherWithSerial {
     public static void main(String[] args) throws IOException {
--- a/hotspot/test/gc/testlibrary/Helpers.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/testlibrary/Helpers.java	Fri Feb 10 08:57:42 2017 -0800
@@ -31,6 +31,9 @@
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
 
 public class Helpers {
 
@@ -320,4 +323,16 @@
         }
     }
 
+    /**
+     * @return a number formatter instance which prints numbers in a human
+     * readable form, like 9_223_372_036_854_775_807.
+     */
+    public static NumberFormat numberFormatter() {
+        DecimalFormat df = new DecimalFormat();
+        DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
+        dfs.setGroupingSeparator('_');
+        dfs.setDecimalSeparator('.');
+        df.setDecimalFormatSymbols(dfs);
+        return df;
+    }
 }
--- a/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -29,7 +29,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build sun.hotspot.WhiteBox
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
--- a/hotspot/test/native/code/test_dependencyContext.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/native/code/test_dependencyContext.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -86,7 +86,7 @@
   NOT_PRODUCT(ASSERT_FALSE(depContext.is_dependent_nmethod(nm)));
 }
 
-TEST(code, dependency_context) {
+TEST_VM(code, dependency_context) {
   test_remove_dependent_nmethod(0, false);
   test_remove_dependent_nmethod(1, false);
   test_remove_dependent_nmethod(2, false);
--- a/hotspot/test/native/gc/g1/test_workerDataArray.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/native/gc/g1/test_workerDataArray.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -123,19 +123,19 @@
   }
 };
 
-TEST_F(BasicWorkerDataArrayTest, sum_test) {
+TEST_VM_F(BasicWorkerDataArrayTest, sum_test) {
   ASSERT_EQ(15u, array.sum());
 }
 
-TEST_F(BasicWorkerDataArrayTest, average_test) {
+TEST_VM_F(BasicWorkerDataArrayTest, average_test) {
   ASSERT_NEAR(5.0, array.average(), epsilon);
 }
 
-TEST_F(BasicWorkerDataArrayTest, print_summary_on_test) {
+TEST_VM_F(BasicWorkerDataArrayTest, print_summary_on_test) {
   ASSERT_STREQ(print_expected_summary(), print_summary());
 }
 
-TEST_F(BasicWorkerDataArrayTest, print_details_on_test) {
+TEST_VM_F(BasicWorkerDataArrayTest, print_details_on_test) {
   ASSERT_STREQ(print_expected_details(), print_details());
 }
 
@@ -161,19 +161,19 @@
   }
 };
 
-TEST_F(AddWorkerDataArrayTest, sum_test) {
+TEST_VM_F(AddWorkerDataArrayTest, sum_test) {
   ASSERT_EQ(18u, array.sum());
 }
 
-TEST_F(AddWorkerDataArrayTest, average_test) {
+TEST_VM_F(AddWorkerDataArrayTest, average_test) {
   ASSERT_NEAR(6.0, array.average(), epsilon);
 }
 
-TEST_F(AddWorkerDataArrayTest, print_summary_on_test) {
+TEST_VM_F(AddWorkerDataArrayTest, print_summary_on_test) {
   ASSERT_STREQ(print_expected_summary(), print_summary());
 }
 
-TEST_F(AddWorkerDataArrayTest, print_details_on_test) {
+TEST_VM_F(AddWorkerDataArrayTest, print_details_on_test) {
   ASSERT_STREQ(print_expected_details(), print_details());
 }
 
@@ -195,19 +195,19 @@
   }
 };
 
-TEST_F(UninitializedElementWorkerDataArrayTest, sum_test) {
+TEST_VM_F(UninitializedElementWorkerDataArrayTest, sum_test) {
   ASSERT_EQ(12u, array.sum());
 }
 
-TEST_F(UninitializedElementWorkerDataArrayTest, average_test) {
+TEST_VM_F(UninitializedElementWorkerDataArrayTest, average_test) {
   ASSERT_NEAR(6.0, array.average(), epsilon);
 }
 
-TEST_F(UninitializedElementWorkerDataArrayTest, print_summary_on_test) {
+TEST_VM_F(UninitializedElementWorkerDataArrayTest, print_summary_on_test) {
   ASSERT_STREQ(print_expected_summary(), print_summary());
 }
 
-TEST_F(UninitializedElementWorkerDataArrayTest, print_details_on_test) {
+TEST_VM_F(UninitializedElementWorkerDataArrayTest, print_details_on_test) {
   ASSERT_STREQ(print_expected_details(), print_details());
 }
 
@@ -229,19 +229,19 @@
   }
 };
 
-TEST_F(UninitializedWorkerDataArrayTest, sum_test) {
+TEST_VM_F(UninitializedWorkerDataArrayTest, sum_test) {
   ASSERT_EQ(0u, array.sum());
 }
 
-TEST_F(UninitializedWorkerDataArrayTest, average_test) {
+TEST_VM_F(UninitializedWorkerDataArrayTest, average_test) {
   ASSERT_NEAR(0.0, array.average(), epsilon);
 }
 
-TEST_F(UninitializedWorkerDataArrayTest, print_summary_on_test) {
+TEST_VM_F(UninitializedWorkerDataArrayTest, print_summary_on_test) {
   ASSERT_STREQ(print_expected_summary(), print_summary());
 }
 
-TEST_F(UninitializedWorkerDataArrayTest, print_details_on_test) {
+TEST_VM_F(UninitializedWorkerDataArrayTest, print_details_on_test) {
   ASSERT_STREQ(print_expected_details(), print_details());
 }
 
@@ -265,18 +265,18 @@
   }
 };
 
-TEST_F(UninitializedDoubleElementWorkerDataArrayTest, sum_test) {
+TEST_VM_F(UninitializedDoubleElementWorkerDataArrayTest, sum_test) {
   ASSERT_NEAR(12.3 / MILLIUNITS, array.sum(), epsilon);
 }
 
-TEST_F(UninitializedDoubleElementWorkerDataArrayTest, average_test) {
+TEST_VM_F(UninitializedDoubleElementWorkerDataArrayTest, average_test) {
   ASSERT_NEAR(6.15 / MILLIUNITS, array.average(), epsilon);
 }
 
-TEST_F(UninitializedDoubleElementWorkerDataArrayTest, print_summary_on_test) {
+TEST_VM_F(UninitializedDoubleElementWorkerDataArrayTest, print_summary_on_test) {
   ASSERT_STREQ(print_expected_summary(), print_summary());
 }
 
-TEST_F(UninitializedDoubleElementWorkerDataArrayTest, print_details_on_test) {
+TEST_VM_F(UninitializedDoubleElementWorkerDataArrayTest, print_details_on_test) {
   ASSERT_STREQ(print_expected_details(), print_details());
 }
--- a/hotspot/test/native/logging/test_log.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/native/logging/test_log.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -41,14 +41,14 @@
 }
 
 #ifdef ASSERT // 'test' tag is debug only
-TEST_F(LogTest, prefix) {
+TEST_VM_F(LogTest, prefix) {
   set_log_config(TestLogFileName, "logging+test=trace");
   log_trace(logging, test)(LOG_LINE_STR);
   EXPECT_TRUE(file_contains_substring(TestLogFileName, LOG_PREFIX_STR LOG_LINE_STR));
 }
 #endif
 
-TEST_F(LogTest, large_message) {
+TEST_VM_F(LogTest, large_message) {
   char big_msg[4096] = {0};
   char Xchar = '~';
 
@@ -68,7 +68,7 @@
   EXPECT_EQ(sizeof(big_msg) - 1, count);
 }
 
-TEST_F(LogTest, enabled_logtarget) {
+TEST_VM_F(LogTest, enabled_logtarget) {
   set_log_config(TestLogFileName, "gc=debug");
 
   LogTarget(Debug, gc) log;
@@ -80,7 +80,7 @@
   EXPECT_TRUE(file_contains_substring(TestLogFileName, LOG_TEST_STRING_LITERAL));
 }
 
-TEST_F(LogTest, disabled_logtarget) {
+TEST_VM_F(LogTest, disabled_logtarget) {
   set_log_config(TestLogFileName, "gc=info");
 
   LogTarget(Debug, gc) log;
@@ -95,7 +95,7 @@
   EXPECT_FALSE(file_contains_substring(TestLogFileName, LOG_TEST_STRING_LITERAL));
 }
 
-TEST_F(LogTest, enabled_loghandle) {
+TEST_VM_F(LogTest, enabled_loghandle) {
   set_log_config(TestLogFileName, "gc=debug");
 
   Log(gc) log;
@@ -109,7 +109,7 @@
   EXPECT_TRUE(file_contains_substring(TestLogFileName, "3 workers"));
 }
 
-TEST_F(LogTest, disabled_loghandle) {
+TEST_VM_F(LogTest, disabled_loghandle) {
   set_log_config(TestLogFileName, "gc=info");
 
   Log(gc) log;
@@ -126,7 +126,7 @@
   EXPECT_FALSE(file_contains_substring(TestLogFileName, "3 workers"));
 }
 
-TEST_F(LogTest, enabled_logtargethandle) {
+TEST_VM_F(LogTest, enabled_logtargethandle) {
   set_log_config(TestLogFileName, "gc=debug");
 
   LogTarget(Debug, gc) log;
@@ -140,7 +140,7 @@
   EXPECT_TRUE(file_contains_substring(TestLogFileName, "3 workers"));
 }
 
-TEST_F(LogTest, disabled_logtargethandle) {
+TEST_VM_F(LogTest, disabled_logtargethandle) {
   set_log_config(TestLogFileName, "gc=info");
 
   LogTarget(Debug, gc) log;
--- a/hotspot/test/native/logging/test_logConfiguration.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/native/logging/test_logConfiguration.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -297,7 +297,7 @@
   }
 }
 
-TEST_F(LogConfigurationTest, configure_stdout) {
+TEST_VM_F(LogConfigurationTest, configure_stdout) {
   // Start out with all logging disabled
   LogConfiguration::disable_logging();
 
@@ -355,7 +355,7 @@
   Test_logconfiguration_subscribe_triggered++;
 }
 
-TEST_F(LogConfigurationTest, subscribe) {
+TEST_VM_F(LogConfigurationTest, subscribe) {
   ResourceMark rm;
   Log(logging) log;
   set_log_config("stdout", "logging*=trace");
--- a/hotspot/test/native/logging/test_logMessageTest.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/native/logging/test_logMessageTest.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -65,7 +65,7 @@
 
 // Verify that messages with multiple levels are written
 // to outputs configured for all the corresponding levels
-TEST_F(LogMessageTest, level_inclusion) {
+TEST_VM_F(LogMessageTest, level_inclusion) {
   const size_t message_count = 10;
   LogMessageBuffer msg[message_count];
 
@@ -119,7 +119,7 @@
 }
 
 // Verify that messages are logged in the order they are added to the log message
-TEST_F(LogMessageTest, line_order) {
+TEST_VM_F(LogMessageTest, line_order) {
   LogMessageBuffer msg;
   msg.info("info line").error("error line").trace("trace line")
       .error("another error").warning("warning line").debug("debug line");
@@ -131,7 +131,7 @@
     << "output missing or in incorrect order";
 }
 
-TEST_F(LogMessageTest, long_message) {
+TEST_VM_F(LogMessageTest, long_message) {
   // Write 10K bytes worth of log data
   LogMessageBuffer msg;
   const size_t size = 10 * K;
@@ -155,7 +155,7 @@
   FREE_C_HEAP_ARRAY(char, data);
 }
 
-TEST_F(LogMessageTest, message_with_many_lines) {
+TEST_VM_F(LogMessageTest, message_with_many_lines) {
   const size_t lines = 100;
   const size_t line_length = 16;
 
@@ -188,7 +188,7 @@
   return prefix_len;
 }
 
-TEST_F(LogMessageTest, prefixing) {
+TEST_VM_F(LogMessageTest, prefixing) {
   LogMessageBuffer msg;
   msg.set_prefix(dummy_prefixer);
   for (int i = 0; i < 3; i++) {
@@ -209,7 +209,7 @@
     << "error in prefixed output";
 }
 
-TEST_F(LogMessageTest, scoped_messages) {
+TEST_VM_F(LogMessageTest, scoped_messages) {
   {
     LogMessage(logging) msg;
     msg.info("scoped info");
@@ -223,7 +223,7 @@
     << "missing output from scoped log message";
 }
 
-TEST_F(LogMessageTest, scoped_flushing) {
+TEST_VM_F(LogMessageTest, scoped_flushing) {
   {
     LogMessage(logging) msg;
     msg.info("manual flush info");
@@ -236,7 +236,7 @@
     << "log file contains duplicate lines from single scoped log message";
 }
 
-TEST_F(LogMessageTest, scoped_reset) {
+TEST_VM_F(LogMessageTest, scoped_reset) {
   {
     LogMessage(logging) msg, partial;
     msg.info("%s", "info reset msg");
--- a/hotspot/test/native/logging/test_logTagSetDescriptions.cpp	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/native/logging/test_logTagSetDescriptions.cpp	Fri Feb 10 08:57:42 2017 -0800
@@ -30,7 +30,7 @@
 #include "unittest.hpp"
 #include "utilities/ostream.hpp"
 
-TEST(LogTagSetDescriptions, describe) {
+TEST_VM(LogTagSetDescriptions, describe) {
   for (LogTagSetDescription* d = tagset_descriptions; d->tagset != NULL; d++) {
     char expected[1 * K];
     d->tagset->label(expected, sizeof(expected), "+");
@@ -46,7 +46,7 @@
   }
 }
 
-TEST(LogTagSetDescriptions, command_line_help) {
+TEST_VM(LogTagSetDescriptions, command_line_help) {
   const char* filename = "logtagset_descriptions";
   FILE* fp = fopen(filename, "w+");
   ASSERT_NE((void*)NULL, fp);
--- a/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/CDSCompressedKPtrs/XShareAuto.java	Fri Feb 10 08:57:42 2017 -0800
@@ -48,8 +48,9 @@
             "-server", "-XX:+UnlockDiagnosticVMOptions",
             "-XX:SharedArchiveFile=./XShareAuto.jsa", "-version");
         output = new OutputAnalyzer(pb.start());
+        String outputString = output.getOutput();
         // We asked for server but it could be aliased to something else
-        if (output.getOutput().contains("Server VM")) {
+        if (outputString.contains("Server VM") && !outputString.contains("emulated-client")) {
             // In server case we don't expect to see sharing flag
             output.shouldNotContain("sharing");
             output.shouldHaveExitValue(0);
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.management
  *          jdk.attach/sun.tools.attach
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run main/othervm/timeout=900 TestOptionsWithRanges
  */
 
--- a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -27,7 +27,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run driver CreateCoredumpOnCrash
  */
 
--- a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -29,7 +29,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run driver ProblematicFrameTest
  */
 
--- a/hotspot/test/runtime/RedefineTests/RedefinePreviousVersions.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/RedefineTests/RedefinePreviousVersions.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -48,20 +48,23 @@
     public static String newRunning =
         "class RedefinePreviousVersions$Running {" +
         "    public static volatile boolean stop = true;" +
+        "    public static volatile boolean running = true;" +
         "    static void localSleep() { }" +
         "    public static void infinite() { }" +
         "}";
 
     static class Running {
         public static volatile boolean stop = false;
+        public static volatile boolean running = false;
         static void localSleep() {
           try{
-            Thread.currentThread().sleep(10);//sleep for 10 ms
+            Thread.sleep(10); // sleep for 10 ms
           } catch(InterruptedException ie) {
           }
         }
 
         public static void infinite() {
+            running = true;
             while (!stop) { localSleep(); }
         }
     }
@@ -70,8 +73,6 @@
 
         if (args.length > 0) {
 
-            String jarFile = System.getProperty("test.src") + "/testcase.jar";
-
             // java -javaagent:redefineagent.jar -Xlog:stuff RedefinePreviousVersions
             ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-javaagent:redefineagent.jar",
                "-Xlog:redefine+class+iklass+add=trace,redefine+class+iklass+purge=trace",
@@ -100,6 +101,10 @@
             }
         }.start();
 
+        while (!Running.running) {
+            Thread.sleep(10); // sleep for 10 ms
+        }
+
         // Since a method of newRunning is running, this class should be added to the previous_version_list
         // of Running, and _has_previous_versions should return true at class unloading.
         RedefineClassHelper.redefineClass(Running.class, newRunning);
--- a/hotspot/test/runtime/ReservedStack/ReservedStackTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/ReservedStack/ReservedStackTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -199,7 +199,9 @@
             // corruptions are still possible.
             boolean supportedPlatform =
                 Platform.isAix() ||
-                (Platform.isLinux() && (Platform.isPPC() || Platform.isX64() || Platform.isX86())) ||
+                (Platform.isLinux() &&
+                  (Platform.isPPC() || Platform.isS390x() || Platform.isX64() ||
+                   Platform.isX86() || Platform.isAArch64())) ||
                 Platform.isOSX() ||
                 Platform.isSolaris();
             if (supportedPlatform && !result.contains("PASSED")) {
--- a/hotspot/test/runtime/ReservedStack/ReservedStackTestCompiler.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/ReservedStack/ReservedStackTestCompiler.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,7 +24,7 @@
 /*
  * @test ReservedStackTestCompiler
  * @summary Run ReservedStackTest with dedicated compilers C1 and C2.
- * @requires vm.flavor == "server"
+ * @requires vm.flavor == "server" & !vm.emulatedClient
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  * @modules java.base/jdk.internal.vm.annotation
--- a/hotspot/test/runtime/SharedArchiveFile/BootAppendTests.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/SharedArchiveFile/BootAppendTests.java	Fri Feb 10 08:57:42 2017 -0800
@@ -27,7 +27,7 @@
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @compile javax/sound/sampled/MyClass.jasm
  * @compile org/omg/CORBA/Context.jasm
  * @compile nonjdk/myPackage/MyClass.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/AccessCheck/AccessExportTwice.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017, 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 Class p1.c1 in an unnamed module cannot read p2.c2 in module second_mod,
+ *          even after p2 is exported to all unnamed. Ensures constant
+ *          access check answers when not accessible due to exportedness.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.base/jdk.internal.module
+ * @compile myloaders/MySameClassLoader.java
+ * @compile p2/c2.java
+ * @compile p1/c1.java
+ * @run main/othervm AccessExportTwice
+ */
+
+import static jdk.test.lib.Asserts.*;
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import myloaders.MySameClassLoader;
+
+//
+// ClassLoader1 --> defines first_mod --> no packages
+//                  defines second_mod --> packages p2
+//
+// first_mod can read second_mod
+// package p2 in second_mod is exported to first_mod
+//
+// class p1.c1 defined in an unnamed module tries to access p2.c2 defined in second_mod
+// Access is not allowed, even after p2 is exported to all unnamed modules.
+
+public class AccessExportTwice {
+
+    // Create a Layer over the boot layer.
+    // Define modules within this layer to test access between
+    // publicly defined classes within packages of those modules.
+    public void createLayerOnBoot() throws Throwable {
+
+        // Define module:     first_mod
+        // Can read:          java.base, second_mod
+        // Packages:          none
+        // Packages exported: none
+        ModuleDescriptor descriptor_first_mod =
+                ModuleDescriptor.module("first_mod")
+                        .requires("java.base")
+                        .requires("second_mod")
+                        .build();
+
+        // Define module:     second_mod
+        // Can read:          java.base
+        // Packages:          p2
+        // Packages exported: p2 is exported to first_mod
+        ModuleDescriptor descriptor_second_mod =
+                ModuleDescriptor.module("second_mod")
+                        .requires("java.base")
+                        .exports("p2", Set.of("first_mod"))
+                        .build();
+
+        // Set up a ModuleFinder containing all modules for this layer
+        ModuleFinder finder = ModuleLibrary.of(descriptor_first_mod, descriptor_second_mod);
+
+        // Resolves "first_mod"
+        Configuration cf = Layer.boot()
+                .configuration()
+                .resolveRequires(finder, ModuleFinder.of(), Set.of("first_mod"));
+
+        // Map each module to the same class loader
+        Map<String, ClassLoader> map = new HashMap<>();
+        map.put("first_mod", MySameClassLoader.loader1);
+        map.put("second_mod", MySameClassLoader.loader1);
+
+        // Create Layer that contains first_mod & second_mod
+        Layer layer = Layer.boot().defineModules(cf, map::get);
+
+        assertTrue(layer.findLoader("first_mod") == MySameClassLoader.loader1);
+        assertTrue(layer.findLoader("second_mod") == MySameClassLoader.loader1);
+        assertTrue(layer.findLoader("java.base") == null);
+
+        Class p2_c2_class = MySameClassLoader.loader1.loadClass("p2.c2");
+        // Use the same loader to load class p1.c1
+        Class p1_c1_class = MySameClassLoader.loader1.loadClass("p1.c1");
+        // First access check for p1.c1
+        try {
+            p1_c1_class.newInstance();
+            throw new RuntimeException("Test Failed, the unnamed module should not have access to public type p2.c2");
+        } catch (IllegalAccessError e) {
+            String message = e.getMessage();
+            if (!(message.contains("cannot access") &&
+                  message.contains("because module second_mod does not export p2 to unnamed module"))) {
+                throw new RuntimeException("Wrong message: " + message);
+            } else {
+                System.out.println("Test Succeeded at attempt #1");
+            }
+        }
+
+        // Export second_mod/p2 to all unnamed modules.
+        Module second_mod = p2_c2_class.getModule();
+        jdk.internal.module.Modules.addExportsToAllUnnamed(second_mod, "p2");
+
+        // Second access check for p1.c1, should have same result as first
+        try {
+            p1_c1_class.newInstance();
+            throw new RuntimeException("Test Failed, access should have been cached above");
+        } catch (IllegalAccessError e) {
+            String message = e.getMessage();
+            if (!(message.contains("cannot access") &&
+                  message.contains("because module second_mod does not export p2 to unnamed module"))) {
+                throw new RuntimeException("Wrong message: " + message);
+            } else {
+                System.out.println("Test Succeeded at attempt #2");
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+      AccessExportTwice test = new AccessExportTwice();
+      test.createLayerOnBoot();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/AccessCheck/AccessReadTwice.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2017, 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 Class p1.c1 in module first_mod cannot read p2.c2 in module second_mod,
+ *          even after a read edge is added between first_mod and second_mod.
+ *          Ensures constant access check answers when not accessible due to readability.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.base/jdk.internal.module
+ * @compile p2/c2.java
+ * @compile p1/c1.java
+ * @compile p4/c4.java
+ * @run main/othervm AccessReadTwice
+ */
+
+import static jdk.test.lib.Asserts.*;
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleFinder;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+//
+// ClassLoader1 --> defines first_mod --> packages p1, p4
+//                  defines second_mod --> package p2
+//
+// package p2 in second_mod is exported to first_mod
+//
+// class p1.c1 defined in first_mod tries to access p2.c2 defined in second_mod
+// Access is not allowed, even after a read edge is added between first_mod and second_mod.
+
+public class AccessReadTwice {
+
+    // Create a Layer over the boot layer.
+    // Define modules within this layer to test access between
+    // publicly defined classes within packages of those modules.
+    public void createLayerOnBoot() throws Throwable {
+
+        // Define module:     first_mod
+        // Can read:          java.base
+        // Packages:          p1, p4
+        // Packages exported: none
+        ModuleDescriptor descriptor_first_mod =
+                ModuleDescriptor.module("first_mod")
+                        .requires("java.base")
+                        .contains(Set.of("p1", "p4"))
+                        .build();
+
+        // Define module:     second_mod
+        // Can read:          java.base
+        // Packages:          p2
+        // Packages exported: p2 is exported to first_mod
+        ModuleDescriptor descriptor_second_mod =
+                ModuleDescriptor.module("second_mod")
+                        .requires("java.base")
+                        .exports("p2", Set.of("first_mod"))
+                        .build();
+
+        // Set up a ModuleFinder containing all modules for this layer
+        ModuleFinder finder = ModuleLibrary.of(descriptor_first_mod, descriptor_second_mod);
+
+        // Resolves "first_mod" and "second_mod"
+        Configuration cf = Layer.boot()
+                .configuration()
+                .resolveRequires(finder, ModuleFinder.of(), Set.of("first_mod", "second_mod"));
+
+        // Map each module to this class loader
+        Map<String, ClassLoader> map = new HashMap<>();
+        ClassLoader loader = AccessReadTwice.class.getClassLoader();
+        map.put("first_mod", loader);
+        map.put("second_mod", loader);
+
+        // Create Layer that contains first_mod & second_mod
+        Layer layer = Layer.boot().defineModules(cf, map::get);
+
+        assertTrue(layer.findLoader("first_mod") == loader);
+        assertTrue(layer.findLoader("second_mod") == loader);
+        assertTrue(layer.findLoader("java.base") == null);
+
+        Class p2_c2_class = loader.loadClass("p2.c2");
+        Class p1_c1_class = loader.loadClass("p1.c1");
+        Class p4_c4_class = loader.loadClass("p4.c4");
+
+        Module first_mod = p1_c1_class.getModule();
+        Module second_mod = p2_c2_class.getModule();
+
+        // Export first_mod/p1 and first_mod/p4 to all unnamed modules so that
+        // this test can use them
+        jdk.internal.module.Modules.addExportsToAllUnnamed(first_mod, "p1");
+        jdk.internal.module.Modules.addExportsToAllUnnamed(first_mod, "p4");
+
+        // First access check for p1.c1
+        try {
+            p1_c1_class.newInstance();
+            throw new RuntimeException("Test Failed, module first_mod should not have access to p2.c2");
+        } catch (IllegalAccessError e) {
+            String message = e.getMessage();
+            if (!(message.contains("cannot access") &&
+                  message.contains("because module first_mod does not read module second_mod"))) {
+                throw new RuntimeException("Wrong message: " + message);
+            } else {
+                System.out.println("Test Succeeded at attempt #1");
+            }
+        }
+
+        // Add a read edge from p4/c4's module (first_mod) to second_mod
+        p4.c4 c4_obj = new p4.c4();
+        c4_obj.addReads(second_mod);
+
+        // Second access check for p1.c1, should have same result as first
+        try {
+            p1_c1_class.newInstance();
+            throw new RuntimeException("Test Failed, access should have been cached above");
+        } catch (IllegalAccessError e) {
+            String message = e.getMessage();
+            if (!(message.contains("cannot access") &&
+                  message.contains("because module first_mod does not read module second_mod"))) {
+                throw new RuntimeException("Wrong message: " + message);
+            } else {
+                System.out.println("Test Succeeded at attempt #2");
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+      AccessReadTwice test = new AccessReadTwice();
+      test.createLayerOnBoot();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/modules/AccessCheck/p4/c4.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// Small class used by multiple hotspot/runtime/modules/AccessCheck/* tests.
+
+package p4;
+
+import java.lang.reflect.Module;
+
+public class c4 {
+    // Add a read edge from c4's module to given module m
+    public void addReads(Module m) {
+        c4.class.getModule().addReads(m);
+    }
+}
--- a/hotspot/test/runtime/modules/JVMAddModulePackage.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/modules/JVMAddModulePackage.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -84,11 +84,11 @@
             // Expected
         }
 
-        // Existing package, expect an IAE
+        // Existing package, expect an ISE
         try {
             ModuleHelper.AddModulePackage(module1, "yourpackage");
-            throw new RuntimeException("Failed to get the expected IAE");
-        } catch(IllegalArgumentException e) {
+            throw new RuntimeException("Failed to get the expected ISE");
+        } catch(IllegalStateException e) {
             // Expected
         }
 
--- a/hotspot/test/runtime/modules/JVMDefineModule.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/runtime/modules/JVMDefineModule.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -127,27 +127,27 @@
             }
         }
 
-        // Duplicate module name, expect an IAE
-        m = ModuleHelper.ModuleObject("module.name", cl, new String[] { "mypackage6" });
+        // Duplicate module name, expect an ISE
+        m = ModuleHelper.ModuleObject("Module_A", cl, new String[] { "mypackage6" });
         assertNotNull(m, "Module should not be null");
         ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage6" });
         try {
             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage6a" });
-            throw new RuntimeException("Failed to get IAE for duplicate module");
-        } catch(IllegalArgumentException e) {
-            if (!e.getMessage().contains("Module module.name is already defined")) {
-              throw new RuntimeException("Failed to get expected IAE message for duplicate module: " + e.getMessage());
+            throw new RuntimeException("Failed to get ISE for duplicate module");
+        } catch(IllegalStateException e) {
+            if (!e.getMessage().contains("Module Module_A is already defined")) {
+              throw new RuntimeException("Failed to get expected ISE message for duplicate module: " + e.getMessage());
             }
         }
 
-        // Package is already defined for class loader, expect an IAE
+        // Package is already defined for class loader, expect an ISE
         m = ModuleHelper.ModuleObject("dupl.pkg.module", cl, new String[] { "mypackage6b" });
         try {
             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage6" });
-            throw new RuntimeException("Failed to get IAE for existing package");
-        } catch(IllegalArgumentException e) {
-            if (!e.getMessage().contains("Package mypackage6 for module dupl.pkg.module already exists for class loader")) {
-              throw new RuntimeException("Failed to get expected IAE message for duplicate package: " + e.getMessage());
+            throw new RuntimeException("Failed to get ISE for existing package");
+        } catch(IllegalStateException e) {
+            if (!e.getMessage().contains("Package mypackage6 for module dupl.pkg.module is already in another module, Module_A, defined to the class loader")) {
+              throw new RuntimeException("Failed to get expected ISE message for duplicate package: " + e.getMessage());
             }
         }
 
--- a/hotspot/test/serviceability/attach/AttachSetGetFlag.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/attach/AttachSetGetFlag.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -30,7 +30,7 @@
  *          java.compiler
  *          java.management
  *          jdk.attach/sun.tools.attach
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run main AttachSetGetFlag
  */
 
--- a/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng/othervm -XX:+SegmentedCodeCache CodeCacheTest
  * @run testng/othervm -XX:-SegmentedCodeCache CodeCacheTest
  * @run testng/othervm -Xint -XX:+SegmentedCodeCache CodeCacheTest
--- a/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
--- a/hotspot/test/serviceability/dcmd/compiler/CompilerDirectivesDCMDTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/compiler/CompilerDirectivesDCMDTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -49,7 +49,7 @@
 
     public void run(CommandExecutor executor) {
 
-        if (Platform.isServer()) {
+        if (Platform.isServer() && !Platform.isEmulatedClient()) {
             filename = System.getProperty("test.src", ".") + File.separator + "control2.txt";
         } else {
             filename = System.getProperty("test.src", ".") + File.separator + "control1.txt";
--- a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @summary Test of diagnostic command Compiler.queue
  * @build sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
--- a/hotspot/test/serviceability/dcmd/framework/HelpTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/framework/HelpTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -36,7 +36,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng/othervm -XX:+UsePerfData HelpTest
  */
 public class HelpTest {
--- a/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -36,7 +36,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng/othervm -XX:+UsePerfData InvalidCommandTest
  */
 public class InvalidCommandTest {
--- a/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -37,7 +37,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng/othervm -XX:+UsePerfData VMVersionTest
  */
 public class VMVersionTest {
--- a/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng ClassHistogramAllTest
  */
 public class ClassHistogramAllTest extends ClassHistogramTest {
--- a/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -36,7 +36,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng ClassHistogramTest
  */
 public class ClassHistogramTest {
--- a/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng HeapDumpAllTest
  */
 public class HeapDumpAllTest extends HeapDumpTest {
--- a/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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,7 +44,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng HeapDumpTest
  */
 public class HeapDumpTest {
--- a/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -34,7 +34,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build FinalizationRunner
  * @run main RunFinalizationTest
  */
--- a/hotspot/test/serviceability/dcmd/gc/RunGCTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -40,7 +40,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng/othervm -Xlog:gc=debug:RunGC.gclog -XX:-ExplicitGCInvokesConcurrent RunGCTest
  */
 public class RunGCTest {
--- a/hotspot/test/serviceability/dcmd/jvmti/LoadAgentDcmdTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/jvmti/LoadAgentDcmdTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -41,7 +41,7 @@
  *          java.compiler
  *          java.instrument
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build SimpleJvmtiAgent
  * @run main ClassFileInstaller SimpleJvmtiAgent
  * @run testng LoadAgentDcmdTest
--- a/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng PrintConcurrentLocksTest
  */
 public class PrintConcurrentLocksTest extends PrintTest {
--- a/hotspot/test/serviceability/dcmd/thread/PrintTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/thread/PrintTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -41,7 +41,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng PrintTest
  */
 public class PrintTest {
--- a/hotspot/test/serviceability/dcmd/vm/ClassHierarchyTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/vm/ClassHierarchyTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng ClassHierarchyTest
  */
 
--- a/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng ClassLoaderStatsTest
  */
 
--- a/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -34,7 +34,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis CommandLineTest
  */
 public class CommandLineTest {
--- a/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -36,7 +36,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng DynLibsTest
  */
 
--- a/hotspot/test/serviceability/dcmd/vm/FlagsTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/vm/FlagsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -33,7 +33,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng/othervm -Xmx129m -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right -XX:-TieredCompilation FlagsTest
  */
 public class FlagsTest {
--- a/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -34,7 +34,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng SystemPropertiesTest
  */
 public class SystemPropertiesTest {
--- a/hotspot/test/serviceability/dcmd/vm/UptimeTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/dcmd/vm/UptimeTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @run testng UptimeTest
  */
 public class UptimeTest {
--- a/hotspot/test/serviceability/jvmti/GetObjectSizeClass.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/jvmti/GetObjectSizeClass.java	Fri Feb 10 08:57:42 2017 -0800
@@ -35,7 +35,7 @@
  *          java.compiler
  *          java.instrument
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build GetObjectSizeClassAgent
  * @run main ClassFileInstaller GetObjectSizeClassAgent
  * @run main GetObjectSizeClass
--- a/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/jvmti/GetObjectSizeOverflow.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -36,7 +36,7 @@
  *          java.compiler
  *          java.instrument
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build GetObjectSizeOverflowAgent
  * @run main ClassFileInstaller GetObjectSizeOverflowAgent
  * @run main GetObjectSizeOverflow
--- a/hotspot/test/serviceability/jvmti/TestRedefineWithUnresolvedClass.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/jvmti/TestRedefineWithUnresolvedClass.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -31,7 +31,7 @@
  *          java.instrument
  *          java.management
  *          jdk.jartool/sun.tools.jar
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build UnresolvedClassAgent
  * @run main TestRedefineWithUnresolvedClass
  */
--- a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapProc.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapProc.java	Fri Feb 10 08:57:42 2017 -0800
@@ -21,12 +21,9 @@
  * questions.
  */
 
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
+import jdk.test.lib.process.ProcessTools;
 
 import sun.management.VMManagement;
 
@@ -38,7 +35,7 @@
         buildLargeHeap(args);
 
         // Print our pid on stdout
-        System.out.println("PID[" + getProcessId() + "]");
+        System.out.println("PID[" + ProcessTools.getProcessId() + "]");
 
         // Wait for input before termination
         System.in.read();
@@ -50,22 +47,4 @@
         }
     }
 
-    public static int getProcessId() throws Exception {
-
-        // Get the current process id using a reflection hack
-        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
-        Field jvm = runtime.getClass().getDeclaredField("jvm");
-
-        jvm.setAccessible(true);
-        VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
-
-        Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
-
-        pid_method.setAccessible(true);
-
-        int pid = (Integer) pid_method.invoke(mgmt);
-
-        return pid;
-    }
-
 }
--- a/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -46,7 +46,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management/sun.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build JMapHProfLargeHeapProc
  * @run main JMapHProfLargeHeapTest
  */
@@ -90,6 +90,9 @@
         try (Scanner largeHeapScanner = new Scanner(
                 largeHeapProc.getInputStream());) {
             String pidstring = null;
+            if (!largeHeapScanner.hasNext()) {
+                throw new RuntimeException ("Test failed: could not open largeHeapScanner.");
+            }
             while ((pidstring = largeHeapScanner.findInLine("PID\\[[0-9].*\\]")) == null) {
                 Thread.sleep(500);
             }
--- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Fri Feb 10 08:57:42 2017 -0800
@@ -59,6 +59,8 @@
             OUT = os;
         }
 
+        boolean passed = false;
+
         try {
             try {
                 if (ManagementFactory.getCompilationMXBean() == null) {
@@ -84,10 +86,10 @@
                     PathHandler.getClassCount(),
                     Compiler.getMethodCount(),
                     System.currentTimeMillis() - start);
+            passed = true;
         } finally {
-            if (os != null) {
-                os.close();
-            }
+            // <clinit> might have started new threads
+            System.exit(passed ? 0 : 1);
         }
     }
 
--- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Fri Feb 10 08:57:42 2017 -0800
@@ -101,10 +101,12 @@
             INITIAL_COMP_LEVEL = 1;
         } else {
             String vmName = System.getProperty("java.vm.name");
-            if (Utils.endsWithIgnoreCase(vmName, " Server VM")) {
+            String vmInfo = System.getProperty("java.vm.info");
+            boolean isEmulatedClient = (vmInfo != null) && vmInfo.contains("emulated-client");
+            if (Utils.endsWithIgnoreCase(vmName, " Server VM") && !isEmulatedClient) {
                 INITIAL_COMP_LEVEL = 4;
             } else if (Utils.endsWithIgnoreCase(vmName, " Client VM")
-                    || Utils.endsWithIgnoreCase(vmName, " Minimal VM")) {
+                    || Utils.endsWithIgnoreCase(vmName, " Minimal VM") || isEmulatedClient) {
                 INITIAL_COMP_LEVEL = 1;
             } else {
                 throw new RuntimeException("Unknown VM: " + vmName);
--- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java	Fri Feb 10 08:57:42 2017 -0800
@@ -50,7 +50,7 @@
         OS("isAix", "isLinux", "isOSX", "isSolaris", "isWindows"),
         VM_TYPE("isClient", "isServer", "isGraal", "isMinimal", "isZero", "isEmbedded"),
         MODE("isInt", "isMixed", "isComp"),
-        IGNORED("isDebugBuild", "isFastDebugBuild", "isSlowDebugBuild",
+        IGNORED("isEmulatedClient", "isDebugBuild", "isFastDebugBuild", "isSlowDebugBuild",
                 "shouldSAAttach", "canPtraceAttachLinux", "canAttachOSX",
                 "isTieredSupported");
 
--- a/hotspot/test/testlibrary_tests/ctw/ClassesDirTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary_tests/ctw/ClassesDirTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -30,11 +30,11 @@
  *          java.base/jdk.internal.reflect
  *          java.management
  * @build sun.hotspot.WhiteBox Foo Bar
- * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
- *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main ClassesDirTest prepare
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes
- * @run main ClassesDirTest check ctw.log
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run driver ClassesDirTest prepare
+ * @run driver ClassesDirTest compile classes
+ * @run driver ClassesDirTest check
  * @summary testing of CompileTheWorld :: classes in directory
  * @author igor.ignatyev@oracle.com
  */
--- a/hotspot/test/testlibrary_tests/ctw/ClassesListTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary_tests/ctw/ClassesListTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -30,11 +30,11 @@
  *          java.base/jdk.internal.reflect
  *          java.management
  * @build sun.hotspot.WhiteBox Foo Bar
- * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
- *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main ClassesListTest prepare
- * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes.lst
- * @run main ClassesListTest check ctw.log
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run driver ClassesListTest prepare
+ * @run driver/timeout=600 ClassesListTest compile classes.lst
+ * @run driver ClassesListTest check
  * @summary testing of CompileTheWorld :: list of classes in file
  * @author igor.ignatyev@oracle.com
  */
--- a/hotspot/test/testlibrary_tests/ctw/CtwTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary_tests/ctw/CtwTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -21,6 +21,7 @@
  * questions.
  */
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.Collections;
 import java.util.ArrayList;
@@ -38,8 +39,20 @@
 
 import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
 
 public abstract class CtwTest {
+    private static final String LOG_FILE = "ctw.log";
+    private static final String[] CTW_COMMAND = {
+        "-Xbootclasspath/a:.",
+        "-XX:+UnlockDiagnosticVMOptions",
+        "-XX:+WhiteBoxAPI",
+        "-Dsun.hotspot.tools.ctw.logfile=" + LOG_FILE,
+        "--add-exports", "java.base/jdk.internal.jimage=ALL-UNNAMED",
+        "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED",
+        "--add-exports", "java.base/jdk.internal.reflect=ALL-UNNAMED",
+        sun.hotspot.tools.ctw.CompileTheWorld.class.getName(),
+    };
     protected final String[] shouldContain;
     protected CtwTest(String[] shouldContain) {
         this.shouldContain = shouldContain;
@@ -54,7 +67,10 @@
                 prepare();
                 break;
             case "check":
-                check(args);
+                check();
+                break;
+            case "compile":
+                compile(args);
                 break;
             default:
                 throw new Error("unregonized action -- " + args[0]);
@@ -63,20 +79,27 @@
 
     protected void prepare() throws Exception { }
 
-    protected void check(String[] args) throws Exception  {
-        if (args.length < 2) {
-            throw new Error("logfile isn't specified");
-        }
-        String logfile = args[1];
-        try (BufferedReader r = Files.newBufferedReader(Paths.get(logfile),
+    protected void check() throws Exception  {
+        try (BufferedReader r = Files.newBufferedReader(Paths.get(LOG_FILE),
                 Charset.defaultCharset())) {
             OutputAnalyzer output = readOutput(r);
-           for (String test : shouldContain) {
+            for (String test : shouldContain) {
                 output.shouldContain(test);
             }
         }
     }
 
+    protected void compile(String[] args) throws Exception {
+        // concat CTW_COMMAND and args w/o 0th element
+        String[] cmd = Arrays.copyOf(CTW_COMMAND, CTW_COMMAND.length + args.length - 1);
+        System.arraycopy(args, 1, cmd, CTW_COMMAND.length, args.length - 1);
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmd);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        dump(output, "compile");
+        output.shouldHaveExitValue(0);
+    }
+
     private static OutputAnalyzer readOutput(BufferedReader reader)
             throws IOException {
         StringBuilder builder = new StringBuilder();
--- a/hotspot/test/testlibrary_tests/ctw/JarDirTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary_tests/ctw/JarDirTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -30,13 +30,13 @@
  *          java.base/jdk.internal.reflect
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build sun.hotspot.WhiteBox Foo Bar
- * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
- *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main JarDirTest prepare
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld jars/*
- * @run main JarDirTest check ctw.log
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run driver JarDirTest prepare
+ * @run driver JarDirTest compile jars/*
+ * @run driver JarDirTest check
  * @summary testing of CompileTheWorld :: jars in directory
  * @author igor.ignatyev@oracle.com
  */
--- a/hotspot/test/testlibrary_tests/ctw/JarsTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary_tests/ctw/JarsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -30,13 +30,13 @@
  *          java.base/jdk.internal.reflect
  *          java.compiler
  *          java.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build sun.hotspot.WhiteBox Foo Bar
- * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
- *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main JarsTest prepare
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld foo.jar bar.jar
- * @run main JarsTest check ctw.log
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox Foo Bar
+ *                                sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run driver JarsTest prepare
+ * @run driver JarsTest compile foo.jar bar.jar
+ * @run driver JarsTest check
  * @summary testing of CompileTheWorld :: jars
  * @author igor.ignatyev@oracle.com
  */
--- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -28,7 +28,7 @@
  * @modules java.base/jdk.internal.misc
  *          java.compiler
  *          java.management/sun.management
- *          jdk.jvmstat/sun.jvmstat.monitor
+ *          jdk.internal.jvmstat/sun.jvmstat.monitor
  * @build sun.hotspot.WhiteBox
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
--- a/jaxp/.hgtags	Fri Feb 10 13:32:11 2017 +0530
+++ b/jaxp/.hgtags	Fri Feb 10 08:57:42 2017 -0800
@@ -397,3 +397,4 @@
 7e3da313b1746578da648155e37dd8526e83153d jdk-9+152
 1384504d2cd0e55c5e0becaeaf40ab05cae959d6 jdk-9+153
 7fa738305436d14c0926df0f04892890cacc766b jdk-9+154
+48fa77af153288b08ba794e1616a7b0685f3b67e jdk-9+155
--- a/jaxp/test/javax/xml/jaxp/unittest/transform/TransformerTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/TransformerTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -24,32 +24,32 @@
 package transform;
 
 import static jaxp.library.JAXPTestUtilities.getSystemProperty;
-import static jaxp.library.JAXPTestUtilities.tryRunWithTmpPermission;
 
-import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.IOException;
-import java.io.StringReader;
 import java.io.StringWriter;
 
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
 import javax.xml.transform.dom.DOMResult;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stax.StAXSource;
 import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
 
 import org.testng.Assert;
 import org.testng.AssertJUnit;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Listeners;
 import org.testng.annotations.Test;
 import org.w3c.dom.Document;
@@ -67,8 +67,7 @@
 import org.xml.sax.XMLReader;
 import org.xml.sax.helpers.AttributesImpl;
 
-import com.sun.org.apache.xml.internal.serialize.OutputFormat;
-import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
+import transform.util.TransformerTestTemplate;
 
 /*
  * @test
@@ -91,250 +90,241 @@
     private static final String NAMESPACE_PREFIXES =
         "http://xml.org/sax/features/namespace-prefixes";
 
-    private static abstract class TestTemplate {
-        protected void printSnippet(String title, String snippet) {
-            StringBuilder div = new StringBuilder();
-            for (int i = 0; i < title.length(); i++)
-                div.append("=");
-            System.out.println(title + "\n" + div + "\n" + snippet + "\n");
-        }
-    }
+    public static class Test6272879 extends TransformerTestTemplate {
 
-    /**
-     * Reads the contents of the given file into a string.
-     * WARNING: this method adds a final line feed even if the last line of the file doesn't contain one.
-     *
-     * @param f
-     * The file to read
-     * @return The content of the file as a string, with line terminators as \"n"
-     * for all platforms
-     * @throws IOException
-     * If there was an error reading
-     */
-    private String getFileContentAsString(File f) throws IOException {
-        try (BufferedReader reader = new BufferedReader(new FileReader(f))) {
-            String line;
-            StringBuilder sb = new StringBuilder();
-            while ((line = reader.readLine()) != null) {
-                sb.append(line).append("\n");
-            }
-            return sb.toString();
-        }
-    }
+        private static String XSL_INPUT =
+            "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
+            "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" + LINE_SEPARATOR +
+            "<xsl:output method=\"xml\" indent=\"no\" encoding=\"ISO-8859-1\"/>" + LINE_SEPARATOR +
+            "<xsl:template match=\"/\">" + LINE_SEPARATOR +
+            "<xsl:element name=\"TransformateurXML\">" + LINE_SEPARATOR +
+            "  <xsl:for-each select=\"XMLUtils/test\">" + LINE_SEPARATOR +
+            "  <xsl:element name=\"test2\">" + LINE_SEPARATOR +
+            "    <xsl:element name=\"valeur2\">" + LINE_SEPARATOR +
+            "      <xsl:attribute name=\"attribut2\">" + LINE_SEPARATOR +
+            "        <xsl:value-of select=\"valeur/@attribut\"/>" + LINE_SEPARATOR +
+            "      </xsl:attribute>" + LINE_SEPARATOR +
+            "      <xsl:value-of select=\"valeur\"/>" + LINE_SEPARATOR +
+            "    </xsl:element>" + LINE_SEPARATOR +
+            "  </xsl:element>" + LINE_SEPARATOR +
+            "  </xsl:for-each>" + LINE_SEPARATOR +
+            "</xsl:element>" + LINE_SEPARATOR +
+            "</xsl:template>" + LINE_SEPARATOR +
+            "</xsl:stylesheet>";
 
-    private class XMLReaderFor6305029 implements XMLReader {
-        private boolean namespaces = true;
-        private boolean namespacePrefixes = false;
-        private EntityResolver resolver;
-        private DTDHandler dtdHandler;
-        private ContentHandler contentHandler;
-        private ErrorHandler errorHandler;
+        private static String XML_INPUT =
+            "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
+            // "<!DOCTYPE XMLUtils [" + LINE_SEPARATOR +
+            // "<!ELEMENT XMLUtils (test*)>" + LINE_SEPARATOR +
+            // "<!ELEMENT test (valeur*)>" + LINE_SEPARATOR +
+            // "<!ELEMENT valeur (#PCDATA)>" + LINE_SEPARATOR +
+            // "<!ATTLIST valeur attribut CDATA #REQUIRED>]>" +
+            // LINE_SEPARATOR +
+            "<XMLUtils>" + LINE_SEPARATOR +
+            "  <test>" + LINE_SEPARATOR +
+            "    <valeur attribut=\"Attribut 1\">Valeur 1</valeur>" + LINE_SEPARATOR +
+            "  </test>" + LINE_SEPARATOR +
+            "  <test>" + LINE_SEPARATOR +
+            "    <valeur attribut=\"Attribut 2\">Valeur 2</valeur>" + LINE_SEPARATOR +
+            "  </test>" + LINE_SEPARATOR +
+            "</XMLUtils>";
 
-        public boolean getFeature(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
-            if (name.equals(NAMESPACES)) {
-                return namespaces;
-            } else if (name.equals(NAMESPACE_PREFIXES)) {
-                return namespacePrefixes;
-            } else {
-                throw new SAXNotRecognizedException();
-            }
-        }
-
-        public void setFeature(final String name, final boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
-            if (name.equals(NAMESPACES)) {
-                namespaces = value;
-            } else if (name.equals(NAMESPACE_PREFIXES)) {
-                namespacePrefixes = value;
-            } else {
-                throw new SAXNotRecognizedException();
-            }
+        public Test6272879() {
+            super(XSL_INPUT, XML_INPUT);
         }
 
-        public Object getProperty(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
-            return null;
-        }
-
-        public void setProperty(final String name, final Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
-        }
-
-        public void setEntityResolver(final EntityResolver theResolver) {
-            this.resolver = theResolver;
-        }
-
-        public EntityResolver getEntityResolver() {
-            return resolver;
-        }
-
-        public void setDTDHandler(final DTDHandler theHandler) {
-            dtdHandler = theHandler;
-        }
-
-        public DTDHandler getDTDHandler() {
-            return dtdHandler;
-        }
-
-        public void setContentHandler(final ContentHandler handler) {
-            contentHandler = handler;
-        }
+        /*
+         * @bug 6272879
+         * @summary Test for JDK-6272879
+         *          DomResult had truncated Strings in some places
+         */
+        @Test
+        public void run() throws TransformerException, ClassNotFoundException, InstantiationException,
+            IllegalAccessException, ClassCastException
+        {
+            // print input
+            printSnippet("Stylesheet:", getXsl());
+            printSnippet("Source before transformation:", getSourceXml());
 
-        public ContentHandler getContentHandler() {
-            return contentHandler;
-        }
-
-        public void setErrorHandler(final ErrorHandler handler) {
-            errorHandler = handler;
-        }
+            // transform to DOM result
+            Transformer t = getTransformer();
+            DOMResult result = new DOMResult();
+            t.transform(getStreamSource(), result);
 
-        public ErrorHandler getErrorHandler() {
-            return errorHandler;
-        }
-
-        public void parse(final InputSource input) throws IOException, SAXException {
-            parse();
-        }
+            // print output
+            printSnippet("Result after transformation:", prettyPrintDOMResult(result));
 
-        public void parse(final String systemId) throws IOException, SAXException {
-            parse();
-        }
-
-        private void parse() throws SAXException {
-            contentHandler.startDocument();
-            contentHandler.startPrefixMapping("prefix", "namespaceUri");
-
-            AttributesImpl atts = new AttributesImpl();
-            if (namespacePrefixes) {
-                atts.addAttribute("", "xmlns:prefix", "xmlns:prefix", "CDATA", "namespaceUri");
+            // do some assertions
+            Document document = (Document)result.getNode();
+            NodeList nodes = document.getElementsByTagName("valeur2");
+            for (int i = 0; i < nodes.getLength(); i++) {
+                Node node = nodes.item(i);
+                AssertJUnit.assertEquals("Node value mismatch",
+                                         "Valeur " + (i + 1),
+                                         node.getFirstChild().getNodeValue());
+                AssertJUnit.assertEquals("Node attribute mismatch",
+                                         "Attribut " + (i + 1),
+                                         node.getAttributes().item(0).getNodeValue());
             }
-
-            contentHandler.startElement("namespaceUri", "localName", namespacePrefixes ? "prefix:localName" : "", atts);
-            contentHandler.endElement("namespaceUri", "localName", namespacePrefixes ? "prefix:localName" : "");
-            contentHandler.endPrefixMapping("prefix");
-            contentHandler.endDocument();
         }
     }
 
-    /*
-     * @bug 6272879
-     * @summary Test for JDK-6272879
-     */
-    @Test
-    public final void testBug6272879() throws Exception {
-        final String xsl =
-                "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
-                "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" + LINE_SEPARATOR +
-                "<xsl:output method=\"xml\" indent=\"no\" encoding=\"ISO-8859-1\"/>" + LINE_SEPARATOR +
-                "<xsl:template match=\"/\">" + LINE_SEPARATOR +
-                "<xsl:element name=\"TransformateurXML\">" + LINE_SEPARATOR +
-                "  <xsl:for-each select=\"XMLUtils/test\">" + LINE_SEPARATOR +
-                "  <xsl:element name=\"test2\">" + LINE_SEPARATOR +
-                "    <xsl:element name=\"valeur2\">" + LINE_SEPARATOR +
-                "      <xsl:attribute name=\"attribut2\">" + LINE_SEPARATOR +
-                "        <xsl:value-of select=\"valeur/@attribut\"/>" + LINE_SEPARATOR +
-                "      </xsl:attribute>" + LINE_SEPARATOR +
-                "      <xsl:value-of select=\"valeur\"/>" + LINE_SEPARATOR +
-                "    </xsl:element>" + LINE_SEPARATOR +
-                "  </xsl:element>" + LINE_SEPARATOR +
-                "  </xsl:for-each>" + LINE_SEPARATOR +
-                "</xsl:element>" + LINE_SEPARATOR +
-                "</xsl:template>" + LINE_SEPARATOR +
-                "</xsl:stylesheet>";
+    public static class Test6305029 extends TransformerTestTemplate {
+
+        private static String XML_INPUT =
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<prefix:localName xmlns:prefix=\"namespaceUri\"/>";
+
+        // custom XMLReader representing XML_INPUT
+        private class MyXMLReader implements XMLReader {
+            private boolean namespaces = true;
+            private boolean namespacePrefixes = false;
+            private EntityResolver resolver;
+            private DTDHandler dtdHandler;
+            private ContentHandler contentHandler;
+            private ErrorHandler errorHandler;
+
+            public boolean getFeature(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+                if (name.equals(NAMESPACES)) {
+                    return namespaces;
+                } else if (name.equals(NAMESPACE_PREFIXES)) {
+                    return namespacePrefixes;
+                } else {
+                    throw new SAXNotRecognizedException();
+                }
+            }
+
+            public void setFeature(final String name, final boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
+                if (name.equals(NAMESPACES)) {
+                    namespaces = value;
+                } else if (name.equals(NAMESPACE_PREFIXES)) {
+                    namespacePrefixes = value;
+                } else {
+                    throw new SAXNotRecognizedException();
+                }
+            }
+
+            public Object getProperty(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
+                return null;
+            }
+
+            public void setProperty(final String name, final Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
+            }
+
+            public void setEntityResolver(final EntityResolver theResolver) {
+                this.resolver = theResolver;
+            }
+
+            public EntityResolver getEntityResolver() {
+                return resolver;
+            }
+
+            public void setDTDHandler(final DTDHandler theHandler) {
+                dtdHandler = theHandler;
+            }
+
+            public DTDHandler getDTDHandler() {
+                return dtdHandler;
+            }
+
+            public void setContentHandler(final ContentHandler handler) {
+                contentHandler = handler;
+            }
 
-        final String sourceXml =
-                "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
-                // "<!DOCTYPE XMLUtils [" + LINE_SEPARATOR +
-                // "<!ELEMENT XMLUtils (test*)>" + LINE_SEPARATOR +
-                // "<!ELEMENT test (valeur*)>" + LINE_SEPARATOR +
-                // "<!ELEMENT valeur (#PCDATA)>" + LINE_SEPARATOR +
-                // "<!ATTLIST valeur attribut CDATA #REQUIRED>]>" +
-                // LINE_SEPARATOR +
-                "<XMLUtils>" + LINE_SEPARATOR +
-                "  <test>" + LINE_SEPARATOR +
-                "    <valeur attribut=\"Attribut 1\">Valeur 1</valeur>" + LINE_SEPARATOR +
-                "  </test>" + LINE_SEPARATOR +
-                "  <test>" + LINE_SEPARATOR +
-                "    <valeur attribut=\"Attribut 2\">Valeur 2</valeur>" + LINE_SEPARATOR +
-                "  </test>" + LINE_SEPARATOR +
-                "</XMLUtils>";
+            public ContentHandler getContentHandler() {
+                return contentHandler;
+            }
+
+            public void setErrorHandler(final ErrorHandler handler) {
+                errorHandler = handler;
+            }
+
+            public ErrorHandler getErrorHandler() {
+                return errorHandler;
+            }
 
-        System.out.println("Stylesheet:");
-        System.out.println("=============================");
-        System.out.println(xsl);
-        System.out.println();
+            public void parse(final InputSource input) throws IOException, SAXException {
+                parse();
+            }
+
+            public void parse(final String systemId) throws IOException, SAXException {
+                parse();
+            }
 
-        System.out.println("Source before transformation:");
-        System.out.println("=============================");
-        System.out.println(sourceXml);
-        System.out.println();
+            private void parse() throws SAXException {
+                contentHandler.startDocument();
+                contentHandler.startPrefixMapping("prefix", "namespaceUri");
+
+                AttributesImpl atts = new AttributesImpl();
+                if (namespacePrefixes) {
+                    atts.addAttribute("", "xmlns:prefix", "xmlns:prefix", "CDATA", "namespaceUri");
+                }
 
-        // transform to DOM result
-        TransformerFactory tf = TransformerFactory.newInstance();
-        Transformer t = tf.newTransformer(new StreamSource(new ByteArrayInputStream(xsl.getBytes())));
-        DOMResult result = new DOMResult();
-        t.transform(new StreamSource(new ByteArrayInputStream(sourceXml.getBytes())), result);
-        Document document = (Document)result.getNode();
+                contentHandler.startElement("namespaceUri", "localName", namespacePrefixes ? "prefix:localName" : "", atts);
+                contentHandler.endElement("namespaceUri", "localName", namespacePrefixes ? "prefix:localName" : "");
+                contentHandler.endPrefixMapping("prefix");
+                contentHandler.endDocument();
+            }
+        }
+
+        public Test6305029() {
+            super(null, XML_INPUT);
+        }
 
-        System.out.println("Result after transformation:");
-        System.out.println("============================");
-        tryRunWithTmpPermission(() -> {
-            OutputFormat format = new OutputFormat();
-            format.setIndenting(true);
-            new XMLSerializer(System.out, format).serialize(document);
-        }, new RuntimePermission("accessClassInPackage.com.sun.org.apache.xml.internal.serialize"));
-        System.out.println();
+        /*
+         * @bug 6305029
+         * @summary Test for JDK-6305029
+         *          Test identity transformation
+         */
+        @Test
+        public void run() throws TransformerFactoryConfigurationError, TransformerException {
+            // get Identity transformer
+            Transformer t = getTransformer();
 
-        System.out.println("Node content for element valeur2:");
-        System.out.println("=================================");
-        NodeList nodes = document.getElementsByTagName("valeur2");
-        for (int i = 0; i < nodes.getLength(); i++) {
-            Node node = nodes.item(i);
-            System.out.println("  Node value: " + node.getFirstChild().getNodeValue());
-            System.out.println("  Node attribute: " + node.getAttributes().item(0).getNodeValue());
+            // test SAXSource from custom XMLReader
+            SAXSource saxSource = new SAXSource(new MyXMLReader(), new InputSource());
+            StringWriter resultWriter = new StringWriter();
+            t.transform(saxSource, new StreamResult(resultWriter));
+            String resultString = resultWriter.toString();
+            printSnippet("Result after transformation from custom SAXSource:", resultString);
+            AssertJUnit.assertEquals("Identity transform of SAXSource", getSourceXml(), resultString);
 
-            AssertJUnit.assertEquals("Node value mismatch", "Valeur " + (i + 1), node.getFirstChild().getNodeValue());
-            AssertJUnit.assertEquals("Node attribute mismatch", "Attribut " + (i + 1), node.getAttributes().item(0).getNodeValue());
+            // test StreamSource
+            printSnippet("Source before transformation of StreamSource:", getSourceXml());
+            resultWriter = new StringWriter();
+            t.transform(getStreamSource(), new StreamResult(resultWriter));
+            resultString = resultWriter.toString();
+            printSnippet("Result after transformation of StreamSource:", resultString);
+            AssertJUnit.assertEquals("Identity transform of StreamSource", getSourceXml(), resultString);
         }
     }
 
-    /*
-     * @bug 6305029
-     * @summary Test for JDK-6305029
-     */
-    @Test
-    public final void testBug6305029() throws TransformerException {
-        final String XML_DOCUMENT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<prefix:localName xmlns:prefix=\"namespaceUri\"/>";
+    public static class Test6505031 extends TransformerTestTemplate {
+
+        public Test6505031() throws IOException {
+            super();
+            setXsl(fromInputStream(getClass().getResourceAsStream("transform.xsl")));
+            setSourceXml(fromInputStream(getClass().getResourceAsStream("template.xml")));
+        }
 
-        // test SAXSource
-        SAXSource saxSource = new SAXSource(new XMLReaderFor6305029(), new InputSource());
-        StringWriter resultWriter = new StringWriter();
-        TransformerFactory tf = TransformerFactory.newInstance();
-        tf.newTransformer().transform(saxSource, new StreamResult(resultWriter));
-        AssertJUnit.assertEquals("Identity transform of SAXSource", XML_DOCUMENT, resultWriter.toString());
-
-        // test StreamSource
-        StreamSource streamSource = new StreamSource(new StringReader(XML_DOCUMENT));
-        resultWriter = new StringWriter();
-        tf.newTransformer().transform(streamSource, new StreamResult(resultWriter));
-        AssertJUnit.assertEquals("Identity transform of StreamSource", XML_DOCUMENT, resultWriter.toString());
+        /*
+         * @bug 6505031
+         * @summary Test transformer parses keys and their values coming from different xml documents.
+         */
+        @Test
+        public void run() throws TransformerFactoryConfigurationError, TransformerException {
+            Transformer t = getTransformer();
+            t.setParameter("config", getClass().getResource("config.xml").toString());
+            t.setParameter("mapsFile", getClass().getResource("maps.xml").toString());
+            StringWriter resultWriter = new StringWriter();
+            t.transform(getStreamSource(), new StreamResult(resultWriter));
+            String resultString = resultWriter.toString();
+            Assert.assertTrue(resultString.contains("map1key1value") && resultString.contains("map2key1value"));
+        }
     }
 
-    /*
-     * @bug 6505031
-     * @summary Test transformer parses keys and their values coming from different xml documents.
-     */
-    @Test
-    public final void testBug6505031() throws TransformerException {
-        TransformerFactory tf = TransformerFactory.newInstance();
-        Transformer t = tf.newTransformer(new StreamSource(getClass().getResource("transform.xsl").toString()));
-        t.setParameter("config", getClass().getResource("config.xml").toString());
-        t.setParameter("mapsFile", getClass().getResource("maps.xml").toString());
-        StringWriter sw = new StringWriter();
-        t.transform(new StreamSource(getClass().getResource("template.xml").toString()), new StreamResult(sw));
-        String s = sw.toString();
-        Assert.assertTrue(s.contains("map1key1value") && s.contains("map2key1value"));
-    }
+    public static class Test8169631 extends TransformerTestTemplate {
 
-    private static class Test8169631 extends TestTemplate {
-        private final static String xsl =
+        private static String XSL_INPUT =
             "<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
             "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
             "  <xsl:template match=\"/\">" + LINE_SEPARATOR +
@@ -345,7 +335,7 @@
             "  </xsl:template>" + LINE_SEPARATOR +
             "</xsl:stylesheet>" + LINE_SEPARATOR;
 
-        private final static String sourceXml =
+        private static String XML_INPUT =
             "<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
             "<envelope xmlns=\"http://www.sap.com/myns\" xmlns:sap=\"http://www.sap.com/myns\">" + LINE_SEPARATOR +
             "  <sap:row sap:attrib=\"a\">1</sap:row>" + LINE_SEPARATOR +
@@ -353,6 +343,10 @@
             "  <row sap:attrib=\"c\">3</row>" + LINE_SEPARATOR +
             "</envelope>" + LINE_SEPARATOR;
 
+        public Test8169631() {
+            super(XSL_INPUT, XML_INPUT);
+        }
+
         /**
          * Utility method to print out transformation result and check values.
          *
@@ -380,103 +374,104 @@
                 type + " should have count of "+ attribCount + " attributes.");
         }
 
-        public void run() throws IOException, TransformerException,
-            SAXException, ParserConfigurationException
+        @DataProvider(name = "testdata8169631")
+        public Object[][] testData()
+            throws TransformerConfigurationException, SAXException, IOException,
+            ParserConfigurationException, XMLStreamException
         {
-            printSnippet("Source:", sourceXml);
-
-            printSnippet("Stylesheet:", xsl);
-
-            // create default transformer (namespace aware)
-            TransformerFactory tf1 = TransformerFactory.newInstance();
-            ByteArrayInputStream bais = new ByteArrayInputStream(xsl.getBytes());
-            Transformer t1 = tf1.newTransformer(new StreamSource(bais));
+            // get Transformers
+            TransformerFactory tf = TransformerFactory.newInstance();
+            Transformer t = getTransformer(tf);
+            Transformer tFromTemplates = getTemplates(tf).newTransformer();
 
-            // test transformation from stream source with namespace support
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            bais = new ByteArrayInputStream(sourceXml.getBytes());
-            t1.transform(new StreamSource(bais), new StreamResult(baos));
-            verifyResult("StreamSource with namespace support", baos.toString(), 0, 1);
+            // get DOMSource objects
+            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+            DOMSource domSourceWithoutNS = getDOMSource(dbf);
+            dbf.setNamespaceAware(true);
+            DOMSource domSourceWithNS = getDOMSource(dbf);
 
-            // test transformation from DOM source with namespace support
-            bais.reset();
-            baos.reset();
-            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-            dbf.setNamespaceAware(true);
-            Document doc = dbf.newDocumentBuilder().parse(new InputSource(bais));
-            t1.transform(new DOMSource(doc), new StreamResult(baos));
-            verifyResult("DOMSource with namespace support", baos.toString(), 0, 1);
+            // get SAXSource objects
+            SAXParserFactory spf = SAXParserFactory.newInstance();
+            SAXSource saxSourceWithoutNS = getSAXSource(spf);
+            spf.setNamespaceAware(true);
+            SAXSource saxSourceWithNS = getSAXSource(spf);
+
+            // get StAXSource objects
+            XMLInputFactory xif = XMLInputFactory.newInstance();
+            StAXSource staxSourceWithNS = getStAXSource(xif);
 
-            // test transformation from DOM source without namespace support
-            bais.reset();
-            baos.reset();
-            dbf.setNamespaceAware(false);
-            doc = dbf.newDocumentBuilder().parse(new InputSource(bais));
-            t1.transform(new DOMSource(doc), new StreamResult(baos));
-            verifyResult("DOMSource without namespace support", baos.toString(), 3, 3);
+            // print XML/XSL snippets to ease understanding of result
+            printSnippet("Source:", getSourceXml());
+            printSnippet("Stylesheet:", getXsl());
 
-            // test transformation from SAX source with namespace support
-            bais.reset();
-            baos.reset();
-            SAXParserFactory spf = SAXParserFactory.newInstance();
-            spf.setNamespaceAware(true);
-            XMLReader xmlr = spf.newSAXParser().getXMLReader();
-            SAXSource saxS = new SAXSource(xmlr, new InputSource(bais));
-            t1.transform(saxS, new StreamResult(baos));
-            verifyResult("SAXSource with namespace support", baos.toString(), 0, 1);
+            return new Object[][] {
+                // test StreamSource input with all transformers
+                // namespace awareness is set by transformer
+                {t, getStreamSource(), "StreamSource with namespace support", 0, 1},
+                {tFromTemplates, getStreamSource(), "StreamSource with namespace support using templates", 0, 1},
+                // now test DOMSource, SAXSource and StAXSource
+                // with rotating use of created transformers
+                // namespace awareness is set by source objects
+                {t, domSourceWithNS, "DOMSource with namespace support", 0, 1},
+                {t, domSourceWithoutNS, "DOMSource without namespace support", 3, 3},
+                {tFromTemplates, saxSourceWithNS, "SAXSource with namespace support", 0, 1},
+                {tFromTemplates, saxSourceWithoutNS, "SAXSource without namespace support", 3, 3},
+                {t, staxSourceWithNS, "StAXSource with namespace support", 0, 1}
+            };
+        }
 
-            // test transformation from SAX source without namespace support
-            bais.reset();
-            baos.reset();
-            spf.setNamespaceAware(false);
-            xmlr = spf.newSAXParser().getXMLReader();
-            saxS = new SAXSource(xmlr, new InputSource(bais));
-            t1.transform(saxS, new StreamResult(baos));
-            verifyResult("SAXSource without namespace support", baos.toString(), 3, 3);
+        /*
+         * @bug 8169631
+         * @summary Test combinations of namespace awareness settings on
+         *          XSL transformations
+         */
+        @Test(dataProvider = "testdata8169631")
+        public void run(Transformer t, Source s, String label, int elementcount, int attributecount)
+            throws TransformerException
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            t.transform(s, new StreamResult(baos));
+            verifyResult(label, baos.toString(), elementcount, attributecount);
         }
     }
 
-    /*
-     * @bug 8169631
-     * @summary Test combinations of namespace awareness settings on
-     *          XSL transformations
-     */
-    @Test
-    public final void testBug8169631() throws IOException, SAXException,
-        TransformerException, ParserConfigurationException
-    {
-        new Test8169631().run();
+    public static class Test8150704 extends TransformerTestTemplate {
+
+        public Test8150704() {
+            super();
+        }
+
+        @DataProvider(name = "testdata8150704")
+        public Object[][] testData() {
+            return new Object[][] {
+                {"Bug8150704-1.xsl", "Bug8150704-1.xml", "Bug8150704-1.ref"},
+                {"Bug8150704-2.xsl", "Bug8150704-2.xml", "Bug8150704-2.ref"}
+            };
+        }
+
+        /*
+         * @bug 8150704
+         * @summary Test that XSL transformation with lots of temporary result
+         *          trees will not run out of DTM IDs.
+         */
+        @Test(dataProvider = "testdata8150704")
+        public void run(String xsl, String xml, String ref) throws IOException, TransformerException {
+            System.out.println("Testing transformation of " + xml + "...");
+            setXsl(fromInputStream(getClass().getResourceAsStream(xsl)));
+            setSourceXml(fromInputStream(getClass().getResourceAsStream(xml)));
+            Transformer t = getTransformer();
+            StringWriter resultWriter = new StringWriter();
+            t.transform(getStreamSource(), new StreamResult(resultWriter));
+            String resultString = resultWriter.toString().replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n").trim();
+            String reference = fromInputStream(getClass().getResourceAsStream(ref)).trim();
+            Assert.assertEquals(resultString, reference, "Output of transformation of " + xml + " does not match reference");
+            System.out.println("Passed.");
+        }
     }
 
-    /*
-     * @bug 8150704
-     * @summary Test that XSL transformation with lots of temporary result
-     *          trees will not run out of DTM IDs.
-     */
-    @Test
-    public final void testBug8150704() throws TransformerException, IOException {
-        System.out.println("Testing transformation of Bug8150704-1.xml...");
-        TransformerFactory tf = TransformerFactory.newInstance();
-        Transformer t = tf.newTransformer(new StreamSource(getClass().getResource("Bug8150704-1.xsl").toString()));
-        StringWriter sw = new StringWriter();
-        t.transform(new StreamSource(getClass().getResource("Bug8150704-1.xml").toString()), new StreamResult(sw));
-        String resultstring = sw.toString().replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n");
-        String reference = getFileContentAsString(new File(getClass().getResource("Bug8150704-1.ref").getPath()));
-        Assert.assertEquals(resultstring, reference, "Output of transformation of Bug8150704-1.xml does not match reference");
-        System.out.println("Passed.");
+    public static class Test8162598 extends TransformerTestTemplate {
 
-        System.out.println("Testing transformation of Bug8150704-2.xml...");
-        t = tf.newTransformer(new StreamSource(getClass().getResource("Bug8150704-2.xsl").toString()));
-        sw = new StringWriter();
-        t.transform(new StreamSource(getClass().getResource("Bug8150704-2.xml").toString()), new StreamResult(sw));
-        resultstring = sw.toString().replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n");
-        reference = getFileContentAsString(new File(getClass().getResource("Bug8150704-2.ref").getPath()));
-        Assert.assertEquals(resultstring, reference, "Output of transformation of Bug8150704-2.xml does not match reference");
-        System.out.println("Passed.");
-    }
-
-    private static class Test8162598 extends TestTemplate {
-        private static final String xsl =
+        private static String XSL_INPUT =
             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + LINE_SEPARATOR +
             "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
             "    <xsl:template match=\"/\">" + LINE_SEPARATOR +
@@ -494,8 +489,13 @@
             "    </xsl:template>" + LINE_SEPARATOR +
             "</xsl:stylesheet>";
 
-        private static final String sourceXml =
+        private static String XML_INPUT =
             "<?xml version=\"1.0\" encoding=\"UTF-8\"?><aaa></aaa>" + LINE_SEPARATOR;
+
+        public Test8162598() {
+            super(XSL_INPUT, XML_INPUT);
+        }
+
         /**
          * Utility method for testBug8162598().
          * Provides a convenient way to check/assert the expected namespaces
@@ -510,7 +510,6 @@
          * @param nsc
          * Expected namespace of the first sibling of the first sibling
          */
-
         private void checkNodeNS(Node test, String nstest, String nsb, String nsc) {
             String testNodeName = test.getNodeName();
             if (nstest == null) {
@@ -532,29 +531,27 @@
             }
         }
 
+        /*
+         * @bug 8162598
+         * @summary Test XSLTC handling of namespaces, especially empty namespace
+         *          definitions to reset the default namespace
+         */
+        @Test
         public void run()  throws Exception {
-            printSnippet("Source:", sourceXml);
-
-            printSnippet("Stylesheet:", xsl);
+            // print input
+            printSnippet("Source:", getSourceXml());
+            printSnippet("Stylesheet:", getXsl());
 
             // transform to DOM result
-            TransformerFactory tf = TransformerFactory.newInstance();
-            ByteArrayInputStream bais = new ByteArrayInputStream(xsl.getBytes());
-            Transformer t = tf.newTransformer(new StreamSource(bais));
+            Transformer t = getTransformer();
             DOMResult result = new DOMResult();
-            bais = new ByteArrayInputStream(sourceXml.getBytes());
-            t.transform(new StreamSource(bais), result);
-            Document document = (Document)result.getNode();
+            t.transform(getStreamSource(), result);
 
-            System.out.println("Result after transformation:");
-            System.out.println("============================");
-            tryRunWithTmpPermission(() -> {
-                OutputFormat format = new OutputFormat();
-                format.setIndenting(true);
-                new XMLSerializer(System.out, format).serialize(document);
-            }, new RuntimePermission("accessClassInPackage.com.sun.org.apache.xml.internal.serialize"));
-            System.out.println();
+            // print output
+            printSnippet("Result after transformation:", prettyPrintDOMResult(result));
 
+            // do some verifications
+            Document document = (Document)result.getNode();
             checkNodeNS(document.getElementsByTagName("test1").item(0), "ns2", "ns2", null);
             checkNodeNS(document.getElementsByTagName("test2").item(0), "ns1", "ns2", null);
             checkNodeNS(document.getElementsByTagName("test3").item(0), null, null, null);
@@ -565,68 +562,74 @@
         }
     }
 
-    /*
-     * @bug 8162598
-     * @summary Test XSLTC handling of namespaces, especially empty namespace
-     *          definitions to reset the default namespace
-     */
-    @Test
-    public final void testBug8162598() throws Exception {
-        new Test8162598().run();
-    }
+    public static class Test8169112 extends TransformerTestTemplate{
+
+        public static String XML_INPUT =
+            "<?xml version=\"1.0\"?><DOCROOT/>";
+
+        public Test8169112() throws IOException {
+            super();
+            setXsl(fromInputStream(getClass().getResourceAsStream("Bug8169112.xsl")));
+            setSourceXml(XML_INPUT);
+        }
 
-    /**
-     * @bug 8169112
-     * @summary Test compilation of large xsl file with outlining.
-     *
-     * This test merely compiles a large xsl file and tests if its bytecode
-     * passes verification by invoking the transform() method for
-     * dummy content. The test succeeds if no Exception is thrown
-     */
-    @Test
-    public final void testBug8169112() throws FileNotFoundException,
-        TransformerException
-    {
-        TransformerFactory tf = TransformerFactory.newInstance();
-        String xslFile = getClass().getResource("Bug8169112.xsl").toString();
-        Transformer t = tf.newTransformer(new StreamSource(xslFile));
-        String xmlIn = "<?xml version=\"1.0\"?><DOCROOT/>";
-        ByteArrayInputStream bis = new ByteArrayInputStream(xmlIn.getBytes());
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        t.transform(new StreamSource(bis), new StreamResult(bos));
+        /**
+         * @throws TransformerException
+         * @bug 8169112
+         * @summary Test compilation of large xsl file with outlining.
+         *
+         * This test merely compiles a large xsl file and tests if its bytecode
+         * passes verification by invoking the transform() method for
+         * dummy content. The test succeeds if no Exception is thrown
+         */
+        @Test
+        public void run() throws TransformerException {
+            Transformer t = getTransformer();
+            t.transform(getStreamSource(), new StreamResult(new ByteArrayOutputStream()));
+        }
     }
 
-    /**
-     * @bug 8169772
-     * @summary Test transformation of DOM with null valued text node
-     *
-     * This test would throw a NullPointerException during transform when the
-     * fix was not present.
-     */
-    @Test
-    public final void testBug8169772() throws ParserConfigurationException,
-        SAXException, IOException, TransformerException
-    {
-        // create a small DOM
-        Document doc = DocumentBuilderFactory.newInstance().
-            newDocumentBuilder().parse(
-                new ByteArrayInputStream(
-                    "<?xml version=\"1.0\"?><DOCROOT/>".getBytes()
-                )
-            );
+    public static class Test8169772 extends TransformerTestTemplate {
+
+        public Test8169772() {
+            super();
+        }
+
+        private Document getDOMWithBadElement() throws SAXException, IOException, ParserConfigurationException {
+            // create a small DOM
+            Document doc = DocumentBuilderFactory.newInstance().
+                newDocumentBuilder().parse(
+                    new ByteArrayInputStream(
+                        "<?xml version=\"1.0\"?><DOCROOT/>".getBytes()
+                    )
+                );
+
+            // insert a bad element
+            Element e = doc.createElement("ERROR");
+            e.appendChild(doc.createTextNode(null));
+            doc.getDocumentElement().appendChild(e);
 
-        // insert a bad element
-        Element e = doc.createElement("ERROR");
-        e.appendChild(doc.createTextNode(null));
-        doc.getDocumentElement().appendChild(e);
+            return doc;
+        }
 
-        // transform
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        TransformerFactory.newInstance().newTransformer().transform(
-            new DOMSource(doc.getDocumentElement()), new StreamResult(bos)
-        );
-        System.out.println("Transformation result (DOM with null text node):");
-        System.out.println("================================================");
-        System.out.println(bos);
+        /**
+         * @throws ParserConfigurationException
+         * @throws IOException
+         * @throws SAXException
+         * @throws TransformerException
+         * @bug 8169772
+         * @summary Test transformation of DOM with null valued text node
+         *
+         * This test would throw a NullPointerException during transform when the
+         * fix was not present.
+         */
+        @Test
+        public void run() throws SAXException, IOException, ParserConfigurationException, TransformerException {
+            Transformer t = getTransformer();
+            StringWriter resultWriter = new StringWriter();
+            DOMSource d = new DOMSource(getDOMWithBadElement().getDocumentElement());
+            t.transform(d, new StreamResult(resultWriter));
+            printSnippet("Transformation result (DOM with null text node):", resultWriter.toString());
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/util/TransformerTestTemplate.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2014, 2017, 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 transform.util;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.stream.Collectors;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamSource;
+
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSSerializer;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/*
+ * Template for Transformer tests
+ */
+public abstract class TransformerTestTemplate {
+    private String xsl = null;
+    private String sourceXml = null;
+
+    public TransformerTestTemplate() {
+        super();
+    }
+
+    public TransformerTestTemplate(String xsl, String sourceXml) {
+        super();
+        this.xsl = xsl;
+        this.sourceXml = sourceXml;
+    }
+
+    public String getXsl() {
+        return xsl;
+    }
+
+    public void setXsl(String xsl) {
+        this.xsl = xsl;
+    }
+
+    public String getSourceXml() {
+        return sourceXml;
+    }
+
+    public void setSourceXml(String sourceXml) {
+        this.sourceXml = sourceXml;
+    }
+
+    public String fromInputStream(InputStream is) throws IOException {
+        try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
+            return br.lines().collect(Collectors.joining("\n"));
+        }
+    }
+
+    // print an XML Snippet under a given title
+    public void printSnippet(String title, String snippet) {
+        StringBuilder div = new StringBuilder();
+        for (int i = 0; i < title.length(); i++)
+            div.append("=");
+        System.out.println(title + "\n" + div + "\n" + snippet + "\n");
+    }
+
+    // pretty print a DOMResult
+    public String prettyPrintDOMResult(DOMResult dr) throws ClassNotFoundException, InstantiationException,
+        IllegalAccessException, ClassCastException
+    {
+        DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
+        DOMImplementationLS domImplementationLS = (DOMImplementationLS)registry.getDOMImplementation("LS");
+        StringWriter writer = new StringWriter();
+        LSOutput formattedOutput = domImplementationLS.createLSOutput();
+        formattedOutput.setCharacterStream(writer);
+        LSSerializer domSerializer = domImplementationLS.createLSSerializer();
+        domSerializer.getDomConfig().setParameter("format-pretty-print", true);
+        domSerializer.getDomConfig().setParameter("xml-declaration", false);
+        domSerializer.write(dr.getNode(), formattedOutput);
+        return writer.toString();
+    }
+
+    public Transformer getTransformer() throws TransformerConfigurationException {
+        return getTransformer(null);
+    }
+
+        // utility to obtain Transformer from TransformerFactory
+    public Transformer getTransformer(TransformerFactory tf)
+        throws TransformerConfigurationException
+    {
+        if (tf == null) {
+            tf = TransformerFactory.newInstance();
+        }
+
+        if (xsl == null) {
+            return tf.newTransformer();
+        } else {
+            return tf.newTransformer(
+                new StreamSource(new ByteArrayInputStream(xsl.getBytes()))
+            );
+        }
+    }
+
+    // utility to obtain Templates from TransformerFactory
+    public Templates getTemplates(TransformerFactory tf)
+        throws TransformerConfigurationException
+    {
+        return tf.newTemplates(
+            new StreamSource(new ByteArrayInputStream(xsl.getBytes()))
+        );
+    }
+
+    // utility to construct StreamSource
+    public StreamSource getStreamSource() {
+        return new StreamSource(
+            new ByteArrayInputStream(sourceXml.getBytes())
+        );
+    }
+
+    // utility to construct DOMSource from DocumentBuilderFactory
+    public DOMSource getDOMSource(DocumentBuilderFactory dbf)
+        throws SAXException, IOException, ParserConfigurationException
+    {
+        return new DOMSource(
+            dbf.newDocumentBuilder().parse(
+                new InputSource(
+                    new ByteArrayInputStream(sourceXml.getBytes())
+                )
+            )
+        );
+    }
+
+    // utility to construct SAXSource from SAXParserFactory
+    public SAXSource getSAXSource(SAXParserFactory spf)
+        throws SAXException, ParserConfigurationException
+    {
+        return new SAXSource(
+            spf.newSAXParser().getXMLReader(),
+            new InputSource(new ByteArrayInputStream(sourceXml.getBytes()))
+        );
+    }
+
+    // utility to construct StAXSource from XMLInputFactory
+    public StAXSource getStAXSource(XMLInputFactory xif)
+        throws XMLStreamException
+    {
+        return new StAXSource(
+            xif.createXMLStreamReader(new StringReader(sourceXml))
+        );
+    }
+}
--- a/jaxws/.hgtags	Fri Feb 10 13:32:11 2017 +0530
+++ b/jaxws/.hgtags	Fri Feb 10 08:57:42 2017 -0800
@@ -400,3 +400,4 @@
 6f8fb1cf7e5f61c40dcc3654f9a623c505f6de1f jdk-9+152
 7a532a9a227137155b905341d4b99939db51220e jdk-9+153
 34af95c7dbff74f3448fcdb7d745524e8a1cc88a jdk-9+154
+9b9918656c97724fd89c04a8547043bbd37f5935 jdk-9+155
--- a/jaxws/src/java.annotations.common/share/classes/javax/annotation/Generated.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.annotation;
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-/**
- * The Generated annotation is used to mark source code that has been generated.
- * It can also be used to differentiate user written code from generated code
- * in a single file. When used, the value element must have the name of the
- * code generator. The recommended convention is to use the fully qualified
- * name of the code generator in the value field .
- * <p>For example: com.company.package.classname.
- * The date element is used to indicate the date the source was generated.
- * The date element must follow the ISO 8601 standard. For example the date
- * element would have the following value 2001-07-04T12:08:56.235-0700
- * which represents 2001-07-04 12:08:56 local time in the U.S. Pacific
- * Time time zone.</p>
- * <p>The comment element is a place holder for any comments that the code
- * generator may want to include in the generated code.</p>
- *
- * @since 1.6, Common Annotations 1.0
- */
-
-@Documented
-@Retention(SOURCE)
-@Target({PACKAGE, TYPE, ANNOTATION_TYPE, METHOD, CONSTRUCTOR, FIELD,
-        LOCAL_VARIABLE, PARAMETER})
-public @interface Generated {
-   /**
-    * The value element MUST have the name of the code generator.
-    * The recommended convention is to use the fully qualified name of the
-    * code generator. For example: com.acme.generator.CodeGen.
-    */
-   String[] value();
-
-   /**
-    * Date when the source was generated.
-    */
-   String date() default "";
-
-   /**
-    * A place holder for any comments that the code generator may want to
-    * include in the generated code.
-    */
-   String comments() default "";
-}
--- a/jaxws/src/java.annotations.common/share/classes/javax/annotation/PostConstruct.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.annotation;
-
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-/**
- * The PostConstruct annotation is used on a method that needs to be executed
- * after dependency injection is done to perform any initialization. This
- * method MUST be invoked before the class is put into service. This
- * annotation MUST be supported on all classes that support dependency
- * injection. The method annotated with PostConstruct MUST be invoked even
- * if the class does not request any resources to be injected. Only one
- * method can be annotated with this annotation. The method on which the
- * PostConstruct annotation is applied MUST fulfill all of the following
- * criteria:
- * <ul>
- * <li>The method MUST NOT have any parameters except in the case of
- * interceptors in which case it takes an InvocationContext object as
- * defined by the Interceptors specification.</li>
- * <li>The method defined on an interceptor class MUST HAVE one of the
- * following signatures:
- * <p>
- * void &#060;METHOD&#062;(InvocationContext)
- * <p>
- * Object &#060;METHOD&#062;(InvocationContext) throws Exception
- * <p>
- * <i>Note: A PostConstruct interceptor method must not throw application
- * exceptions, but it may be declared to throw checked exceptions including
- * the java.lang.Exception if the same interceptor method interposes on
- * business or timeout methods in addition to lifecycle events. If a
- * PostConstruct interceptor method returns a value, it is ignored by
- * the container.</i>
- * </li>
- * <li>The method defined on a non-interceptor class MUST HAVE the
- * following signature:
- * <p>
- * void &#060;METHOD&#062;()
- * </li>
- * <li>The method on which PostConstruct is applied MAY be public, protected,
- * package private or private.</li>
- * <li>The method MUST NOT be static except for the application client.</li>
- * <li>The method MAY be final.</li>
- * <li>If the method throws an unchecked exception the class MUST NOT be put into
- * service except in the case of EJBs where the EJB can handle exceptions and
- * even recover from them.</li></ul>
- *
- * @see javax.annotation.PreDestroy
- * @see javax.annotation.Resource
- * @since 1.6, Common Annotations 1.0
- */
-@Documented
-@Retention (RUNTIME)
-@Target(METHOD)
-public @interface PostConstruct {
-}
--- a/jaxws/src/java.annotations.common/share/classes/javax/annotation/PreDestroy.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.annotation;
-
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-/**
- * The PreDestroy annotation is used on methods as a callback notification to
- * signal that the instance is in the process of being removed by the
- * container. The method annotated with PreDestroy is typically used to
- * release resources that it has been holding. This annotation MUST be
- * supported by all container managed objects that support PostConstruct
- * except the application client container in Java EE 5. The method on which
- * the PreDestroy annotation is applied MUST fulfill all of the following
- * criteria:
- * <ul>
- * <li>The method MUST NOT have any parameters except in the case of
- * interceptors in which case it takes an InvocationContext object as
- * defined by the Interceptors specification.</li>
- * <li>The method defined on an interceptor class MUST HAVE one of the
- * following signatures:
- * <p>
- * void &#060;METHOD&#062;(InvocationContext)
- * <p>
- * Object &#060;METHOD&#062;(InvocationContext) throws Exception
- * <p>
- * <i>Note: A PreDestroy interceptor method must not throw application
- * exceptions, but it may be declared to throw checked exceptions including
- * the java.lang.Exception if the same interceptor method interposes on
- * business or timeout methods in addition to lifecycle events. If a
- * PreDestroy interceptor method returns a value, it is ignored by
- * the container.</i>
- * </li>
- * <li>The method defined on a non-interceptor class MUST HAVE the
- * following signature:
- * <p>
- * void &#060;METHOD&#062;()
- * </li>
- * <li>The method on which PreDestroy is applied MAY be public, protected,
- * package private or private.</li>
- * <li>The method MUST NOT be static.</li>
- * <li>The method MAY be final.</li>
- * <li>If the method throws an unchecked exception it is ignored except in the
- * case of EJBs where the EJB can handle exceptions.</li>
- * </ul>
- *
- * @see javax.annotation.PostConstruct
- * @see javax.annotation.Resource
- * @since 1.6, Common Annotations 1.0
- */
-
-@Documented
-@Retention (RUNTIME)
-@Target(METHOD)
-public @interface PreDestroy {
-}
--- a/jaxws/src/java.annotations.common/share/classes/javax/annotation/Resource.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.annotation;
-
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-/**
- * The Resource annotation marks a resource that is needed
- * by the application.  This annotation may be applied to an
- * application component class, or to fields or methods of the
- * component class.  When the annotation is applied to a
- * field or method, the container will inject an instance
- * of the requested resource into the application component
- * when the component is initialized.  If the annotation is
- * applied to the component class, the annotation declares a
- * resource that the application will look up at runtime. <p>
- *
- * Even though this annotation is not marked Inherited, deployment
- * tools are required to examine all superclasses of any component
- * class to discover all uses of this annotation in all superclasses.
- * All such annotation instances specify resources that are needed
- * by the application component.  Note that this annotation may
- * appear on private fields and methods of superclasses; the container
- * is required to perform injection in these cases as well.
- *
- * @since 1.6, Common Annotations 1.0
- */
-@Target({TYPE, FIELD, METHOD})
-@Retention(RUNTIME)
-public @interface Resource {
-    /**
-     * The JNDI name of the resource.  For field annotations,
-     * the default is the field name.  For method annotations,
-     * the default is the JavaBeans property name corresponding
-     * to the method.  For class annotations, there is no default
-     * and this must be specified.
-     */
-    String name() default "";
-
-    /**
-     * The name of the resource that the reference points to. It can
-     * link to any compatible resource using the global JNDI names.
-     *
-     * @since 1.7, Common Annotations 1.1
-     */
-
-    String lookup() default "";
-
-    /**
-     * The Java type of the resource.  For field annotations,
-     * the default is the type of the field.  For method annotations,
-     * the default is the type of the JavaBeans property.
-     * For class annotations, there is no default and this must be
-     * specified.
-     */
-    Class<?> type() default java.lang.Object.class;
-
-    /**
-     * The two possible authentication types for a resource.
-     */
-    enum AuthenticationType {
-            CONTAINER,
-            APPLICATION
-    }
-
-    /**
-     * The authentication type to use for this resource.
-     * This may be specified for resources representing a
-     * connection factory of any supported type, and must
-     * not be specified for resources of other types.
-     */
-    AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
-
-    /**
-     * Indicates whether this resource can be shared between
-     * this component and other components.
-     * This may be specified for resources representing a
-     * connection factory of any supported type, and must
-     * not be specified for resources of other types.
-     */
-    boolean shareable() default true;
-
-    /**
-     * A product specific name that this resource should be mapped to.
-     * The name of this resource, as defined by the <code>name</code>
-     * element or defaulted, is a name that is local to the application
-     * component using the resource.  (It's a name in the JNDI
-     * <code>java:comp/env</code> namespace.)  Many application servers
-     * provide a way to map these local names to names of resources
-     * known to the application server.  This mapped name is often a
-     * <i>global</i> JNDI name, but may be a name of any form. <p>
-     *
-     * Application servers are not required to support any particular
-     * form or type of mapped name, nor the ability to use mapped names.
-     * The mapped name is product-dependent and often installation-dependent.
-     * No use of a mapped name is portable.
-     */
-    String mappedName() default "";
-
-    /**
-     * Description of this resource.  The description is expected
-     * to be in the default language of the system on which the
-     * application is deployed.  The description can be presented
-     * to the Deployer to help in choosing the correct resource.
-     */
-    String description() default "";
-}
--- a/jaxws/src/java.annotations.common/share/classes/javax/annotation/Resources.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.annotation;
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-/**
- * This class is used to allow multiple resources declarations.
- *
- * @see javax.annotation.Resource
- * @since 1.6, Common Annotations 1.0
- */
-
-@Documented
-@Retention(RUNTIME)
-@Target(TYPE)
-public @interface Resources {
-   /**
-    * Array used for multiple resource declarations.
-    */
-   Resource[] value();
-}
--- a/jaxws/src/java.annotations.common/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * Defines a subset of the Common Annotations API to support programs running
- * on the Java SE Platform.
- */
-module java.annotations.common {
-    exports javax.annotation;
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/java.xml.ws.annotation/share/classes/javax/annotation/Generated.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.annotation;
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ * The Generated annotation is used to mark source code that has been generated.
+ * It can also be used to differentiate user written code from generated code
+ * in a single file. When used, the value element must have the name of the
+ * code generator. The recommended convention is to use the fully qualified
+ * name of the code generator in the value field .
+ * <p>For example: com.company.package.classname.
+ * The date element is used to indicate the date the source was generated.
+ * The date element must follow the ISO 8601 standard. For example the date
+ * element would have the following value 2001-07-04T12:08:56.235-0700
+ * which represents 2001-07-04 12:08:56 local time in the U.S. Pacific
+ * Time time zone.</p>
+ * <p>The comment element is a place holder for any comments that the code
+ * generator may want to include in the generated code.</p>
+ *
+ * @since 1.6, Common Annotations 1.0
+ */
+
+@Documented
+@Retention(SOURCE)
+@Target({PACKAGE, TYPE, ANNOTATION_TYPE, METHOD, CONSTRUCTOR, FIELD,
+        LOCAL_VARIABLE, PARAMETER})
+public @interface Generated {
+   /**
+    * The value element MUST have the name of the code generator.
+    * The recommended convention is to use the fully qualified name of the
+    * code generator. For example: com.acme.generator.CodeGen.
+    */
+   String[] value();
+
+   /**
+    * Date when the source was generated.
+    */
+   String date() default "";
+
+   /**
+    * A place holder for any comments that the code generator may want to
+    * include in the generated code.
+    */
+   String comments() default "";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/java.xml.ws.annotation/share/classes/javax/annotation/PostConstruct.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.annotation;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ * The PostConstruct annotation is used on a method that needs to be executed
+ * after dependency injection is done to perform any initialization. This
+ * method MUST be invoked before the class is put into service. This
+ * annotation MUST be supported on all classes that support dependency
+ * injection. The method annotated with PostConstruct MUST be invoked even
+ * if the class does not request any resources to be injected. Only one
+ * method can be annotated with this annotation. The method on which the
+ * PostConstruct annotation is applied MUST fulfill all of the following
+ * criteria:
+ * <ul>
+ * <li>The method MUST NOT have any parameters except in the case of
+ * interceptors in which case it takes an InvocationContext object as
+ * defined by the Interceptors specification.</li>
+ * <li>The method defined on an interceptor class MUST HAVE one of the
+ * following signatures:
+ * <p>
+ * void &#060;METHOD&#062;(InvocationContext)
+ * <p>
+ * Object &#060;METHOD&#062;(InvocationContext) throws Exception
+ * <p>
+ * <i>Note: A PostConstruct interceptor method must not throw application
+ * exceptions, but it may be declared to throw checked exceptions including
+ * the java.lang.Exception if the same interceptor method interposes on
+ * business or timeout methods in addition to lifecycle events. If a
+ * PostConstruct interceptor method returns a value, it is ignored by
+ * the container.</i>
+ * </li>
+ * <li>The method defined on a non-interceptor class MUST HAVE the
+ * following signature:
+ * <p>
+ * void &#060;METHOD&#062;()
+ * </li>
+ * <li>The method on which PostConstruct is applied MAY be public, protected,
+ * package private or private.</li>
+ * <li>The method MUST NOT be static except for the application client.</li>
+ * <li>The method MAY be final.</li>
+ * <li>If the method throws an unchecked exception the class MUST NOT be put into
+ * service except in the case of EJBs where the EJB can handle exceptions and
+ * even recover from them.</li></ul>
+ *
+ * @see javax.annotation.PreDestroy
+ * @see javax.annotation.Resource
+ * @since 1.6, Common Annotations 1.0
+ */
+@Documented
+@Retention (RUNTIME)
+@Target(METHOD)
+public @interface PostConstruct {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/java.xml.ws.annotation/share/classes/javax/annotation/PreDestroy.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.annotation;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ * The PreDestroy annotation is used on methods as a callback notification to
+ * signal that the instance is in the process of being removed by the
+ * container. The method annotated with PreDestroy is typically used to
+ * release resources that it has been holding. This annotation MUST be
+ * supported by all container managed objects that support PostConstruct
+ * except the application client container in Java EE 5. The method on which
+ * the PreDestroy annotation is applied MUST fulfill all of the following
+ * criteria:
+ * <ul>
+ * <li>The method MUST NOT have any parameters except in the case of
+ * interceptors in which case it takes an InvocationContext object as
+ * defined by the Interceptors specification.</li>
+ * <li>The method defined on an interceptor class MUST HAVE one of the
+ * following signatures:
+ * <p>
+ * void &#060;METHOD&#062;(InvocationContext)
+ * <p>
+ * Object &#060;METHOD&#062;(InvocationContext) throws Exception
+ * <p>
+ * <i>Note: A PreDestroy interceptor method must not throw application
+ * exceptions, but it may be declared to throw checked exceptions including
+ * the java.lang.Exception if the same interceptor method interposes on
+ * business or timeout methods in addition to lifecycle events. If a
+ * PreDestroy interceptor method returns a value, it is ignored by
+ * the container.</i>
+ * </li>
+ * <li>The method defined on a non-interceptor class MUST HAVE the
+ * following signature:
+ * <p>
+ * void &#060;METHOD&#062;()
+ * </li>
+ * <li>The method on which PreDestroy is applied MAY be public, protected,
+ * package private or private.</li>
+ * <li>The method MUST NOT be static.</li>
+ * <li>The method MAY be final.</li>
+ * <li>If the method throws an unchecked exception it is ignored except in the
+ * case of EJBs where the EJB can handle exceptions.</li>
+ * </ul>
+ *
+ * @see javax.annotation.PostConstruct
+ * @see javax.annotation.Resource
+ * @since 1.6, Common Annotations 1.0
+ */
+
+@Documented
+@Retention (RUNTIME)
+@Target(METHOD)
+public @interface PreDestroy {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/java.xml.ws.annotation/share/classes/javax/annotation/Resource.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.annotation;
+
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ * The Resource annotation marks a resource that is needed
+ * by the application.  This annotation may be applied to an
+ * application component class, or to fields or methods of the
+ * component class.  When the annotation is applied to a
+ * field or method, the container will inject an instance
+ * of the requested resource into the application component
+ * when the component is initialized.  If the annotation is
+ * applied to the component class, the annotation declares a
+ * resource that the application will look up at runtime. <p>
+ *
+ * Even though this annotation is not marked Inherited, deployment
+ * tools are required to examine all superclasses of any component
+ * class to discover all uses of this annotation in all superclasses.
+ * All such annotation instances specify resources that are needed
+ * by the application component.  Note that this annotation may
+ * appear on private fields and methods of superclasses; the container
+ * is required to perform injection in these cases as well.
+ *
+ * @since 1.6, Common Annotations 1.0
+ */
+@Target({TYPE, FIELD, METHOD})
+@Retention(RUNTIME)
+public @interface Resource {
+    /**
+     * The JNDI name of the resource.  For field annotations,
+     * the default is the field name.  For method annotations,
+     * the default is the JavaBeans property name corresponding
+     * to the method.  For class annotations, there is no default
+     * and this must be specified.
+     */
+    String name() default "";
+
+    /**
+     * The name of the resource that the reference points to. It can
+     * link to any compatible resource using the global JNDI names.
+     *
+     * @since 1.7, Common Annotations 1.1
+     */
+
+    String lookup() default "";
+
+    /**
+     * The Java type of the resource.  For field annotations,
+     * the default is the type of the field.  For method annotations,
+     * the default is the type of the JavaBeans property.
+     * For class annotations, there is no default and this must be
+     * specified.
+     */
+    Class<?> type() default java.lang.Object.class;
+
+    /**
+     * The two possible authentication types for a resource.
+     */
+    enum AuthenticationType {
+            CONTAINER,
+            APPLICATION
+    }
+
+    /**
+     * The authentication type to use for this resource.
+     * This may be specified for resources representing a
+     * connection factory of any supported type, and must
+     * not be specified for resources of other types.
+     */
+    AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
+
+    /**
+     * Indicates whether this resource can be shared between
+     * this component and other components.
+     * This may be specified for resources representing a
+     * connection factory of any supported type, and must
+     * not be specified for resources of other types.
+     */
+    boolean shareable() default true;
+
+    /**
+     * A product specific name that this resource should be mapped to.
+     * The name of this resource, as defined by the <code>name</code>
+     * element or defaulted, is a name that is local to the application
+     * component using the resource.  (It's a name in the JNDI
+     * <code>java:comp/env</code> namespace.)  Many application servers
+     * provide a way to map these local names to names of resources
+     * known to the application server.  This mapped name is often a
+     * <i>global</i> JNDI name, but may be a name of any form. <p>
+     *
+     * Application servers are not required to support any particular
+     * form or type of mapped name, nor the ability to use mapped names.
+     * The mapped name is product-dependent and often installation-dependent.
+     * No use of a mapped name is portable.
+     */
+    String mappedName() default "";
+
+    /**
+     * Description of this resource.  The description is expected
+     * to be in the default language of the system on which the
+     * application is deployed.  The description can be presented
+     * to the Deployer to help in choosing the correct resource.
+     */
+    String description() default "";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/java.xml.ws.annotation/share/classes/javax/annotation/Resources.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.annotation;
+import java.lang.annotation.*;
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+/**
+ * This class is used to allow multiple resources declarations.
+ *
+ * @see javax.annotation.Resource
+ * @since 1.6, Common Annotations 1.0
+ */
+
+@Documented
+@Retention(RUNTIME)
+@Target(TYPE)
+public @interface Resources {
+   /**
+    * Array used for multiple resource declarations.
+    */
+   Resource[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxws/src/java.xml.ws.annotation/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Defines a subset of the Common Annotations API to support programs running
+ * on the Java SE Platform.
+ */
+module java.xml.ws.annotation {
+    exports javax.annotation;
+}
+
--- a/jaxws/src/java.xml.ws/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jaxws/src/java.xml.ws/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -31,7 +31,7 @@
     requires transitive java.activation;
     requires transitive java.xml;
     requires transitive java.xml.bind;
-    requires java.annotations.common;
+    requires java.xml.ws.annotation;
     requires java.desktop;
     requires java.logging;
     requires java.management;
--- a/jdk/.hgtags	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/.hgtags	Fri Feb 10 08:57:42 2017 -0800
@@ -398,3 +398,4 @@
 1c4411322327aea3f91011ec3977a12a05b09629 jdk-9+153
 c97e7a8b8da062b9070df442f9cf308e10845fb7 jdk-9+154
 e170c858888e83d5c0994504599b6ed7a1fb0cfc jdk-9+155
+7d64e541a6c04c714bcad4c8b553db912f827cd5 jdk-9+156
--- a/jdk/make/src/classes/build/tools/jigsaw/GenGraphs.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/make/src/classes/build/tools/jigsaw/GenGraphs.java	Fri Feb 10 08:57:42 2017 -0800
@@ -153,9 +153,9 @@
      */
     void genDotFile(String name, Set<String> roots) throws IOException {
         Configuration cf =
-            Configuration.empty().resolveRequires(ModuleFinder.ofSystem(),
-                                                  ModuleFinder.of(),
-                                                  roots);
+            Configuration.empty().resolve(ModuleFinder.ofSystem(),
+                                          ModuleFinder.of(),
+                                          roots);
 
         Set<ModuleDescriptor> mds = cf.modules().stream()
                 .map(ResolvedModule::reference)
--- a/jdk/make/src/classes/build/tools/jigsaw/ModuleSummary.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/make/src/classes/build/tools/jigsaw/ModuleSummary.java	Fri Feb 10 08:57:42 2017 -0800
@@ -291,9 +291,9 @@
 
     static Configuration resolve(Set<String> roots) {
         return Configuration.empty()
-            .resolveRequires(ModuleFinder.ofSystem(),
-                             ModuleFinder.of(),
-                             roots);
+            .resolve(ModuleFinder.ofSystem(),
+                     ModuleFinder.of(),
+                     roots);
     }
 
     static class HtmlDocument {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/aix/classes/sun/nio/fs/DefaultFileSystemProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.spi.FileSystemProvider;
+
+/**
+ * Creates this platform's default FileSystemProvider.
+ */
+
+public class DefaultFileSystemProvider {
+    private DefaultFileSystemProvider() { }
+
+    /**
+     * Returns the default FileSystemProvider.
+     */
+    public static FileSystemProvider create() {
+        return new AixFileSystemProvider();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/DefaultFileSystemProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.spi.FileSystemProvider;
+
+/**
+ * Creates this platform's default FileSystemProvider.
+ */
+
+public class DefaultFileSystemProvider {
+    private DefaultFileSystemProvider() { }
+
+    /**
+     * Returns the default FileSystemProvider.
+     */
+    public static FileSystemProvider create() {
+        return new LinuxFileSystemProvider();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/macosx/classes/sun/nio/fs/DefaultFileSystemProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.spi.FileSystemProvider;
+
+/**
+ * Creates this platform's default FileSystemProvider.
+ */
+
+public class DefaultFileSystemProvider {
+    private DefaultFileSystemProvider() { }
+
+    /**
+     * Returns the default FileSystemProvider.
+     */
+    public static FileSystemProvider create() {
+        return new MacOSXFileSystemProvider();
+    }
+}
--- a/jdk/src/java.base/share/classes/java/lang/Class.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java	Fri Feb 10 08:57:42 2017 -0800
@@ -425,6 +425,7 @@
      *         </ul>
      *
      * @since 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static Class<?> forName(Module module, String name) {
@@ -819,6 +820,7 @@
      * @return the module that this class or interface is a member of
      *
      * @since 9
+     * @spec JPMS
      */
     public Module getModule() {
         return module;
@@ -924,6 +926,8 @@
      * this method returns {@code null}.
      *
      * @return the package of this class.
+     * @revised 9
+     * @spec JPMS
      */
     public Package getPackage() {
         if (isPrimitive() || isArray()) {
@@ -951,20 +955,30 @@
      * declaring class} of the {@link #getEnclosingMethod enclosing method} or
      * {@link #getEnclosingConstructor enclosing constructor}.
      *
-     * <p> This method returns {@code null} if this class represents an array type,
-     * a primitive type or void.
+     * <p> If this class represents an array type then this method returns the
+     * package name of the element type. If this class represents a primitive
+     * type or void then the package name "{@code java.lang}" is returned.
      *
      * @return the fully qualified package name
      *
      * @since 9
+     * @spec JPMS
      * @jls 6.7  Fully Qualified Names
      */
     public String getPackageName() {
         String pn = this.packageName;
-        if (pn == null && !isArray() && !isPrimitive()) {
-            String cn = getName();
-            int dot = cn.lastIndexOf('.');
-            pn = (dot != -1) ? cn.substring(0, dot).intern() : "";
+        if (pn == null) {
+            Class<?> c = this;
+            while (c.isArray()) {
+                c = c.getComponentType();
+            }
+            if (c.isPrimitive()) {
+                pn = "java.lang";
+            } else {
+                String cn = c.getName();
+                int dot = cn.lastIndexOf('.');
+                pn = (dot != -1) ? cn.substring(0, dot).intern() : "";
+            }
             this.packageName = pn;
         }
         return pn;
@@ -2491,10 +2505,16 @@
      * Finds a resource with a given name.
      *
      * <p> If this class is in a named {@link Module Module} then this method
-     * will attempt to find the resource in the module by means of the absolute
-     * resource name, subject to the rules for encapsulation specified in the
-     * {@code Module} {@link Module#getResourceAsStream getResourceAsStream}
-     * method.
+     * will attempt to find the resource in the module. This is done by
+     * delegating to the module's class loader {@link
+     * ClassLoader#findResource(String,String) findResource(String,String)}
+     * method, invoking it with the module name and the absolute name of the
+     * resource. Resources in named modules are subject to the rules for
+     * encapsulation specified in the {@code Module} {@link
+     * Module#getResourceAsStream getResourceAsStream} method and so this
+     * method returns {@code null} when the resource is a
+     * non-"{@code .class}" resource in a package that is not open to the
+     * caller's module.
      *
      * <p> Otherwise, if this class is not in a named module then the rules for
      * searching resources associated with a given class are implemented by the
@@ -2503,9 +2523,8 @@
      * the bootstrap class loader, the method delegates to {@link
      * ClassLoader#getSystemResourceAsStream}.
      *
-     * <p> Before finding a resource in the caller's module or delegation to a
-     * class loader, an absolute resource name is constructed from the given
-     * resource name using this algorithm:
+     * <p> Before delegation, an absolute resource name is constructed from the
+     * given resource name using this algorithm:
      *
      * <ul>
      *
@@ -2532,7 +2551,11 @@
      *          least the caller module, or access to the resource is denied
      *          by the security manager.
      * @throws  NullPointerException If {@code name} is {@code null}
+     *
+     * @see Module#getResourceAsStream(String)
      * @since  1.1
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public InputStream getResourceAsStream(String name) {
@@ -2585,10 +2608,16 @@
      * Finds a resource with a given name.
      *
      * <p> If this class is in a named {@link Module Module} then this method
-     * will attempt to find the resource in the module by means of the absolute
-     * resource name, subject to the rules for encapsulation specified in the
-     * {@code Module} {@link Module#getResourceAsStream getResourceAsStream}
-     * method.
+     * will attempt to find the resource in the module. This is done by
+     * delegating to the module's class loader {@link
+     * ClassLoader#findResource(String,String) findResource(String,String)}
+     * method, invoking it with the module name and the absolute name of the
+     * resource. Resources in named modules are subject to the rules for
+     * encapsulation specified in the {@code Module} {@link
+     * Module#getResourceAsStream getResourceAsStream} method and so this
+     * method returns {@code null} when the resource is a
+     * non-"{@code .class}" resource in a package that is not open to the
+     * caller's module.
      *
      * <p> Otherwise, if this class is not in a named module then the rules for
      * searching resources associated with a given class are implemented by the
@@ -2627,6 +2656,8 @@
      *         manager.
      * @throws NullPointerException If {@code name} is {@code null}
      * @since  1.1
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public URL getResource(String name) {
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Fri Feb 10 08:57:42 2017 -0800
@@ -207,6 +207,8 @@
  * @jls 13.1 The Form of a Binary
  * @see      #resolveClass(Class)
  * @since 1.0
+ * @revised 9
+ * @spec JPMS
  */
 public abstract class ClassLoader {
 
@@ -380,12 +382,12 @@
      *         method doesn't allow creation of a new class loader.
      *
      * @since  9
+     * @spec JPMS
      */
     protected ClassLoader(String name, ClassLoader parent) {
         this(checkCreateClassLoader(name), name, parent);
     }
 
-
     /**
      * Creates a new class loader using the specified parent class loader for
      * delegation.
@@ -440,6 +442,7 @@
      * this class loader is not named.
      *
      * @since 9
+     * @spec JPMS
      */
     public String getName() {
         return name;
@@ -710,6 +713,7 @@
      *         if the class could not be found.
      *
      * @since 9
+     * @spec JPMS
      */
     protected Class<?> findClass(String moduleName, String name) {
         if (moduleName == null) {
@@ -834,6 +838,8 @@
      * @see  java.security.SecureClassLoader
      *
      * @since  1.1
+     * @revised 9
+     * @spec JPMS
      */
     protected final Class<?> defineClass(String name, byte[] b, int off, int len)
         throws ClassFormatError
@@ -967,6 +973,9 @@
      *          certificates than this class, or if {@code name} begins with
      *          "{@code java.}" and this class loader is not the platform
      *          class loader or its ancestor.
+     *
+     * @revised 9
+     * @spec JPMS
      */
     protected final Class<?> defineClass(String name, byte[] b, int off, int len,
                                          ProtectionDomain protectionDomain)
@@ -1041,6 +1050,8 @@
      * @see      #defineClass(String, byte[], int, int, ProtectionDomain)
      *
      * @since  1.5
+     * @revised 9
+     * @spec JPMS
      */
     protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
                                          ProtectionDomain protectionDomain)
@@ -1264,11 +1275,11 @@
      * Class loader implementations that support the loading from modules
      * should override this method.
      *
-     * @apiNote This method is the basis for the {@code Class} {@link
-     * Class#getResource getResource} and {@link Class#getResourceAsStream
-     * getResourceAsStream} methods. It is not subject to the rules for
-     * encapsulation specified by {@code Module} {@link
-     * Module#getResourceAsStream getResourceAsStream}.
+     * @apiNote This method is the basis for the {@link
+     * Class#getResource Class.getResource}, {@link Class#getResourceAsStream
+     * Class.getResourceAsStream}, and {@link Module#getResourceAsStream
+     * Module.getResourceAsStream} methods. It is not subject to the rules for
+     * encapsulation specified by {@code Module.getResourceAsStream}.
      *
      * @implSpec The default implementation attempts to find the resource by
      * invoking {@link #findResource(String)} when the {@code moduleName} is
@@ -1292,6 +1303,7 @@
      *
      * @see java.lang.module.ModuleReader#find(String)
      * @since 9
+     * @spec JPMS
      */
     protected URL findResource(String moduleName, String name) throws IOException {
         if (moduleName == null) {
@@ -1342,6 +1354,8 @@
      * @throws  NullPointerException If {@code name} is {@code null}
      *
      * @since  1.1
+     * @revised 9
+     * @spec JPMS
      */
     public URL getResource(String name) {
         Objects.requireNonNull(name);
@@ -1403,6 +1417,8 @@
      * @see  #findResources(String)
      *
      * @since  1.2
+     * @revised 9
+     * @spec JPMS
      */
     public Enumeration<URL> getResources(String name) throws IOException {
         Objects.requireNonNull(name);
@@ -1499,6 +1515,8 @@
      *          denied by the security manager.
      *
      * @since  1.2
+     * @revised 9
+     * @spec JPMS
      */
     protected URL findResource(String name) {
         return null;
@@ -1531,6 +1549,8 @@
      *          If I/O errors occur
      *
      * @since  1.2
+     * @revised 9
+     * @spec JPMS
      */
     protected Enumeration<URL> findResources(String name) throws IOException {
         return Collections.emptyEnumeration();
@@ -1601,6 +1621,8 @@
      *          denied by the security manager.
      *
      * @since  1.1
+     * @revised 9
+     * @spec JPMS
      */
     public static URL getSystemResource(String name) {
         return getSystemClassLoader().getResource(name);
@@ -1636,6 +1658,8 @@
      *          If I/O errors occur
      *
      * @since  1.2
+     * @revised 9
+     * @spec JPMS
      */
     public static Enumeration<URL> getSystemResources(String name)
         throws IOException
@@ -1667,6 +1691,8 @@
      * @throws  NullPointerException If {@code name} is {@code null}
      *
      * @since  1.1
+     * @revised 9
+     * @spec JPMS
      */
     public InputStream getResourceAsStream(String name) {
         Objects.requireNonNull(name);
@@ -1699,6 +1725,8 @@
      *          denied by the security manager.
      *
      * @since  1.1
+     * @revised 9
+     * @spec JPMS
      */
     public static InputStream getSystemResourceAsStream(String name) {
         URL url = getSystemResource(name);
@@ -1749,6 +1777,7 @@
      *
      * @see Module#isNamed()
      * @since 9
+     * @spec JPMS
      */
     public final Module getUnnamedModule() {
         return unnamedModule;
@@ -1772,6 +1801,7 @@
      *          {@link RuntimePermission}{@code ("getClassLoader")}
      *
      * @since 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static ClassLoader getPlatformClassLoader() {
@@ -1847,6 +1877,8 @@
      *          {@link Throwable#getCause()} method.
      *
      * @revised  1.4
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static ClassLoader getSystemClassLoader() {
@@ -2101,6 +2133,8 @@
      *          defined by this class loader
      *
      * @since  1.2
+     * @revised 9
+     * @spec JPMS
      *
      * @see <a href="../../../technotes/guides/jar/jar.html#versioning">
      *      The JAR File Specification: Package Versioning</a>
@@ -2138,6 +2172,7 @@
      *          if {@code name} is {@code null}.
      *
      * @since  9
+     * @spec JPMS
      */
     public final Package getDefinedPackage(String name) {
         Objects.requireNonNull(name, "name cannot be null");
@@ -2160,6 +2195,7 @@
      *         or an zero length array if no package has been defined by this class loader.
      *
      * @since  9
+     * @spec JPMS
      */
     public final Package[] getDefinedPackages() {
         return packages().toArray(Package[]::new);
@@ -2196,6 +2232,8 @@
      * a {@code Package} for the specified class loader.
      *
      * @since  1.2
+     * @revised 9
+     * @spec JPMS
      */
     @Deprecated(since="9")
     protected Package getPackage(String name) {
@@ -2220,6 +2258,8 @@
      *          class loader and its ancestors
      *
      * @since  1.2
+     * @revised 9
+     * @spec JPMS
      */
     protected Package[] getPackages() {
         Stream<Package> pkgs = packages();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/IllegalCallerException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+/**
+ * Thrown to indicate that a method has been called by an inappropriate caller.
+ *
+ * @since 9
+ * @spec JPMS
+ * @see StackWalker#getCallerClass
+ */
+public class IllegalCallerException extends RuntimeException {
+    /**
+     * Constructs an IllegalCallerException with no detail message.
+     */
+    public IllegalCallerException() {
+        super();
+    }
+
+    /**
+     * Constructs an IllegalCallerException with the specified detail
+     * message.
+     *
+     * @param s the String that contains a detailed message (can be null)
+     */
+    public IllegalCallerException(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and
+     * cause.
+     *
+     * @param  message the detail message (can be null)
+     * @param  cause the cause (can be null)
+     */
+    public IllegalCallerException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail
+     * message of {@code (cause==null ? null : cause.toString())} (which
+     * typically contains the class and detail message of {@code cause}).
+     *
+     * @param  cause the cause (can be null)
+     */
+    public IllegalCallerException(Throwable cause) {
+        super(cause);
+    }
+
+    static final long serialVersionUID = -2349421918363102232L;
+}
--- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -55,14 +55,36 @@
      *
      * <p>A single local variable can hold a value of type boolean, byte, char,
      * short, int, float, reference or returnAddress.  A pair of local variables
-     * can hold a value of type long or double.  In other words,
-     * a value of type long or type double occupies two consecutive local
-     * variables.  For a value of primitive type, the element in the
-     * local variable array is an {@link PrimitiveValue} object;
-     * otherwise, the element is an {@code Object}.
+     * can hold a value of type long or double (JVMS section 2.6.1).  Primitive
+     * locals are represented in the returned array as {@code PrimitiveSlot}s,
+     * with longs and doubles occupying a pair of consecutive
+     * {@code PrimitiveSlot}s.
+     *
+     * <p>The current VM implementation does not provide specific type
+     * information for primitive locals.  This method simply returns the raw
+     * contents of the VM's primitive locals on a best-effort basis, without
+     * indicating a specific type.
+     *
+     * <p>The returned array may contain null entries for local variables that
+     * are not live.
      *
-     * <p>The returned array may contain null entries if a local variable is not
-     * live.
+     * @implNote
+     * <p> The specific subclass of {@code PrimitiveSlot} will reflect the
+     * underlying architecture, and will be either {@code PrimitiveSlot32} or
+     * {@code PrimitiveSlot64}.
+     *
+     * <p>How a long or double value is stored in the pair of
+     * {@code PrimitiveSlot}s can vary based on the underlying architecture and
+     * VM implementation.  On 32-bit architectures, long/double values are split
+     * between the two {@code PrimitiveSlot32}s.
+     * On 64-bit architectures, the entire value may be stored in one of the
+     * {@code PrimitiveSlot64}s, with the other {@code PrimitiveSlot64} being
+     * unused.
+     *
+     * <p>The contents of the unused, high-order portion of a
+     * {@code PrimitiveSlot64} (when storing a primitive other than a long or
+     * double) is unspecified.  In particular, the unused bits are not
+     * necessarily zeroed out.
      *
      * @return  the local variable array of this stack frame.
      */
@@ -78,7 +100,7 @@
      * <p>Each entry on the operand stack can hold a value of any Java Virtual
      * Machine Type.
      * For a value of primitive type, the element in the returned array is
-     * an {@link PrimitiveValue} object; otherwise, the element is the {@code Object}
+     * a {@link PrimitiveSlot} object; otherwise, the element is the {@code Object}
      * on the operand stack.
      *
      * @return the operand stack of this stack frame.
@@ -87,107 +109,37 @@
 
     /**
      * <em>UNSUPPORTED</em> This interface is intended to be package-private
-     * or move to an internal package.<p>
+     * or moved to an internal package.<p>
      *
-     * Represents a local variable or an entry on the operand whose value is
+     * Represents a local variable or an entry on the operand stack whose value is
      * of primitive type.
      */
-    public abstract class PrimitiveValue {
+    public abstract class PrimitiveSlot {
         /**
-         * Returns the base type of this primitive value, one of
-         * {@code B, D, C, F, I, J, S, Z}.
-         *
-         * @return Name of a base type
-         * @jvms table 4.3-A
+         * Returns the size, in bytes, of the slot.
          */
-        abstract char type();
+        public abstract int size();
 
         /**
-         * Returns the boolean value if this primitive value is of type boolean.
-         * @return the boolean value if this primitive value is of type boolean.
+         * Returns the int value if this primitive value is of size 4
+         * @return the int value if this primitive value is of size 4
          *
          * @throws UnsupportedOperationException if this primitive value is not
-         * of type boolean.
-         */
-        public boolean booleanValue() {
-            throw new UnsupportedOperationException("this primitive of type " + type());
-        }
-
-        /**
-         * Returns the int value if this primitive value is of type int.
-         * @return the int value if this primitive value is of type int.
-         *
-         * @throws UnsupportedOperationException if this primitive value is not
-         * of type int.
+         * of size 4.
          */
         public int intValue() {
-            throw new UnsupportedOperationException("this primitive of type " + type());
-        }
-
-        /**
-         * Returns the long value if this primitive value is of type long.
-         * @return the long value if this primitive value is of type long.
-         *
-         * @throws UnsupportedOperationException if this primitive value is not
-         * of type long.
-         */
-        public long longValue() {
-            throw new UnsupportedOperationException("this primitive of type " + type());
+            throw new UnsupportedOperationException("this " + size() + "-byte primitive");
         }
 
         /**
-         * Returns the char value if this primitive value is of type char.
-         * @return the char value if this primitive value is of type char.
-         *
-         * @throws UnsupportedOperationException if this primitive value is not
-         * of type char.
-         */
-        public char charValue() {
-            throw new UnsupportedOperationException("this primitive of type " + type());
-        }
-
-        /**
-         * Returns the byte value if this primitive value is of type byte.
-         * @return the byte value if this primitive value is of type byte.
-         *
-         * @throws UnsupportedOperationException if this primitive value is not
-         * of type byte.
-         */
-        public byte byteValue() {
-            throw new UnsupportedOperationException("this primitive of type " + type());
-        }
-
-        /**
-         * Returns the short value if this primitive value is of type short.
-         * @return the short value if this primitive value is of type short.
+         * Returns the long value if this primitive value is of size 8
+         * @return the long value if this primitive value is of size 8
          *
          * @throws UnsupportedOperationException if this primitive value is not
-         * of type short.
-         */
-        public short shortValue() {
-            throw new UnsupportedOperationException("this primitive of type " + type());
-        }
-
-        /**
-         * Returns the float value if this primitive value is of type float.
-         * @return the float value if this primitive value is of type float.
-         *
-         * @throws UnsupportedOperationException if this primitive value is not
-         * of type float.
+         * of size 8.
          */
-        public float floatValue() {
-            throw new UnsupportedOperationException("this primitive of type " + type());
-        }
-
-        /**
-         * Returns the double value if this primitive value is of type double.
-         * @return the double value if this primitive value is of type double.
-         *
-         * @throws UnsupportedOperationException if this primitive value is not
-         * of type double.
-         */
-        public double doubleValue() {
-            throw new UnsupportedOperationException("this primitive of type " + type());
+        public long longValue() {
+            throw new UnsupportedOperationException("this " + size() + "-byte primitive");
         }
     }
 
--- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -24,15 +24,13 @@
  */
 package java.lang;
 
-import java.lang.StackWalker.Option;
-import java.util.EnumSet;
-import java.util.Set;
-
-import static java.lang.StackWalker.ExtendedOption.*;
-
 final class LiveStackFrameInfo extends StackFrameInfo implements LiveStackFrame {
     private static Object[] EMPTY_ARRAY = new Object[0];
 
+    // These flags must match the values maintained in the VM
+    private static final int MODE_INTERPRETED = 0x01;
+    private static final int MODE_COMPILED    = 0x02;
+
     LiveStackFrameInfo(StackWalker walker) {
         super(walker);
     }
@@ -41,6 +39,7 @@
     private Object[] monitors = EMPTY_ARRAY;
     private Object[] locals = EMPTY_ARRAY;
     private Object[] operands = EMPTY_ARRAY;
+    private int mode = 0;
 
     @Override
     public Object[] getMonitors() {
@@ -57,51 +56,44 @@
         return operands;
     }
 
-    /*
-     * Convert primitive value to {@code Primitive} object to represent
-     * a local variable or an element on the operand stack of primitive type.
-     */
-    static PrimitiveValue asPrimitive(boolean value) {
-        return new BooleanPrimitive(value);
-    }
-
-    static PrimitiveValue asPrimitive(int value) {
-        return new IntPrimitive(value);
-    }
-
-    static PrimitiveValue asPrimitive(short value) {
-        return new ShortPrimitive(value);
-    }
-
-    static PrimitiveValue asPrimitive(char value) {
-        return new CharPrimitive(value);
+    @Override
+    public String toString() {
+        StringBuilder retVal = new StringBuilder(super.toString());
+        if (mode != 0) {
+            retVal.append("(");
+            if ((mode & MODE_INTERPRETED) == MODE_INTERPRETED) {
+                retVal.append(" interpreted ");
+            }
+            if ((mode & MODE_COMPILED) == MODE_COMPILED) {
+                retVal.append(" compiled ");
+            }
+            retVal.append(")");
+        }
+        return retVal.toString();
     }
 
-    static PrimitiveValue asPrimitive(byte value) {
-        return new BytePrimitive(value);
-    }
+    /*
+     * Convert primitive value to {@code PrimitiveSlot} object to represent
+     * a local variable or an element on the operand stack of primitive type.
+     */
 
-    static PrimitiveValue asPrimitive(long value) {
-        return new LongPrimitive(value);
+    static PrimitiveSlot asPrimitive(int value) {
+        return new PrimitiveSlot32(value);
     }
 
-    static PrimitiveValue asPrimitive(float value) {
-        return new FloatPrimitive(value);
+    static PrimitiveSlot asPrimitive(long value) {
+        return new PrimitiveSlot64(value);
     }
 
-    static PrimitiveValue asPrimitive(double value) {
-        return new DoublePrimitive(value);
-    }
-
-    private static class IntPrimitive extends PrimitiveValue {
+    private static class PrimitiveSlot32 extends PrimitiveSlot {
         final int value;
-        IntPrimitive(int value) {
+        PrimitiveSlot32(int value) {
             this.value = value;
         }
 
         @Override
-        public char type() {
-            return 'I';
+        public int size() {
+            return 4;
         }
 
         @Override
@@ -115,103 +107,15 @@
         }
     }
 
-    private static class ShortPrimitive extends PrimitiveValue {
-        final short value;
-        ShortPrimitive(short value) {
-            this.value = value;
-        }
-
-        @Override
-        public char type() {
-            return 'S';
-        }
-
-        @Override
-        public short shortValue() {
-            return value;
-        }
-
-        @Override
-        public String toString() {
-            return String.valueOf(value);
-        }
-    }
-
-    private static class BooleanPrimitive extends PrimitiveValue {
-        final boolean value;
-        BooleanPrimitive(boolean value) {
+    private static class PrimitiveSlot64 extends PrimitiveSlot {
+        final long value;
+        PrimitiveSlot64(long value) {
             this.value = value;
         }
 
         @Override
-        public char type() {
-            return 'Z';
-        }
-
-        @Override
-        public boolean booleanValue()  {
-            return value;
-        }
-
-        @Override
-        public String toString() {
-            return String.valueOf(value);
-        }
-    }
-
-    private static class CharPrimitive extends PrimitiveValue {
-        final char value;
-        CharPrimitive(char value) {
-            this.value = value;
-        }
-
-        @Override
-        public char type() {
-            return 'C';
-        }
-
-        @Override
-        public char charValue() {
-            return value;
-        }
-
-        @Override
-        public String toString() {
-            return String.valueOf(value);
-        }
-    }
-
-    private static class BytePrimitive extends PrimitiveValue {
-        final byte value;
-        BytePrimitive(byte value) {
-            this.value = value;
-        }
-
-        @Override
-        public char type() {
-            return 'B';
-        }
-
-        @Override
-        public byte byteValue() {
-            return value;
-        }
-
-        @Override
-        public String toString() {
-            return String.valueOf(value);
-        }
-    }
-
-    private static class LongPrimitive extends PrimitiveValue {
-        final long value;
-        LongPrimitive(long value) {
-            this.value = value;
-        }
-
-        @Override
-        public char type() {
-            return 'J';
+        public int size() {
+            return 8;
         }
 
         @Override
@@ -224,48 +128,4 @@
             return String.valueOf(value);
         }
     }
-
-    private static class FloatPrimitive extends PrimitiveValue {
-        final float value;
-        FloatPrimitive(float value) {
-            this.value = value;
-        }
-
-        @Override
-        public char type() {
-            return 'F';
-        }
-
-        @Override
-        public float floatValue() {
-            return value;
-        }
-
-        @Override
-        public String toString() {
-            return String.valueOf(value);
-        }
-    }
-
-    private static class DoublePrimitive extends PrimitiveValue {
-        final double value;
-        DoublePrimitive(double value) {
-            this.value = value;
-        }
-
-        @Override
-        public char type() {
-            return 'D';
-        }
-
-        @Override
-        public double doubleValue() {
-            return value;
-        }
-
-        @Override
-        public String toString() {
-            return String.valueOf(value);
-        }
-    }
 }
--- a/jdk/src/java.base/share/classes/java/lang/Package.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/Package.java	Fri Feb 10 08:57:42 2017 -0800
@@ -111,6 +111,8 @@
  * @see ClassLoader#definePackage(String, String, String, String, String, String, String, URL)
  *
  * @since 1.2
+ * @revised 9
+ * @spec JPMS
  */
 public class Package extends NamedPackage implements java.lang.reflect.AnnotatedElement {
     /**
@@ -207,6 +209,9 @@
      * is returned if it is not known.
      * @return the vendor that implemented this package, {@code null}
      * is returned if it is not known.
+     *
+     * @revised 9
+     * @spec JPMS
      */
     public String getImplementationVendor() {
         return versionInfo.implVendor;
@@ -334,6 +339,9 @@
      * a {@code Package} for the specified class loader.
      *
      * @see ClassLoader#getDefinedPackage
+     *
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     @Deprecated(since="9")
@@ -356,6 +364,9 @@
      *          class loader and its ancestors
      *
      * @see ClassLoader#getDefinedPackages
+     *
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static Package[] getPackages() {
--- a/jdk/src/java.base/share/classes/java/lang/SecurityManager.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/SecurityManager.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1458,6 +1458,18 @@
     }
 
     /**
+     * Called by java.security.Security
+     */
+    static void invalidatePackageAccessCache() {
+        synchronized (packageAccessLock) {
+            packageAccessValid = false;
+        }
+        synchronized (packageDefinitionLock) {
+            packageDefinitionValid = false;
+        }
+    }
+
+    /**
      * Returns true if the module's loader is the boot or platform loader.
      */
     private static boolean isBootOrPlatformModule(Module m) {
--- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,11 +25,13 @@
 package java.lang;
 
 import jdk.internal.reflect.MethodAccessor;
+import jdk.internal.reflect.ConstructorAccessor;
 import java.lang.StackWalker.Option;
 import java.lang.StackWalker.StackFrame;
 
 import java.lang.annotation.Native;
 import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
 import java.util.HashSet;
 import java.util.NoSuchElementException;
 import java.util.Objects;
@@ -684,7 +686,7 @@
                 frames[n++] = caller;
             }
             if (frames[1] == null) {
-                throw new IllegalStateException("no caller frame");
+                throw new IllegalCallerException("no caller frame");
             }
             return n;
         }
@@ -922,7 +924,8 @@
          */
         final void setBatch(int depth, int startIndex, int endIndex) {
             if (startIndex <= 0 || endIndex <= 0)
-                throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
+                throw new IllegalArgumentException("startIndex=" + startIndex
+                        + " endIndex=" + endIndex);
 
             this.origin = startIndex;
             this.fence = endIndex;
@@ -980,13 +983,18 @@
 
     private static boolean isReflectionFrame(Class<?> c) {
         if (c.getName().startsWith("jdk.internal.reflect") &&
-                !MethodAccessor.class.isAssignableFrom(c)) {
-            throw new InternalError("Not jdk.internal.reflect.MethodAccessor: " + c.toString());
+                !MethodAccessor.class.isAssignableFrom(c) &&
+                !ConstructorAccessor.class.isAssignableFrom(c)) {
+            throw new InternalError("Not jdk.internal.reflect.MethodAccessor"
+                    + " or jdk.internal.reflect.ConstructorAccessor: "
+                    + c.toString());
         }
         // ## should filter all @Hidden frames?
         return c == Method.class ||
-                MethodAccessor.class.isAssignableFrom(c) ||
-                c.getName().startsWith("java.lang.invoke.LambdaForm");
+               c == Constructor.class ||
+               MethodAccessor.class.isAssignableFrom(c) ||
+               ConstructorAccessor.class.isAssignableFrom(c) ||
+               c.getName().startsWith("java.lang.invoke.LambdaForm");
     }
 
 }
--- a/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java	Fri Feb 10 08:57:42 2017 -0800
@@ -92,6 +92,8 @@
      * @throws NullPointerException if {@code declaringClass} or
      *         {@code methodName} is null
      * @since 1.5
+     * @revised 9
+     * @spec JPMS
      */
     public StackTraceElement(String declaringClass, String methodName,
                              String fileName, int lineNumber) {
@@ -128,6 +130,7 @@
      *         or {@code methodName} is {@code null}
      *
      * @since 9
+     * @spec JPMS
      */
     public StackTraceElement(String classLoaderName,
                              String moduleName, String moduleVersion,
@@ -187,6 +190,7 @@
      *         point represented by this stack trace element; {@code null}
      *         if the module name is not available.
      * @since 9
+     * @spec JPMS
      * @see java.lang.reflect.Module#getName()
      */
     public String getModuleName() {
@@ -201,6 +205,7 @@
      *         point represented by this stack trace element; {@code null}
      *         if the module version is not available.
      * @since 9
+     * @spec JPMS
      * @see java.lang.module.ModuleDescriptor.Version
      */
     public String getModuleVersion() {
@@ -216,6 +221,7 @@
      *         if the class loader is not named.
      *
      * @since 9
+     * @spec JPMS
      * @see java.lang.ClassLoader#getName()
      */
     public String getClassLoaderName() {
@@ -329,6 +335,8 @@
      * {@link java.lang.StackWalker.StackFrame}, where an implementation may
      * choose to omit some element in the returned string.
      *
+     * @revised 9
+     * @spec JPMS
      * @see    Throwable#printStackTrace()
      */
     public String toString() {
@@ -376,6 +384,9 @@
      * @return true if the specified object is another
      *         {@code StackTraceElement} instance representing the same
      *         execution point as this instance.
+     *
+     * @revised 9
+     * @spec JPMS
      */
     public boolean equals(Object obj) {
         if (obj==this)
--- a/jdk/src/java.base/share/classes/java/lang/StackWalker.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/StackWalker.java	Fri Feb 10 08:57:42 2017 -0800
@@ -29,6 +29,7 @@
 import java.util.*;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.stream.Stream;
 
 /**
@@ -207,13 +208,23 @@
         /**
          * Shows all reflection frames.
          *
-         * <p>By default, reflection frames are hidden.  This includes the
-         * {@link java.lang.reflect.Method#invoke} method
-         * and the reflection implementation classes. A {@code StackWalker} with
-         * this {@code SHOW_REFLECT_FRAMES} option will show all reflection frames.
-         * The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
+         * <p>By default, reflection frames are hidden.  A {@code StackWalker}
+         * configured with this {@code SHOW_REFLECT_FRAMES} option
+         * will show all reflection frames that
+         * include {@link java.lang.reflect.Method#invoke} and
+         * {@link java.lang.reflect.Constructor#newInstance(Object...)}
+         * and their reflection implementation classes.
+         *
+         * <p>The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
          * reflection frames and it will also show other hidden frames that
          * are implementation-specific.
+         *
+         * @apiNote
+         * This option includes the stack frames representing the invocation of
+         * {@code Method} and {@code Constructor}.  Any utility methods that
+         * are equivalent to calling {@code Method.invoke} or
+         * {@code Constructor.newInstance} such as {@code Class.newInstance}
+         * are not filtered or controlled by any stack walking option.
          */
         SHOW_REFLECT_FRAMES,
         /**
@@ -465,28 +476,31 @@
     }
 
     /**
-     * Gets the {@code Class} object of the caller invoking the method
-     * that calls this {@code getCallerClass} method.
+     * Gets the {@code Class} object of the caller who invoked the method
+     * that invoked {@code getCallerClass}.
      *
-     * <p> Reflection frames, {@link java.lang.invoke.MethodHandle}, and
-     * hidden frames are filtered regardless of the
+     * <p> This method filters {@linkplain Option#SHOW_REFLECT_FRAMES reflection
+     * frames}, {@link java.lang.invoke.MethodHandle}, and
+     * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} regardless of the
      * {@link Option#SHOW_REFLECT_FRAMES SHOW_REFLECT_FRAMES}
      * and {@link Option#SHOW_HIDDEN_FRAMES SHOW_HIDDEN_FRAMES} options
      * this {@code StackWalker} has been configured with.
      *
+     * <p> This method should be called when a caller frame is present.  If
+     * it is called from the bottom most frame on the stack,
+     * {@code IllegalCallerException} will be thrown.
+     *
      * <p> This method throws {@code UnsupportedOperationException}
      * if this {@code StackWalker} is not configured with the
      * {@link Option#RETAIN_CLASS_REFERENCE RETAIN_CLASS_REFERENCE} option.
-     * This method should be called when a caller frame is present.  If
-     * it is called from the last frame on the stack,
-     * {@code IllegalStateException} will be thrown.
      *
      * @apiNote
      * For example, {@code Util::getResourceBundle} loads a resource bundle
-     * on behalf of the caller.  It calls this {@code getCallerClass} method
-     * to find the method calling {@code Util::getResourceBundle} and uses the caller's
-     * class loader to load the resource bundle. The caller class in this example
-     * is the {@code MyTool} class.
+     * on behalf of the caller.  It invokes {@code getCallerClass} to identify
+     * the class whose method called {@code Util::getResourceBundle}.
+     * Then, it obtains the class loader of that class, and uses
+     * the class loader to load the resource bundle. The caller class
+     * in this example is {@code MyTool}.
      *
      * <pre>{@code
      * class Util {
@@ -517,17 +531,17 @@
      * }</pre>
      *
      * When the {@code getCallerClass} method is called from a method that
-     * is the last frame on the stack,
+     * is the bottom most frame on the stack,
      * for example, {@code static public void main} method launched by the
      * {@code java} launcher, or a method invoked from a JNI attached thread,
-     * {@code IllegalStateException} is thrown.
+     * {@code IllegalCallerException} is thrown.
      *
      * @return {@code Class} object of the caller's caller invoking this method.
      *
      * @throws UnsupportedOperationException if this {@code StackWalker}
      *         is not configured with {@link Option#RETAIN_CLASS_REFERENCE
      *         Option.RETAIN_CLASS_REFERENCE}.
-     * @throws IllegalStateException if there is no caller frame, i.e.
+     * @throws IllegalCallerException if there is no caller frame, i.e.
      *         when this {@code getCallerClass} method is called from a method
      *         which is the last frame on the stack.
      */
--- a/jdk/src/java.base/share/classes/java/lang/System.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/System.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1942,13 +1942,12 @@
      * the application classpath or modulepath.
      */
     private static void initPhase3() {
-        // Initialize publicLookup early, to avoid bootstrapping circularities
-        // with security manager using java.lang.invoke infrastructure.
-        java.lang.invoke.MethodHandles.publicLookup();
-
         // set security manager
         String cn = System.getProperty("java.security.manager");
         if (cn != null) {
+            // ensure image reader for java.base is initialized before security manager
+            Object.class.getResource("module-info.class");
+
             if (cn.isEmpty() || "default".equals(cn)) {
                 System.setSecurityManager(new SecurityManager());
             } else {
@@ -2053,6 +2052,9 @@
             public String fastUUID(long lsb, long msb) {
                 return Long.fastUUID(lsb, msb);
             }
+            public void invalidatePackageAccessCache() {
+                SecurityManager.invalidatePackageAccessCache();
+            }
         });
     }
 }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Fri Feb 10 08:57:42 2017 -0800
@@ -141,6 +141,18 @@
         this.markerInterfaces = markerInterfaces;
         this.additionalBridges = additionalBridges;
 
+        if (samMethodName.isEmpty() ||
+                samMethodName.indexOf('.') >= 0 ||
+                samMethodName.indexOf(';') >= 0 ||
+                samMethodName.indexOf('[') >= 0 ||
+                samMethodName.indexOf('/') >= 0 ||
+                samMethodName.indexOf('<') >= 0 ||
+                samMethodName.indexOf('>') >= 0) {
+            throw new LambdaConversionException(String.format(
+                    "Method name '%s' is not legal",
+                    samMethodName));
+        }
+
         if (!samBase.isInterface()) {
             throw new LambdaConversionException(String.format(
                     "Functional interface %s is not an interface",
@@ -275,25 +287,39 @@
                 (implKind == MethodHandleInfo.REF_newInvokeSpecial)
                   ? implDefiningClass
                   : implMethodType.returnType();
-        Class<?> samReturnType = samMethodType.returnType();
         if (!isAdaptableToAsReturn(actualReturnType, expectedType)) {
             throw new LambdaConversionException(
                     String.format("Type mismatch for lambda return: %s is not convertible to %s",
                                   actualReturnType, expectedType));
         }
-        if (!isAdaptableToAsReturnStrict(expectedType, samReturnType)) {
-            throw new LambdaConversionException(
-                    String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
-                                  expectedType, samReturnType));
+
+        // Check descriptors of generated methods
+        checkDescriptor(samMethodType);
+        for (MethodType bridgeMT : additionalBridges) {
+            checkDescriptor(bridgeMT);
         }
-        for (MethodType bridgeMT : additionalBridges) {
-            if (!isAdaptableToAsReturnStrict(expectedType, bridgeMT.returnType())) {
-                throw new LambdaConversionException(
-                        String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
-                                      expectedType, bridgeMT.returnType()));
+    }
+
+    /** Validate that the given descriptor's types are compatible with {@code instantiatedMethodType} **/
+    private void checkDescriptor(MethodType descriptor) throws LambdaConversionException {
+        for (int i = 0; i < instantiatedMethodType.parameterCount(); i++) {
+            Class<?> instantiatedParamType = instantiatedMethodType.parameterType(i);
+            Class<?> descriptorParamType = descriptor.parameterType(i);
+            if (!descriptorParamType.isAssignableFrom(instantiatedParamType)) {
+                String msg = String.format("Type mismatch for instantiated parameter %d: %s is not a subtype of %s",
+                                           i, instantiatedParamType, descriptorParamType);
+                throw new LambdaConversionException(msg);
             }
         }
-     }
+
+        Class<?> instantiatedReturnType = instantiatedMethodType.returnType();
+        Class<?> descriptorReturnType = descriptor.returnType();
+        if (!isAdaptableToAsReturnStrict(instantiatedReturnType, descriptorReturnType)) {
+            String msg = String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
+                                       instantiatedReturnType, descriptorReturnType);
+            throw new LambdaConversionException(msg);
+        }
+    }
 
     /**
      * Check type adaptability for parameter types.
@@ -345,8 +371,8 @@
                || !fromType.equals(void.class) && isAdaptableTo(fromType, toType, false);
     }
     private boolean isAdaptableToAsReturnStrict(Class<?> fromType, Class<?> toType) {
-        if (fromType.equals(void.class)) return toType.equals(void.class);
-        return isAdaptableTo(fromType, toType, true);
+        if (fromType.equals(void.class) || toType.equals(void.class)) return fromType.equals(toType);
+        else return isAdaptableTo(fromType, toType, true);
     }
 
 
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,8 +25,6 @@
 
 package java.lang.invoke;
 
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.reflect.CallerSensitive;
 import jdk.internal.reflect.Reflection;
 import jdk.internal.vm.annotation.ForceInline;
@@ -111,13 +109,17 @@
 
     /**
      * Returns a {@link Lookup lookup object} which is trusted minimally.
-     * It can only be used to create method handles to public members in
+     * The lookup has the {@code PUBLIC} and {@code UNCONDITIONAL} modes.
+     * It can only be used to create method handles to public members of
      * public classes in packages that are exported unconditionally.
      * <p>
-     * For now, the {@linkplain Lookup#lookupClass lookup class} of this lookup
-     * object is in an unnamed module.
-     * Consequently, the lookup context of this lookup object will be the bootstrap
-     * class loader, which means it cannot find user classes.
+     * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
+     * of this lookup object will be {@link java.lang.Object}.
+     *
+     * @apiNote The use of Object is conventional, and because the lookup modes are
+     * limited, there is no special access provided to the internals of Object, its package
+     * or its module. Consequently, the lookup context of this lookup object will be the
+     * bootstrap class loader, which means it cannot find user classes.
      *
      * <p style="font-size:smaller;">
      * <em>Discussion:</em>
@@ -129,17 +131,12 @@
      * Also, it cannot access
      * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
      * @return a lookup object which is trusted minimally
+     *
+     * @revised 9
+     * @spec JPMS
      */
     public static Lookup publicLookup() {
-        // During VM startup then only classes in the java.base module can be
-        // loaded and linked. This is because java.base exports aren't setup until
-        // the module system is initialized, hence types in the unnamed module
-        // (or any named module) can't link to java/lang/Object.
-        if (!jdk.internal.misc.VM.isModuleSystemInited()) {
-            return new Lookup(Object.class, Lookup.PUBLIC);
-        } else {
-            return LookupHelper.PUBLIC_LOOKUP;
-        }
+        return Lookup.PUBLIC_LOOKUP;
     }
 
     /**
@@ -172,6 +169,7 @@
      * @throws IllegalAccessException if the access check specified above fails
      * @throws SecurityException if denied by the security manager
      * @since 9
+     * @spec JPMS
      * @see Lookup#dropLookupMode
      */
     public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
@@ -183,11 +181,11 @@
             throw new IllegalArgumentException(targetClass + " is an array class");
         Module targetModule = targetClass.getModule();
         Module callerModule = lookup.lookupClass().getModule();
-        if (callerModule != targetModule && targetModule.isNamed()) {
-            if (!callerModule.canRead(targetModule))
-                throw new IllegalAccessException(callerModule + " does not read " + targetModule);
+        if (!callerModule.canRead(targetModule))
+            throw new IllegalAccessException(callerModule + " does not read " + targetModule);
+        if (targetModule.isNamed()) {
             String pn = targetClass.getPackageName();
-            assert pn != null && pn.length() > 0 : "unnamed package cannot be in named module";
+            assert pn.length() > 0 : "unnamed package cannot be in named module";
             if (!targetModule.isOpen(pn, callerModule))
                 throw new IllegalAccessException(targetModule + " does not open " + pn + " to " + callerModule);
         }
@@ -601,6 +599,8 @@
      * so that there can be a secure foundation for lookups.
      * Nearly all other methods in the JSR 292 API rely on lookup
      * objects to check access requests.
+     *
+     * @revised 9
      */
     public static final
     class Lookup {
@@ -647,15 +647,33 @@
          *  lookup class and public types in packages exported by other modules
          *  to the module of the lookup class.
          *  @since 9
+         *  @spec JPMS
          */
         public static final int MODULE = PACKAGE << 1;
 
-        private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE | MODULE);
+        /** A single-bit mask representing {@code unconditional} access
+         *  which may contribute to the result of {@link #lookupModes lookupModes}.
+         *  The value is {@code 0x20}, which does not correspond meaningfully to
+         *  any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
+         *  A {@code Lookup} with this lookup mode assumes {@linkplain
+         *  java.lang.reflect.Module#canRead(java.lang.reflect.Module) readability}.
+         *  In conjunction with the {@code PUBLIC} modifier bit, a {@code Lookup}
+         *  with this lookup mode can access all public members of public types
+         *  of all modules where the type is in a package that is {@link
+         *  java.lang.reflect.Module#isExported(String) exported unconditionally}.
+         *  @since 9
+         *  @spec JPMS
+         *  @see #publicLookup()
+         */
+        public static final int UNCONDITIONAL = PACKAGE << 2;
+
+        private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE | MODULE | UNCONDITIONAL);
+        private static final int FULL_POWER_MODES = (ALL_MODES & ~UNCONDITIONAL);
         private static final int TRUSTED   = -1;
 
         private static int fixmods(int mods) {
-            mods &= (ALL_MODES - PACKAGE - MODULE);
-            return (mods != 0) ? mods : (PACKAGE | MODULE);
+            mods &= (ALL_MODES - PACKAGE - MODULE - UNCONDITIONAL);
+            return (mods != 0) ? mods : (PACKAGE | MODULE | UNCONDITIONAL);
         }
 
         /** Tells which class is performing the lookup.  It is this class against
@@ -682,13 +700,14 @@
          *  {@linkplain #PRIVATE PRIVATE (0x02)},
          *  {@linkplain #PROTECTED PROTECTED (0x04)},
          *  {@linkplain #PACKAGE PACKAGE (0x08)},
-         *  and {@linkplain #MODULE MODULE (0x10)}.
+         *  {@linkplain #MODULE MODULE (0x10)},
+         *  and {@linkplain #UNCONDITIONAL UNCONDITIONAL (0x20)}.
          *  <p>
          *  A freshly-created lookup object
-         *  on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
-         *  has all possible bits set, since the caller class can access all its own members,
-         *  all public types in the caller's module, and all public types in packages exported
-         *  by other modules to the caller's module.
+         *  on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has
+         *  all possible bits set, except {@code UNCONDITIONAL}. The lookup can be used to
+         *  access all members of the caller's class, all public types in the caller's module,
+         *  and all public types in packages exported by other modules to the caller's module.
          *  A lookup object on a new lookup class
          *  {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
          *  may have some mode bits set to zero.
@@ -701,6 +720,9 @@
          *  @return the lookup modes, which limit the kinds of access performed by this lookup object
          *  @see #in
          *  @see #dropLookupMode
+         *
+         *  @revised 9
+         *  @spec JPMS
          */
         public int lookupModes() {
             return allowedModes & ALL_MODES;
@@ -712,9 +734,9 @@
          * which in turn is called by a method not in this package.
          */
         Lookup(Class<?> lookupClass) {
-            this(lookupClass, ALL_MODES);
+            this(lookupClass, FULL_POWER_MODES);
             // make sure we haven't accidentally picked up a privileged class:
-            checkUnprivilegedlookupClass(lookupClass, ALL_MODES);
+            checkUnprivilegedlookupClass(lookupClass, FULL_POWER_MODES);
         }
 
         private Lookup(Class<?> lookupClass, int allowedModes) {
@@ -730,19 +752,20 @@
          * However, the resulting {@code Lookup} object is guaranteed
          * to have no more access capabilities than the original.
          * In particular, access capabilities can be lost as follows:<ul>
-         * <li>If the lookup class for this {@code Lookup} is not in a named module,
-         * and the new lookup class is in a named module {@code M}, then no members in
-         * {@code M}'s non-exported packages will be accessible.
-         * <li>If the lookup for this {@code Lookup} is in a named module, and the
-         * new lookup class is in a different module {@code M}, then no members, not even
-         * public members in {@code M}'s exported packages, will be accessible.
-         * <li>If the new lookup class differs from the old one,
-         * protected members will not be accessible by virtue of inheritance.
-         * (Protected members may continue to be accessible because of package sharing.)
+         * <li>If the old lookup class is in a {@link Module#isNamed() named} module, and
+         * the new lookup class is in a different module {@code M}, then no members, not
+         * even public members in {@code M}'s exported packages, will be accessible.
+         * The exception to this is when this lookup is {@link #publicLookup()
+         * publicLookup}, in which case {@code PUBLIC} access is not lost.
+         * <li>If the old lookup class is in an unnamed module, and the new lookup class
+         * is a different module then {@link #MODULE MODULE} access is lost.
+         * <li>If the new lookup class differs from the old one then {@code UNCONDITIONAL} is lost.
          * <li>If the new lookup class is in a different package
          * than the old one, protected and default (package) members will not be accessible.
          * <li>If the new lookup class is not within the same package member
-         * as the old one, private members will not be accessible.
+         * as the old one, private members will not be accessible, and protected members
+         * will not be accessible by virtue of inheritance.
+         * (Protected members may continue to be accessible because of package sharing.)
          * <li>If the new lookup class is not accessible to the old lookup class,
          * then no members, not even public members, will be accessible.
          * (In all other cases, public members will continue to be accessible.)
@@ -757,32 +780,34 @@
          * @return a lookup object which reports the desired lookup class, or the same object
          * if there is no change
          * @throws NullPointerException if the argument is null
+         *
+         * @revised 9
+         * @spec JPMS
          */
         public Lookup in(Class<?> requestedLookupClass) {
             Objects.requireNonNull(requestedLookupClass);
             if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
-                return new Lookup(requestedLookupClass, ALL_MODES);
+                return new Lookup(requestedLookupClass, FULL_POWER_MODES);
             if (requestedLookupClass == this.lookupClass)
                 return this;  // keep same capabilities
-
-            int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
+            int newModes = (allowedModes & FULL_POWER_MODES);
             if (!VerifyAccess.isSameModule(this.lookupClass, requestedLookupClass)) {
-                // Allowed to teleport from an unnamed to a named module but resulting
-                // Lookup has no access to module private members
-                if (this.lookupClass.getModule().isNamed()) {
+                // Need to drop all access when teleporting from a named module to another
+                // module. The exception is publicLookup where PUBLIC is not lost.
+                if (this.lookupClass.getModule().isNamed()
+                    && (this.allowedModes & UNCONDITIONAL) == 0)
                     newModes = 0;
-                } else {
-                    newModes &= ~MODULE;
-                }
+                else
+                    newModes &= ~(MODULE|PACKAGE|PRIVATE|PROTECTED);
             }
             if ((newModes & PACKAGE) != 0
                 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
-                newModes &= ~(PACKAGE|PRIVATE);
+                newModes &= ~(PACKAGE|PRIVATE|PROTECTED);
             }
             // Allow nestmate lookups to be created without special privilege:
             if ((newModes & PRIVATE) != 0
                 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
-                newModes &= ~PRIVATE;
+                newModes &= ~(PRIVATE|PROTECTED);
             }
             if ((newModes & PUBLIC) != 0
                 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
@@ -801,28 +826,29 @@
          * finds members, but with a lookup mode that has lost the given lookup mode.
          * The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
          * MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
-         * {@link #PROTECTED PROTECTED} is always dropped and so the resulting lookup
-         * mode will never have this access capability. When dropping {@code PACKAGE}
-         * then the resulting lookup will not have {@code PACKAGE} or {@code PRIVATE}
-         * access. When dropping {@code MODULE} then the resulting lookup will not
-         * have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code
-         * PUBLIC} is dropped then the resulting lookup has no access.
+         * {@link #PROTECTED PROTECTED} and {@link #UNCONDITIONAL UNCONDITIONAL} are always
+         * dropped and so the resulting lookup mode will never have these access capabilities.
+         * When dropping {@code PACKAGE} then the resulting lookup will not have {@code PACKAGE}
+         * or {@code PRIVATE} access. When dropping {@code MODULE} then the resulting lookup will
+         * not have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code PUBLIC}
+         * is dropped then the resulting lookup has no access.
          * @param modeToDrop the lookup mode to drop
          * @return a lookup object which lacks the indicated mode, or the same object if there is no change
          * @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
-         * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED} or {@code PRIVATE}
+         * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
+         * @see MethodHandles#privateLookupIn
          * @since 9
-         * @see MethodHandles#privateLookupIn
          */
         public Lookup dropLookupMode(int modeToDrop) {
             int oldModes = lookupModes();
-            int newModes = oldModes & ~(modeToDrop | PROTECTED);
+            int newModes = oldModes & ~(modeToDrop | PROTECTED | UNCONDITIONAL);
             switch (modeToDrop) {
                 case PUBLIC: newModes &= ~(ALL_MODES); break;
                 case MODULE: newModes &= ~(PACKAGE | PRIVATE); break;
                 case PACKAGE: newModes &= ~(PRIVATE); break;
                 case PROTECTED:
-                case PRIVATE: break;
+                case PRIVATE:
+                case UNCONDITIONAL: break;
                 default: throw new IllegalArgumentException(modeToDrop + " is not a valid mode to drop");
             }
             if (newModes == oldModes) return this;  // return self if no change
@@ -835,6 +861,12 @@
         /** Package-private version of lookup which is trusted. */
         static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
 
+        /** Version of lookup which is trusted minimally.
+         *  It can only be used to create method handles to publicly accessible
+         *  members in packages that are exported unconditionally.
+         */
+        static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
+
         private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
             String name = lookupClass.getName();
             if (name.startsWith("java.lang.invoke."))
@@ -845,7 +877,7 @@
             // TODO replace with a more formal and less fragile mechanism
             // that does not bluntly restrict classes under packages within
             // java.base from looking up MethodHandles or VarHandles.
-            if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
+            if (allowedModes == FULL_POWER_MODES && lookupClass.getClassLoader() == null) {
                 if ((name.startsWith("java.") &&
                      !name.equals("java.lang.Thread") &&
                      !name.startsWith("java.util.concurrent.")) ||
@@ -866,6 +898,7 @@
          * <ul>
          * <li>If no access is allowed, the suffix is "/noaccess".
          * <li>If only public access to types in exported packages is allowed, the suffix is "/public".
+         * <li>If only public access and unconditional access are allowed, the suffix is "/publicLookup".
          * <li>If only public and module access are allowed, the suffix is "/module".
          * <li>If only public, module and package access are allowed, the suffix is "/package".
          * <li>If only public, module, package, and private access are allowed, the suffix is "/private".
@@ -884,6 +917,9 @@
          * because it requires a direct subclass relationship between
          * caller and callee.)
          * @see #in
+         *
+         * @revised 9
+         * @spec JPMS
          */
         @Override
         public String toString() {
@@ -893,13 +929,15 @@
                 return cname + "/noaccess";
             case PUBLIC:
                 return cname + "/public";
+            case PUBLIC|UNCONDITIONAL:
+                return cname  + "/publicLookup";
             case PUBLIC|MODULE:
                 return cname + "/module";
             case PUBLIC|MODULE|PACKAGE:
                 return cname + "/package";
-            case ALL_MODES & ~PROTECTED:
+            case FULL_POWER_MODES & ~PROTECTED:
                 return cname + "/private";
-            case ALL_MODES:
+            case FULL_POWER_MODES:
                 return cname;
             case TRUSTED:
                 return "/trusted";  // internal only; not exported
@@ -1580,6 +1618,7 @@
             if (refKind == REF_invokeSpecial)
                 refKind = REF_invokeVirtual;
             assert(method.isMethod());
+            @SuppressWarnings("deprecation")
             Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
             return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
         }
@@ -1662,6 +1701,7 @@
         public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
             MemberName ctor = new MemberName(c);
             assert(ctor.isConstructor());
+            @SuppressWarnings("deprecation")
             Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
             return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
         }
@@ -1692,6 +1732,7 @@
             assert(isSetter
                     ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
                     : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
+            @SuppressWarnings("deprecation")
             Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
             return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
         }
@@ -2033,9 +2074,9 @@
                                (defc == refc ||
                                 Modifier.isPublic(refc.getModifiers())));
             if (!classOK && (allowedModes & PACKAGE) != 0) {
-                classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
+                classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), FULL_POWER_MODES) &&
                            (defc == refc ||
-                            VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
+                            VerifyAccess.isClassAccessible(refc, lookupClass(), FULL_POWER_MODES)));
             }
             if (!classOK)
                 return "class is not public";
@@ -2348,53 +2389,6 @@
     }
 
     /**
-     * Helper class used to lazily create PUBLIC_LOOKUP with a lookup class
-     * in an <em>unnamed module</em>.
-     *
-     * @see Lookup#publicLookup
-     */
-    private static class LookupHelper {
-        private static final String UNNAMED = "Unnamed";
-        private static final String OBJECT  = "java/lang/Object";
-
-        private static Class<?> createClass() {
-            try {
-                ClassWriter cw = new ClassWriter(0);
-                cw.visit(Opcodes.V1_8,
-                         Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
-                         UNNAMED,
-                         null,
-                         OBJECT,
-                         null);
-                cw.visitSource(UNNAMED, null);
-                cw.visitEnd();
-                byte[] bytes = cw.toByteArray();
-                ClassLoader loader = new ClassLoader(null) {
-                    @Override
-                    protected Class<?> findClass(String cn) throws ClassNotFoundException {
-                        if (cn.equals(UNNAMED))
-                            return super.defineClass(UNNAMED, bytes, 0, bytes.length);
-                        throw new ClassNotFoundException(cn);
-                    }
-                };
-                return loader.loadClass(UNNAMED);
-            } catch (Exception e) {
-                throw new InternalError(e);
-            }
-        }
-
-        private static final Class<?> PUBLIC_LOOKUP_CLASS = createClass();
-
-        /**
-         * Lookup that is trusted minimally. It can only be used to create
-         * method handles to publicly accessible members in exported packages.
-         *
-         * @see MethodHandles#publicLookup
-         */
-        static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_LOOKUP_CLASS, Lookup.PUBLIC);
-    }
-
-    /**
      * Produces a method handle constructing arrays of a desired type.
      * The return type of the method handle will be the array type.
      * The type of its sole argument will be {@code int}, which specifies the size of the array.
--- a/jdk/src/java.base/share/classes/java/lang/module/Configuration.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/Configuration.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -42,126 +42,48 @@
 import java.util.stream.Stream;
 
 /**
- * The configuration that is the result of resolution or resolution with
- * service binding.
- *
- * <h2><a name="resolution">Resolution</a></h2>
- *
- * <p> Resolution is the process of computing the transitive closure of a set
- * of root modules over a set of observable modules by resolving the
- * dependences expressed by {@code requires} clauses.
- *
- * The <em>dependence graph</em> is augmented with edges that take account of
- * implicitly declared dependences ({@code requires transitive}) to create a
- * <em>readability graph</em>. A {@code Configuration} encapsulates the
- * resulting graph of {@link ResolvedModule resolved modules}.
- *
- * <p> Suppose we have the following observable modules: </p>
- * <pre> {@code
- *     module m1 { requires m2; }
- *     module m2 { requires transitive m3; }
- *     module m3 { }
- *     module m4 { }
- * } </pre>
+ * A configuration that is the result of <a href="package-summary.html#resolution">
+ * resolution</a> or resolution with <a href="package-summary.html#servicebinding">
+ * service binding</a>.
  *
- * <p> If the module {@code m1} is resolved then the resulting configuration
- * contains three modules ({@code m1}, {@code m2}, {@code m3}). The edges in
- * its readability graph are: </p>
- * <pre> {@code
- *     m1 --> m2  (meaning m1 reads m2)
- *     m1 --> m3
- *     m2 --> m3
- * } </pre>
- *
- * <p> Resolution is an additive process. When computing the transitive closure
- * then the dependence relation may include dependences on modules in parent
- * configurations. The result is a <em>relative configuration</em> that is
- * relative to one or more parent configurations and where the readability graph
- * may have edges from modules in the configuration to modules in parent
- * configurations.
- *
- * </p>
- *
- * <p> Suppose we have the following observable modules: </p>
- * <pre> {@code
- *     module m1 { requires m2; requires java.xml; }
- *     module m2 { }
- * } </pre>
+ * <p> A configuration encapsulates the <em>readability graph</em> that is the
+ * output of resolution. A readability graph is a directed graph where the nodes
+ * are of type {@link ResolvedModule} and the edges represent the readability
+ * amongst the modules. {@code Configuration} defines the {@link #modules()
+ * modules()} method to get the set of resolved modules in the graph. {@code
+ * ResolvedModule} defines the {@link ResolvedModule#reads() reads()} method to
+ * get the set of modules that a resolved module reads. The modules that are
+ * read may be in the same configuration or may be in {@link #parents() parent}
+ * configurations. </p>
  *
- * <p> If module {@code m1} is resolved with the configuration for the {@link
- * java.lang.reflect.Layer#boot() boot} layer as the parent then the resulting
- * configuration contains two modules ({@code m1}, {@code m2}). The edges in
- * its readability graph are:
- * <pre> {@code
- *     m1 --> m2
- *     m1 --> java.xml
- * } </pre>
- * where module {@code java.xml} is in the parent configuration. For
- * simplicity, this example omits the implicitly declared dependence on the
- * {@code java.base} module.
- *
- * <a name="automaticmoduleresolution"></a>
- * <p> {@link ModuleDescriptor#isAutomatic() Automatic} modules receive special
- * treatment during resolution. Each automatic module is resolved so that it
- * reads all other modules in the configuration and all parent configurations.
- * Each automatic module is also resolved as if it {@code requires transitive}
- * all other automatic modules in the configuration (and all automatic modules
- * in parent configurations). </p>
-
- * <h2><a name="servicebinding">Service binding</a></h2>
+ * <p> Configuration defines the {@link #resolve(ModuleFinder,List,ModuleFinder,Collection)
+ * resolve} method to resolve a collection of root modules, and the {@link
+ * #resolveAndBind(ModuleFinder,List,ModuleFinder,Collection) resolveAndBind}
+ * method to do resolution with service binding. There are instance and
+ * static variants of both methods. The instance methods create a configuration
+ * with the receiver as the parent configuration. The static methods are for
+ * more advanced cases where there can be more than one parent configuration. </p>
  *
- * <p> Service binding is the process of augmenting a graph of resolved modules
- * from the set of observable modules induced by the service-use dependence
- * ({@code uses} and {@code provides} clauses). Any module that was not
- * previously in the graph requires resolution to compute its transitive
- * closure. Service binding is an iterative process in that adding a module
- * that satisfies some service-use dependence may introduce new service-use
- * dependences. </p>
- *
- * <p> Suppose we have the following observable modules: </p>
- * <pre> {@code
- *     module m1 { exports p; uses p.S; }
- *     module m2 { requires m1; provides p.S with p2.S2; }
- *     module m3 { requires m1; requires m4; provides p.S with p3.S3; }
- *     module m4 { }
- * } </pre>
- *
- * <p> If the module {@code m1} is resolved then the resulting graph of modules
- * has one module ({@code m1}). If the graph is augmented with modules induced
- * by the service-use dependence relation then the configuration will contain
- * four modules ({@code m1}, {@code m2}, {@code m3}, {@code m4}). The edges in
- * its readability graph are: </p>
- * <pre> {@code
- *     m2 --> m1
- *     m3 --> m1
- *     m3 --> m4
- * } </pre>
- * <p> The edges in the conceptual service-use graph are: </p>
- * <pre> {@code
- *     m1 --> m2  (meaning m1 uses a service that is provided by m2)
- *     m1 --> m3
- * } </pre>
- *
- * <p> If this configuration is instantiated as a {@code Layer}, and if code in
- * module {@code m1} uses {@link java.util.ServiceLoader ServiceLoader} to
- * iterate over implementations of {@code p.S.class}, then it will iterate over
- * an instance of {@code p2.S2} and {@code p3.S3}. </p>
+ * <p> Each {@link java.lang.reflect.Layer layer} of modules in the Java virtual
+ * machine is created from a configuration. The configuration for the {@link
+ * java.lang.reflect.Layer#boot() boot} layer is obtained by invoking {@code
+ * Layer.boot().configuration()}. The configuration for the boot layer will
+ * often be the parent when creating new configurations. </p>
  *
  * <h3> Example </h3>
  *
- * <p> The following example uses the {@code resolveRequires} method to resolve
- * a module named <em>myapp</em> with the configuration for the boot layer as
- * the parent configuration. It prints the name of each resolved module and
- * the names of the modules that each module reads. </p>
+ * <p> The following example uses the {@link
+ * #resolve(ModuleFinder,ModuleFinder,Collection) resolve} method to resolve a
+ * module named <em>myapp</em> with the configuration for the boot layer as the
+ * parent configuration. It prints the name of each resolved module and the
+ * names of the modules that each module reads. </p>
  *
  * <pre>{@code
  *    ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
  *
  *    Configuration parent = Layer.boot().configuration();
  *
- *    Configuration cf = parent.resolveRequires(finder,
- *                                              ModuleFinder.of(),
- *                                              Set.of("myapp"));
+ *    Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("myapp"));
  *    cf.modules().forEach(m -> {
  *        System.out.format("%s -> %s%n",
  *            m.name(),
@@ -172,6 +94,7 @@
  * }</pre>
  *
  * @since 9
+ * @spec JPMS
  * @see java.lang.reflect.Layer
  */
 public final class Configuration {
@@ -186,11 +109,23 @@
     private final Set<ResolvedModule> modules;
     private final Map<String, ResolvedModule> nameToModule;
 
+    // module constraints on target
+    private final String osName;
+    private final String osArch;
+    private final String osVersion;
+
+    String osName() { return osName; }
+    String osArch() { return osArch; }
+    String osVersion() { return osVersion; }
+
     private Configuration() {
         this.parents = Collections.emptyList();
         this.graph = Collections.emptyMap();
         this.modules = Collections.emptySet();
         this.nameToModule = Collections.emptyMap();
+        this.osName = null;
+        this.osArch = null;
+        this.osVersion = null;
     }
 
     private Configuration(List<Configuration> parents,
@@ -214,27 +149,30 @@
         this.graph = g;
         this.modules = Set.of(moduleArray);
         this.nameToModule = Map.ofEntries(nameEntries);
+
+        this.osName = resolver.osName();
+        this.osArch = resolver.osArch();
+        this.osVersion = resolver.osVersion();
     }
 
-
     /**
      * Resolves a collection of root modules, with this configuration as its
      * parent, to create a new configuration. This method works exactly as
      * specified by the static {@link
-     * #resolveRequires(ModuleFinder,List,ModuleFinder,Collection) resolveRequires}
+     * #resolve(ModuleFinder,List,ModuleFinder,Collection) resolve}
      * method when invoked with this configuration as the parent. In other words,
      * if this configuration is {@code cf} then this method is equivalent to
      * invoking:
      * <pre> {@code
-     *     Configuration.resolveRequires(before, List.of(cf), after, roots);
+     *     Configuration.resolve(before, List.of(cf), after, roots);
      * }</pre>
      *
      * @param  before
      *         The <em>before</em> module finder to find modules
      * @param  after
-     *         The <em>after</em> module finder to locate modules when a
-     *         module cannot be located by the {@code before} module finder
-     *         and the module is not in this configuration
+     *         The <em>after</em> module finder to locate modules when not
+     *         located by the {@code before} module finder or in parent
+     *         configurations
      * @param  roots
      *         The possibly-empty collection of module names of the modules
      *         to resolve
@@ -242,16 +180,20 @@
      * @return The configuration that is the result of resolving the given
      *         root modules
      *
+     * @throws FindException
+     *         If resolution fails for any of the observability-related reasons
+     *         specified by the static {@code resolve} method
      * @throws ResolutionException
-     *         If resolution or the post-resolution checks fail
+     *         If any of the post-resolution consistency checks specified by
+     *         the  static {@code resolve} method fail
      * @throws SecurityException
      *         If locating a module is denied by the security manager
      */
-    public Configuration resolveRequires(ModuleFinder before,
-                                         ModuleFinder after,
-                                         Collection<String> roots)
+    public Configuration resolve(ModuleFinder before,
+                                 ModuleFinder after,
+                                 Collection<String> roots)
     {
-        return resolveRequires(before, List.of(this), after, roots);
+        return resolve(before, List.of(this), after, roots);
     }
 
 
@@ -259,12 +201,12 @@
      * Resolves a collection of root modules, with service binding, and with
      * this configuration as its parent, to create a new configuration.
      * This method works exactly as specified by the static {@link
-     * #resolveRequiresAndUses(ModuleFinder,List,ModuleFinder,Collection)
-     * resolveRequiresAndUses} method when invoked with this configuration
+     * #resolveAndBind(ModuleFinder,List,ModuleFinder,Collection)
+     * resolveAndBind} method when invoked with this configuration
      * as the parent. In other words, if this configuration is {@code cf} then
      * this method is equivalent to invoking:
      * <pre> {@code
-     *     Configuration.resolveRequiresAndUses(before, List.of(cf), after, roots);
+     *     Configuration.resolveAndBind(before, List.of(cf), after, roots);
      * }</pre>
      *
      *
@@ -272,25 +214,29 @@
      *         The <em>before</em> module finder to find modules
      * @param  after
      *         The <em>after</em> module finder to locate modules when not
-     *         located by the {@code before} module finder and this
-     *         configuration
+     *         located by the {@code before} module finder or in parent
+     *         configurations
      * @param  roots
      *         The possibly-empty collection of module names of the modules
      *         to resolve
      *
-     * @return The configuration that is the result of resolving the given
-     *         root modules
+     * @return The configuration that is the result of resolving, with service
+     *         binding, the given root modules
      *
+     * @throws FindException
+     *         If resolution fails for any of the observability-related reasons
+     *         specified by the static {@code resolve} method
      * @throws ResolutionException
-     *         If resolution or the post-resolution checks fail
+     *         If any of the post-resolution consistency checks specified by
+     *         the  static {@code resolve} method fail
      * @throws SecurityException
      *         If locating a module is denied by the security manager
      */
-    public Configuration resolveRequiresAndUses(ModuleFinder before,
-                                                ModuleFinder after,
-                                                Collection<String> roots)
+    public Configuration resolveAndBind(ModuleFinder before,
+                                        ModuleFinder after,
+                                        Collection<String> roots)
     {
-        return resolveRequiresAndUses(before, List.of(this), after, roots);
+        return resolveAndBind(before, List.of(this), after, roots);
     }
 
 
@@ -301,14 +247,14 @@
      *
      * This method is used to create the configuration for the boot layer.
      */
-    static Configuration resolveRequiresAndUses(ModuleFinder finder,
-                                                Collection<String> roots,
-                                                boolean check,
-                                                PrintStream traceOutput)
+    static Configuration resolveAndBind(ModuleFinder finder,
+                                        Collection<String> roots,
+                                        boolean check,
+                                        PrintStream traceOutput)
     {
         List<Configuration> parents = List.of(empty());
         Resolver resolver = new Resolver(finder, parents, ModuleFinder.of(), traceOutput);
-        resolver.resolveRequires(roots).resolveUses();
+        resolver.resolve(roots).bind();
 
         return new Configuration(parents, resolver, check);
     }
@@ -328,11 +274,11 @@
      *
      * <p> When all modules have been resolved then the resulting dependency
      * graph is checked to ensure that it does not contain cycles. A
-     * readability graph is constructed and in conjunction with the module
+     * readability graph is constructed, and in conjunction with the module
      * exports and service use, checked for consistency. </p>
      *
-     * <p> Resolution and the (post-resolution) consistency checks may fail for
-     * following reasons: </p>
+     * <p> Resolution may fail with {@code FindException} for the following
+     * <em>observability-related</em> reasons: </p>
      *
      * <ul>
      *     <li><p> A root module, or a direct or transitive dependency, is not
@@ -343,6 +289,20 @@
      *     descriptor ({@code module-info.class}) or two versions of the same
      *     module are found in the same directory. </p></li>
      *
+     *     <li><p> A module with the required name is found but the module
+     *     requires a different {@link ModuleDescriptor#osName() operating
+     *     system}, {@link ModuleDescriptor#osArch() architecture}, or {@link
+     *     ModuleDescriptor#osVersion() version} to other modules that have
+     *     been resolved for the new configuration or modules in the parent
+     *     configurations. </p></li>
+     *
+     * </ul>
+     *
+     * <p> Post-resolution consistency checks may fail with {@code
+     * ResolutionException} for the following reasons: </p>
+     *
+     * <ul>
+     *
      *     <li><p> A cycle is detected, say where module {@code m1} requires
      *     module {@code m2} and {@code m2} requires {@code m1}. </p></li>
      *
@@ -356,20 +316,11 @@
      *     module {@code M} nor exported to {@code M} by any module that
      *     {@code M} reads. </p></li>
      *
-     *     <li><p> A module {@code M} declares that it
-     *     "{@code provides ... with q.T}" but package {@code q} is not in
-     *     module {@code M}. </p></li>
+     * </ul>
      *
-     *     <li><p> Two or more modules in the configuration are specific to
-     *     different {@link ModuleDescriptor#osName() operating systems},
-     *     {@link ModuleDescriptor#osArch() architectures}, or {@link
-     *     ModuleDescriptor#osVersion() versions}. </p></li>
-     *
-     *     <li><p> Other implementation specific checks, for example referential
-     *     integrity checks to ensure that different versions of tighly coupled
-     *     modules cannot be combined in the same configuration. </p></li>
-     *
-     * </ul>
+     * @implNote In the implementation then observability of modules may depend
+     * on referential integrity checks that ensure different builds of tightly
+     * coupled modules are not combined in the same configuration.
      *
      * @param  before
      *         The <em>before</em> module finder to find modules
@@ -386,17 +337,22 @@
      * @return The configuration that is the result of resolving the given
      *         root modules
      *
+     * @throws FindException
+     *         If resolution fails for an observability-related reason
      * @throws ResolutionException
-     *         If resolution or the post-resolution checks fail
+     *         If a post-resolution consistency checks fails
      * @throws IllegalArgumentException
-     *         If the list of parents is empty
+     *         If the list of parents is empty, or the list has two or more
+     *         parents with modules for different target operating systems,
+     *         architectures, or versions
+     *
      * @throws SecurityException
      *         If locating a module is denied by the security manager
      */
-    public static Configuration resolveRequires(ModuleFinder before,
-                                                List<Configuration> parents,
-                                                ModuleFinder after,
-                                                Collection<String> roots)
+    public static Configuration resolve(ModuleFinder before,
+                                        List<Configuration> parents,
+                                        ModuleFinder after,
+                                        Collection<String> roots)
     {
         Objects.requireNonNull(before);
         Objects.requireNonNull(after);
@@ -407,7 +363,7 @@
             throw new IllegalArgumentException("'parents' is empty");
 
         Resolver resolver = new Resolver(before, parentList, after, null);
-        resolver.resolveRequires(roots);
+        resolver.resolve(roots);
 
         return new Configuration(parentList, resolver, true);
     }
@@ -417,24 +373,24 @@
      * configuration.
      *
      * <p> This method works exactly as specified by {@link
-     * #resolveRequires(ModuleFinder,List,ModuleFinder,Collection)
-     * resolveRequires} except that the graph of resolved modules is augmented
+     * #resolve(ModuleFinder,List,ModuleFinder,Collection)
+     * resolve} except that the graph of resolved modules is augmented
      * with modules induced by the service-use dependence relation. </p>
      *
      * <p> More specifically, the root modules are resolved as if by calling
-     * {@code resolveRequires}. The resolved modules, and all modules in the
+     * {@code resolve}. The resolved modules, and all modules in the
      * parent configurations, with {@link ModuleDescriptor#uses() service
      * dependences} are then examined. All modules found by the given module
      * finders that {@link ModuleDescriptor#provides() provide} an
      * implementation of one or more of the service types are added to the
      * module graph and then resolved as if by calling the {@code
-     * resolveRequires} method. Adding modules to the module graph may
-     * introduce new service-use dependences and so the process works
-     * iteratively until no more modules are added. </p>
+     * resolve} method. Adding modules to the module graph may introduce new
+     * service-use dependences and so the process works iteratively until no
+     * more modules are added. </p>
      *
-     * <p> As service binding involves resolution then it may fail with {@link
-     * ResolutionException} for exactly the same reasons specified in
-     * {@code resolveRequires}.  </p>
+     * <p> As service binding involves resolution then it may fail with {@code
+     * FindException} or {@code ResolutionException} for exactly the same
+     * reasons specified in {@code resolve}. </p>
      *
      * @param  before
      *         The <em>before</em> module finder to find modules
@@ -448,20 +404,26 @@
      *         The possibly-empty collection of module names of the modules
      *         to resolve
      *
-     * @return The configuration that is the result of resolving the given
-     *         root modules
+     * @return The configuration that is the result of resolving, with service
+     *         binding, the given root modules
      *
+     * @throws FindException
+     *         If resolution fails for any of the observability-related reasons
+     *         specified by the static {@code resolve} method
      * @throws ResolutionException
-     *         If resolution or the post-resolution checks fail
+     *         If any of the post-resolution consistency checks specified by
+     *         the  static {@code resolve} method fail
      * @throws IllegalArgumentException
-     *         If the list of parents is empty
+     *         If the list of parents is empty, or the list has two or more
+     *         parents with modules for different target operating systems,
+     *         architectures, or versions
      * @throws SecurityException
      *         If locating a module is denied by the security manager
      */
-    public static Configuration resolveRequiresAndUses(ModuleFinder before,
-                                                       List<Configuration> parents,
-                                                       ModuleFinder after,
-                                                       Collection<String> roots)
+    public static Configuration resolveAndBind(ModuleFinder before,
+                                               List<Configuration> parents,
+                                               ModuleFinder after,
+                                               Collection<String> roots)
     {
         Objects.requireNonNull(before);
         Objects.requireNonNull(after);
@@ -472,7 +434,7 @@
             throw new IllegalArgumentException("'parents' is empty");
 
         Resolver resolver = new Resolver(before, parentList, after, null);
-        resolver.resolveRequires(roots).resolveUses();
+        resolver.resolve(roots).bind();
 
         return new Configuration(parentList, resolver, true);
     }
--- a/jdk/src/java.base/share/classes/java/lang/module/FindException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/FindException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -26,10 +26,14 @@
 package java.lang.module;
 
 /**
- * Thrown by module finders when finding a module fails.
+ * Thrown by a {@link ModuleFinder ModuleFinder} when an error occurs finding
+ * a module. Also thrown by {@link
+ * Configuration#resolve(ModuleFinder,java.util.List,ModuleFinder,java.util.Collection)
+ * Configuration.resolve} when resolution fails for observability-related
+ * reasons.
  *
- * @see ModuleFinder
  * @since 9
+ * @spec JPMS
  */
 
 public class FindException extends RuntimeException {
--- a/jdk/src/java.base/share/classes/java/lang/module/InvalidModuleDescriptorException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/InvalidModuleDescriptorException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -31,6 +31,7 @@
  *
  * @see ModuleDescriptor#read
  * @since 9
+ * @spec JPMS
  */
 public class InvalidModuleDescriptorException extends RuntimeException {
     private static final long serialVersionUID = 4863390386809347380L;
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -32,6 +32,7 @@
 import java.nio.ByteBuffer;
 import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -56,18 +57,37 @@
 /**
  * A module descriptor.
  *
- * <p> A {@code ModuleDescriptor} is typically created from the binary form
- * of a module declaration. Alternatively, the {@link ModuleDescriptor.Builder}
- * class can be used to create a {@code ModuleDescriptor} from its components.
- * The {@link #module module}, {@link #openModule openModule}, and {@link
- * #automaticModule automaticModule} methods create builders for building
- * different kinds of modules. </p>
+ * <p> A module descriptor describes a named module and defines methods to
+ * obtain each of its components. The module descriptor for a named module
+ * in the Java virtual machine is obtained by invoking the {@link
+ * java.lang.reflect.Module Module}'s {@link java.lang.reflect.Module#getDescriptor
+ * getDescriptor} method. Module descriptors can also be created using the
+ * {@link ModuleDescriptor.Builder} class or by reading the binary form of a
+ * module declaration ({@code module-info.class}) using the {@link
+ * #read(InputStream,Supplier) read} methods defined here. </p>
+ *
+ * <p> A module descriptor describes a <em>normal</em>, open, or automatic
+ * module. <em>Normal</em> modules and open modules describe their {@link
+ * #requires() dependences}, {@link #exports() exported-packages}, the services
+ * that they {@link #uses() use} or {@link #provides() provide}, and other
+ * components. <em>Normal</em> modules may {@link #opens() open} specific
+ * packages. The module descriptor for an open modules does not declare any
+ * open packages (its {@code opens} method returns an empty set) but when
+ * instantiated in the Java virtual machine then it is treated as if all
+ * packages are open. The module descriptor for an automatic module does not
+ * declare any dependences (except for the mandatory dependency on {@code
+ * java.base}), and does not declare any exported or open packages. Automatic
+ * module receive special treatment during resolution so that they read all
+ * other modules in the configuration. When an automatic module is instantiated
+ * in the Java virtual machine then it reads every unnamed module and is
+ * treated as if all packages are exported and open. </p>
  *
  * <p> {@code ModuleDescriptor} objects are immutable and safe for use by
  * multiple concurrent threads.</p>
  *
+ * @see java.lang.reflect.Module
  * @since 9
- * @see java.lang.reflect.Module
+ * @spec JPMS
  */
 
 public class ModuleDescriptor
@@ -75,10 +95,45 @@
 {
 
     /**
+     * A modifier on a module.
+     *
+     * @see ModuleDescriptor#modifiers()
+     * @since 9
+     */
+    public static enum Modifier {
+        /**
+         * An open module. An open module does not declare any open packages
+         * but the resulting module is treated as if all packages are open.
+         */
+        OPEN,
+
+        /**
+         * An automatic module. An automatic module is treated as if it exports
+         * and opens all packages.
+         *
+         * @apiNote This modifier does not correspond to a module flag in the
+         * binary form of a module declaration ({@code module-info.class}).
+         */
+        AUTOMATIC,
+
+        /**
+         * The module was not explicitly or implicitly declared.
+         */
+        SYNTHETIC,
+
+        /**
+         * The module was implicitly declared.
+         */
+        MANDATED;
+    }
+
+
+    /**
      * <p> A dependence upon a module </p>
      *
      * @see ModuleDescriptor#requires()
      * @since 9
+     * @spec JPMS
      */
 
     public final static class Requires
@@ -88,7 +143,9 @@
         /**
          * A modifier on a module dependence.
          *
+         * @see Requires#modifiers()
          * @since 9
+         * @spec JPMS
          */
         public static enum Modifier {
 
@@ -171,14 +228,18 @@
          * Compares this module dependence to another.
          *
          * <p> Two {@code Requires} objects are compared by comparing their
-         * module name lexicographically.  Where the module names are equal then
-         * the sets of modifiers are compared based on a value computed from the
-         * ordinal of each modifier. Where the module names are equal and the
-         * set of modifiers are equal then the version of the modules recorded
-         * at compile-time are compared. When comparing the versions recorded
-         * at compile-time then a dependence that has a recorded version is
-         * considered to succeed a dependence that does not have a recorded
-         * version. </p>
+         * module names lexicographically. Where the module names are equal
+         * then the sets of modifiers are compared in the same way that
+         * module modifiers are compared (see {@link ModuleDescriptor#compareTo
+         * ModuleDescriptor.compareTo}). Where the module names are equal and
+         * the set of modifiers are equal then the version of the modules
+         * recorded at compile-time are compared. When comparing the versions
+         * recorded at compile-time then a dependence that has a recorded
+         * version is considered to succeed a dependence that does not have a
+         * recorded version. </p>
+         *
+         * @param  that
+         *         The module dependence to compare
          *
          * @return A negative integer, zero, or a positive integer if this module
          *         dependence is less than, equal to, or greater than the given
@@ -186,39 +247,22 @@
          */
         @Override
         public int compareTo(Requires that) {
+            if (this == that) return 0;
+
             int c = this.name().compareTo(that.name());
-            if (c != 0)
-                return c;
+            if (c != 0) return c;
 
             // modifiers
-            c = Long.compare(this.modsValue(), that.modsValue());
-            if (c != 0)
-                return c;
+            long v1 = modsValue(this.modifiers());
+            long v2 = modsValue(that.modifiers());
+            c = Long.compare(v1, v2);
+            if (c != 0) return c;
 
             // compiledVersion
-            if (this.compiledVersion != null) {
-                if (that.compiledVersion != null)
-                    c = this.compiledVersion.compareTo(that.compiledVersion);
-                else
-                    c = 1;
-            } else {
-                if (that.compiledVersion != null)
-                    c = -1;
-            }
+            c = compare(this.compiledVersion, that.compiledVersion);
+            if (c != 0) return c;
 
-            return c;
-        }
-
-        /**
-         * Return a value for the modifiers to allow sets of modifiers to be
-         * compared.
-         */
-        private long modsValue() {
-            long value = 0;
-            for (Modifier m : mods) {
-                value += 1 << m.ordinal();
-            }
-            return value;
+            return 0;
         }
 
         /**
@@ -266,9 +310,9 @@
         }
 
         /**
-         * Returns a string describing module dependence.
+         * Returns a string describing this module dependence.
          *
-         * @return A string describing module dependence
+         * @return A string describing this module dependence
          */
         @Override
         public String toString() {
@@ -285,18 +329,23 @@
 
 
     /**
-     * <p> A module export, may be qualified or unqualified. </p>
+     * <p> A package exported by a module, may be qualified or unqualified. </p>
      *
      * @see ModuleDescriptor#exports()
      * @since 9
+     * @spec JPMS
      */
 
-    public final static class Exports {
+    public final static class Exports
+        implements Comparable<Exports>
+    {
 
         /**
-         * A modifier on a module export.
+         * A modifier on an exported package.
          *
+         * @see Exports#modifiers()
          * @since 9
+         * @spec JPMS
          */
         public static enum Modifier {
 
@@ -381,6 +430,52 @@
         }
 
         /**
+         * Compares this module export to another.
+         *
+         * <p> Two {@code Exports} objects are compared by comparing the package
+         * names lexicographically. Where the packages names are equal then the
+         * sets of modifiers are compared in the same way that module modifiers
+         * are compared (see {@link ModuleDescriptor#compareTo
+         * ModuleDescriptor.compareTo}). Where the package names are equal and
+         * the set of modifiers are equal then the set of target modules are
+         * compared. This is done by sorting the names of the target modules
+         * in ascending order, and according to their natural ordering, and then
+         * comparing the corresponding elements lexicographically. Where the
+         * sets differ in size, and the larger set contains all elements of the
+         * smaller set, then the larger set is considered to succeed the smaller
+         * set. </p>
+         *
+         * @param  that
+         *         The module export to compare
+         *
+         * @return A negative integer, zero, or a positive integer if this module
+         *         export is less than, equal to, or greater than the given
+         *         export dependence
+         */
+        @Override
+        public int compareTo(Exports that) {
+            if (this == that) return 0;
+
+            int c = source.compareTo(that.source);
+            if (c != 0)
+                return c;
+
+            // modifiers
+            long v1 = modsValue(this.modifiers());
+            long v2 = modsValue(that.modifiers());
+            c = Long.compare(v1, v2);
+            if (c != 0)
+                return c;
+
+            // targets
+            c = compare(targets, that.targets);
+            if (c != 0)
+                return c;
+
+            return 0;
+        }
+
+        /**
          * Computes a hash code for this module export.
          *
          * <p> The hash code is based upon the modifiers, the package name,
@@ -425,9 +520,9 @@
         }
 
         /**
-         * Returns a string describing module export.
+         * Returns a string describing the exported package.
          *
-         * @return A string describing module export
+         * @return A string describing the exported package
          */
         @Override
         public String toString() {
@@ -441,8 +536,7 @@
 
 
     /**
-     * <p> Represents a module <em>opens</em> directive, may be qualified or
-     * unqualified. </p>
+     * <p> A package opened by a module, may be qualified or unqualified. </p>
      *
      * <p> The <em>opens</em> directive in a module declaration declares a
      * package to be open to allow all types in the package, and all their
@@ -452,26 +546,30 @@
      *
      * @see ModuleDescriptor#opens()
      * @since 9
+     * @spec JPMS
      */
 
-    public final static class Opens {
-
+    public final static class Opens
+        implements Comparable<Opens>
+    {
         /**
-         * A modifier on a module <em>opens</em> directive.
+         * A modifier on an open package.
          *
+         * @see Opens#modifiers()
          * @since 9
+         * @spec JPMS
          */
         public static enum Modifier {
 
             /**
-             * The opens was not explicitly or implicitly declared in the
-             * source of the module declaration.
+             * The open package was not explicitly or implicitly declared in
+             * the source of the module declaration.
              */
             SYNTHETIC,
 
             /**
-             * The opens was implicitly declared in the source of the module
-             * declaration.
+             * The open package was implicitly declared in the source of the
+             * module declaration.
              */
             MANDATED;
 
@@ -544,6 +642,52 @@
         }
 
         /**
+         * Compares this module opens to another.
+         *
+         * <p> Two {@code Opens} objects are compared by comparing the package
+         * names lexicographically. Where the packages names are equal then the
+         * sets of modifiers are compared in the same way that module modifiers
+         * are compared (see {@link ModuleDescriptor#compareTo
+         * ModuleDescriptor.compareTo}). Where the package names are equal and
+         * the set of modifiers are equal then the set of target modules are
+         * compared. This is done by sorting the names of the target modules
+         * in ascending order, and according to their natural ordering, and then
+         * comparing the corresponding elements lexicographically. Where the
+         * sets differ in size, and the larger set contains all elements of the
+         * smaller set, then the larger set is considered to succeed the smaller
+         * set. </p>
+         *
+         * @param  that
+         *         The module opens to compare
+         *
+         * @return A negative integer, zero, or a positive integer if this module
+         *         opens is less than, equal to, or greater than the given
+         *         module opens
+         */
+        @Override
+        public int compareTo(Opens that) {
+            if (this == that) return 0;
+
+            int c = source.compareTo(that.source);
+            if (c != 0)
+                return c;
+
+            // modifiers
+            long v1 = modsValue(this.modifiers());
+            long v2 = modsValue(that.modifiers());
+            c = Long.compare(v1, v2);
+            if (c != 0)
+                return c;
+
+            // targets
+            c = compare(targets, that.targets);
+            if (c != 0)
+                return c;
+
+            return 0;
+        }
+
+        /**
          * Computes a hash code for this module opens.
          *
          * <p> The hash code is based upon the modifiers, the package name,
@@ -588,9 +732,9 @@
         }
 
         /**
-         * Returns a string describing module opens.
+         * Returns a string describing the open package.
          *
-         * @return A string describing module opens
+         * @return A string describing the open package
          */
         @Override
         public String toString() {
@@ -608,10 +752,12 @@
      *
      * @see ModuleDescriptor#provides()
      * @since 9
+     * @spec JPMS
      */
 
-    public final static class Provides {
-
+    public final static class Provides
+        implements Comparable<Provides>
+    {
         private final String service;
         private final List<String> providers;
 
@@ -642,6 +788,46 @@
         public List<String> providers() { return providers; }
 
         /**
+         * Compares this provides to another.
+         *
+         * <p> Two {@code Provides} objects are compared by comparing the fully
+         * qualified class name of the service type lexicographically. Where the
+         * class names are equal then the list of the provider class names are
+         * compared by comparing the corresponding elements of both lists
+         * lexicographically and in sequence. Where the lists differ in size,
+         * {@code N} is the size of the shorter list, and the first {@code N}
+         * corresponding elements are equal, then the longer list is considered
+         * to succeed the shorter list. </p>
+         *
+         * @param  that
+         *         The {@code Provides} to compare
+         *
+         * @return A negative integer, zero, or a positive integer if this provides
+         *         is less than, equal to, or greater than the given provides
+         */
+        public int compareTo(Provides that) {
+            if (this == that) return 0;
+
+            int c = service.compareTo(that.service);
+            if (c != 0) return c;
+
+            // compare provider class names in sequence
+            int size1 = this.providers.size();
+            int size2 = that.providers.size();
+            for (int index=0; index<Math.min(size1, size2); index++) {
+                String e1 = this.providers.get(index);
+                String e2 = that.providers.get(index);
+                c = e1.compareTo(e2);
+                if (c != 0) return c;
+            }
+            if (size1 == size2) {
+                return 0;
+            } else {
+                return (size1 > size2) ? 1 : -1;
+            }
+        }
+
+        /**
          * Computes a hash code for this provides.
          *
          * <p> The hash code is based upon the service type and the set of
@@ -699,7 +885,7 @@
      *
      * <p> A version string has three components: The version number itself, an
      * optional pre-release version, and an optional build version.  Each
-     * component is sequence of tokens; each token is either a non-negative
+     * component is a sequence of tokens; each token is either a non-negative
      * integer or a string.  Tokens are separated by the punctuation characters
      * {@code '.'}, {@code '-'}, or {@code '+'}, or by transitions from a
      * sequence of digits to a sequence of characters that are neither digits
@@ -740,6 +926,7 @@
      *
      * @see ModuleDescriptor#version()
      * @since 9
+     * @spec JPMS
      */
 
     public final static class Version
@@ -1009,36 +1196,26 @@
 
     }
 
-
+
     private final String name;
     private final Version version;
-    private final boolean open;
-
-    // Indicates if synthesised for a JAR file found on the module path
-    private final boolean automatic;
-
-    // Not generated from a module-info.java
-    private final boolean synthetic;
-
+    private final Set<Modifier> modifiers;
+    private final boolean open;  // true if modifiers contains OPEN
+    private final boolean automatic;  // true if modifiers contains AUTOMATIC
     private final Set<Requires> requires;
     private final Set<Exports> exports;
     private final Set<Opens> opens;
     private final Set<String> uses;
     private final Set<Provides> provides;
-
-    // Added post-compilation by tools
     private final Set<String> packages;
     private final String mainClass;
     private final String osName;
     private final String osArch;
     private final String osVersion;
 
-
     private ModuleDescriptor(String name,
                              Version version,
-                             boolean open,
-                             boolean automatic,
-                             boolean synthetic,
+                             Set<Modifier> modifiers,
                              Set<Requires> requires,
                              Set<Exports> exports,
                              Set<Opens> opens,
@@ -1052,10 +1229,9 @@
     {
         this.name = name;
         this.version = version;
-        this.open = open;
-        this.automatic = automatic;
-        this.synthetic = synthetic;
-
+        this.modifiers = emptyOrUnmodifiableSet(modifiers);
+        this.open = modifiers.contains(Modifier.OPEN);
+        this.automatic = modifiers.contains(Modifier.AUTOMATIC);
         assert (requires.stream().map(Requires::name).distinct().count()
                 == requires.size());
         this.requires = emptyOrUnmodifiableSet(requires);
@@ -1072,40 +1248,12 @@
     }
 
     /**
-     * Clones the given module descriptor with an augmented set of packages
-     */
-    ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
-        this.name = md.name;
-        this.version = md.version;
-        this.open = md.open;
-        this.automatic = md.automatic;
-        this.synthetic = md.synthetic;
-
-        this.requires = md.requires;
-        this.exports = md.exports;
-        this.opens = md.opens;
-        this.uses = md.uses;
-        this.provides = md.provides;
-
-        Set<String> packages = new HashSet<>(md.packages);
-        packages.addAll(pkgs);
-        this.packages = emptyOrUnmodifiableSet(packages);
-
-        this.mainClass = md.mainClass;
-        this.osName = md.osName;
-        this.osArch = md.osArch;
-        this.osVersion = md.osVersion;
-    }
-
-    /**
      * Creates a module descriptor from its components.
      * The arguments are pre-validated and sets are unmodifiable sets.
      */
     ModuleDescriptor(String name,
                      Version version,
-                     boolean open,
-                     boolean automatic,
-                     boolean synthetic,
+                     Set<Modifier> modifiers,
                      Set<Requires> requires,
                      Set<Exports> exports,
                      Set<Opens> opens,
@@ -1120,9 +1268,9 @@
                      boolean unused) {
         this.name = name;
         this.version = version;
-        this.open = open;
-        this.automatic = automatic;
-        this.synthetic = synthetic;
+        this.modifiers = modifiers;
+        this.open = modifiers.contains(Modifier.OPEN);
+        this.automatic = modifiers.contains(Modifier.AUTOMATIC);
         this.requires = requires;
         this.exports = exports;
         this.opens = opens;
@@ -1137,7 +1285,7 @@
     }
 
     /**
-     * <p> The module name. </p>
+     * <p> Returns the module name. </p>
      *
      * @return The module name
      */
@@ -1146,11 +1294,19 @@
     }
 
     /**
+     * <p> Returns the set of module modifiers. </p>
+     *
+     * @return A possibly-empty unmodifiable set of modifiers
+     */
+    public Set<Modifier> modifiers() {
+        return modifiers;
+    }
+
+    /**
      * <p> Returns {@code true} if this is an open module. </p>
      *
-     * <p> An open module does not declare any open packages (the {@link #opens()
-     * opens} method returns an empty set) but the resulting module is treated
-     * as if all packages are open. </p>
+     * <p> This method is equivalent to testing if the set of {@link #modifiers
+     * modifiers} contains the {@link Modifier#OPEN OPEN} modifier. </p>
      *
      * @return  {@code true} if this is an open module
      */
@@ -1161,12 +1317,8 @@
     /**
      * <p> Returns {@code true} if this is an automatic module. </p>
      *
-     * <p> An automatic module is defined implicitly rather than explicitly
-     * and therefore does not have a module declaration. JAR files located on
-     * the application module path, or by the {@link ModuleFinder} returned by
-     * {@link ModuleFinder#of(java.nio.file.Path[]) ModuleFinder.of}, are
-     * treated as automatic modules if they do have not have a module
-     * declaration. </p>
+     * <p> This method is equivalent to testing if the set of {@link #modifiers
+     * modifiers} contains the {@link Modifier#OPEN AUTOMATIC} modifier. </p>
      *
      * @return  {@code true} if this is an automatic module
      */
@@ -1175,20 +1327,13 @@
     }
 
     /**
-     * <p> Returns {@code true} if this module descriptor was not generated
-     * from an explicit module declaration ({@code module-info.java})
-     * or an implicit module declaration (an {@link #isAutomatic() automatic}
-     * module). </p>
+     * <p> Returns the set of {@code Requires} objects representing the module
+     * dependences. </p>
      *
-     * @return  {@code true} if this module descriptor was not generated by
-     *          an explicit or implicit module declaration
-     */
-    public boolean isSynthetic() {
-        return synthetic;
-    }
-
-    /**
-     * <p> The dependences of this module. </p>
+     * <p> The set includes a dependency on "{@code java.base}" when this
+     * module is not named "{@code java.base}". If this module is an automatic
+     * module then it does not have a dependency on any module other than
+     * "{@code java.base}". </p>
      *
      * @return  A possibly-empty unmodifiable set of {@link Requires} objects
      */
@@ -1197,7 +1342,11 @@
     }
 
     /**
-     * <p> The module exports. </p>
+     * <p> Returns the set of {@code Exports} objects representing the exported
+     * packages. </p>
+     *
+     * <p> If this module is an automatic module then the set of exports
+     * is empty. </p>
      *
      * @return  A possibly-empty unmodifiable set of exported packages
      */
@@ -1206,16 +1355,11 @@
     }
 
     /**
-     * <p> The module <em>opens</em> directives. </p>
+     * <p> Returns the set of {@code Opens} objects representing the open
+     * packages. </p>
      *
-     * <p> Each {@code Opens} object in the set represents a package (and
-     * the set of target module names when qualified) where all types in the
-     * package, and all their members, not just public types and their public
-     * members, can be reflected on when using APIs that bypass or suppress
-     * default Java language access control checks. </p>
-     *
-     * <p> This method returns an empty set when invoked on {@link #isOpen()
-     * open} module. </p>
+     * <p> If this module is an open module or an automatic module then the
+     * set of open packages is empty. </p>
      *
      * @return  A possibly-empty unmodifiable set of open packages
      */
@@ -1224,7 +1368,10 @@
     }
 
     /**
-     * <p> The service dependences of this module. </p>
+     * <p> Returns the set of service dependences. </p>
+     *
+     * <p> If this module is an automatic module then the set of service
+     * dependences is empty. </p>
      *
      * @return  A possibly-empty unmodifiable set of the fully qualified class
      *          names of the service types used
@@ -1234,7 +1381,8 @@
     }
 
     /**
-     * <p> The services that this module provides. </p>
+     * <p> Returns the set of {@code Provides} objects representing the
+     * services that the module provides. </p>
      *
      * @return The possibly-empty unmodifiable set of the services that this
      *         module provides
@@ -1244,7 +1392,7 @@
     }
 
     /**
-     * Returns this module's version.
+     * <p> Returns the module version. </p>
      *
      * @return This module's version
      */
@@ -1253,10 +1401,10 @@
     }
 
     /**
-     * Returns a string containing this module's name and, if present, its
-     * version.
+     * <p> Returns a string containing the module name and, if present, its
+     * version. </p>
      *
-     * @return A string containing this module's name and, if present, its
+     * @return A string containing the module name and, if present, its
      *         version.
      */
     public String toNameAndVersion() {
@@ -1268,51 +1416,51 @@
     }
 
     /**
-     * Returns the module's main class.
+     * <p> Returns the module main class. </p>
      *
-     * @return The fully qualified class name of this module's main class
+     * @return The fully qualified class name of the module's main class
      */
     public Optional<String> mainClass() {
         return Optional.ofNullable(mainClass);
     }
 
     /**
-     * Returns the operating system name if this module is operating system
+     * Returns the operating system name if the module is operating system
      * specific.
      *
      * @return The operating system name or an empty {@code Optional}
-     *         if this module is not operating system specific
+     *         if the module is not operating system specific
      */
     public Optional<String> osName() {
         return Optional.ofNullable(osName);
     }
 
     /**
-     * Returns the operating system architecture if this module is operating
+     * Returns the operating system architecture if the module is operating
      * system architecture specific.
      *
      * @return The operating system architecture or an empty {@code Optional}
-     *         if this module is not operating system architecture specific
+     *         if the module is not operating system architecture specific
      */
     public Optional<String> osArch() {
         return Optional.ofNullable(osArch);
     }
 
     /**
-     * Returns the operating system version if this module is operating
+     * Returns the operating system version if the module is operating
      * system version specific.
      *
      * @return The operating system version or an empty {@code Optional}
-     *         if this module is not operating system version specific
+     *         if the module is not operating system version specific
      */
     public Optional<String> osVersion() {
         return Optional.ofNullable(osVersion);
     }
 
     /**
-     * Returns the names of all packages in this module.
+     * Returns the set of packages in the module.
      *
-     * @return A possibly-empty unmodifiable set of all packages in the module
+     * @return A possibly-empty unmodifiable set of the packages in the module
      */
     public Set<String> packages() {
         return packages;
@@ -1320,37 +1468,53 @@
 
 
     /**
-     * A builder used for building {@link ModuleDescriptor} objects.
+     * A builder for building {@link ModuleDescriptor} objects.
+     *
+     * <p> {@code ModuleDescriptor} defines the {@link #newModule newModule},
+     * {@link #newOpenModule newOpenModule}, and {@link #newAutomaticModule
+     * newAutomaticModule} methods to create builders for building
+     * <em>normal</em>, open, and automatic modules. </p>
      *
-     * <p> {@code ModuleDescriptor} defines the {@link #module module}, {@link
-     * #openModule openModule}, and {@link #automaticModule automaticModule}
-     * methods to create builders for building different kinds of modules. </p>
+     * <p> The set of packages in the module are accumulated by the {@code
+     * Builder} as the {@link ModuleDescriptor.Builder#exports(String) exports},
+     * {@link ModuleDescriptor.Builder#opens(String) opens},
+     * {@link ModuleDescriptor.Builder#packages(Set) packages},
+     * {@link ModuleDescriptor.Builder#provides(String,List) provides}, and
+     * {@link ModuleDescriptor.Builder#mainClass(String) mainClass} methods are
+     * invoked. </p>
+     *
+     * <p> The module names, package names, and class names that are parameters
+     * specified to the builder methods are the module names, package names,
+     * and qualified names of classes (in named packages) as defined in the
+     * <cite>The Java&trade; Language Specification</cite>. </p>
      *
      * <p> Example usage: </p>
-     * <pre>{@code    ModuleDescriptor descriptor = ModuleDescriptor.module("m1")
-     *         .exports("p")
-     *         .requires("m2")
+     * <pre>{@code    ModuleDescriptor descriptor = ModuleDescriptor.newModule("stats.core")
+     *         .requires("java.base")
+     *         .exports("org.acme.stats.core.clustering")
+     *         .exports("org.acme.stats.core.regression")
+     *         .packages(Set.of("org.acme.stats.core.internal"))
      *         .build();
      * }</pre>
      *
      * @apiNote A {@code Builder} checks the components and invariants as
-     * components are added to the builder. The rational for this is to detect
+     * components are added to the builder. The rationale for this is to detect
      * errors as early as possible and not defer all validation to the
-     * {@link #build build} method. A {@code Builder} cannot be used to create
-     * a {@link ModuleDescriptor#isSynthetic() synthetic} module.
+     * {@link #build build} method.
      *
      * @since 9
+     * @spec JPMS
      */
     public static final class Builder {
         final String name;
-        final boolean strict; // true if module names are checked
+        final boolean strict;
+        final Set<Modifier> modifiers;
         final boolean open;
-        final boolean synthetic;
-        boolean automatic;
+        final boolean automatic;
+        final Set<String> packages = new HashSet<>();
         final Map<String, Requires> requires = new HashMap<>();
         final Map<String, Exports> exports = new HashMap<>();
         final Map<String, Opens> opens = new HashMap<>();
-        final Set<String> concealedPackages = new HashSet<>();
         final Set<String> uses = new HashSet<>();
         final Map<String, Provides> provides = new HashMap<>();
         Version version;
@@ -1362,35 +1526,25 @@
         /**
          * Initializes a new builder with the given module name.
          *
-         * @param strict
-         *        Indicates whether module names are checked or not
+         * If {@code strict} is {@code true} then module, package, and class
+         * names are checked to ensure they are legal names. In addition, the
+         * {@link #build buid} method will add "{@code requires java.base}" if
+         * the dependency is not declared.
          */
-        Builder(String name, boolean strict, boolean open, boolean synthetic) {
+        Builder(String name, boolean strict, Set<Modifier> modifiers) {
             this.name = (strict) ? requireModuleName(name) : name;
             this.strict = strict;
-            this.open = open;
-            this.synthetic = synthetic;
-        }
-
-        /* package */ Builder automatic(boolean automatic) {
-            this.automatic = automatic;
-            return this;
+            this.modifiers = modifiers;
+            this.open = modifiers.contains(Modifier.OPEN);
+            this.automatic = modifiers.contains(Modifier.AUTOMATIC);
+            assert !open || !automatic;
         }
 
         /**
-         * Returns the set of packages that are exported (unconditionally or
-         * unconditionally).
+         * Returns a snapshot of the packages in the module.
          */
-        /* package */ Set<String> exportedPackages() {
-            return exports.keySet();
-        }
-
-        /**
-         * Returns the set of packages that are opened (unconditionally or
-         * unconditionally).
-         */
-        /* package */Set<String> openPackages() {
-            return opens.keySet();
+        /* package */ Set<String> packages() {
+            return Collections.unmodifiableSet(packages);
         }
 
         /**
@@ -1406,8 +1560,12 @@
          *         initialized to build
          * @throws IllegalStateException
          *         If the dependence on the module has already been declared
+         *         or this builder is for an automatic module
          */
         public Builder requires(Requires req) {
+            if (automatic)
+                throw new IllegalStateException("Automatic modules cannot declare"
+                                                + " dependences");
             String mn = req.name();
             if (name.equals(mn))
                 throw new IllegalArgumentException("Dependence on self");
@@ -1433,11 +1591,12 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the module name is {@code null}, is not a legal Java
-         *         identifier, or is equal to the module name that this builder
+         *         If the module name is {@code null}, is not a legal module
+         *         name, or is equal to the module name that this builder
          *         was initialized to build
          * @throws IllegalStateException
          *         If the dependence on the module has already been declared
+         *         or this builder is for an automatic module
          */
         public Builder requires(Set<Requires.Modifier> ms,
                                 String mn,
@@ -1448,6 +1607,23 @@
             return requires(new Requires(ms, mn, compiledVersion));
         }
 
+        /* package */Builder requires(Set<Requires.Modifier> ms,
+                                      String mn,
+                                      String compiledVersion) {
+            Version v = null;
+            try {
+                v = Version.parse(compiledVersion);
+            } catch (IllegalArgumentException e) {
+                // for now, drop un-parsable version when non-strict
+                if (strict) throw e;
+            }
+            if (v == null) {
+                return requires(ms, mn);
+            } else {
+                return requires(ms, mn, v);
+            }
+        }
+
         /**
          * Adds a dependence on a module with the given (and possibly empty)
          * set of modifiers.
@@ -1460,11 +1636,12 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the module name is {@code null}, is not a legal Java
-         *         identifier, or is equal to the module name that this builder
+         *         If the module name is {@code null}, is not a legal module
+         *         name, or is equal to the module name that this builder
          *         was initialized to build
          * @throws IllegalStateException
          *         If the dependence on the module has already been declared
+         *         or this builder is for an automatic module
          */
         public Builder requires(Set<Requires.Modifier> ms, String mn) {
             if (strict)
@@ -1481,18 +1658,19 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the module name is {@code null}, is not a legal Java
-         *         identifier, or is equal to the module name that this builder
+         *         If the module name is {@code null}, is not a legal module
+         *         name, or is equal to the module name that this builder
          *         was initialized to build
          * @throws IllegalStateException
          *         If the dependence on the module has already been declared
+         *         or this builder is for an automatic module
          */
         public Builder requires(String mn) {
             return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
         }
 
         /**
-         * Adds an export.
+         * Adds an exported package.
          *
          * @param  e
          *         The export
@@ -1500,29 +1678,27 @@
          * @return This builder
          *
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method or the package is already
-         *         declared as exported
+         *         If the {@link Exports#source package} is already declared as
+         *         exported or this builder is for an automatic module
          */
         public Builder exports(Exports e) {
-            // can't be exported and concealed
+            if (automatic) {
+                throw new IllegalStateException("Automatic modules cannot declare"
+                                                 + " exported packages");
+            }
             String source = e.source();
-            if (concealedPackages.contains(source)) {
-                throw new IllegalStateException("Package " + source
-                                                 + " already declared");
-            }
             if (exports.containsKey(source)) {
                 throw new IllegalStateException("Exported package " + source
                                                  + " already declared");
             }
-
             exports.put(source, e);
+            packages.add(source);
             return this;
         }
 
         /**
-         * Adds an export, with the given (and possibly empty) set of modifiers,
-         * to export a package to a set of target modules.
+         * Adds an exported package with the given (and possibly empty) set of
+         * modifiers. The package is exported to a set of target modules.
          *
          * @param  ms
          *         The set of modifiers
@@ -1534,33 +1710,34 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the package name or any of the target modules is {@code
-         *         null} or is not a legal Java identifier, or the set of
-         *         targets is empty
+         *         If the package name is {@code null} or is not a legal
+         *         package name, the set of target modules is empty, or the set
+         *         of target modules contains a name that is not a legal module
+         *         name
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method or the package is already
-         *         declared as exported
+         *         If the package is already declared as exported
+         *         or this builder is for an automatic module
          */
         public Builder exports(Set<Exports.Modifier> ms,
                                String pn,
                                Set<String> targets)
         {
-            Exports e = new Exports(ms, requirePackageName(pn), targets);
+            Exports e = new Exports(ms, pn, targets);
 
             // check targets
             targets = e.targets();
             if (targets.isEmpty())
                 throw new IllegalArgumentException("Empty target set");
-            if (strict)
+            if (strict) {
+                requirePackageName(e.source());
                 targets.stream().forEach(Checks::requireModuleName);
-
+            }
             return exports(e);
         }
 
         /**
-         * Adds an unqualified export with the given (and possibly empty) set
-         * of modifiers.
+         * Adds an exported package with the given (and possibly empty) set of
+         * modifiers. The package is exported to all modules.
          *
          * @param  ms
          *         The set of modifiers
@@ -1570,20 +1747,23 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the package name is {@code null} or is not a legal Java
-         *         identifier
+         *         If the package name is {@code null} or is not a legal
+         *         package name
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method or the package is already
-         *         declared as exported
+         *         If the package is already declared as exported
+         *         or this builder is for an automatic module
          */
         public Builder exports(Set<Exports.Modifier> ms, String pn) {
-            Exports e = new Exports(ms, requirePackageName(pn), Collections.emptySet());
+            if (strict) {
+                requirePackageName(pn);
+            }
+            Exports e = new Exports(ms, pn, Collections.emptySet());
             return exports(e);
         }
 
         /**
-         * Adds an export to export a package to a set of target modules.
+         * Adds an exported package. The package is exported to a set of target
+         * modules.
          *
          * @param  pn
          *         The package name
@@ -1593,20 +1773,20 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the package name or any of the target modules is {@code
-         *         null} or is not a legal Java identifier, or the set of
-         *         targets is empty
+         *         If the package name is {@code null} or is not a legal
+         *         package name, the set of target modules is empty, or the set
+         *         of target modules contains a name that is not a legal module
+         *         name
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method or the package is already
-         *         declared as exported
+         *         If the package is already declared as exported
+         *         or this builder is for an automatic module
          */
         public Builder exports(String pn, Set<String> targets) {
             return exports(Collections.emptySet(), pn, targets);
         }
 
         /**
-         * Adds an unqualified export.
+         * Adds an exported package. The package is exported to all modules.
          *
          * @param  pn
          *         The package name
@@ -1614,19 +1794,18 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the package name is {@code null} or is not a legal Java
-         *         identifier
+         *         If the package name is {@code null} or is not a legal
+         *         package name
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method or the package is already
-         *         declared as exported
+         *         If the package is already declared as exported
+         *         or this builder is for an automatic module
          */
         public Builder exports(String pn) {
             return exports(Collections.emptySet(), pn);
         }
 
         /**
-         * Adds an <em>opens</em> directive.
+         * Adds an open package.
          *
          * @param  obj
          *         The {@code Opens} object
@@ -1634,35 +1813,28 @@
          * @return This builder
          *
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method, the package is already
-         *         declared as open, or this is a builder for an open module
+         *         If the package is already declared as open, or this is a
+         *         builder for an open module or automatic module
          */
         public Builder opens(Opens obj) {
-            if (open) {
-                throw new IllegalStateException("open modules cannot declare"
-                                                + " open packages");
+            if (open || automatic) {
+                throw new IllegalStateException("Open or automatic modules cannot"
+                                                + " declare open packages");
             }
-
-            // can't be open and concealed
             String source = obj.source();
-            if (concealedPackages.contains(source)) {
-                throw new IllegalStateException("Package " + source
-                                                + " already declared");
-            }
             if (opens.containsKey(source)) {
                 throw new IllegalStateException("Open package " + source
                                                 + " already declared");
             }
-
             opens.put(source, obj);
+            packages.add(source);
             return this;
         }
 
 
         /**
-         * Adds an <em>opens</em> directive, with the given (and possibly empty)
-         * set of modifiers, to open a package to a set of target modules.
+         * Adds an open package with the given (and possibly empty) set of
+         * modifiers. The package is open to a set of target modules.
          *
          * @param  ms
          *         The set of modifiers
@@ -1674,33 +1846,34 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the package name or any of the target modules is {@code
-         *         null} or is not a legal Java identifier, or the set of
-         *         targets is empty
+         *         If the package name is {@code null} or is not a legal
+         *         package name, the set of target modules is empty, or the set
+         *         of target modules contains a name that is not a legal module
+         *         name
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method, the package is already
-         *         declared as open, or this is a builder for an open module
+         *         If the package is already declared as open, or this is a
+         *         builder for an open module or automatic module
          */
         public Builder opens(Set<Opens.Modifier> ms,
                              String pn,
                              Set<String> targets)
         {
-            Opens e = new Opens(ms, requirePackageName(pn), targets);
+            Opens opens = new Opens(ms, pn, targets);
 
             // check targets
-            targets = e.targets();
+            targets = opens.targets();
             if (targets.isEmpty())
                 throw new IllegalArgumentException("Empty target set");
-            if (strict)
+            if (strict) {
+                requirePackageName(opens.source());
                 targets.stream().forEach(Checks::requireModuleName);
-
-            return opens(e);
+            }
+            return opens(opens);
         }
 
         /**
-         * Adds an <em>opens</em> directive to open a package with the given (and
-         * possibly empty) set of modifiers.
+         * Adds an open package with the given (and possibly empty) set of
+         * modifiers. The package is open to all modules.
          *
          * @param  ms
          *         The set of modifiers
@@ -1710,21 +1883,22 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the package name is {@code null} or is not a legal Java
-         *         identifier
+         *         If the package name is {@code null} or is not a legal
+         *         package name
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method, the package is already
-         *         declared as open, or this is a builder for an open module
+         *         If the package is already declared as open, or this is a
+         *         builder for an open module or automatic module
          */
         public Builder opens(Set<Opens.Modifier> ms, String pn) {
-            Opens e = new Opens(ms, requirePackageName(pn), Collections.emptySet());
+            if (strict) {
+                requirePackageName(pn);
+            }
+            Opens e = new Opens(ms, pn, Collections.emptySet());
             return opens(e);
         }
 
         /**
-         * Adds an <em>opens</em> directive to open a package to a set of target
-         * modules.
+         * Adds an open package. The package is open to a set of target modules.
          *
          * @param  pn
          *         The package name
@@ -1734,20 +1908,20 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the package name or any of the target modules is {@code
-         *         null} or is not a legal Java identifier, or the set of
-         *         targets is empty
+         *         If the package name is {@code null} or is not a legal
+         *         package name, the set of target modules is empty, or the set
+         *         of target modules contains a name that is not a legal module
+         *         name
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method, the package is already
-         *         declared as open, or this is a builder for an open module
+         *         If the package is already declared as open, or this is a
+         *         builder for an open module or automatic module
          */
         public Builder opens(String pn, Set<String> targets) {
             return opens(Collections.emptySet(), pn, targets);
         }
 
         /**
-         * Adds an <em>opens</em> directive to open a package.
+         * Adds an open package. The package is open to all modules.
          *
          * @param  pn
          *         The package name
@@ -1755,12 +1929,11 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the package name is {@code null} or is not a legal Java
-         *         identifier
+         *         If the package name is {@code null} or is not a legal
+         *         package name
          * @throws IllegalStateException
-         *         If the package is already declared as a package with the
-         *         {@link #contains contains} method, the package is already
-         *         declared as open, or this is a builder for an open module
+         *         If the package is already declared as open, or this is a
+         *         builder for an open module or automatic module
          */
         public Builder opens(String pn) {
             return opens(Collections.emptySet(), pn);
@@ -1775,12 +1948,16 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If the service type is {@code null} or is not a legal Java
-         *         identifier
+         *         If the service type is {@code null} or not a qualified name of
+         *         a class in a named package
          * @throws IllegalStateException
          *         If a dependency on the service type has already been declared
+         *         or this is a builder for an an automatic module
          */
         public Builder uses(String service) {
+            if (automatic)
+                throw new IllegalStateException("Automatic modules can not declare"
+                                                + " service dependences");
             if (uses.contains(requireServiceTypeName(service)))
                 throw new IllegalStateException("Dependence upon service "
                                                 + service + " already declared");
@@ -1789,7 +1966,9 @@
         }
 
         /**
-         * Provides a service with one or more implementations.
+         * Provides a service with one or more implementations. The package for
+         * each {@link Provides#providers provider} (or provider factory) is
+         * added to the module if not already added.
          *
          * @param  p
          *         The provides
@@ -1801,16 +1980,18 @@
          *         declared
          */
         public Builder provides(Provides p) {
-            String st = p.service();
-            if (provides.containsKey(st))
+            String service = p.service();
+            if (provides.containsKey(service))
                 throw new IllegalStateException("Providers of service "
-                                                + st + " already declared");
-            provides.put(st, p);
+                                                + service + " already declared");
+            provides.put(service, p);
+            p.providers().forEach(name -> packages.add(packageName(name)));
             return this;
         }
 
         /**
-         * Provides implementations of a service.
+         * Provides implementations of a service. The package for each provider
+         * (or provider factory) is added to the module if not already added.
          *
          * @param  service
          *         The service type
@@ -1821,103 +2002,59 @@
          *
          * @throws IllegalArgumentException
          *         If the service type or any of the provider class names is
-         *         {@code null} or is not a legal Java identifier, or the list
-         *         of provider class names is empty
+         *         {@code null} or not a qualified name of a class in a named
+         *         package, or the list of provider class names is empty
          * @throws IllegalStateException
          *         If the providers for the service type have already been
          *         declared
          */
         public Builder provides(String service, List<String> providers) {
-            if (provides.containsKey(service))
-                throw new IllegalStateException("Providers of service "
-                                                + service + " already declared by " + name);
-
-            Provides p = new Provides(requireServiceTypeName(service), providers);
+            Provides p = new Provides(service, providers);
 
             // check providers after the set has been copied.
             List<String> providerNames = p.providers();
             if (providerNames.isEmpty())
                 throw new IllegalArgumentException("Empty providers set");
-            providerNames.forEach(Checks::requireServiceProviderName);
-            provides.put(service, p);
-            return this;
+            if (strict) {
+                requireServiceTypeName(p.service());
+                providerNames.forEach(Checks::requireServiceProviderName);
+            } else {
+                // Disallow service/providers in unnamed package
+                String pn = packageName(service);
+                if (pn.isEmpty()) {
+                    throw new IllegalArgumentException(service
+                                                       + ": unnamed package");
+                }
+                for (String name : providerNames) {
+                    pn = packageName(name);
+                    if (pn.isEmpty()) {
+                        throw new IllegalArgumentException(name
+                                                           + ": unnamed package");
+                    }
+                }
+            }
+            return provides(p);
         }
 
         /**
-         * Provides an implementation of a service.
-         *
-         * @param  service
-         *         The service type
-         * @param  provider
-         *         The provider or provider factory class name
-         *
-         * @return This builder
-         *
-         * @throws IllegalArgumentException
-         *         If the service type or the provider class name is {@code
-         *         null} or is not a legal Java identifier
-         * @throws IllegalStateException
-         *         If the providers for the service type have already been
-         *         declared
-         */
-        public Builder provides(String service, String provider) {
-            if (provider == null)
-                throw new IllegalArgumentException("'provider' is null");
-            return provides(service, List.of(provider));
-        }
-
-        /**
-         * Adds a (possible empty) set of packages to the module
+         * Adds packages to the module. All packages in the set of package names
+         * that are not in the module are added to module.
          *
          * @param  pns
-         *         The set of package names
+         *         The (possibly empty) set of package names
          *
          * @return This builder
          *
          * @throws IllegalArgumentException
          *         If any of the package names is {@code null} or is not a
-         *         legal Java identifier
-         * @throws IllegalStateException
-         *         If any of packages are already declared as packages in
-         *         the module. This includes packages that are already
-         *         declared as exported or open packages.
+         *         legal package name
          */
-        public Builder contains(Set<String> pns) {
-            pns.forEach(this::contains);
-            return this;
-        }
-
-        /**
-         * Adds a package to the module.
-         *
-         * @param  pn
-         *         The package name
-         *
-         * @return This builder
-         *
-         * @throws IllegalArgumentException
-         *         If the package name is {@code null}, or is not a legal Java
-         *         identifier
-         * @throws IllegalStateException
-         *         If the package is already declared as a package in the
-         *         module. This includes the package already declared as an
-         *         exported or open package.
-         */
-        public Builder contains(String pn) {
-            Checks.requirePackageName(pn);
-            if (concealedPackages.contains(pn)) {
-                throw new IllegalStateException("Package " + pn
-                                                + " already declared");
+        public Builder packages(Set<String> pns) {
+            if (strict) {
+                pns = new HashSet<>(pns);
+                pns.forEach(Checks::requirePackageName);
             }
-            if (exports.containsKey(pn)) {
-                throw new IllegalStateException("Exported package "
-                                                + pn + " already declared");
-            }
-            if (opens.containsKey(pn)) {
-                throw new IllegalStateException("Open package "
-                                                 + pn + " already declared");
-            }
-            concealedPackages.add(pn);
+            this.packages.addAll(pns);
             return this;
         }
 
@@ -1937,22 +2074,35 @@
         /**
          * Sets the module version.
          *
-         * @param  v
+         * @param  vs
          *         The version string to parse
          *
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If {@code v} is null or cannot be parsed as a version string
+         *         If {@code vs} is {@code null} or cannot be parsed as a
+         *         version string
          *
          * @see Version#parse(String)
          */
-        public Builder version(String v) {
-            return version(Version.parse(v));
+        public Builder version(String vs) {
+            Version v;
+            if (strict) {
+                v = Version.parse(vs);
+            } else {
+                try {
+                    v = Version.parse(vs);
+                } catch (IllegalArgumentException ignore) {
+                    // for now, ignore when non-strict
+                    return this;
+                }
+            }
+            return version(v);
         }
 
         /**
-         * Sets the module main class.
+         * Sets the module main class. The package for the main class is added
+         * to the module if not already added.
          *
          * @param  mc
          *         The module main class
@@ -1960,10 +2110,24 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If {@code mainClass} is null or is not a legal Java identifier
+         *         If {@code mainClass} is {@code null} or not a qualified
+         *         name of a class in a named package
          */
         public Builder mainClass(String mc) {
-            mainClass = requireBinaryName("main class name", mc);
+            String pn;
+            if (strict) {
+                mc = requireQualifiedClassName("main class name", mc);
+                pn = packageName(mc);
+                assert !pn.isEmpty();
+            } else {
+                // Disallow main class in unnamed package
+                pn = packageName(mc);
+                if (pn.isEmpty()) {
+                    throw new IllegalArgumentException(mc + ": unnamed package");
+                }
+            }
+            mainClass = mc;
+            packages.add(pn);
             return this;
         }
 
@@ -1976,7 +2140,7 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If {@code name} is null or the empty String
+         *         If {@code name} is {@code null} or the empty String
          */
         public Builder osName(String name) {
             if (name == null || name.isEmpty())
@@ -1994,7 +2158,7 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If {@code name} is null or the empty String
+         *         If {@code name} is {@code null} or the empty String
          */
         public Builder osArch(String arch) {
             if (arch == null || arch.isEmpty())
@@ -2012,7 +2176,7 @@
          * @return This builder
          *
          * @throws IllegalArgumentException
-         *         If {@code name} is null or the empty String
+         *         If {@code name} is {@code null} or the empty String
          */
         public Builder osVersion(String version) {
             if (version == null || version.isEmpty())
@@ -2024,26 +2188,34 @@
         /**
          * Builds and returns a {@code ModuleDescriptor} from its components.
          *
+         * <p> The module will require "{@code java.base}" even if the dependence
+         * has not been declared (the exception is when building a module named
+         * "{@code java.base}" as it cannot require itself). The dependence on
+         * "{@code java.base}" will have the {@link
+         * java.lang.module.ModuleDescriptor.Requires.Modifier#MANDATED MANDATED}
+         * modifier if the dependence was not declared. </p>
+         *
          * @return The module descriptor
          */
         public ModuleDescriptor build() {
             Set<Requires> requires = new HashSet<>(this.requires.values());
-
-            Set<String> packages = new HashSet<>();
-            packages.addAll(exports.keySet());
-            packages.addAll(opens.keySet());
-            packages.addAll(concealedPackages);
-
             Set<Exports> exports = new HashSet<>(this.exports.values());
             Set<Opens> opens = new HashSet<>(this.opens.values());
 
+            // add dependency on java.base
+            if (strict
+                    && !name.equals("java.base")
+                    && !this.requires.containsKey("java.base")) {
+                requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
+                                          "java.base",
+                                          null));
+            }
+
             Set<Provides> provides = new HashSet<>(this.provides.values());
 
             return new ModuleDescriptor(name,
                                         version,
-                                        open,
-                                        automatic,
-                                        synthetic,
+                                        modifiers,
                                         requires,
                                         exports,
                                         opens,
@@ -2062,16 +2234,20 @@
      * Compares this module descriptor to another.
      *
      * <p> Two {@code ModuleDescriptor} objects are compared by comparing their
-     * module name lexicographically.  Where the module names are equal then
-     * the versions, if present, are compared. </p>
-     *
-     * @apiNote For now, the natural ordering is not consistent with equals.
-     * If two module descriptors have equal module names, equal versions if
-     * present, but their corresponding components are not equal, then they
-     * will be considered equal by this method.
+     * module names lexicographically. Where the module names are equal then the
+     * module versions are compared. When comparing the module versions then a
+     * module descriptor with a version is considered to succeed a module
+     * descriptor that does not have a version. Where the module names are equal
+     * and the versions are equal (or not present in both), then the set of
+     * modifiers are compared. Sets of modifiers are compared by comparing
+     * a <em>binary value</em> computed for each set. If a modifier is present
+     * in the set then the bit at the position of its ordinal is {@code 1}
+     * in the binary value, otherwise {@code 0}. If the two set of modifiers
+     * are also equal then the other components of the module descriptors are
+     * compared in a manner that is consistent with {@code equals}. </p>
      *
      * @param  that
-     *         The object to which this module descriptor is to be compared
+     *         The module descriptor to compare
      *
      * @return A negative integer, zero, or a positive integer if this module
      *         descriptor is less than, equal to, or greater than the given
@@ -2079,16 +2255,50 @@
      */
     @Override
     public int compareTo(ModuleDescriptor that) {
+        if (this == that) return 0;
+
         int c = this.name().compareTo(that.name());
         if (c != 0) return c;
-        if (version == null) {
-            if (that.version == null)
-                return 0;
-            return -1;
-        }
-        if (that.version == null)
-            return +1;
-        return version.compareTo(that.version);
+
+        c = compare(this.version, that.version);
+        if (c != 0) return c;
+
+        long v1 = modsValue(this.modifiers());
+        long v2 = modsValue(that.modifiers());
+        c = Long.compare(v1, v2);
+        if (c != 0) return c;
+
+        c = compare(this.requires, that.requires);
+        if (c != 0) return c;
+
+        c = compare(this.packages, that.packages);
+        if (c != 0) return c;
+
+        c = compare(this.exports, that.exports);
+        if (c != 0) return c;
+
+        c = compare(this.opens, that.opens);
+        if (c != 0) return c;
+
+        c = compare(this.uses, that.uses);
+        if (c != 0) return c;
+
+        c = compare(this.provides, that.provides);
+        if (c != 0) return c;
+
+        c = compare(this.mainClass, that.mainClass);
+        if (c != 0) return c;
+
+        c = compare(this.osName, that.osName);
+        if (c != 0) return c;
+
+        c = compare(this.osArch, that.osArch);
+        if (c != 0) return c;
+
+        c = compare(this.osVersion, that.osVersion);
+        if (c != 0) return c;
+
+        return 0;
     }
 
     /**
@@ -2115,10 +2325,9 @@
             return false;
         ModuleDescriptor that = (ModuleDescriptor)ob;
         return (name.equals(that.name)
-                && open == that.open
-                && automatic == that.automatic
-                && synthetic == that.synthetic
+                && modifiers.equals(that.modifiers)
                 && requires.equals(that.requires)
+                && Objects.equals(packages, that.packages)
                 && exports.equals(that.exports)
                 && opens.equals(that.opens)
                 && uses.equals(that.uses)
@@ -2127,12 +2336,9 @@
                 && Objects.equals(mainClass, that.mainClass)
                 && Objects.equals(osName, that.osName)
                 && Objects.equals(osArch, that.osArch)
-                && Objects.equals(osVersion, that.osVersion)
-                && Objects.equals(packages, that.packages));
+                && Objects.equals(osVersion, that.osVersion));
     }
 
-    private transient int hash;  // cached hash code
-
     /**
      * Computes a hash code for this module descriptor.
      *
@@ -2147,10 +2353,9 @@
         int hc = hash;
         if (hc == 0) {
             hc = name.hashCode();
-            hc = hc * 43 + Boolean.hashCode(open);
-            hc = hc * 43 + Boolean.hashCode(automatic);
-            hc = hc * 43 + Boolean.hashCode(synthetic);
+            hc = hc * 43 + Objects.hashCode(modifiers);
             hc = hc * 43 + requires.hashCode();
+            hc = hc * 43 + Objects.hashCode(packages);
             hc = hc * 43 + exports.hashCode();
             hc = hc * 43 + opens.hashCode();
             hc = hc * 43 + uses.hashCode();
@@ -2160,18 +2365,18 @@
             hc = hc * 43 + Objects.hashCode(osName);
             hc = hc * 43 + Objects.hashCode(osArch);
             hc = hc * 43 + Objects.hashCode(osVersion);
-            hc = hc * 43 + Objects.hashCode(packages);
             if (hc == 0)
                 hc = -1;
             hash = hc;
         }
         return hc;
     }
+    private transient int hash;  // cached hash code
 
     /**
-     * Returns a string describing this descriptor.
+     * <p> Returns a string describing the module. </p>
      *
-     * @return A string describing this descriptor
+     * @return A string describing the module
      */
     @Override
     public String toString() {
@@ -2201,31 +2406,50 @@
      *
      * @param  name
      *         The module name
+     * @param  ms
+     *         The set of module modifiers
      *
      * @return A new builder
      *
      * @throws IllegalArgumentException
-     *         If the module name is {@code null} or is not a legal Java
-     *         identifier
+     *         If the module name is {@code null} or is not a legal module
+     *         name, or the set of modifiers contains {@link
+     *         Modifier#AUTOMATIC AUTOMATIC} with other modifiers
      */
-    public static Builder module(String name) {
-        return new Builder(name, true, false, false);
+    public static Builder newModule(String name, Set<Modifier> ms) {
+        Set<Modifier> mods = new HashSet<>(ms);
+        if (mods.contains(Modifier.AUTOMATIC) && mods.size() > 1)
+            throw new IllegalArgumentException("AUTOMATIC cannot be used with"
+                                               + " other modifiers");
+
+        return new Builder(name, true, mods);
+    }
+
+    /**
+     * Instantiates a builder to build a module descriptor for a <em>normal</em>
+     * module. This method is equivalent to invoking {@link #newModule(String,Set)
+     * newModule} with an empty set of {@link ModuleDescriptor.Modifier modifiers}.
+     *
+     * @param  name
+     *         The module name
+     *
+     * @return A new builder
+     *
+     * @throws IllegalArgumentException
+     *         If the module name is {@code null} or is not a legal module
+     *         name
+     */
+    public static Builder newModule(String name) {
+        return new Builder(name, true, Set.of());
     }
 
     /**
      * Instantiates a builder to build a module descriptor for an open module.
-     * An open module does not declare any open packages but the resulting
-     * module is treated as if all packages are open.
+     * This method is equivalent to invoking {@link #newModule(String,Set)
+     * newModule} with the {@link ModuleDescriptor.Modifier#OPEN OPEN} modifier.
      *
-     * <p> As an example, the following creates a module descriptor for an open
-     * name "{@code m}" containing two packages, one of which is exported. </p>
-     * <pre>{@code
-     *     ModuleDescriptor descriptor = ModuleDescriptor.openModule("m")
-     *         .requires("java.base")
-     *         .exports("p")
-     *         .contains("q")
-     *         .build();
-     * }</pre>
+     * <p> The builder for an open module cannot be used to declare any open
+     * packages. </p>
      *
      * @param  name
      *         The module name
@@ -2233,19 +2457,22 @@
      * @return A new builder that builds an open module
      *
      * @throws IllegalArgumentException
-     *         If the module name is {@code null} or is not a legal Java
-     *         identifier
+     *         If the module name is {@code null} or is not a legal module
+     *         name
      */
-    public static Builder openModule(String name) {
-        return new Builder(name, true, true, false);
+    public static Builder newOpenModule(String name) {
+        return new Builder(name, true, Set.of(Modifier.OPEN));
     }
 
     /**
      * Instantiates a builder to build a module descriptor for an automatic
-     * module. Automatic modules receive special treatment during resolution
-     * (see {@link Configuration}) so that they read all other modules. When
-     * Instantiated in the Java virtual machine as a {@link java.lang.reflect.Module}
-     * then the Module reads every unnamed module in the Java virtual machine.
+     * module. This method is equivalent to invoking {@link #newModule(String,Set)
+     * newModule} with the {@link ModuleDescriptor.Modifier#AUTOMATIC AUTOMATIC}
+     * modifier.
+     *
+     * <p> The builder for an automatic module cannot be used to declare module
+     * or service dependences. It also cannot be used to declare any exported
+     * or open packages. </p>
      *
      * @param  name
      *         The module name
@@ -2253,13 +2480,13 @@
      * @return A new builder that builds an automatic module
      *
      * @throws IllegalArgumentException
-     *         If the module name is {@code null} or is not a legal Java
-     *         identifier
+     *         If the module name is {@code null} or is not a legal module
+     *         name
      *
      * @see ModuleFinder#of(Path[])
      */
-    public static Builder automaticModule(String name) {
-        return new Builder(name, true, false, false).automatic(true);
+    public static Builder newAutomaticModule(String name) {
+        return new Builder(name, true, Set.of(Modifier.AUTOMATIC));
     }
 
 
@@ -2269,8 +2496,12 @@
      *
      * <p> If the descriptor encoded in the input stream does not indicate a
      * set of packages in the module then the {@code packageFinder} will be
-     * invoked. If the {@code packageFinder} throws an {@link UncheckedIOException}
-     * then {@link IOException} cause will be re-thrown. </p>
+     * invoked. The set of packages that the {@code packageFinder} returns
+     * must include all the packages that the module exports, opens, as well
+     * as the packages of the service implementations that the module provides,
+     * and the package of the main class (if the module has a main class). If
+     * the {@code packageFinder} throws an {@link UncheckedIOException} then
+     * {@link IOException} cause will be re-thrown. </p>
      *
      * <p> If there are bytes following the module descriptor then it is
      * implementation specific as to whether those bytes are read, ignored,
@@ -2292,7 +2523,9 @@
      * @return The module descriptor
      *
      * @throws InvalidModuleDescriptorException
-     *         If an invalid module descriptor is detected
+     *         If an invalid module descriptor is detected or the set of
+     *         packages returned by the {@code packageFinder} does not include
+     *         all of the packages obtained from the module descriptor
      * @throws IOException
      *         If an I/O error occurs reading from the input stream or {@code
      *         UncheckedIOException} is thrown by the package finder
@@ -2305,8 +2538,12 @@
     }
 
     /**
-     * Reads the binary form of a module declaration from an input stream
-     * as a module descriptor.
+     * Reads the binary form of a module declaration from an input stream as a
+     * module descriptor. This method works exactly as specified by the 2-arg
+     * {@link #read(InputStream,Supplier) read} method with the exception that
+     * a packager finder is not used to find additional packages when the
+     * module descriptor read from the stream does not indicate the set of
+     * packages.
      *
      * @param  in
      *         The input stream
@@ -2327,7 +2564,13 @@
      * as a module descriptor.
      *
      * <p> If the descriptor encoded in the byte buffer does not indicate a
-     * set of packages then the {@code packageFinder} will be invoked. </p>
+     * set of packages in the module then the {@code packageFinder} will be
+     * invoked. The set of packages that the {@code packageFinder} returns
+     * must include all the packages that the module exports, opens, as well
+     * as the packages of the service implementations that the module provides,
+     * and the package of the main class (if the module has a main class). If
+     * the {@code packageFinder} throws an {@link UncheckedIOException} then
+     * {@link IOException} cause will be re-thrown. </p>
      *
      * <p> The module descriptor is read from the buffer stating at index
      * {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
@@ -2353,7 +2596,9 @@
      * @return The module descriptor
      *
      * @throws InvalidModuleDescriptorException
-     *         If an invalid module descriptor is detected
+     *         If an invalid module descriptor is detected or the set of
+     *         packages returned by the {@code packageFinder} does not include
+     *         all of the packages obtained from the module descriptor
      */
     public static ModuleDescriptor read(ByteBuffer bb,
                                         Supplier<Set<String>> packageFinder)
@@ -2362,8 +2607,11 @@
     }
 
     /**
-     * Reads the binary form of a module declaration from a byte buffer
-     * as a module descriptor.
+     * Reads the binary form of a module declaration from a byte buffer as a
+     * module descriptor. This method works exactly as specified by the 2-arg
+     * {@link #read(ByteBuffer,Supplier) read} method with the exception that a
+     * packager finder is not used to find additional packages when the module
+     * descriptor encoded in the buffer does not indicate the set of packages.
      *
      * @param  bb
      *         The byte buffer
@@ -2398,6 +2646,11 @@
         }
     }
 
+    private static String packageName(String cn) {
+        int index = cn.lastIndexOf('.');
+        return (index == -1) ? "" : cn.substring(0, index);
+    }
+
     /**
      * Returns a string containing the given set of modifiers and label.
      */
@@ -2407,6 +2660,36 @@
                 .collect(Collectors.joining(" "));
     }
 
+    private static <T extends Object & Comparable<? super T>>
+    int compare(T obj1, T obj2) {
+        if (obj1 != null) {
+            return (obj2 != null) ? obj1.compareTo(obj2) : 1;
+        } else {
+            return (obj2 == null) ? 0 : -1;
+        }
+    }
+
+    /**
+     * Compares two sets of {@code Comparable} objects.
+     */
+    @SuppressWarnings("unchecked")
+    private static <T extends Object & Comparable<? super T>>
+    int compare(Set<T> s1, Set<T> s2) {
+        T[] a1 = (T[]) s1.toArray();
+        T[] a2 = (T[]) s2.toArray();
+        Arrays.sort(a1);
+        Arrays.sort(a2);
+        return Arrays.compare(a1, a2);
+    }
+
+    private static <E extends Enum<E>> long modsValue(Set<E> set) {
+        long value = 0;
+        for (Enum<E> e : set) {
+            value += 1 << e.ordinal();
+        }
+        return value;
+    }
+
     static {
         /**
          * Setup the shared secret to allow code in other packages access
@@ -2417,19 +2700,21 @@
                 @Override
                 public Builder newModuleBuilder(String mn,
                                                 boolean strict,
-                                                boolean open,
-                                                boolean synthetic) {
-                    return new Builder(mn, strict, open, synthetic);
+                                                Set<ModuleDescriptor.Modifier> modifiers) {
+                    return new Builder(mn, strict, modifiers);
                 }
 
                 @Override
-                public Set<String> exportedPackages(ModuleDescriptor.Builder builder) {
-                    return builder.exportedPackages();
+                public Set<String> packages(ModuleDescriptor.Builder builder) {
+                    return builder.packages();
                 }
 
                 @Override
-                public Set<String> openPackages(ModuleDescriptor.Builder builder) {
-                    return builder.openPackages();
+                public void requires(ModuleDescriptor.Builder builder,
+                                     Set<Requires.Modifier> ms,
+                                     String mn,
+                                     String compiledVersion) {
+                    builder.requires(ms, mn, compiledVersion);
                 }
 
                 @Override
@@ -2467,22 +2752,9 @@
                 }
 
                 @Override
-                public Version newVersion(String v) {
-                    return new Version(v);
-                }
-
-                @Override
-                public ModuleDescriptor newModuleDescriptor(ModuleDescriptor md,
-                                                            Set<String> pkgs) {
-                    return new ModuleDescriptor(md, pkgs);
-                }
-
-                @Override
                 public ModuleDescriptor newModuleDescriptor(String name,
                                                             Version version,
-                                                            boolean open,
-                                                            boolean automatic,
-                                                            boolean synthetic,
+                                                            Set<ModuleDescriptor.Modifier> modifiers,
                                                             Set<Requires> requires,
                                                             Set<Exports> exports,
                                                             Set<Opens> opens,
@@ -2496,9 +2768,7 @@
                                                             int hashCode) {
                     return new ModuleDescriptor(name,
                                                 version,
-                                                open,
-                                                automatic,
-                                                synthetic,
+                                                modifiers,
                                                 requires,
                                                 exports,
                                                 opens,
@@ -2514,12 +2784,12 @@
                 }
 
                 @Override
-                public Configuration resolveRequiresAndUses(ModuleFinder finder,
-                                                            Collection<String> roots,
-                                                            boolean check,
-                                                            PrintStream traceOutput)
+                public Configuration resolveAndBind(ModuleFinder finder,
+                                                    Collection<String> roots,
+                                                    boolean check,
+                                                    PrintStream traceOutput)
                 {
-                    return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
+                    return Configuration.resolveAndBind(finder, roots, check, traceOutput);
                 }
             });
     }
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -42,14 +42,15 @@
 import java.util.Optional;
 import java.util.Set;
 
+import jdk.internal.module.ModuleBootstrap;
 import jdk.internal.module.ModulePath;
 import jdk.internal.module.SystemModuleFinder;
 import sun.security.action.GetPropertyAction;
 
 /**
  * A finder of modules. A {@code ModuleFinder} is used to find modules during
- * <a href="Configuration.html#resolution">resolution</a> or
- * <a href="Configuration.html#servicebinding">service binding</a>.
+ * <a href="package-summary.html#resolution">resolution</a> or
+ * <a href="package-summary.html#servicebinding">service binding</a>.
  *
  * <p> A {@code ModuleFinder} can only find one module with a given name. A
  * {@code ModuleFinder} that finds modules in a sequence of directories, for
@@ -85,6 +86,7 @@
  * <p> A {@code ModuleFinder} is not required to be thread safe. </p>
  *
  * @since 9
+ * @spec JPMS
  */
 
 public interface ModuleFinder {
@@ -124,8 +126,8 @@
      * to find that module. </p>
      *
      * @apiNote This is important to have for methods such as {@link
-     * Configuration#resolveRequiresAndUses resolveRequiresAndUses} that need
-     * to scan the module path to find modules that provide a specific service.
+     * Configuration#resolveAndBind resolveAndBind} that need to scan the
+     * module path to find modules that provide a specific service.
      *
      * @return The set of all module references that this finder locates
      *
@@ -172,7 +174,8 @@
         } else {
             Path mlib = Paths.get(home, "modules");
             if (Files.isDirectory(mlib)) {
-                return of(mlib);
+                // exploded build may be patched
+                return ModulePath.of(ModuleBootstrap.patcher(), mlib);
             } else {
                 throw new InternalError("Unable to detect the run-time image");
             }
@@ -198,13 +201,9 @@
      *
      * <p> If an element is a path to a directory of modules then each entry in
      * the directory is a packaged module or the top-level directory of an
-     * exploded module. The module finder's {@link #find(String) find} or
-     * {@link #findAll() findAll} methods throw {@link FindException} if a
-     * directory containing more than one module with the same name is
-     * encountered. </p>
-     *
-     * <p> If an element in the array is a path to a directory, and that
-     * directory contains a file named {@code module-info.class}, then the
+     * exploded module. It it an error if a directory contains more than one
+     * module with the same name. If an element is a path to a directory, and
+     * that directory contains a file named {@code module-info.class}, then the
      * directory is treated as an exploded module rather than a directory of
      * modules. </p>
      *
@@ -214,9 +213,8 @@
      * entry in a {@link java.util.jar.JarFile#isMultiRelease() multi-release}
      * JAR file) is a modular JAR and is an <em>explicit module</em>.
      * A JAR file that does not have a {@code module-info.class} in the
-     * top-level directory is an {@link ModuleDescriptor#isAutomatic automatic}
-     * module. The {@link ModuleDescriptor} for an automatic module is created as
-     * follows:
+     * top-level directory is created as an automatic module. The components
+     * for the automatic module are derived as follows:
      *
      * <ul>
      *
@@ -248,46 +246,48 @@
      *
      *     </ul></li>
      *
-     *     <li><p> It {@link ModuleDescriptor#requires() requires} {@code
-     *     java.base}. </p></li>
-     *
-     *     <li><p> The set of packages in the module is derived from the names
-     *     of non-directory entries in the JAR file. A candidate package name
-     *     is derived from an entry using the characters up to, but not
-     *     including, the last forward slash. All remaining forward slashes are
-     *     replaced with dot ({@code "."}). If the resulting string is a valid
-     *     Java identifier then it is assumed to be a package name. For example,
-     *     if the JAR file contains an entry "{@code p/q/Foo.class}" then the
-     *     package name derived is "{@code p.q}". All packages are {@link
-     *     ModuleDescriptor#exports() exported}. </p></li>
+     *     <li><p> The set of packages in the module is derived from the
+     *     non-directory entries in the JAR file that have names ending in
+     *     "{@code .class}". A candidate package name is derived from the name
+     *     using the characters up to, but not including, the last forward slash.
+     *     All remaining forward slashes are replaced with dot ({@code "."}). If
+     *     the resulting string is a legal package name then it is assumed to be
+     *     a package name. For example, if the JAR file contains the entry
+     *     "{@code p/q/Foo.class}" then the package name derived is
+     *     "{@code p.q}".</p></li>
      *
      *     <li><p> The contents of entries starting with {@code
      *     META-INF/services/} are assumed to be service configuration files
      *     (see {@link java.util.ServiceLoader}). If the name of a file
-     *     (that follows {@code META-INF/services/}) is a legal Java identifier
-     *     then it is assumed to be the fully-qualified binary name of a
-     *     service type. The entries in the file are assumed to be the
-     *     fully-qualified binary names of provider classes. </p></li>
+     *     (that follows {@code META-INF/services/}) is a legal class name
+     *     then it is assumed to be the fully-qualified class name of a service
+     *     type. The entries in the file are assumed to be the fully-qualified
+     *     class names of provider classes. </p></li>
      *
      *     <li><p> If the JAR file has a {@code Main-Class} attribute in its
-     *     main manifest then its value is the {@link
+     *     main manifest then its value is the module {@link
      *     ModuleDescriptor#mainClass() main class}. </p></li>
      *
      * </ul>
      *
      * <p> If a {@code ModuleDescriptor} cannot be created (by means of the
      * {@link ModuleDescriptor.Builder ModuleDescriptor.Builder} API) for an
-     * automatic module then {@code FindException} is thrown. This can arise,
-     * for example, when a legal Java identifier name cannot be derived from
-     * the file name of the JAR file or where the JAR file contains a {@code
-     * .class} in the top-level directory of the JAR file. </p>
+     * automatic module then {@code FindException} is thrown. This can arise
+     * when a legal module name cannot be derived from the file name of the JAR
+     * file, where the JAR file contains a {@code .class} in the top-level
+     * directory of the JAR file, where an entry in a service configuration
+     * file is not a legal class name or its package name is not in the set of
+     * packages derived for the module, or where the module main class is not
+     * a legal class name or its package is not in the module. </p>
      *
      * <p> In addition to JAR files, an implementation may also support modules
-     * that are packaged in other implementation specific module formats. When
-     * a file is encountered that is not recognized as a packaged module then
-     * {@code FindException} is thrown. An implementation may choose to ignore
-     * some files, {@link java.nio.file.Files#isHidden hidden} files for
-     * example. Paths to files that do not exist are always ignored. </p>
+     * that are packaged in other implementation specific module formats. If
+     * an element in the array specified to this method is a path to a directory
+     * of modules then entries in the directory that not recognized as modules
+     * are ignored. If an element in the array is a path to a packaged module
+     * that is not recognized then a {@code FindException} is thrown when the
+     * file is encountered. Paths to files that do not exist are always ignored.
+     * </p>
      *
      * <p> As with automatic modules, the contents of a packaged or exploded
      * module may need to be <em>scanned</em> in order to determine the packages
@@ -325,7 +325,7 @@
             };
         }
 
-        return new ModulePath(entries);
+        return ModulePath.of(entries);
     }
 
     /**
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java	Fri Feb 10 08:57:42 2017 -0800
@@ -45,7 +45,7 @@
  * module. A module reader is also intended to be used by {@code ClassLoader}
  * implementations that load classes and resources from modules. </p>
  *
- * <p> A resource in a module is identified by a name that is a
+ * <p> A resource in a module is identified by an abstract name that is a
  * '{@code /}'-separated path string. For example, module {@code java.base} may
  * have a resource "{@code java/lang/Object.class}" that, by convention, is the
  * class file for {@code java.lang.Object}. </p>
@@ -61,8 +61,18 @@
  * open}, {@link #read read}, and {@link #list list} methods may throw {@code
  * SecurityException} if access is denied by the security manager. </p>
  *
+ * @implSpec Implementations of {@code ModuleReader} should take great care
+ * when translating an abstract resource name to the location of a resource in
+ * a packaged module or on the file system. Implementations are advised to
+ * treat resource names with elements such as '{@code .},  '{@code ..}',
+ * elements containing file separators, or empty elements as "not found". More
+ * generally, if the resource name is not in the stream of elements that the
+ * {@code list} method returns then the resource should be treated as "not
+ * found" to avoid inconsistencies.
+ *
  * @see ModuleReference
  * @since 9
+ * @spec JPMS
  */
 
 public interface ModuleReader extends Closeable {
@@ -148,6 +158,9 @@
      *         If an I/O error occurs or the module reader is closed
      * @throws SecurityException
      *         If denied by the security manager
+     * @throws OutOfMemoryError
+     *         If the resource is larger than {@code Integer.MAX_VALUE},
+     *         the maximum capacity of a byte buffer
      *
      * @see ClassLoader#defineClass(String, ByteBuffer, java.security.ProtectionDomain)
      */
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java	Fri Feb 10 08:57:42 2017 -0800
@@ -44,6 +44,7 @@
  * @see ModuleFinder
  * @see ModuleReader
  * @since 9
+ * @spec JPMS
  */
 
 public abstract class ModuleReference {
@@ -76,7 +77,7 @@
     /**
      * Returns the location of this module's content, if known.
      *
-     * <p> This URI, when present, is used as the {@linkplain
+     * <p> This URI, when present, can be used as the {@linkplain
      * java.security.CodeSource#getLocation location} value of a {@link
      * java.security.CodeSource CodeSource} so that a module's classes can be
      * granted specific permissions when loaded by a {@link
--- a/jdk/src/java.base/share/classes/java/lang/module/ResolutionException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/ResolutionException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -26,10 +26,12 @@
 package java.lang.module;
 
 /**
- * Thrown when resolving a set of modules or binding fails.
+ * Thrown when resolving a set of modules, or resolving a set of modules with
+ * service binding, fails.
  *
  * @see Configuration
  * @since 9
+ * @spec JPMS
  */
 public class ResolutionException extends RuntimeException {
     private static final long serialVersionUID = -1031186845316729450L;
--- a/jdk/src/java.base/share/classes/java/lang/module/ResolvedModule.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/ResolvedModule.java	Fri Feb 10 08:57:42 2017 -0800
@@ -37,6 +37,7 @@
  * module's content.
  *
  * @since 9
+ * @spec JPMS
  * @see Configuration#modules()
  */
 public final class ResolvedModule {
--- a/jdk/src/java.base/share/classes/java/lang/module/Resolver.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/Resolver.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -49,8 +49,8 @@
 import jdk.internal.module.ModuleReferenceImpl;
 
 /**
- * The resolver used by {@link Configuration#resolveRequires} and
- * {@link Configuration#resolveRequiresAndUses}.
+ * The resolver used by {@link Configuration#resolve} and {@link
+ * Configuration#resolveAndBind}.
  *
  * @implNote The resolver is used at VM startup and so deliberately avoids
  * using lambda and stream usages in code paths used during startup.
@@ -66,7 +66,19 @@
     // maps module name to module reference
     private final Map<String, ModuleReference> nameToReference = new HashMap<>();
 
+    // module constraints on target platform
+    private String osName;
+    private String osArch;
+    private String osVersion;
 
+    String osName() { return osName; }
+    String osArch() { return osArch; }
+    String osVersion() { return osVersion; }
+
+    /**
+     * @throws IllegalArgumentException if there are more than one parent and
+     *         the constraints on the target platform conflict
+     */
     Resolver(ModuleFinder beforeFinder,
              List<Configuration> parents,
              ModuleFinder afterFinder,
@@ -75,15 +87,54 @@
         this.parents = parents;
         this.afterFinder = afterFinder;
         this.traceOutput = traceOutput;
+
+        // record constraints on target platform, checking that they don't conflict
+        for (Configuration parent : parents) {
+            String value = parent.osName();
+            if (value != null) {
+                if (osName == null) {
+                    osName = value;
+                } else {
+                    if (!value.equals(osName)) {
+                        failParentConflict("Operating System", osName, value);
+                    }
+                }
+            }
+            value = parent.osArch();
+            if (value != null) {
+                if (osArch == null) {
+                    osArch = value;
+                } else {
+                    if (!value.equals(osArch)) {
+                        failParentConflict("OS architecture", osArch, value);
+                    }
+                }
+            }
+            value = parent.osVersion();
+            if (value != null) {
+                if (osVersion == null) {
+                    osVersion  = value;
+                } else {
+                    if (!value.equals(osVersion)) {
+                        failParentConflict("OS version", osVersion, value);
+                    }
+                }
+            }
+        }
     }
 
+    private void failParentConflict(String constraint, String s1, String s2) {
+        String msg = "Parents have conflicting constraints on target "
+                     + constraint + ": " + s1 + ", " + s2;
+        throw new IllegalArgumentException(msg);
+    }
 
     /**
      * Resolves the given named modules.
      *
      * @throws ResolutionException
      */
-    Resolver resolveRequires(Collection<String> roots) {
+    Resolver resolve(Collection<String> roots) {
 
         // create the visit stack to get us started
         Deque<ModuleDescriptor> q = new ArrayDeque<>();
@@ -100,7 +151,7 @@
 
                 mref = findWithAfterFinder(root);
                 if (mref == null) {
-                    fail("Module %s not found", root);
+                    findFail("Module %s not found", root);
                 }
             }
 
@@ -109,8 +160,7 @@
                 mref.location().ifPresent(uri -> trace("  (%s)", uri));
             }
 
-            assert mref.descriptor().name().equals(root);
-            nameToReference.put(root, mref);
+            addFoundModule(mref);
             q.push(mref.descriptor());
         }
 
@@ -152,19 +202,19 @@
 
                     mref = findWithAfterFinder(dn);
                     if (mref == null) {
-                        fail("Module %s not found, required by %s",
-                                dn, descriptor.name());
+                        findFail("Module %s not found, required by %s",
+                                 dn, descriptor.name());
                     }
                 }
 
                 if (!nameToReference.containsKey(dn)) {
-                    nameToReference.put(dn, mref);
+                    addFoundModule(mref);
                     q.offer(mref.descriptor());
                     resolved.add(mref.descriptor());
 
                     if (isTracing()) {
                         trace("Module %s located, required by %s",
-                                dn, descriptor.name());
+                              dn, descriptor.name());
                         mref.location().ifPresent(uri -> trace("  (%s)", uri));
                     }
                 }
@@ -181,7 +231,7 @@
      * Augments the set of resolved modules with modules induced by the
      * service-use relation.
      */
-    Resolver resolveUses() {
+    Resolver bind() {
 
         // Scan the finders for all available service provider modules. As
         // java.base uses services then then module finders will be scanned
@@ -246,7 +296,7 @@
                                             mref.location()
                                                 .ifPresent(uri -> trace("  (%s)", uri));
                                         }
-                                        nameToReference.put(pn, mref);
+                                        addFoundModule(mref);
                                         q.push(provider);
                                     }
                                 }
@@ -264,6 +314,81 @@
 
 
     /**
+     * Add the module to the nameToReference map. Also check any constraints on
+     * the target platform with the constraints of other modules.
+     */
+    private void addFoundModule(ModuleReference mref) {
+        ModuleDescriptor descriptor = mref.descriptor();
+        nameToReference.put(descriptor.name(), mref);
+
+        if (descriptor.osName().isPresent()
+                || descriptor.osArch().isPresent()
+                || descriptor.osVersion().isPresent())
+            checkTargetConstraints(descriptor);
+    }
+
+    /**
+     * Check that the module's constraints on the target platform do not
+     * conflict with the constraints of other modules resolved so far or
+     * modules in parent configurations.
+     */
+    private void checkTargetConstraints(ModuleDescriptor descriptor) {
+        String value = descriptor.osName().orElse(null);
+        if (value != null) {
+            if (osName == null) {
+                osName = value;
+            } else {
+                if (!value.equals(osName)) {
+                    failTargetConstraint(descriptor);
+                }
+            }
+        }
+        value = descriptor.osArch().orElse(null);
+        if (value != null) {
+            if (osArch == null) {
+                osArch = value;
+            } else {
+                if (!value.equals(osArch)) {
+                    failTargetConstraint(descriptor);
+                }
+            }
+        }
+        value = descriptor.osVersion().orElse(null);
+        if (value != null) {
+            if (osVersion == null) {
+                osVersion = value;
+            } else {
+                if (!value.equals(osVersion)) {
+                    failTargetConstraint(descriptor);
+                }
+            }
+        }
+    }
+
+    private void failTargetConstraint(ModuleDescriptor md) {
+        String s1 = targetAsString(osName, osArch, osVersion);
+        String s2 = targetAsString(md);
+        findFail("Module %s has constraints on target platform that conflict" +
+                 " with other modules: %s, %s", md.name(), s1, s2);
+    }
+
+    private String targetAsString(ModuleDescriptor descriptor) {
+        String osName = descriptor.osName().orElse(null);
+        String osArch = descriptor.osArch().orElse(null);
+        String osVersion = descriptor.osVersion().orElse(null);
+        return targetAsString(osName, osArch, osVersion);
+    }
+
+    private String targetAsString(String osName, String osArch, String osVersion) {
+        return new StringJoiner("-")
+                .add(Objects.toString(osName, "*"))
+                .add(Objects.toString(osArch, "*"))
+                .add(Objects.toString(osVersion, "*"))
+                .toString();
+    }
+
+
+    /**
      * Execute post-resolution checks and returns the module graph of resolved
      * modules as {@code Map}. The resolved modules will be in the given
      * configuration.
@@ -281,7 +406,6 @@
 
         if (check) {
             detectCycles();
-            checkPlatformConstraints();
             checkHashes();
         }
 
@@ -319,8 +443,7 @@
         if (!visited.contains(descriptor)) {
             boolean added = visitPath.add(descriptor);
             if (!added) {
-                throw new ResolutionException("Cycle detected: " +
-                        cycleAsString(descriptor));
+                resolveFail("Cycle detected: %s", cycleAsString(descriptor));
             }
             for (ModuleDescriptor.Requires requires : descriptor.requires()) {
                 String dn = requires.name();
@@ -354,86 +477,6 @@
 
 
     /**
-     * If there are platform specific modules then check that the OS name,
-     * architecture and version match.
-     *
-     * @apiNote This method does not currently check if the OS matches
-     *          platform specific modules in parent configurations.
-     */
-    private void checkPlatformConstraints() {
-
-        // first module encountered that is platform specific
-        String savedModuleName = null;
-        String savedOsName = null;
-        String savedOsArch = null;
-        String savedOsVersion = null;
-
-        for (ModuleReference mref : nameToReference.values()) {
-            ModuleDescriptor descriptor = mref.descriptor();
-
-            String osName = descriptor.osName().orElse(null);
-            String osArch = descriptor.osArch().orElse(null);
-            String osVersion = descriptor.osVersion().orElse(null);
-
-            if (osName != null || osArch != null || osVersion != null) {
-
-                if (savedModuleName == null) {
-
-                    savedModuleName = descriptor.name();
-                    savedOsName = osName;
-                    savedOsArch = osArch;
-                    savedOsVersion = osVersion;
-
-                } else {
-
-                    boolean matches = platformMatches(osName, savedOsName)
-                            && platformMatches(osArch, savedOsArch)
-                            && platformMatches(osVersion, savedOsVersion);
-
-                    if (!matches) {
-                        String s1 = platformAsString(savedOsName,
-                                                     savedOsArch,
-                                                     savedOsVersion);
-
-                        String s2 = platformAsString(osName, osArch, osVersion);
-                        fail("Mismatching constraints on target platform: "
-                                + savedModuleName + ": " + s1
-                                + ", " + descriptor.name() + ": " + s2);
-                    }
-
-                }
-
-            }
-        }
-
-    }
-
-    /**
-     * Returns true if the s1 and s2 are equal or one of them is null.
-     */
-    private boolean platformMatches(String s1, String s2) {
-        if (s1 == null || s2 == null)
-            return true;
-        else
-            return Objects.equals(s1, s2);
-    }
-
-    /**
-     * Return a string that encodes the OS name/arch/version.
-     */
-    private String platformAsString(String osName,
-                                    String osArch,
-                                    String osVersion) {
-
-        return new StringJoiner("-")
-                .add(Objects.toString(osName, "*"))
-                .add(Objects.toString(osArch, "*"))
-                .add(Objects.toString(osVersion, "*"))
-                .toString();
-
-    }
-
-    /**
      * Checks the hashes in the module descriptor to ensure that they match
      * any recorded hashes.
      */
@@ -460,7 +503,7 @@
                     continue;
 
                 if (!(mref2 instanceof ModuleReferenceImpl)) {
-                    fail("Unable to compute the hash of module %s", dn);
+                    findFail("Unable to compute the hash of module %s", dn);
                 }
 
                 // skip checking the hash if the module has been patched
@@ -469,11 +512,11 @@
                     byte[] recordedHash = hashes.hashFor(dn);
                     byte[] actualHash = other.computeHash(algorithm);
                     if (actualHash == null)
-                        fail("Unable to compute the hash of module %s", dn);
+                        findFail("Unable to compute the hash of module %s", dn);
                     if (!Arrays.equals(recordedHash, actualHash)) {
-                        fail("Hash of %s (%s) differs to expected hash (%s)" +
-                             " recorded in %s", dn, toHexString(actualHash),
-                             toHexString(recordedHash), descriptor.name());
+                        findFail("Hash of %s (%s) differs to expected hash (%s)" +
+                                 " recorded in %s", dn, toHexString(actualHash),
+                                 toHexString(recordedHash), descriptor.name());
                     }
                 }
             }
@@ -694,37 +737,38 @@
             for (ResolvedModule endpoint : reads) {
                 ModuleDescriptor descriptor2 = endpoint.descriptor();
 
-                for (ModuleDescriptor.Exports export : descriptor2.exports()) {
-
-                    if (export.isQualified()) {
-                        if (!export.targets().contains(descriptor1.name()))
-                            continue;
-                    }
-
-                    // source is exported to descriptor2
-                    String source = export.source();
-                    ModuleDescriptor other
-                        = packageToExporter.putIfAbsent(source, descriptor2);
+                if (descriptor2.isAutomatic()) {
+                    // automatic modules read self and export all packages
+                    if (descriptor2 != descriptor1){
+                        for (String source : descriptor2.packages()) {
+                            ModuleDescriptor supplier
+                                = packageToExporter.putIfAbsent(source, descriptor2);
 
-                    if (other != null && other != descriptor2) {
-                        // package might be local to descriptor1
-                        if (other == descriptor1) {
-                            fail("Module %s contains package %s"
-                                 + ", module %s exports package %s to %s",
-                                    descriptor1.name(),
-                                    source,
-                                    descriptor2.name(),
-                                    source,
-                                    descriptor1.name());
-                        } else {
-                            fail("Modules %s and %s export package %s to module %s",
-                                    descriptor2.name(),
-                                    other.name(),
-                                    source,
-                                    descriptor1.name());
+                            // descriptor2 and 'supplier' export source to descriptor1
+                            if (supplier != null) {
+                                failTwoSuppliers(descriptor1, source, descriptor2, supplier);
+                            }
                         }
 
                     }
+                } else {
+                    for (ModuleDescriptor.Exports export : descriptor2.exports()) {
+                        if (export.isQualified()) {
+                            if (!export.targets().contains(descriptor1.name()))
+                                continue;
+                        }
+
+                        // source is exported by descriptor2
+                        String source = export.source();
+                        ModuleDescriptor supplier
+                            = packageToExporter.putIfAbsent(source, descriptor2);
+
+                        // descriptor2 and 'supplier' export source to descriptor1
+                        if (supplier != null) {
+                            failTwoSuppliers(descriptor1, source, descriptor2, supplier);
+                        }
+                    }
+
                 }
             }
 
@@ -735,8 +779,8 @@
                 for (String service : descriptor1.uses()) {
                     String pn = packageName(service);
                     if (!packageToExporter.containsKey(pn)) {
-                        fail("Module %s does not read a module that exports %s",
-                             descriptor1.name(), pn);
+                        resolveFail("Module %s does not read a module that exports %s",
+                                    descriptor1.name(), pn);
                     }
                 }
 
@@ -744,15 +788,8 @@
                 for (ModuleDescriptor.Provides provides : descriptor1.provides()) {
                     String pn = packageName(provides.service());
                     if (!packageToExporter.containsKey(pn)) {
-                        fail("Module %s does not read a module that exports %s",
-                             descriptor1.name(), pn);
-                    }
-
-                    for (String provider : provides.providers()) {
-                        if (!packages.contains(packageName(provider))) {
-                            fail("Provider %s not in module %s",
-                                 provider, descriptor1.name());
-                        }
+                        resolveFail("Module %s does not read a module that exports %s",
+                                    descriptor1.name(), pn);
                     }
                 }
 
@@ -763,6 +800,42 @@
     }
 
     /**
+     * Fail because a module in the configuration exports the same package to
+     * a module that reads both. This includes the case where a module M
+     * containing a package p reads another module that exports p to at least
+     * module M.
+     */
+    private void failTwoSuppliers(ModuleDescriptor descriptor,
+                                  String source,
+                                  ModuleDescriptor supplier1,
+                                  ModuleDescriptor supplier2) {
+
+        if (supplier2 == descriptor) {
+            ModuleDescriptor tmp = supplier1;
+            supplier1 = supplier2;
+            supplier2 = tmp;
+        }
+
+        if (supplier1 == descriptor) {
+            resolveFail("Module %s contains package %s"
+                         + ", module %s exports package %s to %s",
+                    descriptor.name(),
+                    source,
+                    supplier2.name(),
+                    source,
+                    descriptor.name());
+        } else {
+            resolveFail("Modules %s and %s export package %s to module %s",
+                    supplier1.name(),
+                    supplier2.name(),
+                    source,
+                    descriptor.name());
+        }
+
+    }
+
+
+    /**
      * Find a module of the given name in the parent configurations
      */
     private ResolvedModule findInParent(String mn) {
@@ -779,24 +852,16 @@
      * Invokes the beforeFinder to find method to find the given module.
      */
     private ModuleReference findWithBeforeFinder(String mn) {
-        try {
-            return beforeFinder.find(mn).orElse(null);
-        } catch (FindException e) {
-            // unwrap
-            throw new ResolutionException(e.getMessage(), e.getCause());
-        }
+
+        return beforeFinder.find(mn).orElse(null);
+
     }
 
     /**
      * Invokes the afterFinder to find method to find the given module.
      */
     private ModuleReference findWithAfterFinder(String mn) {
-        try {
-            return afterFinder.find(mn).orElse(null);
-        } catch (FindException e) {
-            // unwrap
-            throw new ResolutionException(e.getMessage(), e.getCause());
-        }
+        return afterFinder.find(mn).orElse(null);
     }
 
     /**
@@ -804,34 +869,27 @@
      * and after ModuleFinders.
      */
     private Set<ModuleReference> findAll() {
-        try {
-
-            Set<ModuleReference> beforeModules = beforeFinder.findAll();
-            Set<ModuleReference> afterModules = afterFinder.findAll();
+        Set<ModuleReference> beforeModules = beforeFinder.findAll();
+        Set<ModuleReference> afterModules = afterFinder.findAll();
 
-            if (afterModules.isEmpty())
-                return beforeModules;
+        if (afterModules.isEmpty())
+            return beforeModules;
 
-            if (beforeModules.isEmpty()
-                    && parents.size() == 1
-                    && parents.get(0) == Configuration.empty())
-                return afterModules;
+        if (beforeModules.isEmpty()
+                && parents.size() == 1
+                && parents.get(0) == Configuration.empty())
+            return afterModules;
 
-            Set<ModuleReference> result = new HashSet<>(beforeModules);
-            for (ModuleReference mref : afterModules) {
-                String name = mref.descriptor().name();
-                if (!beforeFinder.find(name).isPresent()
-                        && findInParent(name) == null) {
-                    result.add(mref);
-                }
+        Set<ModuleReference> result = new HashSet<>(beforeModules);
+        for (ModuleReference mref : afterModules) {
+            String name = mref.descriptor().name();
+            if (!beforeFinder.find(name).isPresent()
+                    && findInParent(name) == null) {
+                result.add(mref);
             }
-
-            return result;
+        }
 
-        } catch (FindException e) {
-            // unwrap
-            throw new ResolutionException(e.getMessage(), e.getCause());
-        }
+        return result;
     }
 
     /**
@@ -843,9 +901,17 @@
     }
 
     /**
+     * Throw FindException with the given format string and arguments
+     */
+    private static void findFail(String fmt, Object ... args) {
+        String msg = String.format(fmt, args);
+        throw new FindException(msg);
+    }
+
+    /**
      * Throw ResolutionException with the given format string and arguments
      */
-    private static void fail(String fmt, Object ... args) {
+    private static void resolveFail(String fmt, Object ... args) {
         String msg = String.format(fmt, args);
         throw new ResolutionException(msg);
     }
--- a/jdk/src/java.base/share/classes/java/lang/module/package-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/module/package-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -27,6 +27,112 @@
  * Classes to support module descriptors and creating configurations of modules
  * by means of resolution and service binding.
  *
+ * <h2><a name="resolution">Resolution</a></h2>
+ *
+ * <p> Resolution is the process of computing the transitive closure of a set
+ * of root modules over a set of observable modules by resolving the
+ * dependences expressed by {@link
+ * java.lang.module.ModuleDescriptor.Requires requires} clauses.
+ * The <em>dependence graph</em> is augmented with edges that take account of
+ * implicitly declared dependences ({@code requires transitive}) to create a
+ * <em>readability graph</em>. The result of resolution is a {@link
+ * java.lang.module.Configuration Configuration} that encapsulates the
+ * readability graph. </p>
+ *
+ * <p> As an example, suppose we have the following observable modules: </p>
+ * <pre> {@code
+ *     module m1 { requires m2; }
+ *     module m2 { requires transitive m3; }
+ *     module m3 { }
+ *     module m4 { }
+ * } </pre>
+ *
+ * <p> If the module {@code m1} is resolved then the resulting configuration
+ * contains three modules ({@code m1}, {@code m2}, {@code m3}). The edges in
+ * its readability graph are: </p>
+ * <pre> {@code
+ *     m1 --> m2  (meaning m1 reads m2)
+ *     m1 --> m3
+ *     m2 --> m3
+ * } </pre>
+ *
+ * <p> Resolution is an additive process. When computing the transitive closure
+ * then the dependence relation may include dependences on modules in {@link
+ * java.lang.module.Configuration#parents() parent} configurations. The result
+ * is a <em>relative configuration</em> that is relative to one or more parent
+ * configurations and where the readability graph may have edges from modules
+ * in the configuration to modules in parent configurations. </p>
+ *
+ * <p> As an example, suppose we have the following observable modules: </p>
+ * <pre> {@code
+ *     module m1 { requires m2; requires java.xml; }
+ *     module m2 { }
+ * } </pre>
+ *
+ * <p> If module {@code m1} is resolved with the configuration for the {@link
+ * java.lang.reflect.Layer#boot() boot} layer as the parent then the resulting
+ * configuration contains two modules ({@code m1}, {@code m2}). The edges in
+ * its readability graph are:
+ * <pre> {@code
+ *     m1 --> m2
+ *     m1 --> java.xml
+ * } </pre>
+ * where module {@code java.xml} is in the parent configuration. For
+ * simplicity, this example omits the implicitly declared dependence on the
+ * {@code java.base} module.
+ *
+ * <p> Requires clauses that are "{@code requires static}" express an optional
+ * dependence (except at compile-time). If a module declares that it
+ * "{@code requires static M}" then resolution does not search the observable
+ * modules for "{@code M}". However, if "{@code M}" is resolved (because resolution
+ * resolves a module that requires "{@code M}" without the {@link
+ * java.lang.module.ModuleDescriptor.Requires.Modifier#STATIC static} modifier)
+ * then the readability graph will contain read edges for each module that
+ * "{@code requires static M}". </p>
+ *
+ * <p> {@link java.lang.module.ModuleDescriptor#isAutomatic() Automatic} modules
+ * receive special treatment during resolution. Each automatic module is resolved
+ * so that it reads all other modules in the configuration and all parent
+ * configurations. Each automatic module is also resolved as if it
+ * "{@code requires transitive}" all other automatic modules in the configuration
+ * (and all automatic modules in parent configurations). </p>
+ *
+ * <h2><a name="servicebinding">Service binding</a></h2>
+ *
+ * <p> Service binding is the process of augmenting a graph of resolved modules
+ * from the set of observable modules induced by the service-use dependence
+ * ({@code uses} and {@code provides} clauses). Any module that was not
+ * previously in the graph requires resolution to compute its transitive
+ * closure. Service binding is an iterative process in that adding a module
+ * that satisfies some service-use dependence may introduce new service-use
+ * dependences. </p>
+ *
+ * <p> Suppose we have the following observable modules: </p>
+ * <pre> {@code
+ *     module m1 { exports p; uses p.S; }
+ *     module m2 { requires m1; provides p.S with p2.S2; }
+ *     module m3 { requires m1; requires m4; provides p.S with p3.S3; }
+ *     module m4 { }
+ * } </pre>
+ *
+ * <p> If the module {@code m1} is resolved then the resulting graph of modules
+ * has one module ({@code m1}). If the graph is augmented with modules induced
+ * by the service-use dependence relation then the configuration will contain
+ * four modules ({@code m1}, {@code m2}, {@code m3}, {@code m4}). The edges in
+ * its readability graph are: </p>
+ * <pre> {@code
+ *     m2 --> m1
+ *     m3 --> m1
+ *     m3 --> m4
+ * } </pre>
+ * <p> The edges in the conceptual service-use graph are: </p>
+ * <pre> {@code
+ *     m1 --> m2  (meaning m1 uses a service that is provided by m2)
+ *     m1 --> m3
+ * } </pre>
+ *
+ * <h2>General Exceptions</h2>
+ *
  * <p> Unless otherwise noted, passing a {@code null} argument to a constructor
  * or method of any class or interface in this package will cause a {@link
  * java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
@@ -34,6 +140,7 @@
  * will cause a {@code NullPointerException}, unless otherwise specified. </p>
  *
  * @since 9
+ * @spec JPMS
  */
 
 package java.lang.module;
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -28,38 +28,44 @@
 import java.lang.annotation.Annotation;
 import java.security.AccessController;
 
-import jdk.internal.misc.VM;
 import jdk.internal.reflect.CallerSensitive;
 import jdk.internal.reflect.Reflection;
 import jdk.internal.reflect.ReflectionFactory;
-import sun.security.action.GetPropertyAction;
 
 /**
- * The AccessibleObject class is the base class for Field, Method and
- * Constructor objects.  It provides the ability to flag a reflected
- * object as suppressing default Java language access control checks
- * when it is used. The access checks -- <em>module boundaries</em>,
- * public, default (package) access, protected, and private members --
- * are performed when Fields, Methods or Constructors are used to set
- * or get fields, to invoke methods or to create and initialize new
- * instances of classes, respectively. Unlike access control specified
- * in the <cite>The Java&trade; Language Specification</cite> and
- * <cite>The Java Virtual Machine Specification</cite>, access checks
- * with reflected objects assume {@link Module#canRead readability}.
+ * The {@code AccessibleObject} class is the base class for {@code Field},
+ * {@code Method}, and {@code Constructor} objects (known as <em>reflected
+ * objects</em>). It provides the ability to flag a reflected object as
+ * suppressing checks for Java language access control when it is used. This
+ * permits sophisticated applications with sufficient privilege, such as Java
+ * Object Serialization or other persistence mechanisms, to manipulate objects
+ * in a manner that would normally be prohibited.
  *
- * <p>Setting the {@code accessible} flag in a reflected object
- * permits sophisticated applications with sufficient privilege, such
- * as Java Object Serialization or other persistence mechanisms, to
- * manipulate objects in a manner that would normally be prohibited.
- *
- * <p>By default, a reflected object is <em>not</em> accessible.
+ * <p> Java language access control prevents use of private members outside
+ * their class; package access members outside their package; protected members
+ * outside their package or subclasses; and public members outside their
+ * module unless they are declared in an {@link Module#isExported(String,Module)
+ * exported} package and the user {@link Module#canRead reads} their module. By
+ * default, Java language access control is enforced (with one variation) when
+ * {@code Field}s, {@code Method}s, or {@code Constructor}s are used to get or
+ * set fields, to invoke methods, or to create and initialize new instances of
+ * classes, respectively. Every reflected object checks that the code using it
+ * is in an appropriate class, package, or module. </p>
  *
- * @see Field
- * @see Method
- * @see Constructor
- * @see ReflectPermission
+ * <p> The one variation from Java language access control is that the checks
+ * by reflected objects assume readability. That is, the module containing
+ * the use of a reflected object is assumed to read the module in which
+ * the underlying field, method, or constructor is declared. </p>
  *
+ * <p> Whether the checks for Java language access control can be suppressed
+ * (and thus, whether access can be enabled) depends on whether the reflected
+ * object corresponds to a member in an exported or open package
+ * (see {@link #setAccessible(boolean)}). </p>
+ *
+ * @jls 6.6 Access Control
  * @since 1.2
+ * @revised 9
+ * @spec JPMS
  */
 public class AccessibleObject implements AnnotatedElement {
 
@@ -78,15 +84,11 @@
 
     /**
      * Convenience method to set the {@code accessible} flag for an
-     * array of objects with a single security check (for efficiency).
+     * array of reflected objects with a single security check (for efficiency).
      *
-     * <p>This method cannot be used to enable access to an object that is a
-     * {@link Member member} of a class in a different module to the caller and
-     * where the class is in a package that is not exported to the caller's
-     * module. Additionally, if the member is non-public or its declaring
-     * class is non-public, then this method can only be used to enable access
-     * if the package is {@link Module#isOpen(String,Module) open} to at least
-     * the caller's module.
+     * <p> This method may be used to enable access to all reflected objects in
+     * the array when access to each reflected object can be enabled as
+     * specified by {@link #setAccessible(boolean) setAccessible(boolean)}. </p>
      *
      * <p>If there is a security manager, its
      * {@code checkPermission} method is first called with a
@@ -99,10 +101,15 @@
      * @param array the array of AccessibleObjects
      * @param flag  the new value for the {@code accessible} flag
      *              in each object
-     * @throws InaccessibleObjectException if access cannot be enabled
-     * @throws SecurityException if the request is denied.
+     * @throws InaccessibleObjectException if access cannot be enabled for all
+     *         objects in the array
+     * @throws SecurityException if the request is denied by the security manager
+     *         or an element in the array is a constructor for {@code
+     *         java.lang.Class}
      * @see SecurityManager#checkPermission
      * @see ReflectPermission
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static void setAccessible(AccessibleObject[] array, boolean flag) {
@@ -120,41 +127,143 @@
     }
 
     /**
-     * Set the {@code accessible} flag for this object to
+     * Set the {@code accessible} flag for this reflected object to
      * the indicated boolean value.  A value of {@code true} indicates that
-     * the reflected object should suppress Java language access
-     * checking when it is used.  A value of {@code false} indicates
-     * that the reflected object should enforce Java language access checks
-     * while assuming readability (as noted in the class description).
+     * the reflected object should suppress checks for Java language access
+     * control when it is used. A value of {@code false} indicates that
+     * the reflected object should enforce checks for Java language access
+     * control when it is used, with the variation noted in the class description.
+     *
+     * <p> This method may be used by a caller in class {@code C} to enable
+     * access to a {@link Member member} of {@link Member#getDeclaringClass()
+     * declaring class} {@code D} if any of the following hold: </p>
+     *
+     * <ul>
+     *     <li> {@code C} and {@code D} are in the same module. </li>
+     *
+     *     <li> The member is {@code public} and {@code D} is {@code public} in
+     *     a package that the module containing {@code D} {@link
+     *     Module#isExported(String,Module) exports} to at least the module
+     *     containing {@code C}. </li>
      *
-     * <p>This method cannot be used to enable access to an object that is a
-     * {@link Member member} of a class in a different module to the caller and
-     * where the class is in a package that is not exported to the caller's
-     * module. Additionally, if the member is non-public or its declaring
-     * class is non-public, then this method can only be used to enable access
-     * if the package is {@link Module#isOpen(String,Module) open} to at least
-     * the caller's module.
+     *     <li> The member is {@code protected} {@code static}, {@code D} is
+     *     {@code public} in a package that the module containing {@code D}
+     *     exports to at least the module containing {@code C}, and {@code C}
+     *     is a subclass of {@code D}. </li>
      *
-     * <p>If there is a security manager, its
+     *     <li> {@code D} is in a package that the module containing {@code D}
+     *     {@link Module#isOpen(String,Module) opens} to at least the module
+     *     containing {@code C}.
+     *     All packages in unnamed and open modules are open to all modules and
+     *     so this method always succeeds when {@code D} is in an unnamed or
+     *     open module. </li>
+     * </ul>
+     *
+     * <p> This method cannot be used to enable access to private members,
+     * members with default (package) access, protected instance members, or
+     * protected constructors when the declaring class is in a different module
+     * to the caller and the package containing the declaring class is not open
+     * to the caller's module. </p>
+     *
+     * <p> If there is a security manager, its
      * {@code checkPermission} method is first called with a
      * {@code ReflectPermission("suppressAccessChecks")} permission.
      *
      * @param flag the new value for the {@code accessible} flag
      * @throws InaccessibleObjectException if access cannot be enabled
-     * @throws SecurityException if the request is denied
-     * @see SecurityManager#checkPermission
-     * @see ReflectPermission
+     * @throws SecurityException if the request is denied by the security manager
+     * @see #trySetAccessible
      * @see java.lang.invoke.MethodHandles#privateLookupIn
+     * @revised 9
+     * @spec JPMS
      */
     public void setAccessible(boolean flag) {
         AccessibleObject.checkPermission();
         setAccessible0(flag);
     }
 
-    void setAccessible0(boolean flag) {
+    /**
+     * Sets the accessible flag and returns the new value
+     */
+    boolean setAccessible0(boolean flag) {
         this.override = flag;
+        return flag;
     }
 
+    /**
+     * Set the {@code accessible} flag for this reflected object to {@code true}
+     * if possible. This method sets the {@code accessible} flag, as if by
+     * invoking {@link #setAccessible(boolean) setAccessible(true)}, and returns
+     * the possibly-updated value for the {@code accessible} flag. If access
+     * cannot be enabled, i.e. the checks or Java language access control cannot
+     * be suppressed, this method returns {@code false} (as opposed to {@code
+     * setAccessible(true)} throwing {@code InaccessibleObjectException} when
+     * it fails).
+     *
+     * <p> This method is a no-op if the {@code accessible} flag for
+     * this reflected object is {@code true}.
+     *
+     * <p> For example, a caller can invoke {@code trySetAccessible}
+     * on a {@code Method} object for a private instance method
+     * {@code p.T::privateMethod} to suppress the checks for Java language access
+     * control when the {@code Method} is invoked.
+     * If {@code p.T} class is in a different module to the caller and
+     * package {@code p} is open to at least the caller's module,
+     * the code below successfully sets the {@code accessible} flag
+     * to {@code true}.
+     *
+     * <pre>
+     * {@code
+     *     p.T obj = ....;  // instance of p.T
+     *     :
+     *     Method m = p.T.class.getDeclaredMethod("privateMethod");
+     *     if (m.trySetAccessible()) {
+     *         m.invoke(obj);
+     *     } else {
+     *         // package p is not opened to the caller to access private member of T
+     *         ...
+     *     }
+     * }</pre>
+     *
+     * <p> If there is a security manager, its {@code checkPermission} method
+     * is first called with a {@code ReflectPermission("suppressAccessChecks")}
+     * permission. </p>
+     *
+     * @return {@code true} if the {@code accessible} flag is set to {@code true};
+     *         {@code false} if access cannot be enabled.
+     * @throws SecurityException if the request is denied by the security manager
+     *
+     * @since 9
+     * @spec JPMS
+     * @see java.lang.invoke.MethodHandles#privateLookupIn
+     */
+    @CallerSensitive
+    public final boolean trySetAccessible() {
+        AccessibleObject.checkPermission();
+
+        if (override == true) return true;
+
+        // if it's not a Constructor, Method, Field then no access check
+        if (!Member.class.isInstance(this)) {
+            return setAccessible0(true);
+        }
+
+        // does not allow to suppress access check for Class's constructor
+        Class<?> declaringClass = ((Member) this).getDeclaringClass();
+        if (declaringClass == Class.class && this instanceof Constructor) {
+            return false;
+        }
+
+        if (checkCanSetAccessible(Reflection.getCallerClass(),
+                                  declaringClass,
+                                  false)) {
+            return setAccessible0(true);
+        } else {
+            return false;
+        }
+    }
+
+
    /**
     * If the given AccessibleObject is a {@code Constructor}, {@code Method}
     * or {@code Field} then checks that its declaring class is in a package
@@ -164,22 +273,29 @@
         // do nothing, needs to be overridden by Constructor, Method, Field
     }
 
+
     void checkCanSetAccessible(Class<?> caller, Class<?> declaringClass) {
+        checkCanSetAccessible(caller, declaringClass, true);
+    }
+
+    private boolean checkCanSetAccessible(Class<?> caller,
+                                          Class<?> declaringClass,
+                                          boolean throwExceptionIfDenied) {
         Module callerModule = caller.getModule();
         Module declaringModule = declaringClass.getModule();
 
-        if (callerModule == declaringModule) return;
-        if (callerModule == Object.class.getModule()) return;
-        if (!declaringModule.isNamed()) return;
+        if (callerModule == declaringModule) return true;
+        if (callerModule == Object.class.getModule()) return true;
+        if (!declaringModule.isNamed()) return true;
 
         // package is open to caller
         String pn = packageName(declaringClass);
         if (declaringModule.isOpen(pn, callerModule)) {
-            printStackTraceIfOpenedReflectively(declaringModule, pn, callerModule);
-            return;
+            dumpStackIfOpenedReflectively(declaringModule, pn, callerModule);
+            return true;
         }
 
-        // package is exported to caller and class/member is public
+        // package is exported to caller
         boolean isExported = declaringModule.isExported(pn, callerModule);
         boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
         int modifiers;
@@ -188,48 +304,72 @@
         } else {
             modifiers = ((Field) this).getModifiers();
         }
-        boolean isMemberPublic = Modifier.isPublic(modifiers);
-        if (isExported && isClassPublic && isMemberPublic) {
-            printStackTraceIfExportedReflectively(declaringModule, pn, callerModule);
-            return;
+        if (isExported && isClassPublic) {
+
+            // member is public
+            if (Modifier.isPublic(modifiers)) {
+                dumpStackIfExportedReflectively(declaringModule, pn, callerModule);
+                return true;
+            }
+
+            // member is protected-static
+            if (Modifier.isProtected(modifiers)
+                && Modifier.isStatic(modifiers)
+                && isSubclassOf(caller, declaringClass)) {
+                dumpStackIfExportedReflectively(declaringModule, pn, callerModule);
+                return true;
+            }
         }
 
-        // not accessible
-        String msg = "Unable to make ";
-        if (this instanceof Field)
-            msg += "field ";
-        msg += this + " accessible: " + declaringModule + " does not \"";
-        if (isClassPublic && isMemberPublic)
-            msg += "exports";
-        else
-            msg += "opens";
-        msg += " " + pn + "\" to " + callerModule;
-        InaccessibleObjectException e = new InaccessibleObjectException(msg);
-        if (Reflection.printStackTraceWhenAccessFails()) {
-            e.printStackTrace(System.err);
+        if (throwExceptionIfDenied) {
+            // not accessible
+            String msg = "Unable to make ";
+            if (this instanceof Field)
+                msg += "field ";
+            msg += this + " accessible: " + declaringModule + " does not \"";
+            if (isClassPublic && Modifier.isPublic(modifiers))
+                msg += "exports";
+            else
+                msg += "opens";
+            msg += " " + pn + "\" to " + callerModule;
+            InaccessibleObjectException e = new InaccessibleObjectException(msg);
+            if (Reflection.printStackTraceWhenAccessFails()) {
+                e.printStackTrace(System.err);
+            }
+            throw e;
         }
-        throw e;
+        return false;
     }
 
-    private void printStackTraceIfOpenedReflectively(Module module,
-                                                     String pn,
-                                                     Module other) {
-        printStackTraceIfExposedReflectively(module, pn, other, true);
+    private boolean isSubclassOf(Class<?> queryClass, Class<?> ofClass) {
+        while (queryClass != null) {
+            if (queryClass == ofClass) {
+                return true;
+            }
+            queryClass = queryClass.getSuperclass();
+        }
+        return false;
     }
 
-    private void printStackTraceIfExportedReflectively(Module module,
-                                                       String pn,
-                                                       Module other) {
-        printStackTraceIfExposedReflectively(module, pn, other, false);
+    private void dumpStackIfOpenedReflectively(Module module,
+                                               String pn,
+                                               Module other) {
+        dumpStackIfExposedReflectively(module, pn, other, true);
     }
 
-    private void printStackTraceIfExposedReflectively(Module module,
-                                                      String pn,
-                                                      Module other,
-                                                      boolean open)
+    private void dumpStackIfExportedReflectively(Module module,
+                                                 String pn,
+                                                 Module other) {
+        dumpStackIfExposedReflectively(module, pn, other, false);
+    }
+
+    private void dumpStackIfExposedReflectively(Module module,
+                                                String pn,
+                                                Module other,
+                                                boolean open)
     {
         if (Reflection.printStackTraceWhenAccessSucceeds()
-            && !module.isStaticallyExportedOrOpen(pn, other, open))
+                && !module.isStaticallyExportedOrOpen(pn, other, open))
         {
             String msg = other + " allowed to invoke setAccessible on ";
             if (this instanceof Field)
@@ -256,15 +396,100 @@
     }
 
     /**
-     * Get the value of the {@code accessible} flag for this object.
+     * Get the value of the {@code accessible} flag for this reflected object.
      *
      * @return the value of the object's {@code accessible} flag
+     *
+     * @deprecated
+     * This method is deprecated because its name hints that it checks
+     * if the reflected object is accessible when it actually indicates
+     * if the checks for Java language access control are suppressed.
+     * This method may return {@code false} on a reflected object that is
+     * accessible to the caller. To test if this reflected object is accessible,
+     * it should use {@link #canAccess(Object)}.
+     *
+     * @revised 9
      */
+    @Deprecated(since="9")
     public boolean isAccessible() {
         return override;
     }
 
     /**
+     * Test if the caller can access this reflected object. If this reflected
+     * object corresponds to an instance method or field then this method tests
+     * if the caller can access the given {@code obj} with the reflected object.
+     * For instance methods or fields then the {@code obj} argument must be an
+     * instance of the {@link Member#getDeclaringClass() declaring class}. For
+     * static members and constructors then {@code obj} must be {@code null}.
+     *
+     * <p> This method returns {@code true} if the {@code accessible} flag
+     * is set to {@code true}, i.e. the checks for Java language access control
+     * are suppressed, or if the caller can access the member as
+     * specified in <cite>The Java&trade; Language Specification</cite>,
+     * with the variation noted in the class description. </p>
+     *
+     * @param obj an instance object of the declaring class of this reflected
+     *            object if it is an instance method or field
+     *
+     * @return {@code true} if the caller can access this reflected object.
+     *
+     * @throws IllegalArgumentException
+     *         <ul>
+     *         <li> if this reflected object is a static member or constructor and
+     *              the given {@code obj} is non-{@code null}, or </li>
+     *         <li> if this reflected object is an instance method or field
+     *              and the given {@code obj} is {@code null} or of type
+     *              that is not a subclass of the {@link Member#getDeclaringClass()
+     *              declaring class} of the member.</li>
+     *         </ul>
+     *
+     * @since 9
+     * @spec JPMS
+     * @jls 6.6 Access Control
+     * @see #trySetAccessible
+     * @see #setAccessible(boolean)
+     */
+    @CallerSensitive
+    public final boolean canAccess(Object obj) {
+        if (!Member.class.isInstance(this)) {
+            return override;
+        }
+
+        Class<?> declaringClass = ((Member) this).getDeclaringClass();
+        int modifiers = ((Member) this).getModifiers();
+        if (!Modifier.isStatic(modifiers) &&
+                (this instanceof Method || this instanceof Field)) {
+            if (obj == null) {
+                throw new IllegalArgumentException("null object for " + this);
+            }
+            // if this object is an instance member, the given object
+            // must be a subclass of the declaring class of this reflected object
+            if (!declaringClass.isAssignableFrom(obj.getClass())) {
+                throw new IllegalArgumentException("object is not an instance of "
+                                                   + declaringClass.getName());
+            }
+        } else if (obj != null) {
+            throw new IllegalArgumentException("non-null object for " + this);
+        }
+
+        // access check is suppressed
+        if (override) return true;
+
+        Class<?> caller = Reflection.getCallerClass();
+        Class<?> targetClass;
+        if (this instanceof Constructor) {
+            targetClass = declaringClass;
+        } else {
+            targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
+        }
+        return Reflection.verifyMemberAccess(caller,
+                                             declaringClass,
+                                             targetClass,
+                                             modifiers);
+    }
+
+    /**
      * Constructor: only used by the Java Virtual Machine.
      */
     protected AccessibleObject() {}
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java	Fri Feb 10 08:57:42 2017 -0800
@@ -168,6 +168,13 @@
      * is true. </p>
      *
      * @param flag {@inheritDoc}
+     *
+     * @throws InaccessibleObjectException {@inheritDoc}
+     * @throws SecurityException if the request is denied by the security manager
+     *         or this is a constructor for {@code java.lang.Class}
+     *
+     * @since 9
+     * @spec JPMS
      */
     @Override
     @CallerSensitive
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java	Fri Feb 10 08:57:42 2017 -0800
@@ -158,6 +158,10 @@
         return res;
     }
 
+    /**
+     * @throws InaccessibleObjectException {@inheritDoc}
+     * @throws SecurityException {@inheritDoc}
+     */
     @Override
     @CallerSensitive
     public void setAccessible(boolean flag) {
--- a/jdk/src/java.base/share/classes/java/lang/reflect/InaccessibleObjectException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/InaccessibleObjectException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -30,6 +30,7 @@
  *
  * @see AccessibleObject#setAccessible(boolean)
  * @since 9
+ * @spec JPMS
  */
 
 public class InaccessibleObjectException extends RuntimeException {
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java	Fri Feb 10 08:57:42 2017 -0800
@@ -56,20 +56,19 @@
 /**
  * A layer of modules in the Java virtual machine.
  *
- * <p> A layer is created from a graph of modules that is the {@link
- * Configuration} and a function that maps each module to a {@link ClassLoader}.
+ * <p> A layer is created from a graph of modules in a {@link Configuration}
+ * and a function that maps each module to a {@link ClassLoader}.
  * Creating a layer informs the Java virtual machine about the classes that
- * may be loaded from modules so that the Java virtual machine knows which
- * module that each class is a member of. Each layer, except the {@link
- * #empty() empty} layer, has at least one {@link #parents() parent}. </p>
+ * may be loaded from the modules so that the Java virtual machine knows which
+ * module that each class is a member of. </p>
  *
  * <p> Creating a layer creates a {@link Module} object for each {@link
  * ResolvedModule} in the configuration. For each resolved module that is
  * {@link ResolvedModule#reads() read}, the {@code Module} {@link
  * Module#canRead reads} the corresponding run-time {@code Module}, which may
- * be in the same layer or a parent layer. The {@code Module} {@link
- * Module#isExported(String) exports} the packages described by its {@link
- * ModuleDescriptor}. </p>
+ * be in the same layer or a {@link #parents() parent} layer. The {@code Module}
+ * {@link Module#isExported(String) exports} and {@link Module#isOpen(String)
+ * opens} the packages described by its {@link ModuleDescriptor}. </p>
  *
  * <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
  * {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
@@ -80,7 +79,7 @@
  * a function specified to the method. Each of these methods has an instance
  * and static variant. The instance methods create a layer with the receiver
  * as the parent layer. The static methods are for more advanced cases where
- * there can be more than one parent layer or a {@link Layer.Controller
+ * there can be more than one parent layer or where a {@link Layer.Controller
  * Controller} is needed to control modules in the layer. </p>
  *
  * <p> A Java virtual machine has at least one non-empty layer, the {@link
@@ -93,9 +92,8 @@
  * the {@link #parents() parent} when creating additional layers. </p>
  *
  * <p> As when creating a {@code Configuration},
- * {@link ModuleDescriptor#isAutomatic() automatic} modules receive
- * <a href="../module/Configuration.html#automaticmoduleresolution">special
- * treatment</a> when creating a layer. An automatic module is created in the
+ * {@link ModuleDescriptor#isAutomatic() automatic} modules receive special
+ * treatment when creating a layer. An automatic module is created in the
  * Java virtual machine as a {@code Module} that reads every unnamed {@code
  * Module} in the Java virtual machine. </p>
  *
@@ -115,8 +113,7 @@
  *
  *     Layer parent = Layer.boot();
  *
- *     Configuration cf = parent.configuration()
- *         .resolveRequires(finder, ModuleFinder.of(), Set.of("myapp"));
+ *     Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
  *
  *     ClassLoader scl = ClassLoader.getSystemClassLoader();
  *
@@ -126,6 +123,7 @@
  * }</pre>
  *
  * @since 9
+ * @spec JPMS
  * @see Module#getLayer()
  */
 
@@ -168,10 +166,15 @@
      * module layers return a {@code Controller} that can be used to control
      * modules in the layer.
      *
+     * <p> Unless otherwise specified, passing a {@code null} argument to a
+     * method in this class causes a {@link NullPointerException
+     * NullPointerException} to be thrown. </p>
+     *
      * @apiNote Care should be taken with {@code Controller} objects, they
      * should never be shared with untrusted code.
      *
      * @since 9
+     * @spec JPMS
      */
     public static final class Controller {
         private final Layer layer;
@@ -281,10 +284,8 @@
      *         If the parent of the given configuration is not the configuration
      *         for this layer
      * @throws LayerInstantiationException
-     *         If all modules cannot be defined to the same class loader for any
-     *         of the reasons listed above or the layer cannot be created because
-     *         the configuration contains a module named "{@code java.base}" or
-     *         a module with a package name starting with "{@code java.}"
+     *         If the layer cannot be created for any of the reasons specified
+     *         by the static {@code defineModulesWithOneLoader} method
      * @throws SecurityException
      *         If {@code RuntimePermission("createClassLoader")} or
      *         {@code RuntimePermission("getClassLoader")} is denied by
@@ -325,9 +326,8 @@
      *         If the parent of the given configuration is not the configuration
      *         for this layer
      * @throws LayerInstantiationException
-     *         If the layer cannot be created because the configuration contains
-     *         a module named "{@code java.base}" or a module with a package
-     *         name starting with "{@code java.}"
+     *         If the layer cannot be created for any of the reasons specified
+     *         by the static {@code defineModulesWithManyLoaders} method
      * @throws SecurityException
      *         If {@code RuntimePermission("createClassLoader")} or
      *         {@code RuntimePermission("getClassLoader")} is denied by
@@ -365,14 +365,8 @@
      *         If the parent of the given configuration is not the configuration
      *         for this layer
      * @throws LayerInstantiationException
-     *         If creating the {@code Layer} fails for any of the reasons
-     *         listed above, the layer cannot be created because the
-     *         configuration contains a module named "{@code java.base}",
-     *         a module with a package name starting with "{@code java.}" is
-     *         mapped to a class loader other than the {@link
-     *         ClassLoader#getPlatformClassLoader() platform class loader},
-     *         or the function to map a module name to a class loader returns
-     *         {@code null}
+     *         If the layer cannot be created for any of the reasons specified
+     *         by the static {@code defineModules} method
      * @throws SecurityException
      *         If {@code RuntimePermission("getClassLoader")} is denied by
      *         the security manager
@@ -396,7 +390,6 @@
      * exported to one or more of the modules in this layer. The class
      * loader delegates to the class loader of the module, throwing {@code
      * ClassNotFoundException} if not found by that class loader.
-     *
      * When {@code loadClass} is invoked to load classes that do not map to a
      * module then it delegates to the parent class loader. </p>
      *
@@ -414,6 +407,10 @@
      *
      * </ul>
      *
+     * <p> In addition, a layer cannot be created if the configuration contains
+     * a module named "{@code java.base}" or a module with a package name
+     * starting with "{@code java.}". </p>
+     *
      * <p> If there is a security manager then the class loader created by
      * this method will load classes and resources with privileges that are
      * restricted by the calling context of this method. </p>
@@ -433,9 +430,7 @@
      *         the parent layers, including order
      * @throws LayerInstantiationException
      *         If all modules cannot be defined to the same class loader for any
-     *         of the reasons listed above or the layer cannot be created because
-     *         the configuration contains a module named "{@code java.base}" or
-     *         a module with a package name starting with "{@code java.}"
+     *         of the reasons listed above
      * @throws SecurityException
      *         If {@code RuntimePermission("createClassLoader")} or
      *         {@code RuntimePermission("getClassLoader")} is denied by
@@ -480,7 +475,6 @@
      * module in a parent layer. The class loader delegates to the class loader
      * of the module, throwing {@code ClassNotFoundException} if not found by
      * that class loader.
-     *
      * When {@code loadClass} is invoked to load classes that do not map to a
      * module then it delegates to the parent class loader. </p>
      *
@@ -533,15 +527,19 @@
 
     /**
      * Creates a new layer by defining the modules in the given {@code
-     * Configuration} to the Java virtual machine.
-     * Each module is mapped, by name, to its class loader by means of the
-     * given function. The class loader delegation implemented by these class
-     * loaders must respect module readability. The class loaders should be
+     * Configuration} to the Java virtual machine. The given function maps each
+     * module in the configuration, by name, to a class loader. Creating the
+     * layer informs the Java virtual machine about the classes that may be
+     * loaded so that the Java virtual machine knows which module that each
+     * class is a member of.
+     *
+     * <p> The class loader delegation implemented by the class loaders must
+     * respect module readability. The class loaders should be
      * {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to
      * avoid deadlocks during class loading. In addition, the entity creating
-     * a new layer with this method should arrange that the class loaders are
+     * a new layer with this method should arrange that the class loaders be
      * ready to load from these modules before there are any attempts to load
-     * classes or resources.
+     * classes or resources. </p>
      *
      * <p> Creating a {@code Layer} can fail for the following reasons: </p>
      *
@@ -558,6 +556,13 @@
      *
      * </ul>
      *
+     * <p> In addition, a layer cannot be created if the configuration contains
+     * a module named "{@code java.base}", a configuration contains a module
+     * with a package name starting with "{@code java.}" is mapped to a class
+     * loader other than the {@link ClassLoader#getPlatformClassLoader()
+     * platform class loader}, or the function to map a module name to a class
+     * loader returns {@code null}. </p>
+     *
      * <p> If the function to map a module name to class loader throws an error
      * or runtime exception then it is propagated to the caller of this method.
      * </p>
@@ -565,7 +570,7 @@
      * @apiNote It is implementation specific as to whether creating a Layer
      * with this method is an atomic operation or not. Consequentially it is
      * possible for this method to fail with some modules, but not all, defined
-     * to Java virtual machine.
+     * to the Java virtual machine.
      *
      * @param  cf
      *         The configuration for the layer
@@ -580,14 +585,7 @@
      *         If the parent configurations do not match the configuration of
      *         the parent layers, including order
      * @throws LayerInstantiationException
-     *         If creating the {@code Layer} fails for any of the reasons
-     *         listed above, the layer cannot be created because the
-     *         configuration contains a module named "{@code java.base}",
-     *         a module with a package name starting with "{@code java.}" is
-     *         mapped to a class loader other than the {@link
-     *         ClassLoader#getPlatformClassLoader() platform class loader},
-     *         or the function to map a module name to a class loader returns
-     *         {@code null}
+     *         If creating the layer fails for any of the reasons listed above
      * @throws SecurityException
      *         If {@code RuntimePermission("getClassLoader")} is denied by
      *         the security manager
@@ -763,7 +761,7 @@
 
     /**
      * Returns the module with the given name in this layer, or if not in this
-     * layer, the {@linkplain #parents parents} layers. Finding a module in
+     * layer, the {@linkplain #parents parent} layers. Finding a module in
      * parent layers is equivalent to invoking {@code findModule} on each
      * parent, in search order, until the module is found or all parents have
      * been searched. In a <em>tree of layers</em>  then this is equivalent to
--- a/jdk/src/java.base/share/classes/java/lang/reflect/LayerInstantiationException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/LayerInstantiationException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -31,6 +31,7 @@
  * @see Layer
  *
  * @since 9
+ * @spec JPMS
  */
 public class LayerInstantiationException extends RuntimeException {
     private static final long serialVersionUID = -906239691613568347L;
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java	Fri Feb 10 08:57:42 2017 -0800
@@ -179,6 +179,10 @@
         return res;
     }
 
+    /**
+     * @throws InaccessibleObjectException {@inheritDoc}
+     * @throws SecurityException {@inheritDoc}
+     */
     @Override
     @CallerSensitive
     public void setAccessible(boolean flag) {
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Module.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Module.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -39,7 +39,6 @@
 import java.net.URL;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -74,16 +73,15 @@
  * Java Virtual Machine when a graph of modules is defined to the Java virtual
  * machine to create a module {@link Layer Layer}. </p>
  *
- * <p> An unnamed module does not have a name. There is an unnamed module
- * per {@link ClassLoader ClassLoader} that is obtained by invoking the class
- * loader's {@link ClassLoader#getUnnamedModule() getUnnamedModule} method. The
- * {@link Class#getModule() getModule} method of all types defined by a class
- * loader that are not in a named module return the class loader's unnamed
+ * <p> An unnamed module does not have a name. There is an unnamed module for
+ * each {@link ClassLoader ClassLoader}, obtained by invoking its {@link
+ * ClassLoader#getUnnamedModule() getUnnamedModule} method. All types that are
+ * not in a named module are members of their defining class loader's unnamed
  * module. </p>
  *
  * <p> The package names that are parameters or returned by methods defined in
  * this class are the fully-qualified names of the packages as defined in
- * section 6.5.3 of <cite>The Java&trade; Language Specification </cite>, for
+ * section 6.5.3 of <cite>The Java&trade; Language Specification</cite>, for
  * example, {@code "java.lang"}. </p>
  *
  * <p> Unless otherwise specified, passing a {@code null} argument to a method
@@ -91,6 +89,7 @@
  * be thrown. </p>
  *
  * @since 9
+ * @spec JPMS
  * @see java.lang.Class#getModule
  */
 
@@ -327,8 +326,9 @@
      *
      * @return this module
      *
-     * @throws IllegalStateException
-     *         If this is a named module and the caller is not this module
+     * @throws IllegalCallerException
+     *         If this is a named module and the caller's module is not this
+     *         module
      *
      * @see #canRead
      */
@@ -338,7 +338,7 @@
         if (this.isNamed()) {
             Module caller = Reflection.getCallerClass().getModule();
             if (caller != this) {
-                throw new IllegalStateException(caller + " != " + this);
+                throw new IllegalCallerException(caller + " != " + this);
             }
             implAddReads(other, true);
         }
@@ -533,8 +533,8 @@
         if (other == this && containsPackage(pn))
             return true;
 
-        // all packages in open modules are open
-        if (descriptor.isOpen())
+        // all packages in open and automatic modules are open
+        if (descriptor.isOpen() || descriptor.isAutomatic())
             return containsPackage(pn);
 
         // exported/opened via module declaration/descriptor
@@ -634,8 +634,7 @@
      * the given package to the given module.
      *
      * <p> This method has no effect if the package is already exported (or
-     * <em>open</em>) to the given module. It also has no effect if
-     * invoked on an {@link ModuleDescriptor#isOpen open} module. </p>
+     * <em>open</em>) to the given module. </p>
      *
      * @apiNote As specified in section 5.4.3 of the <cite>The Java&trade;
      * Virtual Machine Specification </cite>, if an attempt to resolve a
@@ -653,8 +652,9 @@
      * @throws IllegalArgumentException
      *         If {@code pn} is {@code null}, or this is a named module and the
      *         package {@code pn} is not a package in this module
-     * @throws IllegalStateException
-     *         If this is a named module and the caller is not this module
+     * @throws IllegalCallerException
+     *         If this is a named module and the caller's module is not this
+     *         module
      *
      * @jvms 5.4.3 Resolution
      * @see #isExported(String,Module)
@@ -665,10 +665,10 @@
             throw new IllegalArgumentException("package is null");
         Objects.requireNonNull(other);
 
-        if (isNamed() && !descriptor.isOpen()) {
+        if (isNamed()) {
             Module caller = Reflection.getCallerClass().getModule();
             if (caller != this) {
-                throw new IllegalStateException(caller + " != " + this);
+                throw new IllegalCallerException(caller + " != " + this);
             }
             implAddExportsOrOpens(pn, other, /*open*/false, /*syncVM*/true);
         }
@@ -686,8 +686,7 @@
      * access control checks.
      *
      * <p> This method has no effect if the package is already <em>open</em>
-     * to the given module. It also has no effect if invoked on an {@link
-     * ModuleDescriptor#isOpen open} module. </p>
+     * to the given module. </p>
      *
      * @param  pn
      *         The package name
@@ -699,9 +698,9 @@
      * @throws IllegalArgumentException
      *         If {@code pn} is {@code null}, or this is a named module and the
      *         package {@code pn} is not a package in this module
-     * @throws IllegalStateException
+     * @throws IllegalCallerException
      *         If this is a named module and this module has not opened the
-     *         package to at least the caller
+     *         package to at least the caller's module
      *
      * @see #isOpen(String,Module)
      * @see AccessibleObject#setAccessible(boolean)
@@ -713,10 +712,10 @@
             throw new IllegalArgumentException("package is null");
         Objects.requireNonNull(other);
 
-        if (isNamed() && !descriptor.isOpen()) {
+        if (isNamed()) {
             Module caller = Reflection.getCallerClass().getModule();
             if (caller != this && !isOpen(pn, caller))
-                throw new IllegalStateException(pn + " is not open to " + caller);
+                throw new IllegalCallerException(pn + " is not open to " + caller);
             implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
         }
 
@@ -767,8 +766,8 @@
         Objects.requireNonNull(other);
         Objects.requireNonNull(pn);
 
-        // all packages are open in unnamed and open modules
-        if (!isNamed() || descriptor.isOpen())
+        // all packages are open in unnamed, open, and automatic modules
+        if (!isNamed() || descriptor.isOpen() || descriptor.isAutomatic())
             return;
 
         // nothing to do if already exported/open to other
@@ -819,17 +818,17 @@
      * passed a reference to the service type by other code. This method is
      * a no-op when invoked on an unnamed module or an automatic module.
      *
-     * <p> This method does not cause {@link
-     * Configuration#resolveRequiresAndUses resolveRequiresAndUses} to be
-     * re-run. </p>
+     * <p> This method does not cause {@link Configuration#resolveAndBind
+     * resolveAndBind} to be re-run. </p>
      *
      * @param  service
      *         The service type
      *
      * @return this module
      *
-     * @throws IllegalStateException
-     *         If this is a named module and the caller is not this module
+     * @throws IllegalCallerException
+     *         If this is a named module and the caller's module is not this
+     *         module
      *
      * @see #canUse(Class)
      * @see ModuleDescriptor#uses()
@@ -841,7 +840,7 @@
         if (isNamed() && !descriptor.isAutomatic()) {
             Module caller = Reflection.getCallerClass().getModule();
             if (caller != this) {
-                throw new IllegalStateException(caller + " != " + this);
+                throw new IllegalCallerException(caller + " != " + this);
             }
             implAddUses(service);
         }
@@ -894,14 +893,13 @@
     // -- packages --
 
     // Additional packages that are added to the module at run-time.
-    // The field is volatile as it may be replaced at run-time
-    private volatile Set<String> extraPackages;
+    private volatile Map<String, Boolean> extraPackages;
 
     private boolean containsPackage(String pn) {
         if (descriptor.packages().contains(pn))
             return true;
-        Set<String> extraPackages = this.extraPackages;
-        if (extraPackages != null && extraPackages.contains(pn))
+        Map<String, Boolean> extraPackages = this.extraPackages;
+        if (extraPackages != null && extraPackages.containsKey(pn))
             return true;
         return false;
     }
@@ -915,7 +913,7 @@
      * added to the module, <a href="Proxy.html#dynamicmodule">dynamic modules</a>
      * for example, after it was loaded.
      *
-     * <p> For unnamed modules, this method is the equivalent of invoking the
+     * <p> For unnamed modules, this method is the equivalent to invoking the
      * {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of
      * this module's class loader and returning the array of package names. </p>
      *
@@ -930,12 +928,12 @@
         if (isNamed()) {
 
             Set<String> packages = descriptor.packages();
-            Set<String> extraPackages = this.extraPackages;
+            Map<String, Boolean> extraPackages = this.extraPackages;
             if (extraPackages == null) {
                 return packages.toArray(new String[0]);
             } else {
                 return Stream.concat(packages.stream(),
-                                     extraPackages.stream())
+                                     extraPackages.keySet().stream())
                         .toArray(String[]::new);
             }
 
@@ -955,10 +953,6 @@
      * Add a package to this module.
      *
      * @apiNote This method is for Proxy use.
-     *
-     * @apiNote This is an expensive operation, not expected to be used often.
-     * At this time then it does not validate that the package name is a
-     * valid java identifier.
      */
     void addPackage(String pn) {
         implAddPackage(pn, true);
@@ -976,49 +970,52 @@
     /**
      * Add a package to this module.
      *
-     * If {@code syncVM} is {@code true} then the VM is notified.
+     * If {@code syncVM} is {@code true} then the VM is notified. This method is
+     * a no-op if this is an unnamed module or the module already contains the
+     * package.
+     *
+     * @throws IllegalArgumentException if the package name is not legal
+     * @throws IllegalStateException if the package is defined to another module
      */
     private void implAddPackage(String pn, boolean syncVM) {
+        // no-op if unnamed module
         if (!isNamed())
-            throw new InternalError("adding package to unnamed module?");
-        if (descriptor.isOpen())
-            throw new InternalError("adding package to open module?");
+            return;
+
+        // no-op if module contains the package
+        if (containsPackage(pn))
+            return;
+
+        // check package name is legal for named modules
         if (pn.isEmpty())
-            throw new InternalError("adding <unnamed> package to module?");
-
-        if (descriptor.packages().contains(pn)) {
-            // already in module
-            return;
+            throw new IllegalArgumentException("Cannot add <unnamed> package");
+        for (int i=0; i<pn.length(); i++) {
+            char c = pn.charAt(i);
+            if (c == '/' || c == ';' || c == '[') {
+                throw new IllegalArgumentException("Illegal character: " + c);
+            }
         }
 
-        Set<String> extraPackages = this.extraPackages;
-        if (extraPackages != null && extraPackages.contains(pn)) {
-            // already added
-            return;
+        // create extraPackages if needed
+        Map<String, Boolean> extraPackages = this.extraPackages;
+        if (extraPackages == null) {
+            synchronized (this) {
+                extraPackages = this.extraPackages;
+                if (extraPackages == null)
+                    this.extraPackages = extraPackages = new ConcurrentHashMap<>();
+            }
         }
-        synchronized (this) {
-            // recheck under lock
-            extraPackages = this.extraPackages;
-            if (extraPackages != null) {
-                if (extraPackages.contains(pn)) {
-                    // already added
-                    return;
-                }
 
-                // copy the set
-                extraPackages = new HashSet<>(extraPackages);
-                extraPackages.add(pn);
-            } else {
-                extraPackages = Collections.singleton(pn);
+        // update VM first in case it fails. This is a no-op if another thread
+        // beats us to add the package first
+        if (syncVM) {
+            // throws IllegalStateException if defined to another module
+            addPackage0(this, pn);
+            if (descriptor.isOpen() || descriptor.isAutomatic()) {
+                addExportsToAll0(this, pn);
             }
-
-            // update VM first, just in case it fails
-            if (syncVM)
-                addPackage0(this, pn);
-
-            // replace with new set
-            this.extraPackages = extraPackages; // volatile write
         }
+        extraPackages.putIfAbsent(pn, Boolean.TRUE);
     }
 
 
@@ -1169,8 +1166,9 @@
                                             Map<String, Module> nameToModule,
                                             Module m)
     {
-        // The VM doesn't know about open modules so need to export all packages
-        if (descriptor.isOpen()) {
+        // The VM doesn't special case open or automatic modules so need to
+        // export all packages
+        if (descriptor.isOpen() || descriptor.isAutomatic()) {
             assert descriptor.opens().isEmpty();
             for (String source : descriptor.packages()) {
                 addExportsToAll0(m, source);
@@ -1375,35 +1373,44 @@
 
 
     /**
-     * Returns an input stream for reading a resource in this module. The
-     * {@code name} parameter is a {@code '/'}-separated path name that
-     * identifies the resource.
+     * Returns an input stream for reading a resource in this module.
+     * The {@code name} parameter is a {@code '/'}-separated path name that
+     * identifies the resource. As with {@link Class#getResourceAsStream
+     * Class.getResourceAsStream}, this method delegates to the module's class
+     * loader {@link ClassLoader#findResource(String,String)
+     * findResource(String,String)} method, invoking it with the module name
+     * (or {@code null} when the module is unnamed) and the name of the
+     * resource. If the resource name has a leading slash then it is dropped
+     * before delegation.
      *
-     * <p> A resource in a named modules may be <em>encapsulated</em> so that
+     * <p> A resource in a named module may be <em>encapsulated</em> so that
      * it cannot be located by code in other modules. Whether a resource can be
-     * located or not is determined as follows:
+     * located or not is determined as follows: </p>
      *
      * <ul>
-     *     <li> The <em>package name</em> of the resource is derived from the
-     *     subsequence of characters that precedes the last {@code '/'} and then
-     *     replacing each {@code '/'} character in the subsequence with
-     *     {@code '.'}. For example, the package name derived for a resource
-     *     named "{@code a/b/c/foo.properties}" is "{@code a.b.c}". </li>
+     *     <li> If the resource name ends with  "{@code .class}" then it is not
+     *     encapsulated. </li>
      *
-     *     <li> If the package name is a package in the module then the package
-     *     must be {@link #isOpen open} the module of the caller of this method.
-     *     If the package is not in the module then the resource is not
-     *     encapsulated. Resources in the unnamed package or "{@code META-INF}",
-     *     for example, are never encapsulated because they can never be
-     *     packages in a named module. </li>
+     *     <li> A <em>package name</em> is derived from the resource name. If
+     *     the package name is a {@link #getPackages() package} in the module
+     *     then the resource can only be located by the caller of this method
+     *     when the package is {@link #isOpen(String,Module) open} to at least
+     *     the caller's module. If the resource is not in a package in the module
+     *     then the resource is not encapsulated. </li>
+     * </ul>
      *
-     *     <li> As a special case, resources ending with "{@code .class}" are
-     *     never encapsulated. </li>
-     * </ul>
+     * <p> In the above, the <em>package name</em> for a resource is derived
+     * from the subsequence of characters that precedes the last {@code '/'} in
+     * the name and then replacing each {@code '/'} character in the subsequence
+     * with {@code '.'}. A leading slash is ignored when deriving the package
+     * name. As an example, the package name derived for a resource named
+     * "{@code a/b/c/foo.properties}" is "{@code a.b.c}". A resource name
+     * with the name "{@code META-INF/MANIFEST.MF}" is never encapsulated
+     * because "{@code META-INF}" is not a legal package name. </p>
      *
      * <p> This method returns {@code null} if the resource is not in this
      * module, the resource is encapsulated and cannot be located by the caller,
-     * or access to the resource is denied by the security manager.
+     * or access to the resource is denied by the security manager. </p>
      *
      * @param  name
      *         The resource name
@@ -1413,11 +1420,13 @@
      * @throws IOException
      *         If an I/O error occurs
      *
-     * @see java.lang.module.ModuleReader#open(String)
+     * @see Class#getResourceAsStream(String)
      */
     @CallerSensitive
     public InputStream getResourceAsStream(String name) throws IOException {
-        Objects.requireNonNull(name);
+        if (name.startsWith("/")) {
+            name = name.substring(1);
+        }
 
         if (isNamed() && !ResourceHelper.isSimpleResource(name)) {
             Module caller = Reflection.getCallerClass().getModule();
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,7 @@
 
 package java.lang.reflect;
 
+import java.lang.module.ModuleDescriptor;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
@@ -52,6 +53,9 @@
 import sun.security.action.GetPropertyAction;
 import sun.security.util.SecurityConstants;
 
+import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
+
+
 /**
  *
  * {@code Proxy} provides static methods for creating objects that act like instances
@@ -164,7 +168,8 @@
  * methods is specified as follows:
  *
  * <ol>
- * <li>If all the proxy interfaces are in <em>exported</em> packages:
+ * <li>If all the proxy interfaces are in <em>exported</em> or <em>open</em>
+ *     packages:
  * <ol type="a">
  * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
  *     <em>public</em> in a package exported by the
@@ -178,10 +183,11 @@
  *     <a href="#restrictions">not possible</a>.</li>
  * </ol>
  * </li>
- * <li>If at least one proxy interface is a <em>non-exported</em> package:
+ * <li>If at least one proxy interface is in a package that is
+ *     <em>non-exported</em> and <em>non-open</em>:
  * <ol type="a">
  * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
- *     <em>public</em> in a <em>non-exported</em> package of
+ *     <em>public</em> in a <em>non-exported</em>, <em>non-open</em> package of
  *     <a href="#dynamicmodule"><em>dynamic module</em>.</a>
  *     The names of the package and the module are unspecified.</li>
  *
@@ -195,21 +201,22 @@
  * </ol>
  *
  * <p>
- * Note that if proxy interfaces with a mix of accessibilities --
- * exported public, exported non-public, non-exported public, non-exported non-public --
- * are proxied by the same instance, then the proxy class's accessibility is
+ * Note that if proxy interfaces with a mix of accessibilities -- for example,
+ * an exported public interface and a non-exported non-public interface -- are
+ * proxied by the same instance, then the proxy class's accessibility is
  * governed by the least accessible proxy interface.
  * <p>
  * Note that it is possible for arbitrary code to obtain access to a proxy class
- * in an exported package with {@link AccessibleObject#setAccessible setAccessible},
- * whereas a proxy class in a non-exported package is never accessible to
+ * in an open package with {@link AccessibleObject#setAccessible setAccessible},
+ * whereas a proxy class in a non-open package is never accessible to
  * code outside the module of the proxy class.
  *
  * <p>
- * Throughout this specification, a "non-exported package" refers to a package that
- * is not exported to all modules. Specifically, it refers to a package that
- * either is not exported at all by its containing module or is exported in a
- * qualified fashion by its containing module.
+ * Throughout this specification, a "non-exported package" refers to a package
+ * that is not exported to all modules, and a "non-open package" refers to
+ * a package that is not open to all modules.  Specifically, these terms refer to
+ * a package that either is not exported/open by its containing module or is
+ * exported/open in a qualified fashion by its containing module.
  *
  * <h3><a name="dynamicmodule">Dynamic Modules</a></h3>
  * <p>
@@ -272,6 +279,8 @@
  * @author      Peter Jones
  * @see         InvocationHandler
  * @since       1.3
+ * @revised 9
+ * @spec JPMS
  */
 public class Proxy implements java.io.Serializable {
     private static final long serialVersionUID = -2222568056686623797L;
@@ -358,6 +367,8 @@
      *      to create a proxy instance instead.
      *
      * @see <a href="#membership">Package and Module Membership of Proxy Class</a>
+     * @revised 9
+     * @spec JPMS
      */
     @Deprecated
     @CallerSensitive
@@ -855,7 +866,11 @@
                 // create a dynamic module and setup module access
                 String mn = "jdk.proxy" + counter.incrementAndGet();
                 String pn = PROXY_PACKAGE_PREFIX + "." + mn;
-                Module m = Modules.defineModule(ld, mn, Collections.singleton(pn));
+                ModuleDescriptor descriptor =
+                    ModuleDescriptor.newModule(mn, Set.of(SYNTHETIC))
+                                    .packages(Set.of(pn))
+                                    .build();
+                Module m = Modules.defineModule(ld, descriptor, null);
                 Modules.addReads(m, Proxy.class.getModule());
                 // java.base to create proxy instance
                 Modules.addExports(m, pn, Object.class.getModule());
@@ -955,6 +970,8 @@
      *          {@code null}
      *
      * @see <a href="#membership">Package and Module Membership of Proxy Class</a>
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static Object newProxyInstance(ClassLoader loader,
@@ -1039,6 +1056,9 @@
      * @return  {@code true} if the class is a proxy class and
      *          {@code false} otherwise
      * @throws  NullPointerException if {@code cl} is {@code null}
+     *
+     * @revised 9
+     * @spec JPMS
      */
     public static boolean isProxyClass(Class<?> cl) {
         return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl);
--- a/jdk/src/java.base/share/classes/java/lang/reflect/package-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/package-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -45,5 +45,7 @@
  * members declared by a given class.
  *
  * @since 1.1
+ * @revised 9
+ * @spec JPMS
  */
 package java.lang.reflect;
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java	Fri Feb 10 08:57:42 2017 -0800
@@ -228,6 +228,7 @@
      *         allow creation of a class loader.
      *
      * @since 9
+     * @spec JPMS
      */
     public URLClassLoader(String name,
                           URL[] urls,
@@ -262,6 +263,7 @@
      *         creation of a class loader.
      *
      * @since 9
+     * @spec JPMS
      */
     public URLClassLoader(String name, URL[] urls, ClassLoader parent,
                           URLStreamHandlerFactory factory) {
@@ -558,6 +560,9 @@
      * @throws      IllegalArgumentException if the package name is
      *              already defined by this class loader
      * @return      the newly defined {@code Package} object
+     *
+     * @revised 9
+     * @spec JPMS
      */
     protected Package definePackage(String name, Manifest man, URL url) {
         String path = name.replace('.', '/').concat("/");
--- a/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java	Fri Feb 10 08:57:42 2017 -0800
@@ -125,6 +125,7 @@
      *         doesn't allow creation of a class loader.
      *
      * @since 9
+     * @spec JPMS
      */
     protected SecureClassLoader(String name, ClassLoader parent) {
         super(name, parent);
--- a/jdk/src/java.base/share/classes/java/security/Security.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/security/Security.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,11 +25,12 @@
 
 package java.security;
 
-import java.lang.reflect.*;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.io.*;
 import java.net.URL;
+
+import jdk.internal.misc.SharedSecrets;
 import sun.security.util.Debug;
 import sun.security.util.PropertyExpander;
 
@@ -800,9 +801,6 @@
      * "package.definition", we need to signal to the SecurityManager
      * class that the value has just changed, and that it should
      * invalidate it's local cache values.
-     *
-     * Rather than create a new API entry for this function,
-     * we use reflection to set a private variable.
      */
     private static void invalidateSMCache(String key) {
 
@@ -810,42 +808,8 @@
         final boolean pd = key.equals("package.definition");
 
         if (pa || pd) {
-            AccessController.doPrivileged(new PrivilegedAction<>() {
-                public Void run() {
-                    try {
-                        /* Get the class via the bootstrap class loader. */
-                        Class<?> cl = Class.forName(
-                            "java.lang.SecurityManager", false, null);
-                        Field f = null;
-                        boolean accessible = false;
-
-                        if (pa) {
-                            f = cl.getDeclaredField("packageAccessValid");
-                            accessible = f.isAccessible();
-                            f.setAccessible(true);
-                        } else {
-                            f = cl.getDeclaredField("packageDefinitionValid");
-                            accessible = f.isAccessible();
-                            f.setAccessible(true);
-                        }
-                        f.setBoolean(f, false);
-                        f.setAccessible(accessible);
-                    }
-                    catch (Exception e1) {
-                        /* If we couldn't get the class, it hasn't
-                         * been loaded yet.  If there is no such
-                         * field, we shouldn't try to set it.  There
-                         * shouldn't be a security execption, as we
-                         * are loaded by boot class loader, and we
-                         * are inside a doPrivileged() here.
-                         *
-                         * NOOP: don't do anything...
-                         */
-                    }
-                    return null;
-                }  /* run */
-            });  /* PrivilegedAction */
-        }  /* if */
+            SharedSecrets.getJavaLangAccess().invalidatePackageAccessCache();
+        }
     }
 
     private static void check(String directive) {
--- a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java	Fri Feb 10 08:57:42 2017 -0800
@@ -350,6 +350,8 @@
  * @see MissingResourceException
  * @see ResourceBundleProvider
  * @since 1.1
+ * @revised 9
+ * @spec JPMS
  */
 public abstract class ResourceBundle {
 
@@ -870,6 +872,8 @@
      * @throws UnsupportedOperationException
      *         if this method is called in a named module
      * @since 1.6
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static final ResourceBundle getBundle(String baseName,
@@ -938,6 +942,7 @@
      *         specified module
      * @return a resource bundle for the given base name and the default locale
      * @since 9
+     * @spec JPMS
      * @see ResourceBundleProvider
      */
     @CallerSensitive
@@ -991,6 +996,7 @@
      *         be found in the specified {@code module}
      * @return a resource bundle for the given base name and locale in the module
      * @since 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static ResourceBundle getBundle(String baseName, Locale targetLocale, Module module) {
@@ -1036,6 +1042,8 @@
      * @throws UnsupportedOperationException
      *         if this method is called in a named module
      * @since 1.6
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static final ResourceBundle getBundle(String baseName, Locale targetLocale,
@@ -1243,6 +1251,8 @@
      * @exception MissingResourceException
      *        if no resource bundle for the specified base name can be found
      * @since 1.2
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static ResourceBundle getBundle(String baseName, Locale locale,
@@ -1465,6 +1475,8 @@
      * @throws UnsupportedOperationException
      *         if this method is called in a named module
      * @since 1.6
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static ResourceBundle getBundle(String baseName, Locale targetLocale,
@@ -2194,6 +2206,8 @@
      * by the caller's module.
      *
      * @since 1.6
+     * @revised 9
+     * @spec JPMS
      * @see ResourceBundle.Control#getTimeToLive(String,Locale)
      */
     @CallerSensitive
@@ -2475,6 +2489,8 @@
      * of {@link ResourceBundleControlProvider} are ignored in named modules.
      *
      * @since 1.6
+     * @revised 9
+     * @spec JPMS
      * @see java.util.spi.ResourceBundleProvider
      */
     public static class Control {
@@ -3103,6 +3119,8 @@
          *        if an error occurred when reading resources using
          *        any I/O operations
          * @see java.util.spi.ResourceBundleProvider#getBundle(String, Locale)
+         * @revised 9
+         * @spec JPMS
          */
         public ResourceBundle newBundle(String baseName, Locale locale, String format,
                                         ClassLoader loader, boolean reload)
--- a/jdk/src/java.base/share/classes/java/util/ServiceLoader.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/ServiceLoader.java	Fri Feb 10 08:57:42 2017 -0800
@@ -119,7 +119,7 @@
  * and deployed as an explicit module must have an appropriate <i>uses</i>
  * clause in its <i>module descriptor</i> to declare that the module uses
  * implementations of the service. A corresponding requirement is that a
- * provider deployed as a named module must have an appropriate
+ * provider deployed as an explicit module must have an appropriate
  * <i>provides</i> clause in its module descriptor to declare that the module
  * provides an implementation of the service. The <i>uses</i> and
  * <i>provides</i> allow consumers of a service to be <i>linked</i> to modules
@@ -203,8 +203,11 @@
  *     ordering of modules in a layer, is not defined. </li>
  *
  *     <li> If a named module declares more than one provider then the providers
- *     are located in the order that they appear in the {@code provides} table of
- *     the {@code Module} class file attribute ({@code module-info.class}). </li>
+ *     are located in the iteration order of the {@link
+ *     java.lang.module.ModuleDescriptor.Provides#providers() providers} list.
+ *     Providers added dynamically by instrumentation agents ({@link
+ *     java.lang.instrument.Instrumentation#redefineModule redefineModule})
+ *     are always located after providers declared by the module. </li>
  *
  *     <li> When locating providers in unnamed modules then the ordering is
  *     based on the order that the class loader's {@link
@@ -335,6 +338,8 @@
  *
  * @author Mark Reinhold
  * @since 1.6
+ * @revised 9
+ * @spec JPMS
  */
 
 public final class ServiceLoader<S>
@@ -386,6 +391,7 @@
      *
      * @param  <S> The service type
      * @since 9
+     * @spec JPMS
      */
     public static interface Provider<S> extends Supplier<S> {
         /**
@@ -927,26 +933,28 @@
             } else {
                 catalog = ServicesCatalog.getServicesCatalogOrNull(loader);
             }
-            Stream<ServiceProvider> stream1;
+            List<ServiceProvider> providers;
             if (catalog == null) {
-                stream1 = Stream.empty();
+                providers = List.of();
             } else {
-                stream1 = catalog.findServices(serviceName).stream();
+                providers = catalog.findServices(serviceName);
             }
 
             // modules in custom layers that define modules to the class loader
-            Stream<ServiceProvider> stream2;
             if (loader == null) {
-                stream2 = Stream.empty();
+                return providers.iterator();
             } else {
+                List<ServiceProvider> allProviders = new ArrayList<>(providers);
                 Layer bootLayer = Layer.boot();
-                stream2 = JLRM_ACCESS.layers(loader)
-                        .filter(l -> (l != bootLayer))
-                        .map(l -> providers(l))
-                        .flatMap(List::stream);
+                Iterator<Layer> iterator = JLRM_ACCESS.layers(loader).iterator();
+                while (iterator.hasNext()) {
+                    Layer layer = iterator.next();
+                    if (layer != bootLayer) {
+                        allProviders.addAll(providers(layer));
+                    }
+                }
+                return allProviders.iterator();
             }
-
-            return Stream.concat(stream1, stream2).iterator();
         }
 
         @Override
@@ -1214,6 +1222,9 @@
      *
      * @return  An iterator that lazily loads providers for this loader's
      *          service
+     *
+     * @revised 9
+     * @spec JPMS
      */
     public Iterator<S> iterator() {
 
@@ -1279,8 +1290,10 @@
      * provider to be loaded. </p>
      *
      * <p> If this loader's provider caches are cleared by invoking the {@link
-     * #reload() reload} method then existing streams for this service
-     * loader should be discarded. </p>
+     * #reload() reload} method then existing streams for this service loader
+     * should be discarded. The returned stream's source {@code Spliterator} is
+     * <em>fail-fast</em> and will throw {@link ConcurrentModificationException}
+     * if the provider cache has been cleared. </p>
      *
      * <p> The following examples demonstrate usage. The first example
      * creates a stream of providers, the second example is the same except
@@ -1300,6 +1313,7 @@
      * @return  A stream that lazily loads providers for this loader's service
      *
      * @since 9
+     * @spec JPMS
      */
     public Stream<Provider<S>> stream() {
         // use cached providers as the source when all providers loaded
@@ -1414,6 +1428,9 @@
      *         if the service type is not accessible to the caller or the
      *         caller is in an explicit module and its module descriptor does
      *         not declare that it uses {@code service}
+     *
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static <S> ServiceLoader<S> load(Class<S> service,
@@ -1457,6 +1474,9 @@
      *         if the service type is not accessible to the caller or the
      *         caller is in an explicit module and its module descriptor does
      *         not declare that it uses {@code service}
+     *
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static <S> ServiceLoader<S> load(Class<S> service) {
@@ -1490,6 +1510,9 @@
      *         if the service type is not accessible to the caller or the
      *         caller is in an explicit module and its module descriptor does
      *         not declare that it uses {@code service}
+     *
+     * @revised 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static <S> ServiceLoader<S> loadInstalled(Class<S> service) {
@@ -1522,6 +1545,7 @@
      *         not declare that it uses {@code service}
      *
      * @since 9
+     * @spec JPMS
      */
     @CallerSensitive
     public static <S> ServiceLoader<S> load(Layer layer, Class<S> service) {
@@ -1551,6 +1575,7 @@
      *         or error is thrown when locating or instantiating the provider.
      *
      * @since 9
+     * @spec JPMS
      */
     public Optional<S> findFirst() {
         Iterator<S> iterator = iterator();
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java	Fri Feb 10 08:57:42 2017 -0800
@@ -40,6 +40,7 @@
 import java.lang.invoke.VarHandle;
 import java.security.AccessController;
 import java.security.AccessControlContext;
+import java.security.Permission;
 import java.security.Permissions;
 import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
@@ -132,24 +133,30 @@
  *  </tr>
  * </table>
  *
- * <p>The common pool is by default constructed with default
- * parameters, but these may be controlled by setting the following
- * {@linkplain System#getProperty system properties}:
+ * <p>The parameters used to construct the common pool may be controlled by
+ * setting the following {@linkplain System#getProperty system properties}:
  * <ul>
  * <li>{@code java.util.concurrent.ForkJoinPool.common.parallelism}
  * - the parallelism level, a non-negative integer
  * <li>{@code java.util.concurrent.ForkJoinPool.common.threadFactory}
- * - the class name of a {@link ForkJoinWorkerThreadFactory}
+ * - the class name of a {@link ForkJoinWorkerThreadFactory}.
+ * The {@linkplain ClassLoader#getSystemClassLoader() system class loader}
+ * is used to load this class.
  * <li>{@code java.util.concurrent.ForkJoinPool.common.exceptionHandler}
- * - the class name of a {@link UncaughtExceptionHandler}
+ * - the class name of a {@link UncaughtExceptionHandler}.
+ * The {@linkplain ClassLoader#getSystemClassLoader() system class loader}
+ * is used to load this class.
  * <li>{@code java.util.concurrent.ForkJoinPool.common.maximumSpares}
  * - the maximum number of allowed extra threads to maintain target
  * parallelism (default 256).
  * </ul>
- * If a {@link SecurityManager} is present and no factory is
- * specified, then the default pool uses a factory supplying
- * threads that have no {@link Permissions} enabled.
- * The system class loader is used to load these classes.
+ * If no thread factory is supplied via a system property, then the
+ * common pool uses a factory that uses the system class loader as the
+ * {@linkplain Thread#getContextClassLoader() thread context class loader}.
+ * In addition, if a {@link SecurityManager} is present, then
+ * the common pool uses a factory supplying threads that have no
+ * {@link Permissions} enabled.
+ *
  * Upon any error in establishing these settings, default parameters
  * are used. It is possible to disable or limit the use of threads in
  * the common pool by setting the parallelism property to zero, and/or
@@ -638,20 +645,38 @@
          *
          * @param pool the pool this thread works in
          * @return the new worker thread, or {@code null} if the request
-         *         to create a thread is rejected.
+         *         to create a thread is rejected
          * @throws NullPointerException if the pool is null
          */
         public ForkJoinWorkerThread newThread(ForkJoinPool pool);
     }
 
+    static AccessControlContext contextWithPermissions(Permission ... perms) {
+        Permissions permissions = new Permissions();
+        for (Permission perm : perms)
+            permissions.add(perm);
+        return new AccessControlContext(
+            new ProtectionDomain[] { new ProtectionDomain(null, permissions) });
+    }
+
     /**
      * Default ForkJoinWorkerThreadFactory implementation; creates a
-     * new ForkJoinWorkerThread.
+     * new ForkJoinWorkerThread using the system class loader as the
+     * thread context class loader.
      */
     private static final class DefaultForkJoinWorkerThreadFactory
         implements ForkJoinWorkerThreadFactory {
+        private static final AccessControlContext ACC = contextWithPermissions(
+            new RuntimePermission("getClassLoader"),
+            new RuntimePermission("setContextClassLoader"));
+
         public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
-            return new ForkJoinWorkerThread(pool);
+            return AccessController.doPrivileged(
+                new PrivilegedAction<>() {
+                    public ForkJoinWorkerThread run() {
+                        return new ForkJoinWorkerThread(
+                            pool, ClassLoader.getSystemClassLoader()); }},
+                ACC);
         }
     }
 
@@ -3244,26 +3269,20 @@
          * An ACC to restrict permissions for the factory itself.
          * The constructed workers have no permissions set.
          */
-        private static final AccessControlContext INNOCUOUS_ACC;
-        static {
-            Permissions innocuousPerms = new Permissions();
-            innocuousPerms.add(modifyThreadPermission);
-            innocuousPerms.add(new RuntimePermission(
-                                   "enableContextClassLoaderOverride"));
-            innocuousPerms.add(new RuntimePermission(
-                                   "modifyThreadGroup"));
-            INNOCUOUS_ACC = new AccessControlContext(new ProtectionDomain[] {
-                    new ProtectionDomain(null, innocuousPerms)
-                });
-        }
+        private static final AccessControlContext ACC = contextWithPermissions(
+            modifyThreadPermission,
+            new RuntimePermission("enableContextClassLoaderOverride"),
+            new RuntimePermission("modifyThreadGroup"),
+            new RuntimePermission("getClassLoader"),
+            new RuntimePermission("setContextClassLoader"));
 
         public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
-            return AccessController.doPrivileged(new PrivilegedAction<>() {
-                public ForkJoinWorkerThread run() {
-                    return new ForkJoinWorkerThread.
-                        InnocuousForkJoinWorkerThread(pool);
-                }}, INNOCUOUS_ACC);
+            return AccessController.doPrivileged(
+                new PrivilegedAction<>() {
+                    public ForkJoinWorkerThread run() {
+                        return new ForkJoinWorkerThread.
+                            InnocuousForkJoinWorkerThread(pool); }},
+                ACC);
         }
     }
-
 }
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java	Fri Feb 10 08:57:42 2017 -0800
@@ -36,6 +36,8 @@
 package java.util.concurrent;
 
 import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
 
 /**
@@ -88,11 +90,26 @@
     }
 
     /**
+     * Version for use by the default pool.  Supports setting the
+     * context class loader.  This is a separate constructor to avoid
+     * affecting the protected constructor.
+     */
+    ForkJoinWorkerThread(ForkJoinPool pool, ClassLoader ccl) {
+        super("aForkJoinWorkerThread");
+        super.setContextClassLoader(ccl);
+        this.pool = pool;
+        this.workQueue = pool.registerWorker(this);
+    }
+
+    /**
      * Version for InnocuousForkJoinWorkerThread.
      */
-    ForkJoinWorkerThread(ForkJoinPool pool, ThreadGroup threadGroup,
+    ForkJoinWorkerThread(ForkJoinPool pool,
+                         ClassLoader ccl,
+                         ThreadGroup threadGroup,
                          AccessControlContext acc) {
         super(threadGroup, null, "aForkJoinWorkerThread");
+        super.setContextClassLoader(ccl);
         ThreadLocalRandom.setInheritedAccessControlContext(this, acc);
         ThreadLocalRandom.eraseThreadLocals(this); // clear before registering
         this.pool = pool;
@@ -179,20 +196,21 @@
 
     /**
      * A worker thread that has no permissions, is not a member of any
-     * user-defined ThreadGroup, and erases all ThreadLocals after
+     * user-defined ThreadGroup, uses the system class loader as
+     * thread context class loader, and erases all ThreadLocals after
      * running each top-level task.
      */
     static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread {
         /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
         private static final ThreadGroup innocuousThreadGroup =
-                java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction<>() {
-                        public ThreadGroup run() {
-                            ThreadGroup group = Thread.currentThread().getThreadGroup();
-                            for (ThreadGroup p; (p = group.getParent()) != null; )
-                                group = p;
-                            return new ThreadGroup(group, "InnocuousForkJoinWorkerThreadGroup");
-                        }});
+            java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<>() {
+                    public ThreadGroup run() {
+                        ThreadGroup group = Thread.currentThread().getThreadGroup();
+                        for (ThreadGroup p; (p = group.getParent()) != null; )
+                            group = p;
+                        return new ThreadGroup(group, "InnocuousForkJoinWorkerThreadGroup");
+                    }});
 
         /** An AccessControlContext supporting no privileges */
         private static final AccessControlContext INNOCUOUS_ACC =
@@ -202,7 +220,10 @@
                 });
 
         InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
-            super(pool, innocuousThreadGroup, INNOCUOUS_ACC);
+            super(pool,
+                  ClassLoader.getSystemClassLoader(),
+                  innocuousThreadGroup,
+                  INNOCUOUS_ACC);
         }
 
         @Override // to erase ThreadLocals
@@ -210,11 +231,6 @@
             ThreadLocalRandom.eraseThreadLocals(this);
         }
 
-        @Override // to always report system loader
-        public ClassLoader getContextClassLoader() {
-            return ClassLoader.getSystemClassLoader();
-        }
-
         @Override // to silently fail
         public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }
 
--- a/jdk/src/java.base/share/classes/java/util/spi/AbstractResourceBundleProvider.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/spi/AbstractResourceBundleProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -81,6 +81,7 @@
  *     ResourceBundleProvider Service Providers</a>
  *
  * @since 9
+ * @spec JPMS
  */
 public abstract class AbstractResourceBundleProvider implements ResourceBundleProvider {
     private static final JavaUtilResourceBundleAccess RB_ACCESS =
--- a/jdk/src/java.base/share/classes/java/util/spi/ResourceBundleControlProvider.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/spi/ResourceBundleControlProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -44,6 +44,8 @@
  *
  * @author Masayoshi Okutsu
  * @since 1.8
+ * @revised 9
+ * @spec JPMS
  * @see ResourceBundle#getBundle(String, java.util.Locale, ClassLoader, ResourceBundle.Control)
  *      ResourceBundle.getBundle
  * @see java.util.ServiceLoader#load(Class)
--- a/jdk/src/java.base/share/classes/java/util/spi/ResourceBundleProvider.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/java/util/spi/ResourceBundleProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -57,6 +57,7 @@
  * @see <a href="../ResourceBundle.html#RBP_support">
  *     ResourceBundleProvider Service Providers</a>
  * @since 9
+ * @spec JPMS
  */
 public interface ResourceBundleProvider {
     /**
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java	Fri Feb 10 08:57:42 2017 -0800
@@ -186,7 +186,7 @@
     public Entry getEntry(Section section, String name) {
         String entry = section.jmodDir() + "/" + name;
         ZipEntry ze = zipfile.getEntry(entry);
-        return (ze != null) ? new Entry(ze) : null;
+        return (ze == null || ze.isDirectory()) ? null : new Entry(ze);
     }
 
     /**
@@ -201,7 +201,7 @@
     {
         String entry = section.jmodDir() + "/" + name;
         ZipEntry e = zipfile.getEntry(entry);
-        if (e == null) {
+        if (e == null || e.isDirectory()) {
             throw new IOException(name + " not found: " + file);
         }
         return zipfile.getInputStream(e);
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java	Fri Feb 10 08:57:42 2017 -0800
@@ -57,8 +57,9 @@
 import java.util.jar.Manifest;
 import java.util.stream.Stream;
 
+import jdk.internal.misc.VM;
 import jdk.internal.module.ModulePatcher.PatchedModuleReader;
-import jdk.internal.misc.VM;
+import jdk.internal.module.SystemModules;
 
 
 /**
@@ -135,7 +136,7 @@
 
     // maps package name to loaded module for modules in the boot layer
     private static final Map<String, LoadedModule> packageToModule
-        = new ConcurrentHashMap<>(1024);
+        = new ConcurrentHashMap<>(SystemModules.PACKAGES_IN_BOOT_LAYER);
 
     // maps a module name to a module reference
     private final Map<String, ModuleReference> nameToModule;
@@ -922,13 +923,13 @@
      * Returns the ModuleReader for the given module.
      */
     private ModuleReader moduleReaderFor(ModuleReference mref) {
-        return moduleToReader.computeIfAbsent(mref, m -> createModuleReader(mref));
+        return moduleToReader.computeIfAbsent(mref, BuiltinClassLoader::createModuleReader);
     }
 
     /**
      * Creates a ModuleReader for the given module.
      */
-    private ModuleReader createModuleReader(ModuleReference mref) {
+    private static ModuleReader createModuleReader(ModuleReference mref) {
         try {
             return mref.open();
         } catch (IOException e) {
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/ResourceHelper.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ResourceHelper.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -24,6 +24,10 @@
  */
 package jdk.internal.loader;
 
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
 import jdk.internal.module.Checks;
 
 /**
@@ -34,7 +38,8 @@
     private ResourceHelper() { }
 
     /**
-     * Returns the <em>package name</em> for a resource.
+     * Returns the <em>package name</em> for a resource or the empty package if
+     * the resource name does not contain a slash.
      */
     public static String getPackageName(String name) {
         int index = name.lastIndexOf('/');
@@ -46,19 +51,75 @@
     }
 
     /**
-     * Returns true if the resource is a <em>simple resource</em> that can
-     * never be encapsulated. Resources ending in "{@code .class}" or where
-     * the package name is not a Java identifier are resources that can
-     * never be encapsulated.
+     * Returns true if the resource is a <em>simple resource</em>. Simple
+     * resources can never be encapsulated. Resources ending in "{@code .class}"
+     * or where the package name is not a legal package name can not be
+     * encapsulated.
      */
     public static boolean isSimpleResource(String name) {
         int len = name.length();
         if (len > 6 && name.endsWith(".class")) {
             return true;
         }
-        if (!Checks.isJavaIdentifier(getPackageName(name))) {
+        if (!Checks.isPackageName(getPackageName(name))) {
             return true;
         }
         return false;
     }
+
+    /**
+     * Converts a resource name to a file path. Returns {@code null} if the
+     * resource name cannot be converted into a file path. Resource names
+     * with empty elements, or elements that are "." or ".." are rejected,
+     * as is a resource name that translates to a file path with a root
+     * component.
+     */
+    public static Path toFilePath(String name) {
+        // scan the resource name to eagerly reject obviously invalid names
+        int next;
+        int off = 0;
+        while ((next = name.indexOf('/', off)) != -1) {
+            int len = next - off;
+            if (!mayTranslate(name, off, len)) {
+                return null;
+            }
+            off = next + 1;
+        }
+        int rem = name.length() - off;
+        if (!mayTranslate(name, off, rem)) {
+            return null;
+        }
+
+        // convert to file path
+        Path path;
+        if (File.separatorChar == '/') {
+            path = Paths.get(name);
+        } else {
+            // not allowed to embed file separators
+            if (name.contains(File.separator))
+                return null;
+            path = Paths.get(name.replace('/', File.separatorChar));
+        }
+
+        // file path not allowed to have root component
+        return (path.getRoot() == null) ? path : null;
+    }
+
+    /**
+     * Returns {@code true} if the element in a resource name is a candidate
+     * to translate to the element of a file path.
+     */
+    private static boolean mayTranslate(String name, int off, int len) {
+        if (len <= 2) {
+            if (len == 0)
+                return false;
+            boolean starsWithDot = (name.charAt(off) == '.');
+            if (len == 1 && starsWithDot)
+                return false;
+            if (len == 2 && starsWithDot && (name.charAt(off+1) == '.'))
+                return false;
+        }
+        return true;
+    }
+
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java	Fri Feb 10 08:57:42 2017 -0800
@@ -174,4 +174,9 @@
      * Invokes Long.fastUUID
      */
     String fastUUID(long lsb, long msb);
+
+    /**
+     * Invalidate package access cache
+     */
+    void invalidatePackageAccessCache();
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -59,20 +59,21 @@
      */
     ModuleDescriptor.Builder newModuleBuilder(String mn,
                                               boolean strict,
-                                              boolean open,
-                                              boolean synthetic);
+                                              Set<ModuleDescriptor.Modifier> ms);
+
+    /**
+     * Returns a snapshot of the packages in the module.
+     */
+    Set<String> packages(ModuleDescriptor.Builder builder);
 
     /**
-     * Returns the set of packages that are exported (unconditionally or
-     * unconditionally).
+     * Adds a dependence on a module with the given (possibly un-parsable)
+     * version string.
      */
-    Set<String> exportedPackages(ModuleDescriptor.Builder builder);
-
-    /**
-     * Returns the set of packages that are opened (unconditionally or
-     * unconditionally).
-     */
-    Set<String> openPackages(ModuleDescriptor.Builder builder);
+    void requires(ModuleDescriptor.Builder builder,
+                  Set<Requires.Modifier> ms,
+                  String mn,
+                  String compiledVersion);
 
     /**
      * Returns a {@code ModuleDescriptor.Requires} of the given modifiers
@@ -114,23 +115,11 @@
     Provides newProvides(String service, List<String> providers);
 
     /**
-     * Returns a {@code ModuleDescriptor.Version} of the given version.
-     */
-    Version newVersion(String v);
-
-    /**
-     * Clones the given module descriptor with an augmented set of packages
-     */
-    ModuleDescriptor newModuleDescriptor(ModuleDescriptor md, Set<String> pkgs);
-
-    /**
      * Returns a new {@code ModuleDescriptor} instance.
      */
     ModuleDescriptor newModuleDescriptor(String name,
                                          Version version,
-                                         boolean open,
-                                         boolean automatic,
-                                         boolean synthetic,
+                                         Set<ModuleDescriptor.Modifier> ms,
                                          Set<Requires> requires,
                                          Set<Exports> exports,
                                          Set<Opens> opens,
@@ -148,9 +137,9 @@
      * and the empty configuration as the parent. The post resolution
      * checks are optionally run.
      */
-    Configuration resolveRequiresAndUses(ModuleFinder finder,
-                                         Collection<String> roots,
-                                         boolean check,
-                                         PrintStream traceOutput);
+    Configuration resolveAndBind(ModuleFinder finder,
+                                 Collection<String> roots,
+                                 boolean check,
+                                 PrintStream traceOutput);
 
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Builder.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Builder.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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 @@
 import jdk.internal.misc.SharedSecrets;
 
 /**
- * This builder is optimized for reconstituting ModuleDescriptor
+ * This builder is optimized for reconstituting the {@code ModuleDescriptor}s
  * for system modules.  The validation should be done at jlink time.
  *
  * 1. skip name validation
@@ -136,9 +136,7 @@
     }
 
     final String name;
-    boolean open;
-    boolean automatic;
-    boolean synthetic;
+    boolean open, synthetic, mandated;
     Set<Requires> requires;
     Set<Exports> exports;
     Set<Opens> opens;
@@ -165,13 +163,13 @@
         return this;
     }
 
-    Builder automatic(boolean value) {
-        this.automatic = value;
+    Builder synthetic(boolean value) {
+        this.synthetic = value;
         return this;
     }
 
-    Builder synthetic(boolean value) {
-        this.synthetic = value;
+    Builder mandated(boolean value) {
+        this.mandated = value;
         return this;
     }
 
@@ -228,13 +226,10 @@
      *
      * @throws IllegalArgumentException if {@code v} is null or cannot be
      *         parsed as a version string
-     * @throws IllegalStateException if the module version is already set
      *
      * @see Version#parse(String)
      */
     public Builder version(String v) {
-        if (version != null)
-            throw new IllegalStateException("module version already set");
         Version ver = cachedVersion;
         if (ver != null && v.equals(ver.toString())) {
             version = ver;
@@ -246,63 +241,63 @@
 
     /**
      * Sets the module main class.
-     *
-     * @throws IllegalStateException if already set
      */
     public Builder mainClass(String mc) {
-        if (mainClass != null)
-            throw new IllegalStateException("main class already set");
         mainClass = mc;
         return this;
     }
 
     /**
      * Sets the OS name.
-     *
-     * @throws IllegalStateException if already set
      */
     public Builder osName(String name) {
-        if (osName != null)
-            throw new IllegalStateException("OS name already set");
         this.osName = name;
         return this;
     }
 
     /**
      * Sets the OS arch.
-     *
-     * @throws IllegalStateException if already set
      */
     public Builder osArch(String arch) {
-        if (osArch != null)
-            throw new IllegalStateException("OS arch already set");
         this.osArch = arch;
         return this;
     }
 
     /**
      * Sets the OS version.
-     *
-     * @throws IllegalStateException if already set
      */
     public Builder osVersion(String version) {
-        if (osVersion != null)
-            throw new IllegalStateException("OS version already set");
         this.osVersion = version;
         return this;
     }
 
     /**
+     * Returns an immutable set of the module modifiers derived from the flags.
+     */
+    private Set<ModuleDescriptor.Modifier> modifiers() {
+        int n = 0;
+        if (open) n++;
+        if (synthetic) n++;
+        if (mandated) n++;
+        if (n == 0) {
+            return Collections.emptySet();
+        } else {
+            ModuleDescriptor.Modifier[] mods = new ModuleDescriptor.Modifier[n];
+            if (open) mods[--n] = ModuleDescriptor.Modifier.OPEN;
+            if (synthetic) mods[--n] = ModuleDescriptor.Modifier.SYNTHETIC;
+            if (mandated) mods[--n] = ModuleDescriptor.Modifier.MANDATED;
+            return Set.of(mods);
+        }
+    }
+
+    /**
      * Builds a {@code ModuleDescriptor} from the components.
      */
     public ModuleDescriptor build(int hashCode) {
         assert name != null;
-
         return JLMA.newModuleDescriptor(name,
                                         version,
-                                        open,
-                                        automatic,
-                                        synthetic,
+                                        modifiers(),
                                         requires,
                                         exports,
                                         opens,
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Checks.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Checks.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -26,7 +26,7 @@
 package jdk.internal.module;
 
 /**
- * Utility class for checking module name and binary names.
+ * Utility class for checking module, package, and class names.
  */
 
 public final class Checks {
@@ -58,8 +58,6 @@
             throw new IllegalArgumentException(name + ": Invalid module name"
                     + ": '" + id + "' is not a Java identifier");
         }
-        //if (!Character.isJavaIdentifierStart(last))
-        //    throw new IllegalArgumentException(name + ": Module name ends in digit");
         return name;
     }
 
@@ -77,8 +75,6 @@
         int last = isJavaIdentifier(name, off, name.length() - off);
         if (last == -1)
             return false;
-        //if (!Character.isJavaIdentifierStart(last))
-        //    return false;
         return true;
     }
 
@@ -89,40 +85,62 @@
      *         package name
      */
     public static String requirePackageName(String name) {
-        return requireBinaryName("package name", name);
+        return requireTypeName("package name", name);
     }
 
     /**
-     * Checks a name to ensure that it's a legal type name.
+     * Returns {@code true} if the given name is a legal package name.
+     */
+    public static boolean isPackageName(String name) {
+        return isTypeName(name);
+    }
+
+    /**
+     * Checks a name to ensure that it's a legal qualified class name
      *
      * @throws IllegalArgumentException if name is null or not a legal
-     *         type name
+     *         qualified class name
      */
     public static String requireServiceTypeName(String name) {
-        return requireBinaryName("service type name", name);
+        return requireQualifiedClassName("service type name", name);
     }
 
     /**
-     * Checks a name to ensure that it's a legal type name.
+     * Checks a name to ensure that it's a legal qualified class name.
      *
      * @throws IllegalArgumentException if name is null or not a legal
-     *         type name
+     *         qualified class name
      */
     public static String requireServiceProviderName(String name) {
-        return requireBinaryName("service provider name", name);
+        return requireQualifiedClassName("service provider name", name);
     }
 
     /**
-     * Returns {@code true} if the given name is a legal binary name.
+     * Checks a name to ensure that it's a legal qualified class name in
+     * a named package.
+     *
+     * @throws IllegalArgumentException if name is null or not a legal
+     *         qualified class name in a named package
      */
-    public static boolean isJavaIdentifier(String name) {
-        return isBinaryName(name);
+    public static String requireQualifiedClassName(String what, String name) {
+        requireTypeName(what, name);
+        if (name.indexOf('.') == -1)
+            throw new IllegalArgumentException(name + ": is not a qualified name of"
+                                               + " a Java class in a named package");
+        return name;
     }
 
     /**
-     * Returns {@code true} if the given name is a legal binary name.
+     * Returns {@code true} if the given name is a legal class name.
      */
-    public static boolean isBinaryName(String name) {
+    public static boolean isClassName(String name) {
+        return isTypeName(name);
+    }
+
+    /**
+     * Returns {@code true} if the given name is a legal type name.
+     */
+    private static boolean isTypeName(String name) {
         int next;
         int off = 0;
         while ((next = name.indexOf('.', off)) != -1) {
@@ -135,12 +153,12 @@
     }
 
     /**
-     * Checks if the given name is a legal binary name.
+     * Checks if the given name is a legal type name.
      *
      * @throws IllegalArgumentException if name is null or not a legal
-     *         binary name
+     *         type name
      */
-    public static String requireBinaryName(String what, String name) {
+    private static String requireTypeName(String what, String name) {
         if (name == null)
             throw new IllegalArgumentException("Null " + what);
         int next;
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -26,6 +26,7 @@
 package jdk.internal.module;
 
 import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Builder;
 import java.lang.module.ModuleDescriptor.Requires;
 import java.lang.module.ModuleDescriptor.Exports;
 import java.lang.module.ModuleDescriptor.Opens;
@@ -98,14 +99,17 @@
 
             // module_flags
             int module_flags = cr.readUnsignedShort(off);
-            boolean open = ((module_flags & ACC_OPEN) != 0);
-            boolean synthetic = ((module_flags & ACC_SYNTHETIC) != 0);
             off += 2;
 
-            ModuleDescriptor.Builder builder = JLMA.newModuleBuilder(mn,
-                                                                     false,
-                                                                     open,
-                                                                     synthetic);
+            Set<ModuleDescriptor.Modifier> modifiers = new HashSet<>();
+            if ((module_flags & ACC_OPEN) != 0)
+                modifiers.add(ModuleDescriptor.Modifier.OPEN);
+            if ((module_flags & ACC_SYNTHETIC) != 0)
+                modifiers.add(ModuleDescriptor.Modifier.SYNTHETIC);
+            if ((module_flags & ACC_MANDATED) != 0)
+                modifiers.add(ModuleDescriptor.Modifier.MANDATED);
+
+            Builder builder = JLMA.newModuleBuilder(mn, false, modifiers);
 
             // module_version
             String module_version = cr.readUTF8(off, buf);
@@ -142,19 +146,13 @@
                         mods.add(Requires.Modifier.MANDATED);
                 }
 
-
                 // requires_version
-                Version compiledVersion = null;
                 String requires_version = cr.readUTF8(off, buf);
                 off += 2;
-                if (requires_version != null) {
-                    compiledVersion = Version.parse(requires_version);
-                }
-
-                if (compiledVersion == null) {
+                if (requires_version == null) {
                     builder.requires(mods, dn);
                 } else {
-                    builder.requires(mods, dn, compiledVersion);
+                    JLMA.requires(builder, mods, dn, requires_version);
                 }
             }
 
@@ -283,11 +281,14 @@
             attr.putShort(module_name_index);
 
             // module_flags
+            Set<ModuleDescriptor.Modifier> modifiers = descriptor.modifiers();
             int module_flags = 0;
-            if (descriptor.isOpen())
+            if (modifiers.contains(ModuleDescriptor.Modifier.OPEN))
                 module_flags |= ACC_OPEN;
-            if (descriptor.isSynthetic())
+            if (modifiers.contains(ModuleDescriptor.Modifier.SYNTHETIC))
                 module_flags |= ACC_SYNTHETIC;
+            if (modifiers.contains(ModuleDescriptor.Modifier.MANDATED))
+                module_flags |= ACC_MANDATED;
             attr.putShort(module_flags);
 
             // module_version
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileConstants.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileConstants.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -46,8 +46,8 @@
     // access, requires, exports, and opens flags
     public static final int ACC_MODULE        = 0x8000;
     public static final int ACC_OPEN          = 0x0020;
-    public static final int ACC_TRANSITIVE    = 0x0010;
-    public static final int ACC_STATIC_PHASE  = 0x0020;
+    public static final int ACC_TRANSITIVE    = 0x0020;
+    public static final int ACC_STATIC_PHASE  = 0x0040;
     public static final int ACC_SYNTHETIC     = 0x1000;
     public static final int ACC_MANDATED      = 0x8000;
 
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -46,6 +46,7 @@
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
+import java.util.stream.Stream;
 
 import jdk.internal.loader.BootLoader;
 import jdk.internal.loader.BuiltinClassLoader;
@@ -114,7 +115,12 @@
         long t0 = System.nanoTime();
 
         // system modules (may be patched)
-        ModuleFinder systemModules = ModuleFinder.ofSystem();
+        ModuleFinder systemModules;
+        if (SystemModules.MODULE_NAMES.length > 0) {
+            systemModules = SystemModuleFinder.getInstance();
+        } else {
+            systemModules = ModuleFinder.ofSystem();
+        }
 
         PerfCounters.systemModulesTime.addElapsedTimeFrom(t0);
 
@@ -275,10 +281,10 @@
 
         // run the resolver to create the configuration
         Configuration cf = SharedSecrets.getJavaLangModuleAccess()
-                .resolveRequiresAndUses(finder,
-                                        roots,
-                                        needPostResolutionChecks,
-                                        traceOutput);
+                .resolveAndBind(finder,
+                                roots,
+                                needPostResolutionChecks,
+                                traceOutput);
 
         // time to create configuration
         PerfCounters.resolveTime.addElapsedTimeFrom(t3);
@@ -318,20 +324,20 @@
         // if needed check that there are no split packages in the set of
         // resolved modules for the boot layer
         if (SystemModules.hasSplitPackages() || needPostResolutionChecks) {
-                Map<String, String> packageToModule = new HashMap<>();
-                for (ResolvedModule resolvedModule : cf.modules()) {
-                    ModuleDescriptor descriptor =
-                        resolvedModule.reference().descriptor();
-                    String name = descriptor.name();
-                    for (String p : descriptor.packages()) {
-                        String other = packageToModule.putIfAbsent(p, name);
-                        if (other != null) {
-                            fail("Package " + p + " in both module "
-                                 + name + " and module " + other);
-                        }
+            Map<String, String> packageToModule = new HashMap<>();
+            for (ResolvedModule resolvedModule : cf.modules()) {
+                ModuleDescriptor descriptor =
+                    resolvedModule.reference().descriptor();
+                String name = descriptor.name();
+                for (String p : descriptor.packages()) {
+                    String other = packageToModule.putIfAbsent(p, name);
+                    if (other != null) {
+                        fail("Package " + p + " in both module "
+                             + name + " and module " + other);
                     }
                 }
             }
+        }
 
         long t4 = System.nanoTime();
 
@@ -380,10 +386,9 @@
                                             Set<String> otherMods)
     {
         // resolve all root modules
-        Configuration cf = Configuration.empty()
-                .resolveRequires(finder,
-                                 ModuleFinder.of(),
-                                 roots);
+        Configuration cf = Configuration.empty().resolve(finder,
+                                                         ModuleFinder.of(),
+                                                         roots);
 
         // module name -> reference
         Map<String, ModuleReference> map = new HashMap<>();
@@ -416,7 +421,7 @@
 
     /**
      * Creates a finder from the module path that is the value of the given
-     * system property.
+     * system property and optionally patched by --patch-module
      */
     private static ModuleFinder createModulePathFinder(String prop) {
         String s = System.getProperty(prop);
@@ -429,7 +434,7 @@
             for (String dir: dirs) {
                 paths[i++] = Paths.get(dir);
             }
-            return ModuleFinder.of(paths);
+            return ModulePath.of(patcher, paths);
         }
     }
 
@@ -528,6 +533,7 @@
         if (!extraOpens.isEmpty()) {
             addExtraExportsOrOpens(bootLayer, extraOpens, true);
         }
+
     }
 
     private static void addExtraExportsOrOpens(Layer bootLayer,
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -37,7 +37,6 @@
 import java.lang.module.ModuleDescriptor.Requires;
 import java.lang.module.ModuleDescriptor.Exports;
 import java.lang.module.ModuleDescriptor.Opens;
-import java.lang.module.ModuleDescriptor.Version;
 import java.nio.ByteBuffer;
 import java.nio.BufferUnderflowException;
 import java.util.ArrayList;
@@ -51,7 +50,6 @@
 
 import jdk.internal.misc.JavaLangModuleAccess;
 import jdk.internal.misc.SharedSecrets;
-import jdk.internal.module.ModuleResolution;
 
 import static jdk.internal.module.ClassFileConstants.*;
 
@@ -221,7 +219,7 @@
         Set<String> attributes = new HashSet<>();
 
         Builder builder = null;
-        Set<String> packages = null;
+        Set<String> allPackages = null;
         String mainClass = null;
         String[] osValues = null;
         ModuleHashes hashes = null;
@@ -245,7 +243,7 @@
                     break;
 
                 case MODULE_PACKAGES :
-                    packages = readModulePackagesAttribute(in, cpool);
+                    allPackages = readModulePackagesAttribute(in, cpool);
                     break;
 
                 case MODULE_MAIN_CLASS :
@@ -284,51 +282,44 @@
             throw invalidModuleDescriptor(MODULE + " attribute not found");
         }
 
+        // ModuleMainClass and ModuleTarget attributes
+        if (mainClass != null) {
+            builder.mainClass(mainClass);
+        }
+        if (osValues != null) {
+            if (osValues[0] != null) builder.osName(osValues[0]);
+            if (osValues[1] != null) builder.osArch(osValues[1]);
+            if (osValues[2] != null) builder.osVersion(osValues[2]);
+        }
+
         // If the ModulePackages attribute is not present then the packageFinder
         // is used to find the set of packages
         boolean usedPackageFinder = false;
-        if (packages == null && packageFinder != null) {
+        if (allPackages == null && packageFinder != null) {
             try {
-                packages = new HashSet<>(packageFinder.get());
+                allPackages = packageFinder.get();
             } catch (UncheckedIOException x) {
                 throw x.getCause();
             }
             usedPackageFinder = true;
         }
-        if (packages != null) {
-            Set<String> exportedPackages = JLMA.exportedPackages(builder);
-            Set<String> openPackages = JLMA.openPackages(builder);
-            if (packages.containsAll(exportedPackages)
-                    && packages.containsAll(openPackages)) {
-                packages.removeAll(exportedPackages);
-                packages.removeAll(openPackages);
-            } else {
-                // the set of packages is not complete
-                Set<String> exportedAndOpenPackages = new HashSet<>();
-                exportedAndOpenPackages.addAll(exportedPackages);
-                exportedAndOpenPackages.addAll(openPackages);
-                for (String pn : exportedAndOpenPackages) {
-                    if (!packages.contains(pn)) {
-                        String tail;
-                        if (usedPackageFinder) {
-                            tail = " not found by package finder";
-                        } else {
-                            tail = " missing from ModulePackages attribute";
-                        }
-                        throw invalidModuleDescriptor("Package " + pn + tail);
-                    }
+        if (allPackages != null) {
+            Set<String> knownPackages = JLMA.packages(builder);
+            if (!allPackages.containsAll(knownPackages)) {
+                Set<String> missingPackages = new HashSet<>(knownPackages);
+                missingPackages.removeAll(allPackages);
+                assert !missingPackages.isEmpty();
+                String missingPackage = missingPackages.iterator().next();
+                String tail;
+                if (usedPackageFinder) {
+                    tail = " not found in module";
+                } else {
+                    tail = " missing from ModulePackages class file attribute";
                 }
-                assert false; // should not get here
-            }
-            builder.contains(packages);
-        }
+                throw invalidModuleDescriptor("Package " + missingPackage + tail);
 
-        if (mainClass != null)
-            builder.mainClass(mainClass);
-        if (osValues != null) {
-            if (osValues[0] != null) builder.osName(osValues[0]);
-            if (osValues[1] != null) builder.osArch(osValues[1]);
-            if (osValues[2] != null) builder.osVersion(osValues[2]);
+            }
+            builder.packages(allPackages);
         }
 
         ModuleDescriptor descriptor = builder.build();
@@ -347,10 +338,17 @@
         String mn = cpool.getModuleName(module_name_index);
 
         int module_flags = in.readUnsignedShort();
+
+        Set<ModuleDescriptor.Modifier> modifiers = new HashSet<>();
         boolean open = ((module_flags & ACC_OPEN) != 0);
-        boolean synthetic = ((module_flags & ACC_SYNTHETIC) != 0);
+        if (open)
+            modifiers.add(ModuleDescriptor.Modifier.OPEN);
+        if ((module_flags & ACC_SYNTHETIC) != 0)
+            modifiers.add(ModuleDescriptor.Modifier.SYNTHETIC);
+        if ((module_flags & ACC_MANDATED) != 0)
+            modifiers.add(ModuleDescriptor.Modifier.MANDATED);
 
-        Builder builder = JLMA.newModuleBuilder(mn, false, open, synthetic);
+        Builder builder = JLMA.newModuleBuilder(mn, false, modifiers);
 
         int module_version_index = in.readUnsignedShort();
         if (module_version_index != 0) {
@@ -381,16 +379,11 @@
             }
 
             int requires_version_index = in.readUnsignedShort();
-            Version compiledVersion = null;
-            if (requires_version_index != 0) {
-                String vs = cpool.getUtf8(requires_version_index);
-                compiledVersion = Version.parse(vs);
-            }
-
-            if (compiledVersion == null) {
+            if (requires_version_index == 0) {
                 builder.requires(mods, dn);
             } else {
-                builder.requires(mods, dn, compiledVersion);
+                String vs = cpool.getUtf8(requires_version_index);
+                JLMA.requires(builder, mods, dn, vs);
             }
 
             if (dn.equals("java.base"))
@@ -629,10 +622,7 @@
 
     /**
      * Return true if the given attribute name is the name of a pre-defined
-     * attribute that is not allowed in the class file.
-     *
-     * Except for Module, InnerClasses, SourceFile, SourceDebugExtension, and
-     * Deprecated, none of the pre-defined attributes in JVMS 4.7 may appear.
+     * attribute in JVMS 4.7 that is not allowed in a module-info class.
      */
     private static boolean isAttributeDisallowed(String name) {
         Set<String> notAllowed = predefinedNotAllowed;
@@ -640,6 +630,7 @@
             notAllowed = Set.of(
                     "ConstantValue",
                     "Code",
+                    "Deprecated",
                     "StackMapTable",
                     "Exceptions",
                     "EnclosingMethod",
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java	Fri Feb 10 08:57:42 2017 -0800
@@ -56,7 +56,7 @@
     // the packages in the ModulePackages attribute
     private Set<String> packages;
 
-    // the value of the module_version in Module attribute
+    // the value for the module version in the Module attribute
     private Version version;
 
     // the value of the ModuleMainClass attribute
@@ -78,7 +78,11 @@
     }
 
     /**
-     * Sets the set of packages for the ModulePackages attribute
+     * Sets the packages for the ModulePackages attribute
+     *
+     * @apiNote This method does not check that the package names are legal
+     * package names or that the set of packages is a super set of the
+     * packages in the module.
      */
     public ModuleInfoExtender packages(Set<String> packages) {
         this.packages = Collections.unmodifiableSet(packages);
@@ -86,7 +90,7 @@
     }
 
     /**
-     * Sets the value of the module_version in Module attribute.
+     * Sets the value for the module version in the Module attribute
      */
     public ModuleInfoExtender version(Version version) {
         this.version = version;
@@ -95,6 +99,9 @@
 
     /**
      * Sets the value of the ModuleMainClass attribute.
+     *
+     * @apiNote This method does not check that the main class is a legal
+     * class name in a named package.
      */
     public ModuleInfoExtender mainClass(String mainClass) {
         this.mainClass = mainClass;
@@ -133,7 +140,7 @@
 
     /**
      * A ClassVisitor that supports adding class file attributes. If an
-     * attribute already exists then the first occurence of the attribute
+     * attribute already exists then the first occurrence of the attribute
      * is replaced.
      */
     private static class AttributeAddingClassVisitor extends ClassVisitor {
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -41,13 +41,6 @@
  * are generated at build time.
  */
 final class ModuleLoaderMap {
-    /*
-     * The list of boot modules and platform modules are generated at build time.
-     */
-    private static final String[] BOOT_MODULES
-        = new String[] { "@@BOOT_MODULE_NAMES@@" };
-    private static final String[] PLATFORM_MODULES
-        = new String[] { "@@PLATFORM_MODULE_NAMES@@" };
 
     /**
      * Returns the function to map modules in the given configuration to the
@@ -55,6 +48,10 @@
      */
     static Function<String, ClassLoader> mappingFunction(Configuration cf) {
 
+        // The list of boot modules and platform modules are generated at build time.
+        final String[] BOOT_MODULES = new String[] { "@@BOOT_MODULE_NAMES@@" };
+        final String[] PLATFORM_MODULES = new String[] { "@@PLATFORM_MODULE_NAMES@@" };
+
         Set<String> bootModules = new HashSet<>(BOOT_MODULES.length);
         for (String mn : BOOT_MODULES) {
             bootModules.add(mn);
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -31,6 +31,7 @@
 import java.io.InputStream;
 import java.io.UncheckedIOException;
 import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Builder;
 import java.lang.module.ModuleReader;
 import java.lang.module.ModuleReference;
 import java.net.MalformedURLException;
@@ -54,6 +55,7 @@
 import java.util.stream.Stream;
 
 import jdk.internal.loader.Resource;
+import jdk.internal.loader.ResourceHelper;
 import jdk.internal.misc.JavaLangModuleAccess;
 import jdk.internal.misc.SharedSecrets;
 import sun.net.www.ParseUtil;
@@ -108,8 +110,11 @@
         if (paths == null)
             return mref;
 
-        // scan the JAR file or directory tree to get the set of packages
+        // Scan the JAR file or directory tree to get the set of packages.
+        // For automatic modules then packages that do not contain class files
+        // must be ignored.
         Set<String> packages = new HashSet<>();
+        boolean isAutomatic = descriptor.isAutomatic();
         try {
             for (Path file : paths) {
                 if (Files.isRegularFile(file)) {
@@ -118,8 +123,10 @@
                     // is not supported by the boot class loader
                     try (JarFile jf = new JarFile(file.toFile())) {
                         jf.stream()
+                          .filter(e -> !e.isDirectory()
+                                  && (!isAutomatic || e.getName().endsWith(".class")))
                           .map(e -> toPackageName(file, e))
-                          .filter(Checks::isJavaIdentifier)
+                          .filter(Checks::isPackageName)
                           .forEach(packages::add);
                     }
 
@@ -129,8 +136,10 @@
                     Path top = file;
                     Files.find(top, Integer.MAX_VALUE,
                                ((path, attrs) -> attrs.isRegularFile()))
+                            .filter(path -> !isAutomatic
+                                    || path.toString().endsWith(".class"))
                             .map(path -> toPackageName(top, path))
-                            .filter(Checks::isJavaIdentifier)
+                            .filter(Checks::isPackageName)
                             .forEach(packages::add);
 
                 }
@@ -141,10 +150,30 @@
         }
 
         // if there are new packages then we need a new ModuleDescriptor
-        Set<String> original = descriptor.packages();
-        packages.addAll(original);
-        if (packages.size() > original.size()) {
-            descriptor = JLMA.newModuleDescriptor(descriptor, packages);
+        packages.removeAll(descriptor.packages());
+        if (!packages.isEmpty()) {
+            Builder builder = JLMA.newModuleBuilder(descriptor.name(),
+                                                    /*strict*/ false,
+                                                    descriptor.modifiers());
+            if (!descriptor.isAutomatic()) {
+                descriptor.requires().forEach(builder::requires);
+                descriptor.exports().forEach(builder::exports);
+                descriptor.opens().forEach(builder::opens);
+                descriptor.uses().forEach(builder::uses);
+            }
+            descriptor.provides().forEach(builder::provides);
+
+            descriptor.version().ifPresent(builder::version);
+            descriptor.mainClass().ifPresent(builder::mainClass);
+            descriptor.osName().ifPresent(builder::osName);
+            descriptor.osArch().ifPresent(builder::osArch);
+            descriptor.osVersion().ifPresent(builder::osVersion);
+
+            // original + new packages
+            builder.packages(descriptor.packages());
+            builder.packages(packages);
+
+            descriptor = builder.build();
         }
 
         // return a module reference to the patched module
@@ -471,23 +500,14 @@
 
         @Override
         public Resource find(String name) throws IOException {
-            Path file = Paths.get(name.replace('/', File.separatorChar));
-            if (file.getRoot() == null) {
-                file = dir.resolve(file);
-            } else {
-                // drop the root component so that the resource is
-                // located relative to the module directory
-                int n = file.getNameCount();
-                if (n == 0)
-                    return null;
-                file = dir.resolve(file.subpath(0, n));
+            Path path = ResourceHelper.toFilePath(name);
+            if (path != null) {
+                Path file = dir.resolve(path);
+                if (Files.isRegularFile(file)) {
+                    return newResource(name, dir, file);
+                }
             }
-
-            if (Files.isRegularFile(file)) {
-                return newResource(name, dir, file);
-            } else {
-                return null;
-            }
+            return null;
         }
 
         private Resource newResource(String name, Path top, Path file) {
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -35,7 +35,6 @@
 import java.lang.module.FindException;
 import java.lang.module.InvalidModuleDescriptorException;
 import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Requires;
 import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReference;
 import java.net.URI;
@@ -70,12 +69,11 @@
 
 /**
  * A {@code ModuleFinder} that locates modules on the file system by searching
- * a sequence of directories or packaged modules.
- *
- * The {@code ModuleFinder} can be created to work in either the run-time
- * or link-time phases. In both cases it locates modular JAR and exploded
- * modules. When created for link-time then it additionally locates
- * modules in JMOD files.
+ * a sequence of directories or packaged modules. The ModuleFinder can be
+ * created to work in either the run-time or link-time phases. In both cases it
+ * locates modular JAR and exploded modules. When created for link-time then it
+ * additionally locates modules in JMOD files. The ModuleFinder can also
+ * optionally patch any modules that it locates with a ModulePatcher.
  */
 
 public class ModulePath implements ModuleFinder {
@@ -87,6 +85,9 @@
     // true for the link phase (supports modules packaged in JMOD format)
     private final boolean isLinkPhase;
 
+    // for patching modules, can be null
+    private final ModulePatcher patcher;
+
     // the entries on this module path
     private final Path[] entries;
     private int next;
@@ -94,19 +95,51 @@
     // map of module name to module reference map for modules already located
     private final Map<String, ModuleReference> cachedModules = new HashMap<>();
 
-    public ModulePath(Runtime.Version version, boolean isLinkPhase, Path... entries) {
+
+    private ModulePath(Runtime.Version version,
+                       boolean isLinkPhase,
+                       ModulePatcher patcher,
+                       Path... entries) {
         this.releaseVersion = version;
         this.isLinkPhase = isLinkPhase;
+        this.patcher = patcher;
         this.entries = entries.clone();
         for (Path entry : this.entries) {
             Objects.requireNonNull(entry);
         }
     }
 
-    public ModulePath(Path... entries) {
-        this(JarFile.runtimeVersion(), false, entries);
+    /**
+     * Returns a ModuleFinder that that locates modules on the file system by
+     * searching a sequence of directories and/or packaged modules. The modules
+     * may be patched by the given ModulePatcher.
+     */
+    public static ModuleFinder of(ModulePatcher patcher, Path... entries) {
+        return new ModulePath(JarFile.runtimeVersion(), false, patcher, entries);
     }
 
+    /**
+     * Returns a ModuleFinder that that locates modules on the file system by
+     * searching a sequence of directories and/or packaged modules.
+     */
+    public static ModuleFinder of(Path... entries) {
+        return of((ModulePatcher)null, entries);
+    }
+
+    /**
+     * Returns a ModuleFinder that that locates modules on the file system by
+     * searching a sequence of directories and/or packaged modules.
+     *
+     * @param version The release version to use for multi-release JAR files
+     * @param isLinkPhase {@code true} if the link phase to locate JMOD files
+     */
+    public static ModuleFinder of(Runtime.Version version,
+                                  boolean isLinkPhase,
+                                  Path... entries) {
+        return new ModulePath(version, isLinkPhase, null, entries);
+    }
+
+
     @Override
     public Optional<ModuleReference> find(String name) {
         Objects.requireNonNull(name);
@@ -195,8 +228,7 @@
             if (attrs.isDirectory()) {
                 Path mi = entry.resolve(MODULE_INFO);
                 if (!Files.exists(mi)) {
-                    // does not exist or unable to determine so assume a
-                    // directory of modules
+                    // assume a directory of modules
                     return scanDirectory(entry);
                 }
             }
@@ -206,10 +238,16 @@
             if (mref != null) {
                 String name = mref.descriptor().name();
                 return Collections.singletonMap(name, mref);
+            }
+
+            // not recognized
+            String msg;
+            if (!isLinkPhase && entry.toString().endsWith(".jmod")) {
+                msg = "JMOD format not supported at execution time";
             } else {
-                // skipped
-                return Collections.emptyMap();
+                msg = "Module format not recognized";
             }
+            throw new FindException(msg + ": " + entry);
 
         } catch (IOException ioe) {
             throw new FindException(ioe);
@@ -266,14 +304,11 @@
 
 
     /**
-     * Locates a packaged or exploded module, returning a {@code ModuleReference}
-     * to the module. Returns {@code null} if the entry is skipped because it is
-     * to a directory that does not contain a module-info.class or it's a hidden
-     * file.
+     * Reads a packaged or exploded module, returning a {@code ModuleReference}
+     * to the module. Returns {@code null} if the entry is not recognized.
      *
      * @throws IOException if an I/O error occurs
-     * @throws FindException if the file is not recognized as a module or an
-     *         error occurs parsing its module descriptor
+     * @throws FindException if an error occurs parsing its module descriptor
      */
     private ModuleReference readModule(Path entry, BasicFileAttributes attrs)
         throws IOException
@@ -282,24 +317,16 @@
 
             if (attrs.isDirectory()) {
                 return readExplodedModule(entry); // may return null
-            }
-
-            String fn = entry.getFileName().toString();
-            if (attrs.isRegularFile()) {
-                if (fn.endsWith(".jar")) {
-                    return readJar(entry);
-                } else if (fn.endsWith(".jmod")) {
-                    if (isLinkPhase)
+            } else {
+                String fn = entry.getFileName().toString();
+                if (attrs.isRegularFile()) {
+                    if (fn.endsWith(".jar")) {
+                        return readJar(entry);
+                    } else if (isLinkPhase && fn.endsWith(".jmod")) {
                         return readJMod(entry);
-                    throw new FindException("JMOD files not supported: " + entry);
+                    }
                 }
-            }
-
-            // skip hidden files
-            if (fn.startsWith(".") || Files.isHidden(entry)) {
                 return null;
-            } else {
-                throw new FindException("Unrecognized module: " + entry);
             }
 
         } catch (InvalidModuleDescriptorException e) {
@@ -327,7 +354,7 @@
         }
     }
 
-    // -- jmod files --
+    // -- JMOD files --
 
     private Set<String> jmodPackages(JmodFile jf) {
         return jf.stream()
@@ -339,7 +366,7 @@
     }
 
     /**
-     * Returns a {@code ModuleReference} to a module in jmod file on the
+     * Returns a {@code ModuleReference} to a module in JMOD file on the
      * file system.
      *
      * @throws IOException
@@ -362,7 +389,7 @@
 
     /**
      * Returns the service type corresponding to the name of a services
-     * configuration file if it is a valid Java identifier.
+     * configuration file if it is a legal type name.
      *
      * For example, if called with "META-INF/services/p.S" then this method
      * returns a container with the value "p.S".
@@ -374,7 +401,7 @@
             String prefix = cf.substring(0, index);
             if (prefix.equals(SERVICES_PREFIX)) {
                 String sn = cf.substring(index);
-                if (Checks.isJavaIdentifier(sn))
+                if (Checks.isClassName(sn))
                     return Optional.of(sn);
             }
         }
@@ -403,11 +430,10 @@
      *
      * 1. The module name (and optionally the version) is derived from the file
      *    name of the JAR file
-     * 2. All packages are exported and open
-     * 3. It has no non-exported/non-open packages
-     * 4. The contents of any META-INF/services configuration files are mapped
+     * 2. All packages are derived from the .class files in the JAR file
+     * 3. The contents of any META-INF/services configuration files are mapped
      *    to "provides" declarations
-     * 5. The Main-Class attribute in the main attributes of the JAR manifest
+     * 4. The Main-Class attribute in the main attributes of the JAR manifest
      *    is mapped to the module descriptor mainClass
      */
     private ModuleDescriptor deriveModuleDescriptor(JarFile jf)
@@ -443,9 +469,7 @@
         mn = cleanModuleName(mn);
 
         // Builder throws IAE if module name is empty or invalid
-        ModuleDescriptor.Builder builder
-            = ModuleDescriptor.automaticModule(mn)
-                .requires(Set.of(Requires.Modifier.MANDATED), "java.base");
+        ModuleDescriptor.Builder builder = ModuleDescriptor.newAutomaticModule(mn);
         if (vs != null)
             builder.version(vs);
 
@@ -453,17 +477,22 @@
         Map<Boolean, Set<String>> map = VersionedStream.stream(jf)
                 .filter(e -> !e.isDirectory())
                 .map(JarEntry::getName)
+                .filter(e -> (e.endsWith(".class") ^ e.startsWith(SERVICES_PREFIX)))
                 .collect(Collectors.partitioningBy(e -> e.startsWith(SERVICES_PREFIX),
                                                    Collectors.toSet()));
 
-        Set<String> resources = map.get(Boolean.FALSE);
+        Set<String> classFiles = map.get(Boolean.FALSE);
         Set<String> configFiles = map.get(Boolean.TRUE);
-        // all packages are exported and open
-        resources.stream()
+
+        // the packages containing class files
+        Set<String> packages = classFiles.stream()
                 .map(this::toPackageName)
                 .flatMap(Optional::stream)
                 .distinct()
-                .forEach(pn -> builder.exports(pn).opens(pn));
+                .collect(Collectors.toSet());
+
+        // all packages are exported and open
+        builder.packages(packages);
 
         // map names of service configuration files to service names
         Set<String> serviceNames = configFiles.stream()
@@ -481,6 +510,11 @@
                 String cn;
                 while ((cn = nextLine(reader)) != null) {
                     if (cn.length() > 0) {
+                        String pn = packageName(cn);
+                        if (!packages.contains(pn)) {
+                            String msg = "Provider class " + cn + " not in module";
+                            throw new IOException(msg);
+                        }
                         providerClasses.add(cn);
                     }
                 }
@@ -494,8 +528,15 @@
         if (man != null) {
             Attributes attrs = man.getMainAttributes();
             String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
-            if (mainClass != null)
-                builder.mainClass(mainClass.replace("/", "."));
+            if (mainClass != null) {
+                mainClass = mainClass.replace("/", ".");
+                String pn = packageName(mainClass);
+                if (!packages.contains(pn)) {
+                    String msg = "Main-Class " + mainClass + " not in module";
+                    throw new IOException(msg);
+                }
+                builder.mainClass(mainClass);
+            }
         }
 
         return builder.build();
@@ -569,10 +610,10 @@
                 try {
                     ModuleDescriptor md = deriveModuleDescriptor(jf);
                     attrs = new ModuleInfo.Attributes(md, null, null);
-                } catch (IllegalArgumentException iae) {
+                } catch (IllegalArgumentException e) {
                     throw new FindException(
                         "Unable to derive module descriptor for: "
-                        + jf.getName(), iae);
+                        + jf.getName(), e);
                 }
 
             } else {
@@ -580,7 +621,7 @@
                                         () -> jarPackages(jf));
             }
 
-            return ModuleReferences.newJarModule(attrs, file);
+            return ModuleReferences.newJarModule(attrs, patcher, file);
         }
     }
 
@@ -617,7 +658,15 @@
             // for now
             return null;
         }
-        return ModuleReferences.newExplodedModule(attrs, dir);
+        return ModuleReferences.newExplodedModule(attrs, patcher, dir);
+    }
+
+    /**
+     * Maps a type name to its package name.
+     */
+    private static String packageName(String cn) {
+        int index = cn.lastIndexOf('.');
+        return (index == -1) ? "" : cn.substring(0, index);
     }
 
     /**
@@ -629,19 +678,18 @@
      */
     private Optional<String> toPackageName(String name) {
         assert !name.endsWith("/");
-
         int index = name.lastIndexOf("/");
         if (index == -1) {
             if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
                 throw new IllegalArgumentException(name
-                        + " found in top-level directory:"
+                        + " found in top-level directory"
                         + " (unnamed package not allowed in module)");
             }
             return Optional.empty();
         }
 
         String pn = name.substring(0, index).replace('/', '.');
-        if (Checks.isJavaIdentifier(pn)) {
+        if (Checks.isPackageName(pn)) {
             return Optional.of(pn);
         } else {
             // not a valid package name
@@ -654,7 +702,7 @@
      * name.
      *
      * @throws IllegalArgumentException if the name is a class file in
-     *         the top-level directory (and it's not module-info.class)
+     *          the top-level directory (and it's not module-info.class)
      */
     private Optional<String> toPackageName(Path file) {
         assert file.getRoot() == null;
@@ -664,14 +712,14 @@
             String name = file.toString();
             if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
                 throw new IllegalArgumentException(name
-                        + " found in in top-level directory"
+                        + " found in top-level directory"
                         + " (unnamed package not allowed in module)");
             }
             return Optional.empty();
         }
 
         String pn = parent.toString().replace(File.separatorChar, '.');
-        if (Checks.isJavaIdentifier(pn)) {
+        if (Checks.isPackageName(pn)) {
             return Optional.of(pn);
         } else {
             // not a valid package name
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -163,7 +163,14 @@
 
     @Override
     public String toString() {
-        return super.toString();
+        StringBuilder sb = new StringBuilder();
+        sb.append("[module ");
+        sb.append(descriptor().name());
+        sb.append(", location=");
+        sb.append(location().orElseThrow(() -> new InternalError()));
+        if (isPatched()) sb.append(" (patched)");
+        sb.append("]");
+        return sb.toString();
     }
 
 }
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java	Fri Feb 10 08:57:42 2017 -0800
@@ -36,7 +36,6 @@
 import java.nio.ByteBuffer;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -51,7 +50,7 @@
 import java.util.zip.ZipFile;
 
 import jdk.internal.jmod.JmodFile;
-import jdk.internal.misc.JavaLangAccess;
+import jdk.internal.loader.ResourceHelper;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.module.ModuleHashes.HashSupplier;
 import jdk.internal.util.jar.VersionedStream;
@@ -65,20 +64,16 @@
  */
 
 class ModuleReferences {
-
-    private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
-
     private ModuleReferences() { }
 
     /**
-     * Creates a ModuleReference to a module or to patched module when
-     * creating modules for the boot Layer and --patch-module is specified.
+     * Creates a ModuleReference to a possibly-patched module
      */
     private static ModuleReference newModule(ModuleInfo.Attributes attrs,
                                              URI uri,
                                              Supplier<ModuleReader> supplier,
+                                             ModulePatcher patcher,
                                              HashSupplier hasher) {
-
         ModuleReference mref = new ModuleReferenceImpl(attrs.descriptor(),
                                                        uri,
                                                        supplier,
@@ -86,38 +81,42 @@
                                                        attrs.recordedHashes(),
                                                        hasher,
                                                        attrs.moduleResolution());
-        if (JLA.getBootLayer() == null)
-            mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
+        if (patcher != null)
+            mref = patcher.patchIfNeeded(mref);
 
         return mref;
     }
 
     /**
-     * Creates a ModuleReference to a module packaged as a modular JAR.
+     * Creates a ModuleReference to a possibly-patched module in a modular JAR.
      */
-    static ModuleReference newJarModule(ModuleInfo.Attributes attrs, Path file) {
+    static ModuleReference newJarModule(ModuleInfo.Attributes attrs,
+                                        ModulePatcher patcher,
+                                        Path file) {
         URI uri = file.toUri();
         Supplier<ModuleReader> supplier = () -> new JarModuleReader(file, uri);
         HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
-        return newModule(attrs, uri, supplier, hasher);
+        return newModule(attrs, uri, supplier, patcher, hasher);
     }
 
     /**
-     * Creates a ModuleReference to a module packaged as a JMOD.
+     * Creates a ModuleReference to a module in a JMOD file.
      */
     static ModuleReference newJModModule(ModuleInfo.Attributes attrs, Path file) {
         URI uri = file.toUri();
         Supplier<ModuleReader> supplier = () -> new JModModuleReader(file, uri);
         HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
-        return newModule(attrs, uri, supplier, hasher);
+        return newModule(attrs, uri, supplier, null, hasher);
     }
 
     /**
-     * Creates a ModuleReference to an exploded module.
+     * Creates a ModuleReference to a possibly-patched exploded module.
      */
-    static ModuleReference newExplodedModule(ModuleInfo.Attributes attrs, Path dir) {
+    static ModuleReference newExplodedModule(ModuleInfo.Attributes attrs,
+                                             ModulePatcher patcher,
+                                             Path dir) {
         Supplier<ModuleReader> supplier = () -> new ExplodedModuleReader(dir);
-        return newModule(attrs, dir.toUri(), supplier, null);
+        return newModule(attrs, dir.toUri(), supplier, patcher, null);
     }
 
 
@@ -243,7 +242,8 @@
         }
 
         private JarEntry getEntry(String name) {
-            return jf.getJarEntry(Objects.requireNonNull(name));
+            JarEntry entry = jf.getJarEntry(Objects.requireNonNull(name));
+            return (entry == null || entry.isDirectory()) ? null : entry;
         }
 
         @Override
@@ -370,32 +370,33 @@
         }
 
         /**
-         * Returns a Path to access to the given resource.
-         */
-        private Path toPath(String name) {
-            Path path = Paths.get(name.replace('/', File.separatorChar));
-            if (path.getRoot() == null) {
-                return dir.resolve(path);
-            } else {
-                // drop the root component so that the resource is
-                // located relative to the module directory
-                int n = path.getNameCount();
-                return (n > 0) ? dir.resolve(path.subpath(0, n)) : null;
-            }
-        }
-
-        /**
          * Throws IOException if the module reader is closed;
          */
         private void ensureOpen() throws IOException {
             if (closed) throw new IOException("ModuleReader is closed");
         }
 
+        /**
+         * Returns a Path to access the given resource. Returns null if the
+         * resource name does not convert to a file path that locates a regular
+         * file in the module.
+         */
+        private Path toFilePath(String name) {
+            Path path = ResourceHelper.toFilePath(name);
+            if (path != null) {
+                Path file = dir.resolve(path);
+                if (Files.isRegularFile(file)) {
+                    return file;
+                }
+            }
+            return null;
+        }
+
         @Override
         public Optional<URI> find(String name) throws IOException {
             ensureOpen();
-            Path path = toPath(name);
-            if (path != null && Files.isRegularFile(path)) {
+            Path path = toFilePath(name);
+            if (path != null) {
                 try {
                     return Optional.of(path.toUri());
                 } catch (IOError e) {
@@ -409,8 +410,8 @@
         @Override
         public Optional<InputStream> open(String name) throws IOException {
             ensureOpen();
-            Path path = toPath(name);
-            if (path != null && Files.isRegularFile(path)) {
+            Path path = toFilePath(name);
+            if (path != null) {
                 return Optional.of(Files.newInputStream(path));
             } else {
                 return Optional.empty();
@@ -420,8 +421,8 @@
         @Override
         public Optional<ByteBuffer> read(String name) throws IOException {
             ensureOpen();
-            Path path = toPath(name);
-            if (path != null && Files.isRegularFile(path)) {
+            Path path = toFilePath(name);
+            if (path != null) {
                 return Optional.of(ByteBuffer.wrap(Files.readAllBytes(path)));
             } else {
                 return Optional.empty();
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java	Fri Feb 10 08:57:42 2017 -0800
@@ -82,8 +82,8 @@
                                       String name,
                                       Set<String> packages)
     {
-        ModuleDescriptor descriptor = ModuleDescriptor.module(name)
-                .contains(packages)
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule(name)
+                .packages(packages)
                 .build();
 
         return JLRMA.defineModule(loader, descriptor, null);
@@ -185,7 +185,8 @@
     /**
      * Adds a package to a module's content.
      *
-     * This method is a no-op if the module already contains the package.
+     * This method is a no-op if the module already contains the package or the
+     * module is an unnamed module.
      */
     public static void addPackage(Module m, String pn) {
         JLRMA.addPackage(m, pn);
--- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java	Fri Feb 10 08:57:42 2017 -0800
@@ -80,8 +80,6 @@
         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.packages");
     private static final PerfCounter exportsCount
         = PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");
-    // ImageReader used to access all modules in the image
-    private static final ImageReader imageReader;
 
     // singleton finder to find modules in the run-time images
     private static final SystemModuleFinder INSTANCE;
@@ -96,13 +94,28 @@
      */
     static {
         long t0 = System.nanoTime();
-        imageReader = ImageReaderFactory.getImageReader();
 
         INSTANCE = new SystemModuleFinder();
 
         initTime.addElapsedTimeFrom(t0);
     }
 
+    /**
+     * Holder class for the ImageReader
+     */
+    private static class SystemImage {
+        static final ImageReader READER;
+        static {
+            long t0 = System.nanoTime();
+            READER = ImageReaderFactory.getImageReader();
+            initTime.addElapsedTimeFrom(t0);
+        }
+
+        static ImageReader reader() {
+            return READER;
+        }
+    }
+
     private static boolean isFastPathSupported() {
        return SystemModules.MODULE_NAMES.length > 0;
     }
@@ -114,7 +127,7 @@
 
         // this happens when java.base is patched with java.base
         // from an exploded image
-        return imageReader.getModuleNames();
+        return SystemImage.reader().getModuleNames();
     }
 
     // the set of modules in the run-time image
@@ -151,6 +164,7 @@
             descriptors = new ModuleDescriptor[n];
             recordedHashes = new ModuleHashes[n];
             moduleResolutions = new ModuleResolution[n];
+            ImageReader imageReader = SystemImage.reader();
             for (int i = 0; i < names.length; i++) {
                 String mn = names[i];
                 ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
@@ -291,6 +305,7 @@
             Objects.requireNonNull(name);
             if (closed)
                 throw new IOException("ModuleReader is closed");
+            ImageReader imageReader = SystemImage.reader();
             if (imageReader != null) {
                 return imageReader.findLocation(module, name);
             } else {
@@ -330,7 +345,7 @@
         public Optional<ByteBuffer> read(String name) throws IOException {
             ImageLocation location = findImageLocation(name);
             if (location != null) {
-                return Optional.of(imageReader.getResourceBuffer(location));
+                return Optional.of(SystemImage.reader().getResourceBuffer(location));
             } else {
                 return Optional.empty();
             }
@@ -372,7 +387,7 @@
             stack = new ArrayDeque<>();
 
             // push the root node to the stack to get started
-            ImageReader.Node dir = imageReader.findNode(moduleRoot);
+            ImageReader.Node dir = SystemImage.reader().findNode(moduleRoot);
             if (dir == null || !dir.isDirectory())
                 throw new IOException(moduleRoot + " not a directory");
             stack.push(dir);
@@ -390,7 +405,7 @@
                     String name = node.getName();
                     if (node.isDirectory()) {
                         // build node
-                        ImageReader.Node dir = imageReader.findNode(name);
+                        ImageReader.Node dir = SystemImage.reader().findNode(name);
                         assert dir.isDirectory();
                         stack.push(dir);
                     } else {
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -211,15 +211,7 @@
         if (currentModule == memberModule)
            return true;  // same module (named or unnamed)
 
-        // memberClass may be primitive or array class
-        Class<?> c = memberClass;
-        while (c.isArray()) {
-            c = c.getComponentType();
-        }
-        if (c.isPrimitive())
-            return true;
-
-        String pkg = c.getPackageName();
+        String pkg = memberClass.getPackageName();
         boolean allowed = memberModule.isExported(pkg, currentModule);
         if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
             if (!SharedSecrets.getJavaLangReflectModuleAccess()
@@ -237,10 +229,6 @@
     private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
         if (c1.getClassLoader() != c2.getClassLoader())
             return false;
-        while (c1.isArray())
-            c1 = c1.getComponentType();
-        while (c2.isArray())
-            c2 = c2.getComponentType();
         return Objects.equals(c1.getPackageName(), c2.getPackageName());
     }
 
@@ -378,12 +366,6 @@
         }
     }
 
-    public static void enableStackTraces() {
-        printStackWhenAccessFails = true;
-        printStackWhenAccessSucceeds = true;
-        printStackPropertiesSet = true;
-    }
-
     public static boolean printStackTraceWhenAccessFails() {
         ensurePrintStackPropertiesSet();
         return printStackWhenAccessFails;
@@ -413,11 +395,7 @@
         if (m2.isNamed())
             memberSuffix = " (in " + m2 + ")";
 
-        Class<?> c = memberClass;
-        while (c.isArray()) {
-            c = c.getComponentType();
-        }
-        String memberPackageName = c.getPackageName();
+        String memberPackageName = memberClass.getPackageName();
 
         String msg = currentClass + currentSuffix + " cannot access ";
         if (m2.isExported(memberPackageName, m1)) {
--- a/jdk/src/java.base/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the foundational APIs of the Java SE Platform.
+ *
+ * @since 9
  */
 module java.base {
 
--- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -39,6 +39,7 @@
 
     private VerifyAccess() { }  // cannot instantiate
 
+    private static final int UNCONDITIONAL_ALLOWED = java.lang.invoke.MethodHandles.Lookup.UNCONDITIONAL;
     private static final int MODULE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.MODULE;
     private static final int PACKAGE_ONLY = 0;
     private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE;
@@ -92,7 +93,7 @@
                                              int      allowedModes) {
         if (allowedModes == 0)  return false;
         assert((allowedModes & PUBLIC) != 0 &&
-               (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED)) == 0);
+               (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
         // The symbolic reference class (refc) must always be fully verified.
         if (!isClassAccessible(refc, lookupClass, allowedModes)) {
             return false;
@@ -173,7 +174,7 @@
                                             int allowedModes) {
         if (allowedModes == 0)  return false;
         assert((allowedModes & PUBLIC) != 0 &&
-               (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED)) == 0);
+               (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
         int mods = getClassModifiers(refc);
         if (isPublic(mods)) {
 
@@ -191,22 +192,17 @@
                 (lookupModule == refModule))
                 return true;
 
-            // check readability
-            if (lookupModule.canRead(refModule)) {
+            // check readability when UNCONDITIONAL not allowed
+            if (((allowedModes & UNCONDITIONAL_ALLOWED) != 0)
+                || lookupModule.canRead(refModule)) {
 
                 // check that refc is in an exported package
-                Class<?> c = refc;
-                while (c.isArray()) {
-                    c = c.getComponentType();
-                }
-                if (c.isPrimitive())
-                    return true;
                 if ((allowedModes & MODULE_ALLOWED) != 0) {
-                    if (refModule.isExported(c.getPackageName(), lookupModule))
+                    if (refModule.isExported(refc.getPackageName(), lookupModule))
                         return true;
                 } else {
                     // exported unconditionally
-                    if (refModule.isExported(c.getPackageName()))
+                    if (refModule.isExported(refc.getPackageName()))
                         return true;
                 }
 
--- a/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java	Fri Feb 10 08:57:42 2017 -0800
@@ -591,8 +591,8 @@
                 c = Class.forName(m, cn);
             }
         } catch (LinkageError le) {
-            abort(null, "java.launcher.module.error3",
-                    mainClass, m.getName(), le.getLocalizedMessage());
+            abort(null, "java.launcher.module.error3", mainClass, m.getName(),
+                    le.getClass().getName() + ": " + le.getLocalizedMessage());
         }
         if (c == null) {
             abort(null, "java.launcher.module.error2", mainClass, mainModule);
@@ -645,7 +645,8 @@
                 }
             }
         } catch (LinkageError le) {
-            abort(le, "java.launcher.cls.error6", cn, le.getLocalizedMessage());
+            abort(le, "java.launcher.cls.error6", cn,
+                    le.getClass().getName() + ": " + le.getLocalizedMessage());
         }
         return mainClass;
     }
@@ -966,6 +967,10 @@
                     ostream.print("open ");
                 if (md.isAutomatic())
                     ostream.print("automatic ");
+                if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC))
+                    ostream.print("synthetic ");
+                if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED))
+                    ostream.print("mandated ");
                 ostream.println("module " + midAndLocation(md, mref.location()));
 
                 // unqualified exports (sorted by package)
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java	Fri Feb 10 08:57:42 2017 -0800
@@ -32,7 +32,9 @@
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.security.AccessController;
 import java.security.Permission;
+import java.security.PrivilegedAction;
 
 import jdk.internal.jimage.ImageLocation;
 import jdk.internal.jimage.ImageReader;
@@ -51,7 +53,11 @@
 public class JavaRuntimeURLConnection extends URLConnection {
 
     // ImageReader to access resources in jimage
-    private static final ImageReader reader = ImageReaderFactory.getImageReader();
+    private static final ImageReader reader;
+    static {
+        PrivilegedAction<ImageReader> pa = ImageReaderFactory::getImageReader;
+        reader = AccessController.doPrivileged(pa);
+    }
 
     // the module and resource name in the URL
     private final String module;
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -37,6 +37,7 @@
 import java.security.Signature;
 import java.security.SignatureException;
 import java.security.Timestamp;
+import java.security.cert.CertPathValidatorException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CertPath;
@@ -48,6 +49,7 @@
 import java.util.Set;
 
 import sun.security.timestamp.TimestampToken;
+import sun.security.util.ConstraintsParameters;
 import sun.security.util.Debug;
 import sun.security.util.DerEncoder;
 import sun.security.util.DerInputStream;
@@ -321,6 +323,8 @@
                 data = content.getContentBytes();
             }
 
+            ConstraintsParameters cparams =
+                    new ConstraintsParameters(timestamp);
             String digestAlgname = getDigestAlgorithmId().getName();
 
             byte[] dataSigned;
@@ -347,11 +351,11 @@
                 if (messageDigest == null) // fail if there is no message digest
                     return null;
 
-                // check that algorithm is not restricted
-                if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET,
-                        digestAlgname, null)) {
-                    throw new SignatureException("Digest check failed. " +
-                            "Disabled algorithm used: " + digestAlgname);
+                // check that digest algorithm is not restricted
+                try {
+                    JAR_DISABLED_CHECK.permits(digestAlgname, cparams);
+                } catch (CertPathValidatorException e) {
+                    throw new SignatureException(e.getMessage(), e);
                 }
 
                 MessageDigest md = MessageDigest.getInstance(digestAlgname);
@@ -385,17 +389,18 @@
             String algname = AlgorithmId.makeSigAlg(
                     digestAlgname, encryptionAlgname);
 
-            // check that algorithm is not restricted
-            if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) {
-                throw new SignatureException("Signature check failed. " +
-                        "Disabled algorithm used: " + algname);
+            // check that jar signature algorithm is not restricted
+            try {
+                JAR_DISABLED_CHECK.permits(algname, cparams);
+            } catch (CertPathValidatorException e) {
+                throw new SignatureException(e.getMessage(), e);
             }
 
             X509Certificate cert = getCertificate(block);
-            PublicKey key = cert.getPublicKey();
             if (cert == null) {
                 return null;
             }
+            PublicKey key = cert.getPublicKey();
 
             // check if the public key is restricted
             if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -28,6 +28,7 @@
 import java.security.AlgorithmConstraints;
 import java.security.CryptoPrimitive;
 import java.security.Timestamp;
+import java.security.cert.CertPathValidator;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -53,9 +54,10 @@
 import java.security.spec.DSAPublicKeySpec;
 
 import sun.security.util.AnchorCertificates;
-import sun.security.util.CertConstraintParameters;
+import sun.security.util.ConstraintsParameters;
 import sun.security.util.Debug;
 import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.validator.Validator;
 import sun.security.x509.X509CertImpl;
 import sun.security.x509.X509CRLImpl;
 import sun.security.x509.AlgorithmId;
@@ -79,6 +81,7 @@
     private final Date pkixdate;
     private PublicKey prevPubKey;
     private final Timestamp jarTimestamp;
+    private final String variant;
 
     private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
         Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
@@ -109,64 +112,36 @@
      *
      * @param anchor the trust anchor selected to validate the target
      *     certificate
-     */
-    public AlgorithmChecker(TrustAnchor anchor) {
-        this(anchor, certPathDefaultConstraints, null);
-    }
-
-    /**
-     * Create a new {@code AlgorithmChecker} with the
-     * given {@code TrustAnchor} and {@code AlgorithmConstraints}.
-     *
-     * @param anchor the trust anchor selected to validate the target
-     *     certificate
-     * @param constraints the algorithm constraints (or null)
-     *
-     * @throws IllegalArgumentException if the {@code anchor} is null
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    public AlgorithmChecker(TrustAnchor anchor,
-            AlgorithmConstraints constraints) {
-        this(anchor, constraints, null);
-    }
-
-    /**
-     * Create a new {@code AlgorithmChecker} with the
-     * given {@code AlgorithmConstraints}.
-     * <p>
-     * Note that this constructor will be used to check a certification
-     * path where the trust anchor is unknown, or a certificate list which may
-     * contain the trust anchor. This constructor is used by SunJSSE.
-     *
-     * @param constraints the algorithm constraints (or null)
-     */
-    public AlgorithmChecker(AlgorithmConstraints constraints) {
-        this.prevPubKey = null;
-        this.trustedPubKey = null;
-        this.constraints = constraints;
-        this.pkixdate = null;
-        this.jarTimestamp = null;
+    public AlgorithmChecker(TrustAnchor anchor, String variant) {
+        this(anchor, certPathDefaultConstraints, null, variant);
     }
 
     /**
      * Create a new {@code AlgorithmChecker} with the given
-     * {@code Timestamp}.
+     * {@code AlgorithmConstraints}, {@code Timestamp}, and/or {@code Variant}.
      * <p>
-     * Note that this constructor will be used to check a certification
-     * path for signed JAR files that are timestamped.
+     * Note that this constructor can initialize a variation of situations where
+     * the AlgorithmConstraints, Timestamp, or Variant maybe known.
      *
+     * @param constraints the algorithm constraints (or null)
      * @param jarTimestamp Timestamp passed for JAR timestamp constraint
      *                     checking. Set to null if not applicable.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    public AlgorithmChecker(Timestamp jarTimestamp) {
+    public AlgorithmChecker(AlgorithmConstraints constraints,
+            Timestamp jarTimestamp, String variant) {
         this.prevPubKey = null;
         this.trustedPubKey = null;
-        this.constraints = certPathDefaultConstraints;
-        if (jarTimestamp == null) {
-            throw new IllegalArgumentException(
-                    "Timestamp cannot be null");
-        }
-        this.pkixdate = jarTimestamp.getTimestamp();
+        this.constraints = (constraints == null ? certPathDefaultConstraints :
+                constraints);
+        this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() :
+                null);
         this.jarTimestamp = jarTimestamp;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
     }
 
     /**
@@ -178,12 +153,13 @@
      * @param constraints the algorithm constraints (or null)
      * @param pkixdate Date the constraints are checked against. The value is
      *             either the PKIXParameter date or null for the current date.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      *
      * @throws IllegalArgumentException if the {@code anchor} is null
      */
     public AlgorithmChecker(TrustAnchor anchor,
-            AlgorithmConstraints constraints,
-            Date pkixdate) {
+            AlgorithmConstraints constraints, Date pkixdate, String variant) {
 
         if (anchor != null) {
             if (anchor.getTrustedCert() != null) {
@@ -207,6 +183,7 @@
         this.constraints = constraints;
         this.pkixdate = pkixdate;
         this.jarTimestamp = null;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
     }
 
     /**
@@ -217,11 +194,13 @@
      *     certificate
      * @param pkixdate Date the constraints are checked against. The value is
      *             either the PKIXParameter date or null for the current date.
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      *
      * @throws IllegalArgumentException if the {@code anchor} is null
      */
-    public AlgorithmChecker(TrustAnchor anchor, Date pkixdate) {
-        this(anchor, certPathDefaultConstraints, pkixdate);
+    public AlgorithmChecker(TrustAnchor anchor, Date pkixdate, String variant) {
+        this(anchor, certPathDefaultConstraints, pkixdate, variant);
     }
 
     // Check this 'cert' for restrictions in the AnchorCertificates
@@ -286,6 +265,28 @@
                 null, null, -1, PKIXReason.INVALID_KEY_USAGE);
         }
 
+        X509CertImpl x509Cert;
+        AlgorithmId algorithmId;
+        try {
+            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
+            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
+        } catch (CertificateException ce) {
+            throw new CertPathValidatorException(ce);
+        }
+
+        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
+        PublicKey currPubKey = cert.getPublicKey();
+        String currSigAlg = x509Cert.getSigAlgName();
+
+        // Check the signature algorithm and parameters against constraints.
+        if (!constraints.permits(SIGNATURE_PRIMITIVE_SET, currSigAlg,
+                currSigAlgParams)) {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on signature " +
+                            "algorithm: " + currSigAlg, null, null, -1,
+                    BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
         // Assume all key usage bits are set if key usage is not present
         Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
 
@@ -322,101 +323,74 @@
             }
         }
 
-        PublicKey currPubKey = cert.getPublicKey();
-
-        if (constraints instanceof DisabledAlgorithmConstraints) {
-            // Check against DisabledAlgorithmConstraints certpath constraints.
-            // permits() will throw exception on failure.
-            ((DisabledAlgorithmConstraints)constraints).permits(primitives,
-                new CertConstraintParameters((X509Certificate)cert,
-                        trustedMatch, pkixdate, jarTimestamp));
-            // If there is no previous key, set one and exit
-            if (prevPubKey == null) {
-                prevPubKey = currPubKey;
-                return;
-            }
-        }
+        ConstraintsParameters cp =
+                new ConstraintsParameters((X509Certificate)cert,
+                        trustedMatch, pkixdate, jarTimestamp, variant);
 
-        X509CertImpl x509Cert;
-        AlgorithmId algorithmId;
-        try {
-            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
-            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
-        } catch (CertificateException ce) {
-            throw new CertPathValidatorException(ce);
-        }
-
-        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
-        String currSigAlg = x509Cert.getSigAlgName();
+        // Check against local constraints if it is DisabledAlgorithmConstraints
+        if (constraints instanceof DisabledAlgorithmConstraints) {
+            ((DisabledAlgorithmConstraints)constraints).permits(currSigAlg, cp);
+            // DisabledAlgorithmsConstraints does not check primitives, so key
+            // additional key check.
 
-        // If 'constraints' is not of DisabledAlgorithmConstraints, check all
-        // everything individually
-        if (!(constraints instanceof DisabledAlgorithmConstraints)) {
-            // Check the current signature algorithm
-            if (!constraints.permits(
-                    SIGNATURE_PRIMITIVE_SET,
-                    currSigAlg, currSigAlgParams)) {
-                throw new CertPathValidatorException(
-                        "Algorithm constraints check failed on signature " +
-                                "algorithm: " + currSigAlg, null, null, -1,
-                        BasicReason.ALGORITHM_CONSTRAINED);
-            }
-
+        } else {
+            // Perform the default constraints checking anyway.
+            certPathDefaultConstraints.permits(currSigAlg, cp);
+            // Call locally set constraints to check key with primitives.
             if (!constraints.permits(primitives, currPubKey)) {
                 throw new CertPathValidatorException(
-                        "Algorithm constraints check failed on keysize: " +
-                                sun.security.util.KeyUtil.getKeySize(currPubKey),
+                        "Algorithm constraints check failed on key " +
+                                currPubKey.getAlgorithm() + " with size of " +
+                                sun.security.util.KeyUtil.getKeySize(currPubKey) +
+                                "bits",
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
 
+        // If there is no previous key, set one and exit
+        if (prevPubKey == null) {
+            prevPubKey = currPubKey;
+            return;
+        }
+
         // Check with previous cert for signature algorithm and public key
-        if (prevPubKey != null) {
-            if (!constraints.permits(
-                    SIGNATURE_PRIMITIVE_SET,
-                    currSigAlg, prevPubKey, currSigAlgParams)) {
-                throw new CertPathValidatorException(
+        if (!constraints.permits(
+                SIGNATURE_PRIMITIVE_SET,
+                currSigAlg, prevPubKey, currSigAlgParams)) {
+            throw new CertPathValidatorException(
                     "Algorithm constraints check failed on " +
                             "signature algorithm: " + currSigAlg,
                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
+        // Inherit key parameters from previous key
+        if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
+            // Inherit DSA parameters from previous key
+            if (!(prevPubKey instanceof DSAPublicKey)) {
+                throw new CertPathValidatorException("Input key is not " +
+                        "of a appropriate type for inheriting parameters");
             }
 
-            // Inherit key parameters from previous key
-            if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
-                // Inherit DSA parameters from previous key
-                if (!(prevPubKey instanceof DSAPublicKey)) {
-                    throw new CertPathValidatorException("Input key is not " +
-                        "of a appropriate type for inheriting parameters");
-                }
-
-                DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
-                if (params == null) {
-                    throw new CertPathValidatorException(
+            DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
+            if (params == null) {
+                throw new CertPathValidatorException(
                         "Key parameters missing from public key.");
-                }
+            }
 
-                try {
-                    BigInteger y = ((DSAPublicKey)currPubKey).getY();
-                    KeyFactory kf = KeyFactory.getInstance("DSA");
-                    DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
-                                                       params.getP(),
-                                                       params.getQ(),
-                                                       params.getG());
-                    currPubKey = kf.generatePublic(ks);
-                } catch (GeneralSecurityException e) {
-                    throw new CertPathValidatorException("Unable to generate " +
+            try {
+                BigInteger y = ((DSAPublicKey)currPubKey).getY();
+                KeyFactory kf = KeyFactory.getInstance("DSA");
+                DSAPublicKeySpec ks = new DSAPublicKeySpec(y, params.getP(),
+                        params.getQ(), params.getG());
+                currPubKey = kf.generatePublic(ks);
+            } catch (GeneralSecurityException e) {
+                throw new CertPathValidatorException("Unable to generate " +
                         "key with inherited parameters: " + e.getMessage(), e);
-                }
             }
         }
 
         // reset the previous public key
         prevPubKey = currPubKey;
-
-        // check the extended key usage, ignore the check now
-        // List<String> extendedKeyUsages = x509Cert.getExtendedKeyUsage();
-
-        // DO NOT remove any unresolved critical extensions
     }
 
     /**
@@ -456,8 +430,10 @@
      *
      * @param key the public key to verify the CRL signature
      * @param crl the target CRL
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    static void check(PublicKey key, X509CRL crl)
+    static void check(PublicKey key, X509CRL crl, String variant)
                         throws CertPathValidatorException {
 
         X509CRLImpl x509CRLImpl = null;
@@ -468,7 +444,7 @@
         }
 
         AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
-        check(key, algorithmId);
+        check(key, algorithmId, variant);
     }
 
     /**
@@ -476,20 +452,16 @@
      *
      * @param key the public key to verify the CRL signature
      * @param algorithmId signature algorithm Algorithm ID
+     * @param variant is the Validator variants of the operation. A null value
+     *                passed will set it to Validator.GENERIC.
      */
-    static void check(PublicKey key, AlgorithmId algorithmId)
+    static void check(PublicKey key, AlgorithmId algorithmId, String variant)
                         throws CertPathValidatorException {
         String sigAlgName = algorithmId.getName();
         AlgorithmParameters sigAlgParams = algorithmId.getParameters();
 
-        if (!certPathDefaultConstraints.permits(
-                SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
-            throw new CertPathValidatorException(
-                "Algorithm constraints check failed on signature algorithm: " +
-                sigAlgName + " is disabled",
-                null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
+        certPathDefaultConstraints.permits(new ConstraintsParameters(
+                sigAlgName, sigAlgParams, key, variant));
     }
-
 }
 
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -33,6 +33,7 @@
 import java.util.*;
 
 import sun.security.util.Debug;
+import sun.security.validator.Validator;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.x509.*;
 
@@ -66,6 +67,20 @@
      * an X509CRLSelector with certificateChecking set.
      */
     public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
+            boolean signFlag, PublicKey prevKey, String provider,
+            List<CertStore> certStores, boolean[] reasonsMask,
+            Set<TrustAnchor> trustAnchors, Date validity, String variant)
+            throws CertStoreException
+    {
+        return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
+                reasonsMask, trustAnchors, validity, variant);
+    }
+    /**
+     * Return the X509CRLs matching this selector. The selector must be
+     * an X509CRLSelector with certificateChecking set.
+     */
+    // Called by com.sun.deploy.security.RevocationChecker
+    public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
                                               boolean signFlag,
                                               PublicKey prevKey,
                                               String provider,
@@ -76,7 +91,7 @@
         throws CertStoreException
     {
         return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
-                       reasonsMask, trustAnchors, validity);
+                reasonsMask, trustAnchors, validity, Validator.VAR_GENERIC);
     }
 
     /**
@@ -91,7 +106,8 @@
                                               List<CertStore> certStores,
                                               boolean[] reasonsMask,
                                               Set<TrustAnchor> trustAnchors,
-                                              Date validity)
+                                              Date validity,
+                                              String variant)
         throws CertStoreException
     {
         X509Certificate cert = selector.getCertificateChecking();
@@ -120,7 +136,7 @@
                 DistributionPoint point = t.next();
                 Collection<X509CRL> crls = getCRLs(selector, certImpl,
                     point, reasonsMask, signFlag, prevKey, prevCert, provider,
-                    certStores, trustAnchors, validity);
+                    certStores, trustAnchors, validity, variant);
                 results.addAll(crls);
             }
             if (debug != null) {
@@ -145,7 +161,7 @@
         X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask,
         boolean signFlag, PublicKey prevKey, X509Certificate prevCert,
         String provider, List<CertStore> certStores,
-        Set<TrustAnchor> trustAnchors, Date validity)
+        Set<TrustAnchor> trustAnchors, Date validity, String variant)
             throws CertStoreException {
 
         // check for full name
@@ -208,7 +224,7 @@
                 selector.setIssuerNames(null);
                 if (selector.match(crl) && verifyCRL(certImpl, point, crl,
                         reasonsMask, signFlag, prevKey, prevCert, provider,
-                        trustAnchors, certStores, validity)) {
+                        trustAnchors, certStores, validity, variant)) {
                     crls.add(crl);
                 }
             } catch (IOException | CRLException e) {
@@ -316,7 +332,7 @@
         X509CRL crl, boolean[] reasonsMask, boolean signFlag,
         PublicKey prevKey, X509Certificate prevCert, String provider,
         Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
-        Date validity) throws CRLException, IOException {
+        Date validity, String variant) throws CRLException, IOException {
 
         if (debug != null) {
             debug.println("DistributionPointFetcher.verifyCRL: " +
@@ -663,7 +679,7 @@
 
         // check the crl signature algorithm
         try {
-            AlgorithmChecker.check(prevKey, crl);
+            AlgorithmChecker.check(prevKey, crl, variant);
         } catch (CertPathValidatorException cpve) {
             if (debug != null) {
                 debug.println("CRL signature algorithm check failed: " + cpve);
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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,7 @@
 
 import sun.security.action.GetIntegerAction;
 import sun.security.util.Debug;
+import sun.security.validator.Validator;
 import sun.security.x509.AccessDescription;
 import sun.security.x509.AuthorityInfoAccessExtension;
 import sun.security.x509.GeneralName;
@@ -94,42 +95,6 @@
 
     private OCSP() {}
 
-    /**
-     * Obtains the revocation status of a certificate using OCSP using the most
-     * common defaults. The OCSP responder URI is retrieved from the
-     * certificate's AIA extension. The OCSP responder certificate is assumed
-     * to be the issuer's certificate (or issued by the issuer CA).
-     *
-     * @param cert the certificate to be checked
-     * @param issuerCert the issuer certificate
-     * @return the RevocationStatus
-     * @throws IOException if there is an exception connecting to or
-     *    communicating with the OCSP responder
-     * @throws CertPathValidatorException if an exception occurs while
-     *    encoding the OCSP Request or validating the OCSP Response
-     */
-    public static RevocationStatus check(X509Certificate cert,
-                                         X509Certificate issuerCert)
-        throws IOException, CertPathValidatorException {
-        CertId certId = null;
-        URI responderURI = null;
-        try {
-            X509CertImpl certImpl = X509CertImpl.toImpl(cert);
-            responderURI = getResponderURI(certImpl);
-            if (responderURI == null) {
-                throw new CertPathValidatorException
-                    ("No OCSP Responder URI in certificate");
-            }
-            certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
-        } catch (CertificateException | IOException e) {
-            throw new CertPathValidatorException
-                ("Exception while encoding OCSPRequest", e);
-        }
-        OCSPResponse ocspResponse = check(Collections.singletonList(certId),
-            responderURI, new OCSPResponse.IssuerInfo(issuerCert), null, null,
-            Collections.<Extension>emptyList());
-        return (RevocationStatus)ocspResponse.getSingleResponse(certId);
-    }
 
     /**
      * Obtains the revocation status of a certificate using OCSP.
@@ -146,6 +111,8 @@
      * @throws CertPathValidatorException if an exception occurs while
      *    encoding the OCSP Request or validating the OCSP Response
      */
+
+    // Called by com.sun.deploy.security.TrustDecider
     public static RevocationStatus check(X509Certificate cert,
                                          X509Certificate issuerCert,
                                          URI responderURI,
@@ -154,27 +121,27 @@
         throws IOException, CertPathValidatorException
     {
         return check(cert, issuerCert, responderURI, responderCert, date,
-                     Collections.<Extension>emptyList());
+                     Collections.<Extension>emptyList(), Validator.VAR_GENERIC);
     }
 
-    // Called by com.sun.deploy.security.TrustDecider
+
     public static RevocationStatus check(X509Certificate cert,
-                                         X509Certificate issuerCert,
-                                         URI responderURI,
-                                         X509Certificate responderCert,
-                                         Date date, List<Extension> extensions)
+            X509Certificate issuerCert, URI responderURI,
+            X509Certificate responderCert, Date date, List<Extension> extensions,
+            String variant)
         throws IOException, CertPathValidatorException
     {
-        return check(cert, responderURI, null, issuerCert, responderCert, date, extensions);
+        return check(cert, responderURI, null, issuerCert, responderCert, date,
+                extensions, variant);
     }
 
     public static RevocationStatus check(X509Certificate cert,
             URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
             X509Certificate responderCert, Date date,
-            List<Extension> extensions)
+            List<Extension> extensions, String variant)
             throws IOException, CertPathValidatorException
     {
-        CertId certId = null;
+        CertId certId;
         try {
             X509CertImpl certImpl = X509CertImpl.toImpl(cert);
             certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
@@ -184,7 +151,7 @@
         }
         OCSPResponse ocspResponse = check(Collections.singletonList(certId),
                 responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
-                responderCert, date, extensions);
+                responderCert, date, extensions, variant);
         return (RevocationStatus) ocspResponse.getSingleResponse(certId);
     }
 
@@ -206,10 +173,10 @@
      * @throws CertPathValidatorException if an exception occurs while
      *    encoding the OCSP Request or validating the OCSP Response
      */
-        static OCSPResponse check(List<CertId> certIds, URI responderURI,
+    static OCSPResponse check(List<CertId> certIds, URI responderURI,
                               OCSPResponse.IssuerInfo issuerInfo,
                               X509Certificate responderCert, Date date,
-                              List<Extension> extensions)
+                              List<Extension> extensions, String variant)
         throws IOException, CertPathValidatorException
     {
         byte[] nonce = null;
@@ -226,7 +193,7 @@
 
             // verify the response
             ocspResponse.verify(certIds, issuerInfo, responderCert, date,
-                    nonce);
+                    nonce, variant);
         } catch (IOException ioe) {
             throw new CertPathValidatorException(
                 "Unable to determine revocation status due to network error",
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -41,7 +41,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 import javax.security.auth.x500.X500Principal;
 
@@ -375,7 +374,8 @@
     }
 
     void verify(List<CertId> certIds, IssuerInfo issuerInfo,
-            X509Certificate responderCert, Date date, byte[] nonce)
+            X509Certificate responderCert, Date date, byte[] nonce,
+            String variant)
         throws CertPathValidatorException
     {
         switch (responseStatus) {
@@ -508,7 +508,8 @@
                 // Check algorithm constraints specified in security property
                 // "jdk.certpath.disabledAlgorithms".
                 AlgorithmChecker algChecker =
-                        new AlgorithmChecker(issuerInfo.getAnchor(), date);
+                        new AlgorithmChecker(issuerInfo.getAnchor(), date,
+                                variant);
                 algChecker.init(false);
                 algChecker.check(signerCert, Collections.<String>emptySet());
 
@@ -568,7 +569,7 @@
         if (signerCert != null) {
             // Check algorithm constraints specified in security property
             // "jdk.certpath.disabledAlgorithms".
-            AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId);
+            AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId, variant);
 
             if (!verifySignature(signerCert)) {
                 throw new CertPathValidatorException(
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -87,6 +87,7 @@
         private Set<TrustAnchor> anchors;
         private List<X509Certificate> certs;
         private Timestamp timestamp;
+        private String variant;
 
         ValidatorParams(CertPath cp, PKIXParameters params)
             throws InvalidAlgorithmParameterException
@@ -102,8 +103,9 @@
         ValidatorParams(PKIXParameters params)
             throws InvalidAlgorithmParameterException
         {
-            if (params instanceof PKIXTimestampParameters) {
-                timestamp = ((PKIXTimestampParameters) params).getTimestamp();
+            if (params instanceof PKIXExtendedParameters) {
+                timestamp = ((PKIXExtendedParameters) params).getTimestamp();
+                variant = ((PKIXExtendedParameters) params).getVariant();
             }
 
             this.anchors = params.getTrustAnchors();
@@ -199,6 +201,10 @@
         Timestamp timestamp() {
             return timestamp;
         }
+
+        String variant() {
+            return variant;
+        }
     }
 
     static class BuilderParams extends ValidatorParams {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -173,9 +173,10 @@
         // add standard checkers that we will be using
         certPathCheckers.add(untrustedChecker);
         if (params.timestamp() == null) {
-            certPathCheckers.add(new AlgorithmChecker(anchor, params.date()));
+            certPathCheckers.add(new AlgorithmChecker(anchor, params.date(), null));
         } else {
-            certPathCheckers.add(new AlgorithmChecker(params.timestamp()));
+            certPathCheckers.add(new AlgorithmChecker(null,
+                    params.timestamp(), params.variant()));
         }
         certPathCheckers.add(new KeyChecker(certPathLen,
                                             params.targetCertConstraints()));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXExtendedParameters.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package sun.security.provider.certpath;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Timestamp;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStore;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.TrustAnchor;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is a wrapper for PKIXBuilderParameters so that a Timestamp object
+ * and a string for the variant type, can be passed when doing certpath
+ * checking.
+ */
+
+public class PKIXExtendedParameters extends PKIXBuilderParameters {
+
+    private final PKIXBuilderParameters p;
+    private Timestamp jarTimestamp;
+    private final String variant;
+
+    public PKIXExtendedParameters(PKIXBuilderParameters params,
+            Timestamp timestamp, String variant)
+            throws InvalidAlgorithmParameterException {
+        super(params.getTrustAnchors(), null);
+        p = params;
+        jarTimestamp = timestamp;
+        this.variant = variant;
+    }
+
+    public Timestamp getTimestamp() {
+        return jarTimestamp;
+    }
+    public void setTimestamp(Timestamp t) {
+        jarTimestamp = t;
+    }
+
+    public String getVariant() {
+        return variant;
+    }
+
+    @Override
+    public void setDate(Date d) {
+        p.setDate(d);
+    }
+
+    @Override
+    public void addCertPathChecker(PKIXCertPathChecker c) {
+        p.addCertPathChecker(c);
+    }
+
+    @Override
+    public void setMaxPathLength(int maxPathLength) {
+        p.setMaxPathLength(maxPathLength);
+    }
+
+    @Override
+    public int getMaxPathLength() {
+        return p.getMaxPathLength();
+    }
+
+    @Override
+    public String toString() {
+        return p.toString();
+    }
+
+    @Override
+    public Set<TrustAnchor> getTrustAnchors() {
+        return p.getTrustAnchors();
+    }
+
+    @Override
+    public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
+            throws InvalidAlgorithmParameterException {
+        // To avoid problems with PKIXBuilderParameter's constructors
+        if (p == null) {
+            return;
+        }
+        p.setTrustAnchors(trustAnchors);
+    }
+
+    @Override
+    public Set<String> getInitialPolicies() {
+        return p.getInitialPolicies();
+    }
+
+    @Override
+    public void setInitialPolicies(Set<String> initialPolicies) {
+        p.setInitialPolicies(initialPolicies);
+    }
+
+    @Override
+    public void setCertStores(List<CertStore> stores) {
+        p.setCertStores(stores);
+    }
+
+    @Override
+    public void addCertStore(CertStore store) {
+        p.addCertStore(store);
+    }
+
+    @Override
+    public List<CertStore> getCertStores() {
+        return p.getCertStores();
+    }
+
+    @Override
+    public void setRevocationEnabled(boolean val) {
+        p.setRevocationEnabled(val);
+    }
+
+    @Override
+    public boolean isRevocationEnabled() {
+        return p.isRevocationEnabled();
+    }
+
+    @Override
+    public void setExplicitPolicyRequired(boolean val) {
+        p.setExplicitPolicyRequired(val);
+    }
+
+    @Override
+    public boolean isExplicitPolicyRequired() {
+        return p.isExplicitPolicyRequired();
+    }
+
+    @Override
+    public void setPolicyMappingInhibited(boolean val) {
+        p.setPolicyMappingInhibited(val);
+    }
+
+    @Override
+    public boolean isPolicyMappingInhibited() {
+        return p.isPolicyMappingInhibited();
+    }
+
+    @Override
+    public void setAnyPolicyInhibited(boolean val) {
+        p.setAnyPolicyInhibited(val);
+    }
+
+    @Override
+    public boolean isAnyPolicyInhibited() {
+        return p.isAnyPolicyInhibited();
+    }
+
+    @Override
+    public void setPolicyQualifiersRejected(boolean qualifiersRejected) {
+        p.setPolicyQualifiersRejected(qualifiersRejected);
+    }
+
+    @Override
+    public boolean getPolicyQualifiersRejected() {
+        return p.getPolicyQualifiersRejected();
+    }
+
+    @Override
+    public Date getDate() {
+        return p.getDate();
+    }
+
+    @Override
+    public void setCertPathCheckers(List<PKIXCertPathChecker> checkers) {
+        p.setCertPathCheckers(checkers);
+    }
+
+    @Override
+    public List<PKIXCertPathChecker> getCertPathCheckers() {
+        return p.getCertPathCheckers();
+    }
+
+    @Override
+    public String getSigProvider() {
+        return p.getSigProvider();
+    }
+
+    @Override
+    public void setSigProvider(String sigProvider) {
+        p.setSigProvider(sigProvider);
+    }
+
+    @Override
+    public CertSelector getTargetCertConstraints() {
+        return p.getTargetCertConstraints();
+    }
+
+    @Override
+    public void setTargetCertConstraints(CertSelector selector) {
+        // To avoid problems with PKIXBuilderParameter's constructors
+        if (p == null) {
+            return;
+        }
+        p.setTargetCertConstraints(selector);
+    }
+
+}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXTimestampParameters.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-/*
- * 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package sun.security.provider.certpath;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.Timestamp;
-import java.security.cert.CertSelector;
-import java.security.cert.CertStore;
-import java.security.cert.PKIXBuilderParameters;
-import java.security.cert.PKIXCertPathChecker;
-import java.security.cert.TrustAnchor;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
-/**
- * This class is a wrapper for PKIXBuilderParameters so that a Timestamp object
- * can be passed alone when PKIXCertPath is checking signed jar files.
- */
-
-public class PKIXTimestampParameters extends PKIXBuilderParameters {
-
-    private final PKIXBuilderParameters p;
-    private Timestamp jarTimestamp;
-
-    public PKIXTimestampParameters(PKIXBuilderParameters params,
-            Timestamp timestamp) throws InvalidAlgorithmParameterException {
-        super(params.getTrustAnchors(), null);
-        p = params;
-        jarTimestamp = timestamp;
-    }
-
-    public Timestamp getTimestamp() {
-        return jarTimestamp;
-    }
-    public void setTimestamp(Timestamp t) {
-        jarTimestamp = t;
-    }
-
-    @Override
-    public void setDate(Date d) {
-        p.setDate(d);
-    }
-
-    @Override
-    public void addCertPathChecker(PKIXCertPathChecker c) {
-        p.addCertPathChecker(c);
-    }
-
-    @Override
-    public void setMaxPathLength(int maxPathLength) {
-        p.setMaxPathLength(maxPathLength);
-    }
-
-    @Override
-    public int getMaxPathLength() {
-        return p.getMaxPathLength();
-    }
-
-    @Override
-    public String toString() {
-        return p.toString();
-    }
-
-    @Override
-    public Set<TrustAnchor> getTrustAnchors() {
-        return p.getTrustAnchors();
-    }
-
-    @Override
-    public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
-            throws InvalidAlgorithmParameterException {
-        // To avoid problems with PKIXBuilderParameter's constructors
-        if (p == null) {
-            return;
-        }
-        p.setTrustAnchors(trustAnchors);
-    }
-
-    @Override
-    public Set<String> getInitialPolicies() {
-        return p.getInitialPolicies();
-    }
-
-    @Override
-    public void setInitialPolicies(Set<String> initialPolicies) {
-        p.setInitialPolicies(initialPolicies);
-    }
-
-    @Override
-    public void setCertStores(List<CertStore> stores) {
-        p.setCertStores(stores);
-    }
-
-    @Override
-    public void addCertStore(CertStore store) {
-        p.addCertStore(store);
-    }
-
-    @Override
-    public List<CertStore> getCertStores() {
-        return p.getCertStores();
-    }
-
-    @Override
-    public void setRevocationEnabled(boolean val) {
-        p.setRevocationEnabled(val);
-    }
-
-    @Override
-    public boolean isRevocationEnabled() {
-        return p.isRevocationEnabled();
-    }
-
-    @Override
-    public void setExplicitPolicyRequired(boolean val) {
-        p.setExplicitPolicyRequired(val);
-    }
-
-    @Override
-    public boolean isExplicitPolicyRequired() {
-        return p.isExplicitPolicyRequired();
-    }
-
-    @Override
-    public void setPolicyMappingInhibited(boolean val) {
-        p.setPolicyMappingInhibited(val);
-    }
-
-    @Override
-    public boolean isPolicyMappingInhibited() {
-        return p.isPolicyMappingInhibited();
-    }
-
-    @Override
-    public void setAnyPolicyInhibited(boolean val) {
-        p.setAnyPolicyInhibited(val);
-    }
-
-    @Override
-    public boolean isAnyPolicyInhibited() {
-        return p.isAnyPolicyInhibited();
-    }
-
-    @Override
-    public void setPolicyQualifiersRejected(boolean qualifiersRejected) {
-        p.setPolicyQualifiersRejected(qualifiersRejected);
-    }
-
-    @Override
-    public boolean getPolicyQualifiersRejected() {
-        return p.getPolicyQualifiersRejected();
-    }
-
-    @Override
-    public Date getDate() {
-        return p.getDate();
-    }
-
-    @Override
-    public void setCertPathCheckers(List<PKIXCertPathChecker> checkers) {
-        p.setCertPathCheckers(checkers);
-    }
-
-    @Override
-    public List<PKIXCertPathChecker> getCertPathCheckers() {
-        return p.getCertPathCheckers();
-    }
-
-    @Override
-    public String getSigProvider() {
-        return p.getSigProvider();
-    }
-
-    @Override
-    public void setSigProvider(String sigProvider) {
-        p.setSigProvider(sigProvider);
-    }
-
-    @Override
-    public CertSelector getTargetCertConstraints() {
-        return p.getTargetCertConstraints();
-    }
-
-    @Override
-    public void setTargetCertConstraints(CertSelector selector) {
-        // To avoid problems with PKIXBuilderParameter's constructors
-        if (p == null) {
-            return;
-        }
-        p.setTargetCertConstraints(selector);
-    }
-
-}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -579,7 +579,7 @@
                     approvedCRLs.addAll(DistributionPointFetcher.getCRLs(
                                         sel, signFlag, prevKey, prevCert,
                                         params.sigProvider(), certStores,
-                                        reasonsMask, anchors, null));
+                                        reasonsMask, anchors, null, params.variant()));
                 }
             } catch (CertStoreException e) {
                 if (e instanceof CertStoreTypeException) {
@@ -727,7 +727,7 @@
                     }
                 }
                 response.verify(Collections.singletonList(certId), issuerInfo,
-                        responderCert, params.date(), nonce);
+                        responderCert, params.date(), nonce, params.variant());
 
             } else {
                 URI responderURI = (this.responderURI != null)
@@ -741,7 +741,7 @@
 
                 response = OCSP.check(Collections.singletonList(certId),
                         responderURI, issuerInfo, responderCert, null,
-                        ocspExtensions);
+                        ocspExtensions, params.variant());
             }
         } catch (IOException e) {
             throw new CertPathValidatorException(
@@ -853,7 +853,7 @@
                     if (DistributionPointFetcher.verifyCRL(
                             certImpl, point, crl, reasonsMask, signFlag,
                             prevKey, null, params.sigProvider(), anchors,
-                            certStores, params.date()))
+                            certStores, params.date(), params.variant()))
                     {
                         results.add(crl);
                     }
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, 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
@@ -344,7 +344,7 @@
 
                 // add the algorithm checker
                 checkers.add(new AlgorithmChecker(builder.trustAnchor,
-                        buildParams.date()));
+                        buildParams.date(), null));
 
                 BasicChecker basicChecker = null;
                 if (nextState.keyParamsNeeded()) {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/EllipticCurvesExtension.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/EllipticCurvesExtension.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -43,6 +43,9 @@
 
 final class EllipticCurvesExtension extends HelloExtension {
 
+    /* Class and subclass dynamic debugging support */
+    private static final Debug debug = Debug.getInstance("ssl");
+
     private static final int ARBITRARY_PRIME = 0xff01;
     private static final int ARBITRARY_CHAR2 = 0xff02;
 
@@ -159,6 +162,11 @@
                     }   // ignore unknown curves
                 }
             }
+            if (idList.isEmpty() && JsseJce.isEcAvailable()) {
+                throw new IllegalArgumentException(
+                    "System property jdk.tls.namedGroups(" + property + ") " +
+                    "contains no supported elliptic curves");
+            }
         } else {        // default curves
             int[] ids;
             if (requireFips) {
@@ -183,16 +191,17 @@
             }
         }
 
-        if (idList.isEmpty()) {
-            throw new IllegalArgumentException(
-                "System property jdk.tls.namedGroups(" + property + ") " +
-                "contains no supported elliptic curves");
-        } else {
-            supportedCurveIds = new int[idList.size()];
-            int i = 0;
-            for (Integer id : idList) {
-                supportedCurveIds[i++] = id;
-            }
+        if (debug != null && idList.isEmpty()) {
+            Debug.log(
+                "Initialized [jdk.tls.namedGroups|default] list contains " +
+                "no available elliptic curves. " +
+                (property != null ? "(" + property + ")" : "[Default]"));
+        }
+
+        supportedCurveIds = new int[idList.size()];
+        int i = 0;
+        for (Integer id : idList) {
+            supportedCurveIds[i++] = id;
         }
     }
 
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -37,6 +37,7 @@
 
 import sun.security.provider.certpath.AlgorithmChecker;
 import sun.security.action.GetPropertyAction;
+import sun.security.validator.Validator;
 
 public abstract class SSLContextImpl extends SSLContextSpi {
 
@@ -1436,7 +1437,7 @@
                 constraints = new SSLAlgorithmConstraints(sslSocket, true);
             }
 
-            checkAlgorithmConstraints(chain, constraints);
+            checkAlgorithmConstraints(chain, constraints, isClient);
         }
     }
 
@@ -1478,12 +1479,12 @@
                 constraints = new SSLAlgorithmConstraints(engine, true);
             }
 
-            checkAlgorithmConstraints(chain, constraints);
+            checkAlgorithmConstraints(chain, constraints, isClient);
         }
     }
 
     private void checkAlgorithmConstraints(X509Certificate[] chain,
-            AlgorithmConstraints constraints) throws CertificateException {
+            AlgorithmConstraints constraints, boolean isClient) throws CertificateException {
 
         try {
             // Does the certificate chain end with a trusted certificate?
@@ -1501,7 +1502,9 @@
 
             // A forward checker, need to check from trust to target
             if (checkedLength >= 0) {
-                AlgorithmChecker checker = new AlgorithmChecker(constraints);
+                AlgorithmChecker checker =
+                        new AlgorithmChecker(constraints, null,
+                                (isClient ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER));
                 checker.init(false);
                 for (int i = checkedLength; i >= 0; i--) {
                     Certificate cert = chain[i];
--- a/jdk/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -39,6 +39,7 @@
 import javax.net.ssl.*;
 
 import sun.security.provider.certpath.AlgorithmChecker;
+import sun.security.validator.Validator;
 
 /**
  * The new X509 key manager implementation. The main differences to the
@@ -661,6 +662,15 @@
 
             return CheckResult.OK;
         }
+
+        public String getValidator() {
+            if (this == CLIENT) {
+                return Validator.VAR_TLS_CLIENT;
+            } else if (this == SERVER) {
+                return Validator.VAR_TLS_SERVER;
+            }
+            return Validator.VAR_GENERIC;
+        }
     }
 
     // enum for the result of the extension check
@@ -774,7 +784,8 @@
 
             // check the algorithm constraints
             if (constraints != null &&
-                    !conformsToAlgorithmConstraints(constraints, chain)) {
+                    !conformsToAlgorithmConstraints(constraints, chain,
+                            checkType.getValidator())) {
 
                 if (useDebug) {
                     debug.println("Ignoring alias " + alias +
@@ -811,9 +822,10 @@
     }
 
     private static boolean conformsToAlgorithmConstraints(
-            AlgorithmConstraints constraints, Certificate[] chain) {
+            AlgorithmConstraints constraints, Certificate[] chain,
+            String variant) {
 
-        AlgorithmChecker checker = new AlgorithmChecker(constraints);
+        AlgorithmChecker checker = new AlgorithmChecker(constraints, null, variant);
         try {
             checker.init(false);
         } catch (CertPathValidatorException cpve) {
--- a/jdk/src/java.base/share/classes/sun/security/util/CertConstraintParameters.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.util;
-
-import java.security.Timestamp;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-
-/**
- * This class is a wrapper for keeping state and passing objects between PKIX,
- * AlgorithmChecker, and DisabledAlgorithmConstraints.
- */
-public class CertConstraintParameters {
-    // A certificate being passed to check against constraints.
-    private final X509Certificate cert;
-    // This is true if the trust anchor in the certificate chain matches a cert
-    // in AnchorCertificates
-    private final boolean trustedMatch;
-    // PKIXParameter date
-    private final Date pkixDate;
-    // Timestamp of the signed JAR file
-    private final Timestamp jarTimestamp;
-
-    public CertConstraintParameters(X509Certificate c, boolean match,
-            Date pkixdate, Timestamp jarTime) {
-        cert = c;
-        trustedMatch = match;
-        pkixDate = pkixdate;
-        jarTimestamp = jarTime;
-    }
-
-    public CertConstraintParameters(X509Certificate c) {
-        this(c, false, null, null);
-    }
-
-    // Returns if the trust anchor has a match if anchor checking is enabled.
-    public boolean isTrustedMatch() {
-        return trustedMatch;
-    }
-
-    public X509Certificate getCertificate() {
-        return cert;
-    }
-
-    public Date getPKIXParamDate() {
-        return pkixDate;
-    }
-
-    public Timestamp getJARTimestamp() {
-        return jarTimestamp;
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016, 2017 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import sun.security.validator.Validator;
+
+import java.security.AlgorithmParameters;
+import java.security.Key;
+import java.security.Timestamp;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+/**
+ * This class contains parameters for checking against constraints that extend
+ * past the publicly available parameters in java.security.AlgorithmConstraints.
+
+ * This is currently on passed between  between PKIX, AlgorithmChecker,
+ * and DisabledAlgorithmConstraints.
+ */
+public class ConstraintsParameters {
+    /*
+     * The below 3 values are used the same as the permit() methods
+     * published in java.security.AlgorithmConstraints.
+     */
+    // Algorithm string to be checked against constraints
+    private final String algorithm;
+    // AlgorithmParameters to the algorithm being checked
+    private final AlgorithmParameters algParams;
+    // Public Key being checked against constraints
+    private final Key publicKey;
+
+    /*
+     * New values that are checked against constraints that the current public
+     * API does not support.
+     */
+    // A certificate being passed to check against constraints.
+    private final X509Certificate cert;
+    // This is true if the trust anchor in the certificate chain matches a cert
+    // in AnchorCertificates
+    private final boolean trustedMatch;
+    // PKIXParameter date
+    private final Date pkixDate;
+    // Timestamp of the signed JAR file
+    private final Timestamp jarTimestamp;
+    private final String variant;
+
+    public ConstraintsParameters(X509Certificate c, boolean match,
+            Date pkixdate, Timestamp jarTime, String variant) {
+        cert = c;
+        trustedMatch = match;
+        pkixDate = pkixdate;
+        jarTimestamp = jarTime;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+        algorithm = null;
+        algParams = null;
+        publicKey = null;
+    }
+
+    public ConstraintsParameters(String algorithm, AlgorithmParameters params,
+            Key key, String variant) {
+        this.algorithm = algorithm;
+        algParams = params;
+        this.publicKey = key;
+        cert = null;
+        trustedMatch = false;
+        pkixDate = null;
+        jarTimestamp = null;
+        this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+    }
+
+
+    public ConstraintsParameters(X509Certificate c) {
+        this(c, false, null, null,
+                Validator.VAR_GENERIC);
+    }
+
+    public ConstraintsParameters(Timestamp jarTime) {
+        this(null, false, null, jarTime, Validator.VAR_GENERIC);
+    }
+
+    public String getAlgorithm() {
+        return algorithm;
+    }
+
+    public AlgorithmParameters getAlgParams() {
+        return algParams;
+    }
+
+    public Key getPublicKey() {
+        return publicKey;
+    }
+    // Returns if the trust anchor has a match if anchor checking is enabled.
+    public boolean isTrustedMatch() {
+        return trustedMatch;
+    }
+
+    public X509Certificate getCertificate() {
+        return cert;
+    }
+
+    public Date getPKIXParamDate() {
+        return pkixDate;
+    }
+
+    public Timestamp getJARTimestamp() {
+        return jarTimestamp;
+    }
+
+    public String getVariant() {
+        return variant;
+    }
+}
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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,8 @@
 
 package sun.security.util;
 
+import sun.security.validator.Validator;
+
 import java.security.CryptoPrimitive;
 import java.security.AlgorithmParameters;
 import java.security.Key;
@@ -32,10 +34,12 @@
 import java.security.cert.CertPathValidatorException.BasicReason;
 import java.security.cert.X509Certificate;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -100,12 +104,6 @@
     @Override
     public final boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, AlgorithmParameters parameters) {
-
-        if (primitives == null || primitives.isEmpty()) {
-            throw new IllegalArgumentException(
-                        "No cryptographic primitive specified");
-        }
-
         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
     }
 
@@ -133,6 +131,18 @@
         return checkConstraints(primitives, algorithm, key, parameters);
     }
 
+    public final void permits(ConstraintsParameters cp)
+            throws CertPathValidatorException {
+        permits(cp.getAlgorithm(), cp);
+    }
+
+    public final void permits(String algorithm, Key key,
+            AlgorithmParameters params, String variant)
+            throws CertPathValidatorException {
+        permits(algorithm, new ConstraintsParameters(algorithm, params, key,
+                (variant == null) ? Validator.VAR_GENERIC : variant));
+    }
+
     /*
      * Check if a x509Certificate object is permitted.  Check if all
      * algorithms are allowed, certificate constraints, and the
@@ -140,18 +150,10 @@
      *
      * Uses new style permit() which throws exceptions.
      */
-    public final void permits(Set<CryptoPrimitive> primitives,
-            CertConstraintParameters cp) throws CertPathValidatorException {
-        checkConstraints(primitives, cp);
-    }
 
-    /*
-     * Check if Certificate object is within the constraints.
-     * Uses new style permit() which throws exceptions.
-     */
-    public final void permits(Set<CryptoPrimitive> primitives,
-            X509Certificate cert) throws CertPathValidatorException {
-        checkConstraints(primitives, new CertConstraintParameters(cert));
+    public final void permits(String algorithm, ConstraintsParameters cp)
+            throws CertPathValidatorException {
+        algorithmConstraints.permits(algorithm, cp);
     }
 
     // Check if a string is contained inside the property
@@ -174,7 +176,7 @@
             throw new IllegalArgumentException("The key cannot be null");
         }
 
-        // check the signature algorithm
+        // check the signature algorithm with parameters
         if (algorithm != null && algorithm.length() != 0) {
             if (!permits(primitives, algorithm, parameters)) {
                 return false;
@@ -190,36 +192,6 @@
         return algorithmConstraints.permits(key);
     }
 
-    /*
-     * Check algorithm constraints with Certificate
-     * Uses new style permit() which throws exceptions.
-     */
-    private void checkConstraints(Set<CryptoPrimitive> primitives,
-            CertConstraintParameters cp) throws CertPathValidatorException {
-
-        X509Certificate cert = cp.getCertificate();
-        String algorithm = cert.getSigAlgName();
-
-        // Check signature algorithm is not disabled
-        if (!permits(primitives, algorithm, null)) {
-            throw new CertPathValidatorException(
-                    "Algorithm constraints check failed on disabled "+
-                            "signature algorithm: " + algorithm,
-                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
-
-        // Check key algorithm is not disabled
-        if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
-            throw new CertPathValidatorException(
-                    "Algorithm constraints check failed on disabled "+
-                            "public key algorithm: " + algorithm,
-                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
-
-        // Check the certificate and key constraints
-        algorithmConstraints.permits(cp);
-
-    }
 
     /**
      * Key and Certificate Constraints
@@ -234,13 +206,13 @@
      * 'true' means the operation is allowed.
      * 'false' means it failed the constraints and is disallowed.
      *
-     * When passing CertConstraintParameters through permit(), an exception
+     * When passing ConstraintsParameters through permit(), an exception
      * will be thrown on a failure to better identify why the operation was
      * disallowed.
      */
 
     private static class Constraints {
-        private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
+        private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
 
         private static class Holder {
             private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
@@ -260,23 +232,22 @@
 
                 // Check if constraint is a complete disabling of an
                 // algorithm or has conditions.
-                String algorithm;
-                String policy;
                 int space = constraintEntry.indexOf(' ');
-                if (space > 0) {
-                    algorithm = AlgorithmDecomposer.hashName(
-                            constraintEntry.substring(0, space).
-                                    toUpperCase(Locale.ENGLISH));
-                    policy = constraintEntry.substring(space + 1);
-                } else {
-                    algorithm = constraintEntry.toUpperCase(Locale.ENGLISH);
-                    if (!constraintsMap.containsKey(algorithm)) {
-                        constraintsMap.putIfAbsent(algorithm,
-                                new HashSet<>());
-                    }
+                String algorithm = AlgorithmDecomposer.hashName(
+                        ((space > 0 ? constraintEntry.substring(0, space) :
+                                constraintEntry).
+                                toUpperCase(Locale.ENGLISH)));
+                List<Constraint> constraintList =
+                        constraintsMap.getOrDefault(algorithm,
+                                new ArrayList<>(1));
+                constraintsMap.putIfAbsent(algorithm, constraintList);
+                if (space <= 0) {
+                    constraintList.add(new DisabledConstraint(algorithm));
                     continue;
                 }
 
+                String policy = constraintEntry.substring(space + 1);
+
                 // Convert constraint conditions into Constraint classes
                 Constraint c, lastConstraint = null;
                 // Allow only one jdkCA entry per constraint entry
@@ -315,7 +286,7 @@
                         c = new jdkCAConstraint(algorithm);
                         jdkCALimit = true;
 
-                    } else if(entry.startsWith("denyAfter") &&
+                    } else if (entry.startsWith("denyAfter") &&
                             (matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))
                                     .matches()) {
                         if (debug != null) {
@@ -332,6 +303,12 @@
                         c = new DenyAfterConstraint(algorithm, year, month,
                                 day);
                         denyAfterLimit = true;
+                    } else if (entry.startsWith("usage")) {
+                        String s[] = (entry.substring(5)).trim().split(" ");
+                        c = new UsageConstraint(algorithm, s);
+                        if (debug != null) {
+                            debug.println("Constraints usage length is " + s.length);
+                        }
                     } else {
                         throw new IllegalArgumentException("Error in security" +
                                 " property. Constraint unknown: " + entry);
@@ -340,11 +317,7 @@
                     // Link multiple conditions for a single constraint
                     // into a linked list.
                     if (lastConstraint == null) {
-                        if (!constraintsMap.containsKey(algorithm)) {
-                            constraintsMap.putIfAbsent(algorithm,
-                                    new HashSet<>());
-                        }
-                        constraintsMap.get(algorithm).add(c);
+                        constraintList.add(c);
                     } else {
                         lastConstraint.nextConstraint = c;
                     }
@@ -354,17 +327,17 @@
         }
 
         // Get applicable constraints based off the signature algorithm
-        private Set<Constraint> getConstraints(String algorithm) {
+        private List<Constraint> getConstraints(String algorithm) {
             return constraintsMap.get(algorithm);
         }
 
         // Check if KeySizeConstraints permit the specified key
         public boolean permits(Key key) {
-            Set<Constraint> set = getConstraints(key.getAlgorithm());
-            if (set == null) {
+            List<Constraint> list = getConstraints(key.getAlgorithm());
+            if (list == null) {
                 return true;
             }
-            for (Constraint constraint : set) {
+            for (Constraint constraint : list) {
                 if (!constraint.permits(key)) {
                     if (debug != null) {
                         debug.println("keySizeConstraint: failed key " +
@@ -377,31 +350,35 @@
         }
 
         // Check if constraints permit this cert.
-        public void permits(CertConstraintParameters cp)
+        public void permits(String algorithm, ConstraintsParameters cp)
                 throws CertPathValidatorException {
             X509Certificate cert = cp.getCertificate();
 
             if (debug != null) {
-                debug.println("Constraints.permits(): " + cert.getSigAlgName());
+                debug.println("Constraints.permits(): " + algorithm +
+                        " Variant: " + cp.getVariant());
             }
 
             // Get all signature algorithms to check for constraints
-            Set<String> algorithms =
-                    AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
-            if (algorithms == null || algorithms.isEmpty()) {
-                return;
+            Set<String> algorithms = new HashSet<>();
+            if (algorithm != null) {
+                algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
             }
 
-            // Attempt to add the public key algorithm to the set
-            algorithms.add(cert.getPublicKey().getAlgorithm());
-
+            // Attempt to add the public key algorithm if cert provided
+            if (cert != null) {
+                algorithms.add(cert.getPublicKey().getAlgorithm());
+            }
+            if (cp.getPublicKey() != null) {
+                algorithms.add(cp.getPublicKey().getAlgorithm());
+            }
             // Check all applicable constraints
-            for (String algorithm : algorithms) {
-                Set<Constraint> set = getConstraints(algorithm);
-                if (set == null) {
+            for (String alg : algorithms) {
+                List<Constraint> list = getConstraints(alg);
+                if (list == null) {
                     continue;
                 }
-                for (Constraint constraint : set) {
+                for (Constraint constraint : list) {
                     constraint.permits(cp);
                 }
             }
@@ -467,17 +444,17 @@
 
         /**
          * Check if an algorithm constraint is permitted with a given
-         * CertConstraintParameters.
+         * ConstraintsParameters.
          *
          * If the check inside of {@code permits()} fails, it must call
-         * {@code next()} with the same {@code CertConstraintParameters}
+         * {@code next()} with the same {@code ConstraintsParameters}
          * parameter passed if multiple constraints need to be checked.
          *
          * @param cp CertConstraintParameter containing certificate info
          * @throws CertPathValidatorException if constraint disallows.
          *
          */
-        public abstract void permits(CertConstraintParameters cp)
+        public abstract void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException;
 
         /**
@@ -491,12 +468,12 @@
          * were disallowed, the last constraint will throw
          * {@code CertPathValidatorException}.
          *
-         * @param cp CertConstraintParameters
+         * @param cp ConstraintsParameters
          * @return 'true' if constraint allows the operation, 'false' if
          * we are at the end of the constraint list or,
          * {@code nextConstraint} is null.
          */
-        boolean next(CertConstraintParameters cp)
+        boolean next(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             if (nextConstraint != null) {
                 nextConstraint.permits(cp);
@@ -525,6 +502,14 @@
             }
             return false;
         }
+
+        String extendedMsg(ConstraintsParameters cp) {
+            return (cp.getCertificate() == null ? "." :
+                    " used with certificate: " +
+                            cp.getCertificate().getSubjectX500Principal() +
+                    (cp.getVariant() != Validator.VAR_GENERIC ?
+                            ".  Usage was " + cp.getVariant() : "."));
+        }
     }
 
     /*
@@ -537,11 +522,11 @@
         }
 
         /*
-         * Check if CertConstraintParameters has a trusted match, if it does
+         * Check if ConstraintsParameters has a trusted match, if it does
          * call next() for any following constraints. If it does not, exit
          * as this constraint(s) does not restrict the operation.
          */
-        public void permits(CertConstraintParameters cp)
+        public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
             if (debug != null) {
                 debug.println("jdkCAConstraints.permits(): " + algorithm);
@@ -554,8 +539,7 @@
                 }
                 throw new CertPathValidatorException(
                         "Algorithm constraints check failed on certificate " +
-                                "anchor limits. " + algorithm + " used with " +
-                                cp.getCertificate().getSubjectX500Principal(),
+                        "anchor limits. " + algorithm + extendedMsg(cp),
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
@@ -615,7 +599,7 @@
           * constraints. Throw an exception if this is the last constraint.
           */
          @Override
-         public void permits(CertConstraintParameters cp)
+         public void permits(ConstraintsParameters cp)
                  throws CertPathValidatorException {
              Date currentDate;
              String errmsg;
@@ -628,7 +612,7 @@
                  errmsg = "PKIXParameter date: ";
              } else {
                  currentDate = new Date();
-                 errmsg = "Certificate date: ";
+                 errmsg = "Current date: ";
              }
 
              if (!denyAfterDate.after(currentDate)) {
@@ -637,9 +621,9 @@
                  }
                  throw new CertPathValidatorException(
                          "denyAfter constraint check failed: " + algorithm +
-                                 " used with Constraint date: " +
-                                 dateFormat.format(denyAfterDate) + "; "
-                                 + errmsg + dateFormat.format(currentDate),
+                         " used with Constraint date: " +
+                         dateFormat.format(denyAfterDate) + "; " + errmsg +
+                         dateFormat.format(currentDate) + extendedMsg(cp),
                          null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
              }
          }
@@ -661,6 +645,48 @@
      }
 
     /*
+     * The usage constraint is for the "usage" keyword.  It checks against the
+     * variant value in ConstraintsParameters.
+     */
+    private static class UsageConstraint extends Constraint {
+        String[] usages;
+
+        UsageConstraint(String algorithm, String[] usages) {
+            this.algorithm = algorithm;
+            this.usages = usages;
+        }
+
+        public void permits(ConstraintsParameters cp)
+                throws CertPathValidatorException {
+            for (String usage : usages) {
+
+                String v = null;
+                if (usage.compareToIgnoreCase("TLSServer") == 0) {
+                    v = Validator.VAR_TLS_SERVER;
+                } else if (usage.compareToIgnoreCase("TLSClient") == 0) {
+                    v = Validator.VAR_TLS_CLIENT;
+                } else if (usage.compareToIgnoreCase("SignedJAR") == 0) {
+                    v = Validator.VAR_PLUGIN_CODE_SIGNING;
+                }
+
+                if (debug != null) {
+                    debug.println("Checking if usage constraint " + v +
+                            " matches " + cp.getVariant());
+                }
+                if (cp.getVariant().compareTo(v) == 0) {
+                    if (next(cp)) {
+                        return;
+                    }
+                    throw new CertPathValidatorException("Usage constraint " +
+                            usage + " check failed: " + algorithm +
+                            extendedMsg(cp),
+                            null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+                }
+            }
+        }
+    }
+
+    /*
      * This class contains constraints dealing with the key size
      * support limits per algorithm.   e.g.  "keySize <= 1024"
      */
@@ -713,17 +739,22 @@
          * constraint  Any permitted constraint will exit the linked list
          * to allow the operation.
          */
-        public void permits(CertConstraintParameters cp)
+        public void permits(ConstraintsParameters cp)
                 throws CertPathValidatorException {
-            if (!permitsImpl(cp.getCertificate().getPublicKey())) {
+            Key key = null;
+            if (cp.getPublicKey() != null) {
+                key = cp.getPublicKey();
+            } else if (cp.getCertificate() != null) {
+                key = cp.getCertificate().getPublicKey();
+            }
+            if (key != null && !permitsImpl(key)) {
                 if (nextConstraint != null) {
                     nextConstraint.permits(cp);
                     return;
                 }
                 throw new CertPathValidatorException(
                         "Algorithm constraints check failed on keysize limits. "
-                                + algorithm + " " + size + "bit key used with "
-                                + cp.getCertificate().getSubjectX500Principal(),
+                        + algorithm + " " + size + "bit key" + extendedMsg(cp),
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
             }
         }
@@ -762,5 +793,26 @@
             return true;
         }
     }
+
+    /*
+     * This constraint is used for the complete disabling of the algorithm.
+     */
+    private static class DisabledConstraint extends Constraint {
+        DisabledConstraint(String algo) {
+            algorithm = algo;
+        }
+
+        public void permits(ConstraintsParameters cp)
+                throws CertPathValidatorException {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on disabled " +
+                            "algorithm: " + algorithm + extendedMsg(cp),
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
+        public boolean permits(Key key) {
+            return false;
+        }
+    }
 }
 
--- a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -28,25 +28,23 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.CodeSigner;
-import java.security.CryptoPrimitive;
+import java.security.GeneralSecurityException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SignatureException;
+import java.security.Timestamp;
 import java.security.cert.CertPath;
 import java.security.cert.X509Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.util.ArrayList;
 import java.util.Base64;
-import java.util.Collections;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 import java.util.jar.Attributes;
 import java.util.jar.JarException;
 import java.util.jar.JarFile;
@@ -61,9 +59,6 @@
     /* Are we debugging ? */
     private static final Debug debug = Debug.getInstance("jar");
 
-    private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
-            Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
-
     private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
             new DisabledAlgorithmConstraints(
                     DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
@@ -97,6 +92,14 @@
     /* for generating certpath objects */
     private CertificateFactory certificateFactory = null;
 
+    /** Algorithms that have been checked if they are weak. */
+    private Map<String, Boolean> permittedAlgs= new HashMap<>();
+
+    /** TSA timestamp of signed jar.  The newest timestamp is used.  If there
+     *  was no TSA timestamp used when signed, current time is used ("null").
+     */
+    private Timestamp timestamp = null;
+
     /**
      * Create the named SignatureFileVerifier.
      *
@@ -222,15 +225,8 @@
 
     /** get digest from cache */
 
-    private MessageDigest getDigest(String algorithm) throws SignatureException {
-        // check that algorithm is not restricted
-        if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) {
-            SignatureException e =
-                    new SignatureException("SignatureFile check failed. " +
-                            "Disabled algorithm used: " + algorithm);
-            throw e;
-        }
-
+    private MessageDigest getDigest(String algorithm)
+            throws SignatureException {
         if (createdDigests == null)
             createdDigests = new HashMap<>();
 
@@ -302,6 +298,27 @@
         if (newSigners == null)
             return;
 
+        /*
+         * Look for the latest timestamp in the signature block.  If an entry
+         * has no timestamp, use current time (aka null).
+         */
+        for (CodeSigner s: newSigners) {
+            if (debug != null) {
+                debug.println("Gathering timestamp for:  " + s.toString());
+            }
+            if (s.getTimestamp() == null) {
+                timestamp = null;
+                break;
+            } else if (timestamp == null) {
+                timestamp = s.getTimestamp();
+            } else {
+                if (timestamp.getTimestamp().before(
+                        s.getTimestamp().getTimestamp())) {
+                    timestamp = s.getTimestamp();
+                }
+            }
+        }
+
         Iterator<Map.Entry<String,Attributes>> entries =
                                 sf.getEntries().entrySet().iterator();
 
@@ -345,6 +362,68 @@
     }
 
     /**
+     * Check if algorithm is permitted using the permittedAlgs Map.
+     * If the algorithm is not in the map, check against disabled algorithms and
+     * store the result. If the algorithm is in the map use that result.
+     * False is returned for weak algorithm, true for good algorithms.
+     */
+    boolean permittedCheck(String key, String algorithm) {
+        Boolean permitted = permittedAlgs.get(algorithm);
+        if (permitted == null) {
+            try {
+                JAR_DISABLED_CHECK.permits(algorithm,
+                        new ConstraintsParameters(timestamp));
+            } catch(GeneralSecurityException e) {
+                permittedAlgs.put(algorithm, Boolean.FALSE);
+                permittedAlgs.put(key.toUpperCase(), Boolean.FALSE);
+                if (debug != null) {
+                    if (e.getMessage() != null) {
+                        debug.println(key + ":  " + e.getMessage());
+                    } else {
+                        debug.println(key + ":  " + algorithm +
+                                " was disabled, no exception msg given.");
+                        e.printStackTrace();
+                    }
+                }
+                return false;
+            }
+
+            permittedAlgs.put(algorithm, Boolean.TRUE);
+            return true;
+        }
+
+        // Algorithm has already been checked, return the value from map.
+        return permitted.booleanValue();
+    }
+
+    /**
+     * With a given header (*-DIGEST*), return a string that lists all the
+     * algorithms associated with the header.
+     * If there are none, return "Unknown Algorithm".
+     */
+    String getWeakAlgorithms(String header) {
+        String w = "";
+        try {
+            for (String key : permittedAlgs.keySet()) {
+                if (key.endsWith(header)) {
+                    w += key.substring(0, key.length() - header.length()) + " ";
+                }
+            }
+        } catch (RuntimeException e) {
+            w = "Unknown Algorithm(s).  Error processing " + header + ".  " +
+                    e.getMessage();
+        }
+
+        // This means we have an error in finding weak algorithms, run in
+        // debug mode to see permittedAlgs map's values.
+        if (w.length() == 0) {
+            return "Unknown Algorithm(s)";
+        }
+
+        return w;
+    }
+
+    /**
      * See if the whole manifest was signed.
      */
     private boolean verifyManifestHash(Manifest sf,
@@ -354,6 +433,7 @@
     {
         Attributes mattr = sf.getMainAttributes();
         boolean manifestSigned = false;
+        boolean weakAlgs = true;
 
         // go through all the attributes and process *-Digest-Manifest entries
         for (Map.Entry<Object,Object> se : mattr.entrySet()) {
@@ -364,6 +444,15 @@
                 // 16 is length of "-Digest-Manifest"
                 String algorithm = key.substring(0, key.length()-16);
 
+                // Check if this algorithm is permitted, skip if false.
+                if (!permittedCheck(key, algorithm)) {
+                    continue;
+                }
+
+                // A non-weak algorithm was used, any weak algorithms found do
+                // not need to be reported.
+                weakAlgs = false;
+
                 manifestDigests.add(key);
                 manifestDigests.add(se.getValue());
                 MessageDigest digest = getDigest(algorithm);
@@ -373,15 +462,14 @@
                         Base64.getMimeDecoder().decode((String)se.getValue());
 
                     if (debug != null) {
-                     debug.println("Signature File: Manifest digest " +
-                                          digest.getAlgorithm());
-                     debug.println( "  sigfile  " + toHex(expectedHash));
-                     debug.println( "  computed " + toHex(computedHash));
-                     debug.println();
+                        debug.println("Signature File: Manifest digest " +
+                                algorithm);
+                        debug.println( "  sigfile  " + toHex(expectedHash));
+                        debug.println( "  computed " + toHex(computedHash));
+                        debug.println();
                     }
 
-                    if (MessageDigest.isEqual(computedHash,
-                                              expectedHash)) {
+                    if (MessageDigest.isEqual(computedHash, expectedHash)) {
                         manifestSigned = true;
                     } else {
                         //XXX: we will continue and verify each section
@@ -389,15 +477,31 @@
                 }
             }
         }
+
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms used, throw an exception.
+        if (weakAlgs) {
+            String weakAlgorithms = getWeakAlgorithms("-DIGEST-MANIFEST");
+            throw new SignatureException("Manifest hash check failed " +
+                    "(DIGEST-MANIFEST). Disabled algorithm(s) used: " +
+                    weakAlgorithms);
+        }
         return manifestSigned;
     }
 
-    private boolean verifyManifestMainAttrs(Manifest sf,
-                                        ManifestDigester md)
+    private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
          throws IOException, SignatureException
     {
         Attributes mattr = sf.getMainAttributes();
         boolean attrsVerified = true;
+        boolean weakAlgs = true;
 
         // go through all the attributes and process
         // digest entries for the manifest main attributes
@@ -408,6 +512,15 @@
                 String algorithm =
                         key.substring(0, key.length() - ATTR_DIGEST.length());
 
+                // Check if this algorithm is permitted, skip if false.
+                if (!permittedCheck(key, algorithm)) {
+                    continue;
+                }
+
+                // A non-weak algorithm was used, any weak algorithms found do
+                // not need to be reported.
+                weakAlgs = false;
+
                 MessageDigest digest = getDigest(algorithm);
                 if (digest != null) {
                     ManifestDigester.Entry mde =
@@ -425,8 +538,7 @@
                      debug.println();
                     }
 
-                    if (MessageDigest.isEqual(computedHash,
-                                              expectedHash)) {
+                    if (MessageDigest.isEqual(computedHash, expectedHash)) {
                         // good
                     } else {
                         // we will *not* continue and verify each section
@@ -442,6 +554,23 @@
             }
         }
 
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms used, throw an exception.
+        if (weakAlgs) {
+            String weakAlgorithms = getWeakAlgorithms("-DIGEST-" +
+                    ManifestDigester.MF_MAIN_ATTRS);
+            throw new SignatureException("Manifest Main Attribute check " +
+                    "failed (DIGEST-" + ManifestDigester.MF_MAIN_ATTRS +
+                    "). " + "Disabled algorithm(s) used: " + weakAlgorithms);
+        }
+
         // this method returns 'true' if either:
         //      . manifest main attributes were not signed, or
         //      . manifest main attributes were signed and verified
@@ -464,6 +593,7 @@
     {
         boolean oneDigestVerified = false;
         ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
+        boolean weakAlgs = true;
 
         if (mde == null) {
             throw new SecurityException(
@@ -471,7 +601,6 @@
         }
 
         if (sfAttr != null) {
-
             //sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder();
             //hex.encodeBuffer(data, System.out);
 
@@ -483,6 +612,15 @@
                     // 7 is length of "-Digest"
                     String algorithm = key.substring(0, key.length()-7);
 
+                    // Check if this algorithm is permitted, skip if false.
+                    if (!permittedCheck(key, algorithm)) {
+                        continue;
+                    }
+
+                    // A non-weak algorithm was used, any weak algorithms found do
+                    // not need to be reported.
+                    weakAlgs = false;
+
                     MessageDigest digest = getDigest(algorithm);
 
                     if (digest != null) {
@@ -532,6 +670,23 @@
                 }
             }
         }
+
+        if (debug != null) {
+            debug.println("PermittedAlgs mapping: ");
+            for (String key : permittedAlgs.keySet()) {
+                debug.println(key + " : " +
+                        permittedAlgs.get(key).toString());
+            }
+        }
+
+        // If there were only weak algorithms used, throw an exception.
+        if (weakAlgs) {
+            String weakAlgorithms = getWeakAlgorithms("DIGEST");
+            throw new SignatureException("Manifest Main Attribute check " +
+                    "failed (DIGEST). " + "Disabled algorithm(s) used: " +
+                    weakAlgorithms);
+        }
+
         return oneDigestVerified;
     }
 
--- a/jdk/src/java.base/share/classes/sun/security/validator/PKIXValidator.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/validator/PKIXValidator.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -33,7 +33,7 @@
 import javax.security.auth.x500.X500Principal;
 import sun.security.action.GetBooleanAction;
 import sun.security.provider.certpath.AlgorithmChecker;
-import sun.security.provider.certpath.PKIXTimestampParameters;
+import sun.security.provider.certpath.PKIXExtendedParameters;
 
 /**
  * Validator implementation built on the PKIX CertPath API. This
@@ -199,9 +199,9 @@
         PKIXBuilderParameters pkixParameters = null;
         if (parameter instanceof Timestamp && plugin) {
             try {
-                pkixParameters = new PKIXTimestampParameters(
+                pkixParameters = new PKIXExtendedParameters(
                         (PKIXBuilderParameters) parameterTemplate.clone(),
-                        (Timestamp) parameter);
+                        (Timestamp) parameter, variant);
             } catch (InvalidAlgorithmParameterException e) {
                 // ignore exception
             }
@@ -211,7 +211,8 @@
 
         // add new algorithm constraints checker
         if (constraints != null) {
-            pkixParameters.addCertPathChecker(new AlgorithmChecker(constraints));
+            pkixParameters.addCertPathChecker(
+                    new AlgorithmChecker(constraints, null, variant));
         }
 
         // attach it to the PKIXBuilderParameters.
--- a/jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -155,12 +155,14 @@
 
         // create default algorithm constraints checker
         TrustAnchor anchor = new TrustAnchor(anchorCert, null);
-        AlgorithmChecker defaultAlgChecker = new AlgorithmChecker(anchor);
+        AlgorithmChecker defaultAlgChecker =
+                new AlgorithmChecker(anchor, variant);
 
         // create application level algorithm constraints checker
         AlgorithmChecker appAlgChecker = null;
         if (constraints != null) {
-            appAlgChecker = new AlgorithmChecker(anchor, constraints);
+            appAlgChecker = new AlgorithmChecker(anchor, constraints, null,
+                    variant);
         }
 
         // verify top down, starting at the certificate issued by
--- a/jdk/src/java.base/share/conf/security/java.security	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/conf/security/java.security	Fri Feb 10 08:57:42 2017 -0800
@@ -116,6 +116,13 @@
 # Example:
 #   jdk.security.provider.preferred=AES/GCM/NoPadding:SunJCE, \
 #         MessageDigest.SHA-256:SUN, Group.HmacSHA2:SunJCE
+#
+#ifdef solaris-sparc
+# Optional Solaris-SPARC configuration for non-FIPS 140 configurations.
+#   jdk.security.provider.preferred=AES:SunJCE, SHA1:SUN, Group.SHA2:SUN, \
+#   HmacSHA1:SunJCE, Group.HmacSHA2:SunJCE
+#
+#endif
 #jdk.security.provider.preferred=
 
 
@@ -240,6 +247,7 @@
 #
 # The default value is an empty string, which is equivalent to
 #   securerandom.drbg.config=Hash_DRBG,SHA-256,128,none
+#
 securerandom.drbg.config=
 
 #
@@ -262,23 +270,27 @@
 
 # The default is to have a single system-wide policy file,
 # and a policy file in the user's home directory.
+#
 policy.url.1=file:${java.home}/conf/security/java.policy
 policy.url.2=file:${user.home}/.java.policy
 
 # whether or not we expand properties in the policy file
 # if this is set to false, properties (${...}) will not be expanded in policy
 # files.
+#
 policy.expandProperties=true
 
 # whether or not we allow an extra policy to be passed on the command line
 # with -Djava.security.policy=somefile. Comment out this line to disable
 # this feature.
+#
 policy.allowSystemProperty=true
 
 # whether or not we look into the IdentityScope for trusted Identities
 # when encountering a 1.1 signed JAR file. If the identity is found
 # and is trusted, we grant it AllPermission. Note: the default policy
 # provider (sun.security.provider.PolicyFile) does not support this property.
+#
 policy.ignoreIdentityScope=false
 
 #
@@ -360,7 +372,6 @@
 # For this reason the default caching policy is to maintain these
 # results for 10 seconds.
 #
-#
 networkaddress.cache.negative.ttl=10
 
 #
@@ -460,8 +471,10 @@
 # Example,
 #   krb5.kdc.bad.policy = tryLast
 #   krb5.kdc.bad.policy = tryLess:2,2000
+#
 krb5.kdc.bad.policy = tryLast
 
+#
 # Algorithm restrictions for certification path (CertPath) processing
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -481,7 +494,8 @@
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint | CAConstraint | DenyAfterConstraint
+#       KeySizeConstraint | CAConstraint | DenyAfterConstraint |
+#       UsageConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
@@ -498,6 +512,9 @@
 #   DenyAfterConstraint:
 #       denyAfter YYYY-MM-DD
 #
+#   UsageConstraint:
+#       usage [TLSServer] [TLSClient] [SignedJAR]
+#
 # The "AlgorithmName" is the standard algorithm name of the disabled
 # algorithm. See "Java Cryptography Architecture Standard Algorithm Name
 # Documentation" for information about Standard Algorithm Names.  Matching
@@ -547,6 +564,19 @@
 #       Example:  To deny usage of RSA 2048 bit certificates after Feb 3 2020,
 #       use the following:  "RSA keySize == 2048 & denyAfter 2020-02-03"
 #
+#   UsageConstraint:
+#     usage [TLSServer] [TLSClient] [SignedJAR]
+#       This constraint prohibits the specified algorithm for
+#       a specified usage.  This should be used when disabling an algorithm
+#       for all usages is not practical. 'TLSServer' restricts the algorithm
+#       in TLS server certificate chains when server authentication is
+#       performed. 'TLSClient' restricts the algorithm in TLS client
+#       certificate chains when client authentication is performed.
+#       'SignedJAR' constrains use of certificates in signed jar files.
+#       The usage type follows the keyword and more than one usage type can
+#       be specified with a whitespace delimiter.
+#       Example:  "SHA1 usage TLSServer TLSClient"
+#
 # When an algorithm must satisfy more than one constraint, it must be
 # delimited by an ampersand '&'.  For example, to restrict certificates in a
 # chain that terminate at a distribution provided trust anchor and contain
@@ -572,35 +602,6 @@
     RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
 
 #
-# RMI Registry Serial Filter
-#
-# The filter pattern uses the same format as jdk.serialFilter.
-# This filter can override the builtin filter if additional types need to be
-# allowed or rejected from the RMI Registry.
-#
-# Note: This property is currently used by the JDK Reference implementation.
-# It is not guaranteed to be examined and used by other implementations.
-#
-#sun.rmi.registry.registryFilter=pattern;pattern
-#
-# RMI Distributed Garbage Collector (DGC) Serial Filter
-#
-# The filter pattern uses the same format as jdk.serialFilter.
-# This filter can override the builtin filter if additional types need to be
-# allowed or rejected from the RMI DGC.
-#
-# Note: This property is currently used by the JDK Reference implementation.
-# It is not guaranteed to be examined and used by other implementations.
-#
-# The builtin DGC filter can approximately be represented as the filter pattern:
-#
-#sun.rmi.transport.dgcFilter=\
-#    java.rmi.server.ObjID;\
-#    java.rmi.server.UID;\
-#    java.rmi.dgc.VMID;\
-#    java.rmi.dgc.Lease;\
-#    maxdepth=5;maxarray=10000
-
 # Algorithm restrictions for signed JAR files
 #
 # In some environments, certain algorithms or key lengths may be undesirable
@@ -615,17 +616,20 @@
 #       " DisabledAlgorithm { , DisabledAlgorithm } "
 #
 #   DisabledAlgorithm:
-#       AlgorithmName [Constraint]
+#       AlgorithmName [Constraint] { '&' Constraint }
 #
 #   AlgorithmName:
 #       (see below)
 #
 #   Constraint:
-#       KeySizeConstraint
+#       KeySizeConstraint | DenyAfterConstraint
 #
 #   KeySizeConstraint:
 #       keySize Operator KeyLength
 #
+#   DenyAfterConstraint:
+#       denyAfter YYYY-MM-DD
+#
 #   Operator:
 #       <= | < | == | != | >= | >
 #
@@ -636,9 +640,12 @@
 # implementation. It is not guaranteed to be examined and used by other
 # implementations.
 #
+# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
+#
 jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
       DSA keySize < 1024
 
+#
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS/DTLS) processing
 #
@@ -939,3 +946,32 @@
 #
 #jdk.serialFilter=pattern;pattern
 
+#
+# RMI Registry Serial Filter
+#
+# The filter pattern uses the same format as jdk.serialFilter.
+# This filter can override the builtin filter if additional types need to be
+# allowed or rejected from the RMI Registry.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#sun.rmi.registry.registryFilter=pattern;pattern
+#
+# RMI Distributed Garbage Collector (DGC) Serial Filter
+#
+# The filter pattern uses the same format as jdk.serialFilter.
+# This filter can override the builtin filter if additional types need to be
+# allowed or rejected from the RMI DGC.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# The builtin DGC filter can approximately be represented as the filter pattern:
+#
+#sun.rmi.transport.dgcFilter=\
+#    java.rmi.server.ObjID;\
+#    java.rmi.server.UID;\
+#    java.rmi.dgc.VMID;\
+#    java.rmi.dgc.Lease;\
+#    maxdepth=5;maxarray=10000
--- a/jdk/src/java.base/share/lib/security/default.policy	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/lib/security/default.policy	Fri Feb 10 08:57:42 2017 -0800
@@ -102,6 +102,8 @@
 };
 
 grant codeBase "jrt:/java.xml.ws" {
+    permission java.net.NetPermission
+                   "getProxySelector";
     permission java.lang.RuntimePermission
                    "accessClassInPackage.com.sun.org.apache.xml.internal.resolver";
     permission java.lang.RuntimePermission
@@ -213,3 +215,7 @@
     permission java.lang.RuntimePermission "accessClassInPackage.com.sun.java.swing.plaf.*";
     permission java.lang.RuntimePermission "accessClassInPackage.com.apple.*";
 };
+
+grant codeBase "jrt:/jdk.vm.compiler" {
+    permission java.security.AllPermission;
+};
--- a/jdk/src/java.base/share/native/launcher/main.c	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/native/launcher/main.c	Fri Feb 10 08:57:42 2017 -0800
@@ -130,10 +130,10 @@
 
         // Add first arg, which is the app name
         JLI_List_add(args, JLI_StringDup(argv[0]));
-        // Append JAVA_OPTIONS
-        if (JLI_AddArgsFromEnvVar(args, JAVA_OPTIONS)) {
+        // Append JDK_JAVA_OPTIONS
+        if (JLI_AddArgsFromEnvVar(args, JDK_JAVA_OPTIONS)) {
             // JLI_SetTraceLauncher is not called yet
-            // Show _JAVA_OPTIONS content along with JAVA_OPTIONS to aid diagnosis
+            // Show _JAVA_OPTIONS content along with JDK_JAVA_OPTIONS to aid diagnosis
             if (getenv(JLDEBUG_ENV_ENTRY)) {
                 char *tmp = getenv("_JAVA_OPTIONS");
                 if (NULL != tmp) {
--- a/jdk/src/java.base/share/native/libjli/args.c	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/native/libjli/args.c	Fri Feb 10 08:57:42 2017 -0800
@@ -34,7 +34,7 @@
     #define NO_JNI
   #endif
   #define JLI_ReportMessage(...) printf(__VA_ARGS__)
-  #define JAVA_OPTIONS "JAVA_OPTIONS"
+  #define JDK_JAVA_OPTIONS "JDK_JAVA_OPTIONS"
   int IsWhiteSpaceOption(const char* name) { return 1; }
 #else
   #include "java.h"
@@ -429,10 +429,6 @@
 }
 
 jboolean JLI_AddArgsFromEnvVar(JLI_List args, const char *var_name) {
-
-#ifndef ENABLE_JAVA_OPTIONS
-    return JNI_FALSE;
-#else
     char *env = getenv(var_name);
     char *p, *arg;
     char quote;
@@ -519,7 +515,6 @@
     }
 
     return JNI_TRUE;
-#endif
 }
 
 #ifdef DEBUG_ARGFILE
--- a/jdk/src/java.base/share/native/libjli/java.h	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/share/native/libjli/java.h	Fri Feb 10 08:57:42 2017 -0800
@@ -71,7 +71,7 @@
 
 #define SPLASH_FILE_ENV_ENTRY "_JAVA_SPLASH_FILE"
 #define SPLASH_JAR_ENV_ENTRY "_JAVA_SPLASH_JAR"
-#define JAVA_OPTIONS "JAVA_OPTIONS"
+#define JDK_JAVA_OPTIONS "JDK_JAVA_OPTIONS"
 
 /*
  * Pointers to the needed JNI invocation API, initialized by LoadJavaVM.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.spi.FileSystemProvider;
+
+/**
+ * Creates this platform's default FileSystemProvider.
+ */
+
+public class DefaultFileSystemProvider {
+    private DefaultFileSystemProvider() { }
+
+    /**
+     * Returns the default FileSystemProvider.
+     */
+    public static FileSystemProvider create() {
+        return new SolarisFileSystemProvider();
+    }
+}
--- a/jdk/src/java.base/unix/classes/sun/nio/fs/DefaultFileSystemProvider.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.nio.fs;
-
-import java.nio.file.spi.FileSystemProvider;
-import sun.security.action.GetPropertyAction;
-
-/**
- * Creates this platform's default FileSystemProvider.
- */
-
-public class DefaultFileSystemProvider {
-    private DefaultFileSystemProvider() { }
-
-    @SuppressWarnings("unchecked")
-    private static FileSystemProvider createProvider(String cn) {
-        Class<FileSystemProvider> c;
-        try {
-            c = (Class<FileSystemProvider>)Class.forName(cn);
-        } catch (ClassNotFoundException x) {
-            throw new AssertionError(x);
-        }
-        try {
-            @SuppressWarnings("deprecation")
-            FileSystemProvider result = c.newInstance();
-            return result;
-        } catch (IllegalAccessException | InstantiationException x) {
-            throw new AssertionError(x);
-        }
-    }
-
-    /**
-     * Returns the default FileSystemProvider.
-     */
-    public static FileSystemProvider create() {
-        String osname = GetPropertyAction.privilegedGetProperty("os.name");
-        if (osname.equals("SunOS"))
-            return createProvider("sun.nio.fs.SolarisFileSystemProvider");
-        if (osname.equals("Linux"))
-            return createProvider("sun.nio.fs.LinuxFileSystemProvider");
-        if (osname.contains("OS X"))
-            return createProvider("sun.nio.fs.MacOSXFileSystemProvider");
-        if (osname.equals("AIX"))
-            return createProvider("sun.nio.fs.AixFileSystemProvider");
-        throw new AssertionError("Platform not recognized");
-    }
-}
--- a/jdk/src/java.base/windows/native/libjli/cmdtoargs.c	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.base/windows/native/libjli/cmdtoargs.c	Fri Feb 10 08:57:42 2017 -0800
@@ -205,9 +205,9 @@
     size_t i, cnt;
 
     JLI_List envArgs = JLI_List_new(1);
-    if (JLI_AddArgsFromEnvVar(envArgs, JAVA_OPTIONS)) {
+    if (JLI_AddArgsFromEnvVar(envArgs, JDK_JAVA_OPTIONS)) {
         // JLI_SetTraceLauncher is not called yet
-        // Show _JAVA_OPTIONS content along with JAVA_OPTIONS to aid diagnosis
+        // Show _JAVA_OPTIONS content along with JDK_JAVA_OPTIONS to aid diagnosis
         if (getenv(JLDEBUG_ENV_ENTRY)) {
             char *tmp = getenv("_JAVA_OPTIONS");
             if (NULL != tmp) {
--- a/jdk/src/java.datatransfer/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.datatransfer/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines an API for transferring data between and within applications.
+ *
+ * @since 9
  */
 module java.datatransfer {
     exports java.awt.datatransfer;
--- a/jdk/src/java.desktop/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.desktop/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -26,6 +26,8 @@
 /**
  * Defines the AWT and Swing user interface toolkits, plus APIs for
  * accessibility, audio, imaging, printing, and JavaBeans.
+ *
+ * @since 9
  */
 module java.desktop {
     requires transitive java.datatransfer;
--- a/jdk/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java	Fri Feb 10 08:57:42 2017 -0800
@@ -229,6 +229,7 @@
      *         or {@code null} if no transform is performed
      *
      * @since  9
+     * @spec JPMS
      */
     default byte[]
     transform(  Module              module,
--- a/jdk/src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java	Fri Feb 10 08:57:42 2017 -0800
@@ -714,6 +714,7 @@
      * @throws NullPointerException if any of the arguments are {@code null} or
      *         any of the Sets or Maps contains a {@code null} key or value
      * @since 9
+     * @spec JPMS
      */
     void redefineModule(Module module,
                         Set<Module> extraReads,
--- a/jdk/src/java.instrument/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.instrument/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -26,6 +26,8 @@
 /**
  * Defines services that allow agents to
  * instrument programs running on the JVM.
+ *
+ * @since 9
  */
 module java.instrument {
     exports java.lang.instrument;
--- a/jdk/src/java.logging/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.logging/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the Java Logging API.
+ *
+ * @since 9
  */
 module java.logging {
     exports java.util.logging;
--- a/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java	Fri Feb 10 08:57:42 2017 -0800
@@ -38,6 +38,7 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
 import java.io.Serializable;
+import java.lang.module.ModuleDescriptor;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
@@ -107,6 +108,8 @@
 import sun.rmi.transport.LiveRef;
 import java.io.NotSerializableException;
 
+import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
+
 /**
  * <p>A connection to a remote RMI connector.  Usually, such
  * connections are made using {@link
@@ -2020,8 +2023,14 @@
                 Module rmiModule = RemoteRef.class.getModule();
 
                 String pkg = packageOf(pRefClassName);
-                assert pkg != null && pkg.length() > 0 && !pkg.equals(packageOf(proxyRefCName));
-                Module m = Modules.defineModule(cl, "jdk.remoteref", Collections.singleton(pkg));
+                assert pkg != null && pkg.length() > 0 &&
+                        !pkg.equals(packageOf(proxyRefCName));
+
+                ModuleDescriptor descriptor =
+                    ModuleDescriptor.newModule("jdk.remoteref", Set.of(SYNTHETIC))
+                        .packages(Set.of(pkg))
+                        .build();
+                Module m = Modules.defineModule(cl, descriptor, null);
 
                 // jdk.remoteref needs to read to java.base and jmxModule
                 Modules.addReads(m, Object.class.getModule());
--- a/jdk/src/java.management.rmi/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.management.rmi/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -46,6 +46,7 @@
  *           and load the appropriate {@code JMXConnectorServerProvider} service
  *           implementation for the given protocol.
  *
+ * @since 9
  */
 module java.management.rmi {
 
--- a/jdk/src/java.management/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.management/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,6 +28,8 @@
  * <P>
  * The JMX API consists of interfaces for monitoring and management of the
  * JVM and other components in the Java runtime.
+ *
+ * @since 9
  */
 module java.management {
 
--- a/jdk/src/java.naming/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.naming/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the Java Naming and Directory Interface (JNDI) API.
+ *
+ * @since 9
  */
 module java.naming {
     requires java.security.sasl;
--- a/jdk/src/java.prefs/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.prefs/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the Preferences API.
+ *
+ * @since 9
  */
 module java.prefs {
     requires java.xml;
--- a/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationInstantiator.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationInstantiator.java	Fri Feb 10 08:57:42 2017 -0800
@@ -60,7 +60,20 @@
     * initialization data, and
     *
     * <li> returning a MarshalledObject containing the stub for the
-    * remote object it created </ul>
+    * remote object it created.</ul>
+    *
+    * <p>In order for activation to be successful, one of the following requirements
+    * must be met, otherwise {@link ActivationException} is thrown:
+    *
+    * <ul><li>The class to be activated and the special activation constructor are both public,
+    * and the class resides in a package that is
+    * {@linkplain java.lang.reflect.Module#isExported(String,java.lang.reflect.Module) exported}
+    * to at least the {@code java.rmi} module; or
+    *
+    * <li>The class to be activated resides in a package that is
+    * {@linkplain java.lang.reflect.Module#isOpen(String,java.lang.reflect.Module) open}
+    * to at least the {@code java.rmi} module.
+    * </ul>
     *
     * @param id the object's activation identifier
     * @param desc the object's descriptor
--- a/jdk/src/java.rmi/share/classes/java/rmi/activation/Activator.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.rmi/share/classes/java/rmi/activation/Activator.java	Fri Feb 10 08:57:42 2017 -0800
@@ -48,7 +48,7 @@
  * The <code>Activator</code> works closely with
  * <code>ActivationSystem</code>, which provides a means for registering
  * groups and objects within those groups, and <code>ActivationMonitor</code>,
- * which recives information about active and inactive objects and inactive
+ * which receives information about active and inactive objects and inactive
  * groups. <p>
  *
  * The activator is responsible for monitoring and detecting when
--- a/jdk/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java	Fri Feb 10 08:57:42 2017 -0800
@@ -107,8 +107,9 @@
  * the binary name of the root class with the suffix {@code _Stub}.
  *
  * <li>The stub class is loaded by name using the class loader of the root
- * class. The stub class must extend {@link RemoteStub} and must have a
- * public constructor that has one parameter of type {@link RemoteRef}.
+ * class. The stub class must be public, it must extend {@link RemoteStub}, it must
+ * reside in a package that is exported to at least the {@code java.rmi} module, and it
+ * must have a public constructor that has one parameter of type {@link RemoteRef}.
  *
  * <li>Finally, an instance of the stub class is constructed with a
  * {@link RemoteRef}.
@@ -124,12 +125,21 @@
  *
  * <ul>
  *
- * <li>The proxy's class is defined by the class loader of the remote
- * object's class.
+ * <li>The proxy's class is defined according to the specifications for the
+ * <a href="{@docRoot}/java/lang/reflect/Proxy.html#membership">
+ * {@code Proxy}
+ * </a>
+ * class, using the class loader of the remote object's class.
  *
  * <li>The proxy implements all the remote interfaces implemented by the
  * remote object's class.
  *
+ * <li>Each remote interface must either be public and reside in a package that is
+ * {@linkplain java.lang.reflect.Module#isExported(String,java.lang.reflect.Module) exported}
+ * to at least the {@code java.rmi} module, or it must reside in a package that is
+ * {@linkplain java.lang.reflect.Module#isOpen(String,java.lang.reflect.Module) open}
+ * to at least the {@code java.rmi} module.
+ *
  * <li>The proxy's invocation handler is a {@link
  * RemoteObjectInvocationHandler} instance constructed with a
  * {@link RemoteRef}.
--- a/jdk/src/java.rmi/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.rmi/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the Remote Method Invocation (RMI) API.
+ *
+ * @since 9
  */
 module java.rmi {
     requires java.logging;
--- a/jdk/src/java.scripting/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.scripting/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the Scripting API.
+ *
+ * @since 9
  */
 module java.scripting {
     exports javax.script;
--- a/jdk/src/java.se.ee/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.se.ee/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,6 +28,8 @@
  * <P>
  * This module requires {@code java.se} and supplements it with modules
  * that define CORBA and Java EE APIs. These modules are upgradeable.
+ *
+ * @since 9
  */
 @SuppressWarnings("deprecation")
 module java.se.ee {
--- a/jdk/src/java.se/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.se/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,6 +28,8 @@
  * <P>
  * The modules defining CORBA and Java EE APIs are not required by
  * this module, but they are required by {@code java.se.ee}.
+ *
+ * @since 9
  */
 module java.se {
     requires transitive java.compiler;
--- a/jdk/src/java.security.jgss/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.security.jgss/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -27,6 +27,8 @@
  * Defines the Java binding of the IETF Generic Security Services API (GSS-API).
  * <P>
  * This module also contains GSS-API mechanisms including Kerberos v5 and SPNEGO.
+ *
+ * @since 9
  */
 module java.security.jgss {
     requires java.naming;
--- a/jdk/src/java.security.sasl/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.security.sasl/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -29,6 +29,8 @@
  * <P>
  * This module also contains SASL mechanisms including DIGEST-MD5,
  * CRAM-MD5, and NTLM.
+ *
+ * @since 9
  */
 module java.security.sasl {
     requires java.logging;
--- a/jdk/src/java.smartcardio/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.smartcardio/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the Java Smart Card I/O API.
+ *
+ * @since 9
  */
 module java.smartcardio {
     exports javax.smartcardio;
--- a/jdk/src/java.sql.rowset/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.sql.rowset/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the JDBC RowSet API.
+ *
+ * @since 9
  */
 module java.sql.rowset {
     requires transitive java.logging;
--- a/jdk/src/java.sql/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.sql/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the JDBC API.
+ *
+ * @since 9
  */
 module java.sql {
     requires transitive java.logging;
--- a/jdk/src/java.transaction/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.transaction/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,6 +28,8 @@
  * <P>
  * The subset consists of RMI exception types which are mapped to CORBA system
  * exceptions by the 'Java Language to IDL Mapping Specification'.
+ *
+ * @since 9
  */
 module java.transaction {
     requires transitive java.rmi;
--- a/jdk/src/java.xml.crypto/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/java.xml.crypto/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines an API for XML cryptography.
+ *
+ * @since 9
  */
 module java.xml.crypto {
     requires transitive java.xml;
--- a/jdk/src/jdk.attach/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.attach/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the attach API.
+ *
+ * @since 9
  */
 module jdk.attach {
     requires jdk.internal.jvmstat;
--- a/jdk/src/jdk.crypto.ucrypto/solaris/conf/security/ucrypto-solaris.cfg	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/conf/security/ucrypto-solaris.cfg	Fri Feb 10 08:57:42 2017 -0800
@@ -2,8 +2,5 @@
 # Configuration file for the OracleUcrypto provider
 #
 disabledServices = {
-  # disabled due to Solaris bug 7121679
-  Cipher.AES/CFB128/PKCS5Padding
-  Cipher.AES/CFB128/NoPadding
 }
 
--- a/jdk/src/jdk.editpad/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.editpad/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Implementation of the edit pad service.
+ *
+ * @since 9
  */
 module jdk.editpad {
     requires jdk.internal.ed;
--- a/jdk/src/jdk.incubator.httpclient/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -26,6 +26,8 @@
 /**
  * Defines the high-level HTTP and WebSocket API.
  * {@Incubating}
+ *
+ * @since 9
  */
 module jdk.incubator.httpclient {
     requires java.base;
--- a/jdk/src/jdk.internal.ed/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.internal.ed/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -26,6 +26,8 @@
 /**
  * Internal editor support for JDK tools.  Includes the Service Provider
  * Interface to built-in editors.
+ *
+ * @since 9
  */
 module jdk.internal.ed {
 
--- a/jdk/src/jdk.internal.le/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.internal.le/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Internal API for line editing
+ *
+ * @since 9
  */
 module jdk.internal.le {
     exports jdk.internal.jline to
--- a/jdk/src/jdk.internal.opt/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.internal.opt/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Internal option processing API
+ *
+ * @since 9
  */
 module jdk.internal.opt {
     exports jdk.internal.joptsimple to jdk.jlink, jdk.jshell;
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java	Fri Feb 10 08:57:42 2017 -0800
@@ -157,8 +157,7 @@
                     for (String dir : dirs) {
                         paths[i++] = Paths.get(dir);
                     }
-                    jartool.moduleFinder =
-                        new ModulePath(Runtime.version(), true, paths);
+                    jartool.moduleFinder = ModulePath.of(Runtime.version(), true, paths);
                 }
             },
             new Option(false, OptionType.CREATE_UPDATE, "--do-not-resolve-by-default") {
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Fri Feb 10 08:57:42 2017 -0800
@@ -699,7 +699,7 @@
         }
         String pn = toPackageName(name);
         // add if this is a class or resource in a package
-        if (Checks.isJavaIdentifier(pn)) {
+        if (Checks.isPackageName(pn)) {
             packages.add(pn);
         }
     }
@@ -1995,7 +1995,7 @@
             }
             // get a resolved module graph
             Configuration config =
-                Configuration.empty().resolveRequires(system, finder, roots);
+                Configuration.empty().resolve(system, finder, roots);
 
             // filter modules resolved from the system module finder
             this.modules = config.modules().stream()
--- a/jdk/src/jdk.jdi/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jdi/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Defines the Java Debugger Interface.
+ *
+ * @since 9
  */
 module jdk.jdi {
     requires jdk.attach;
--- a/jdk/src/jdk.jdwp.agent/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jdwp.agent/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -25,6 +25,8 @@
 
 /**
  * Java Debug Wire Protocol.
+ *
+ * @since 9
  */
 module jdk.jdwp.agent {
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties	Fri Feb 10 08:57:42 2017 -0800
@@ -98,3 +98,4 @@
 err.no.jimage=no jimage provided
 err.option.unsupported={0} not supported: {1}
 err.unknown.option=unknown option: {0}
+err.cannot.create.dir=cannot create directory {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Fri Feb 10 08:57:42 2017 -0800
@@ -29,6 +29,7 @@
 import java.io.PrintWriter;
 import java.io.UncheckedIOException;
 import java.lang.module.Configuration;
+import java.lang.module.FindException;
 import java.lang.module.ModuleDescriptor;
 import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReference;
@@ -232,7 +233,7 @@
 
             return EXIT_OK;
         } catch (PluginException | IllegalArgumentException |
-                 UncheckedIOException |IOException | ResolutionException e) {
+                 UncheckedIOException |IOException | FindException | ResolutionException e) {
             log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage());
             if (DEBUG) {
                 e.printStackTrace(log);
@@ -370,7 +371,7 @@
      */
     private ModuleFinder modulePathFinder() {
         Path[] entries = options.modulePath.toArray(new Path[0]);
-        ModuleFinder finder = new ModulePath(Runtime.version(), true, entries);
+        ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
         if (!options.limitMods.isEmpty()) {
             finder = limitFinder(finder, options.limitMods, Collections.emptySet());
         }
@@ -388,7 +389,7 @@
                                                Set<String> roots)
     {
         Path[] entries = paths.toArray(new Path[0]);
-        ModuleFinder finder = new ModulePath(Runtime.version(), true, entries);
+        ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
 
         // if limitmods is specified then limit the universe
         if (!limitMods.isEmpty()) {
@@ -418,9 +419,9 @@
         }
 
         Configuration cf = Configuration.empty()
-                .resolveRequires(finder,
-                                 ModuleFinder.of(),
-                                 roots);
+                .resolve(finder,
+                         ModuleFinder.of(),
+                         roots);
 
         // emit warning for modules that end with a digit
         cf.modules().stream()
@@ -458,9 +459,9 @@
 
         // resolve all root modules
         Configuration cf = Configuration.empty()
-                .resolveRequires(finder,
-                                 ModuleFinder.of(),
-                                 roots);
+                .resolve(finder,
+                         ModuleFinder.of(),
+                         roots);
 
         // module name -> reference
         Map<String, ModuleReference> map = new HashMap<>();
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java	Fri Feb 10 08:57:42 2017 -0800
@@ -51,7 +51,7 @@
         ModuleDescriptor md = mod.descriptor();
 
         // drop hashes
-        ModuleDescriptor.Builder builder = ModuleDescriptor.module(md.name());
+        ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(md.name());
         md.requires().stream()
           .forEach(builder::requires);
         md.exports().stream()
@@ -62,12 +62,7 @@
           .forEach(builder::uses);
         md.provides().stream()
           .forEach(builder::provides);
-
-        // build the proper concealed packages
-        Set<String> concealed = new HashSet<>(mod.packages());
-        md.exports().stream().map(ModuleDescriptor.Exports::source).forEach(concealed::remove);
-        md.opens().stream().map(ModuleDescriptor.Opens::source).forEach(concealed::remove);
-        concealed.stream().forEach(builder::contains);
+        builder.packages(md.packages());
 
         md.version().ifPresent(builder::version);
         md.mainClass().ifPresent(builder::mainClass);
@@ -124,7 +119,7 @@
             }
         };
 
-        return Configuration.empty().resolveRequires(
+        return Configuration.empty().resolve(
             finder, ModuleFinder.of(), nameToModRef.keySet());
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java	Fri Feb 10 08:57:42 2017 -0800
@@ -718,13 +718,13 @@
     static Layer createPluginsLayer(List<Path> paths) {
 
         Path[] dirs = paths.toArray(new Path[0]);
-        ModuleFinder finder = new ModulePath(Runtime.version(), true, dirs);
+        ModuleFinder finder = ModulePath.of(Runtime.version(), true, dirs);
         Configuration bootConfiguration = Layer.boot().configuration();
         try {
             Configuration cf = bootConfiguration
-                .resolveRequiresAndUses(ModuleFinder.of(),
-                                        finder,
-                                        Collections.emptySet());
+                .resolveAndBind(ModuleFinder.of(),
+                                finder,
+                                Collections.emptySet());
             ClassLoader scl = ClassLoader.getSystemClassLoader();
             return Layer.boot().defineModulesWithOneLoader(cf, scl);
         } catch (Exception ex) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java	Fri Feb 10 08:57:42 2017 -0800
@@ -771,9 +771,12 @@
                 if (md.isOpen()) {
                     setModuleBit("open", true);
                 }
-                if (md.isSynthetic()) {
+                if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC)) {
                     setModuleBit("synthetic", true);
                 }
+                if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED)) {
+                    setModuleBit("mandated", true);
+                }
             }
 
             /*
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Fri Feb 10 08:57:42 2017 -0800
@@ -34,6 +34,7 @@
 import java.io.PrintWriter;
 import java.io.UncheckedIOException;
 import java.lang.module.Configuration;
+import java.lang.module.FindException;
 import java.lang.module.ModuleReader;
 import java.lang.module.ModuleReference;
 import java.lang.module.ModuleFinder;
@@ -851,8 +852,8 @@
             // get a resolved module graph
             Configuration config = null;
             try {
-                config = Configuration.empty().resolveRequires(system, finder, roots);
-            } catch (ResolutionException e) {
+                config = Configuration.empty().resolve(system, finder, roots);
+            } catch (FindException | ResolutionException e) {
                 throw new CommandException("err.module.resolution.fail", e.getMessage());
             }
 
@@ -1392,7 +1393,7 @@
                 options.legalNotices = getLastElement(opts.valuesOf(legalNotices));
             if (opts.has(modulePath)) {
                 Path[] dirs = getLastElement(opts.valuesOf(modulePath)).toArray(new Path[0]);
-                options.moduleFinder = new ModulePath(Runtime.version(), true, dirs);
+                options.moduleFinder = ModulePath.of(Runtime.version(), true, dirs);
             }
             if (opts.has(moduleVersion))
                 options.moduleVersion = getLastElement(opts.valuesOf(moduleVersion));
--- a/jdk/src/jdk.security.auth/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.security.auth/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -26,6 +26,8 @@
 /**
  * Contains the implementation of the javax.security.auth.* interfaces and
  * various authentication modules.
+ *
+ * @since 9
  */
 module jdk.security.auth {
     requires transitive java.naming;
--- a/jdk/src/jdk.security.jgss/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/src/jdk.security.jgss/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -26,6 +26,8 @@
 /**
  * Defines Java extensions to the GSS-API and an implementation of the SASL
  * GSSAPI mechanism.
+ *
+ * @since 9
  */
 module jdk.security.jgss {
     requires transitive java.security.jgss;
--- a/jdk/test/ProblemList.txt	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/ProblemList.txt	Fri Feb 10 08:57:42 2017 -0800
@@ -251,12 +251,11 @@
 
 tools/pack200/CommandLineTests.java                             8059906 generic-all
 
-tools/launcher/ArgsEnvVar.java					8173712 generic-all
 tools/launcher/FXLauncherTest.java                              8068049 linux-all,macosx-all
 
-tools/jimage/JImageExtractTest.java                             8169713 generic-all
-tools/jimage/JImageListTest.java                                8169713 generic-all
-tools/jimage/JImageVerifyTest.java                              8169713 generic-all
+tools/jimage/JImageExtractTest.java                             8170120 generic-all
+tools/jimage/JImageListTest.java                                8170120 generic-all
+tools/jimage/JImageVerifyTest.java                              8170120 generic-all
 
 
 tools/jlink/multireleasejar/JLinkMultiReleaseJarTest.java       8169971 windows-x64
@@ -267,7 +266,7 @@
 
 com/sun/jdi/RedefineImplementor.sh                              8004127 generic-all
 
-com/sun/jdi/JdbMethodExitTest.sh                                6902121 generic-all
+com/sun/jdi/JdbMethodExitTest.sh                                8171483 generic-all
 
 com/sun/jdi/RepStep.java                                        8043571 generic-all
 
@@ -296,6 +295,8 @@
 
 sun/tools/jcmd/TestJcmdSanity.java                              8031482 windows-all
 
+sun/tools/jstat/jstatClassloadOutput1.sh                        8173942 generic-all
+
 sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java    8057732 generic-all
 
 demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java       8151899 generic-all
@@ -308,6 +309,6 @@
 
 javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java 8169737 linux-all
 
-javax/xml/ws/clientjar/TestWsImport.java			8170370 generic-all
+javax/xml/ws/clientjar/TestWsImport.java			8173317 generic-all
 
 ############################################################################
--- a/jdk/test/TEST.groups	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/TEST.groups	Fri Feb 10 08:57:42 2017 -0800
@@ -273,6 +273,7 @@
     jdk/internal/jline \
     com/sun/jndi \
     com/sun/corba \
+    org/omg/CORBA \
     lib/testlibrary \
     sample
 
--- a/jdk/test/com/oracle/security/ucrypto/TestAES.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/com/oracle/security/ucrypto/TestAES.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7088989 8014374 8167512
+ * @bug 7088989 8014374 8167512 8173708
  * @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
  * @key randomness
  * @run main TestAES
@@ -177,6 +177,12 @@
                     k += c.doFinal(eout, firstPartLen+1, eout.length - firstPartLen - 1, dout, k);
                     if (!checkArrays(in, in.length, dout, k)) testPassed = false;
                 } catch(Exception ex) {
+                    if (ex instanceof BadPaddingException &&
+                            algos[i].indexOf("CFB128") != -1 &&
+                            p.getName().equals("OracleUcrypto")) {
+                        System.out.println("Ignore due to a pre-S11.3 bug: " + ex);
+                        continue;
+                    }
                     System.out.println("Unexpected Exception: " + algos[i]);
                     ex.printStackTrace();
                     testPassed = false;
--- a/jdk/test/java/io/FilePermission/ReadFileOnPath.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/io/FilePermission/ReadFileOnPath.java	Fri Feb 10 08:57:42 2017 -0800
@@ -57,7 +57,7 @@
                 "module-info.class", "base", "p/App.class", "p/child");
 
         // exploded module
-        test("--module-path", "modules", "-m", "m/p.App", "SS+++++");
+        test("--module-path", "modules", "-m", "m/p.App", "SS++++0");
 
         // module in jar
         test("--module-path", "new.jar", "-m", "m/p.App", "SSSS++0");
--- a/jdk/test/java/lang/Class/forName/modules/TestLayer.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/Class/forName/modules/TestLayer.java	Fri Feb 10 08:57:42 2017 -0800
@@ -46,9 +46,9 @@
         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
 
         Configuration parent = Layer.boot().configuration();
-        Configuration cf = parent.resolveRequiresAndUses(ModuleFinder.of(),
-                                                         finder,
-                                                         modules);
+        Configuration cf = parent.resolveAndBind(ModuleFinder.of(),
+                                                 finder,
+                                                 modules);
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
--- a/jdk/test/java/lang/Class/forName/modules/src/m3/p3/NoAccess.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/Class/forName/modules/src/m3/p3/NoAccess.java	Fri Feb 10 08:57:42 2017 -0800
@@ -50,9 +50,9 @@
         Layer bootLayer = Layer.boot();
         Configuration parent = bootLayer.configuration();
 
-        Configuration cf = parent.resolveRequiresAndUses(finder,
-                                                         ModuleFinder.of(),
-                                                         Set.of("m1", "m2"));
+        Configuration cf = parent.resolveAndBind(finder,
+                                                 ModuleFinder.of(),
+                                                 Set.of("m1", "m2"));
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = bootLayer.defineModulesWithManyLoaders(cf, scl);
--- a/jdk/test/java/lang/Class/getPackageName/Basic.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/Class/getPackageName/Basic.java	Fri Feb 10 08:57:42 2017 -0800
@@ -154,8 +154,8 @@
         return new Object[][] {
 
             { Basic.class,                  TEST_PACKAGE },
-            { Basic[].class,                null },
-            { Basic[][].class,              null },
+            { Basic[].class,                TEST_PACKAGE },
+            { Basic[][].class,              TEST_PACKAGE },
 
             { getNestedClass1(),            TEST_PACKAGE },
             { getNestedClass2(),            TEST_PACKAGE },
@@ -174,14 +174,14 @@
             { getAnonymousClass6(),         TEST_PACKAGE },
 
             { Object.class,                 "java.lang" },
-            { Object[].class,               null },
-            { Object[][].class,             null },
+            { Object[].class,               "java.lang" },
+            { Object[][].class,             "java.lang" },
 
-            { int.class,                    null },
-            { int[].class,                  null },
-            { int[][].class,                null },
+            { int.class,                    "java.lang" },
+            { int[].class,                  "java.lang" },
+            { int[][].class,                "java.lang" },
 
-            { void.class,                   null },
+            { void.class,                   "java.lang" },
 
         };
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/ClassLoaderTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2017, 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 8168423
+ * @summary Different types of ClassLoader running with(out) SecurityManager and
+ *          (in)valid security policy file.
+ * @library /lib/testlibrary
+ * @modules java.base/jdk.internal.module
+ * @build JarUtils CompilerUtils
+ * @run main/timeout=240 ClassLoaderTest
+ */
+import java.io.File;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.module.ModuleDescriptor;
+import jdk.internal.module.ModuleInfoWriter;
+import jdk.testlibrary.ProcessTools;
+
+public class ClassLoaderTest {
+
+    private static final String SRC = System.getProperty("test.src");
+    private static final Path CL_SRC = Paths.get(SRC, "TestClassLoader.java");
+    private static final Path C_SRC = Paths.get(SRC, "TestClient.java");
+    private static final Path CL_BIN = Paths.get("classes", "clbin");
+    private static final Path C_BIN = Paths.get("classes", "cbin");
+    private static final Path ARTIFACT_DIR = Paths.get("jars");
+    private static final Path VALID_POLICY = Paths.get(SRC, "valid.policy");
+    private static final Path INVALID_POLICY
+            = Paths.get(SRC, "malformed.policy");
+    private static final Path NO_POLICY = null;
+    private static final String LOCALE = "-Duser.language=en -Duser.region=US";
+    /*
+     * Here is the naming convention followed for each jar.
+     * cl.jar   - Regular custom class loader jar.
+     * mcl.jar  - Modular custom class loader jar.
+     * c.jar    - Regular client jar.
+     * mc.jar   - Modular client jar.
+     * amc.jar  - Modular client referring automated custom class loader jar.
+     */
+    private static final Path CL_JAR = ARTIFACT_DIR.resolve("cl.jar");
+    private static final Path MCL_JAR = ARTIFACT_DIR.resolve("mcl.jar");
+    private static final Path C_JAR = ARTIFACT_DIR.resolve("c.jar");
+    private static final Path MC_JAR = ARTIFACT_DIR.resolve("mc.jar");
+    private static final Path AMC_JAR = ARTIFACT_DIR.resolve("amc.jar");
+    private static final Map<String, String> MSG_MAP = new HashMap<>();
+
+    static {
+        // This mapping help process finding expected message based
+        // on the key passed as argument while executing java command.
+        MSG_MAP.put("MissingModule", "Module cl not found, required by mc");
+        MSG_MAP.put("ErrorPolicy", "java.security.policy: error parsing file");
+        MSG_MAP.put(
+                "SystemCL", "jdk.internal.loader.ClassLoaders$AppClassLoader");
+        MSG_MAP.put("CustomCL", "cl.TestClassLoader");
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        // Generates regular and modular jars before start processing it.
+        setUp();
+        processForEachPolicyFile();
+    }
+
+    /**
+     * Test cases are based on the following logic,
+     *  for (policyFile : {"NO_POLICY", "VALID", "MALFORMED"}) {
+     *      for (classLoader : {"SystemClassLoader", "CustomClassLoader"}){
+     *          for (clientModule : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
+     *              for (classLoaderModule : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
+     *                  Create and run java command for each possible Test case
+     *              }
+     *          }
+     *      }
+     *  }
+     */
+    private static void processForEachPolicyFile() throws Exception {
+
+        final String regCLloc = CL_JAR.toFile().getAbsolutePath();
+        final String modCLloc = MCL_JAR.toFile().getAbsolutePath();
+        final String regCloc = C_JAR.toFile().getAbsolutePath();
+        final String modCloc = MC_JAR.toFile().getAbsolutePath();
+        final String autoModCloc = AMC_JAR.toFile().getAbsolutePath();
+        final String separator = File.pathSeparator;
+
+        for (Path policy
+                : new Path[]{NO_POLICY, VALID_POLICY, INVALID_POLICY}) {
+            final String policyFile = (policy != null)
+                    ? policy.toFile().getAbsolutePath() : null;
+            final boolean malformedPolicy
+                    = (policy == null) ? false : policy.equals(INVALID_POLICY);
+
+            for (boolean useSCL : new boolean[]{true, false}) {
+                final String clVmArg = (useSCL) ? ""
+                        : "-Djava.system.class.loader=cl.TestClassLoader";
+                final String autoAddModArg
+                        = (useSCL) ? "" : "--add-modules=cl";
+                final String addmodArg = (useSCL) ? "" : "--add-modules=mcl";
+                final String sMArg = (policy != null) ? String.format(
+                        "-Djava.security.manager -Djava.security.policy=%s",
+                        policyFile) : "";
+                final String smMsg = (policy != null) ? "With SecurityManager"
+                        : "Without SecurityManager";
+                final String expectedResult = ((!malformedPolicy)
+                        ? ((useSCL) ? "PASS SystemCL" : "PASS CustomCL")
+                        : "FAIL ErrorPolicy");
+
+                // NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED
+                System.out.printf("Case:- Modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s -m mc/c.TestClient",
+                    modCloc, separator, modCLloc, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+                System.out.printf("Case:- Modular Client and %s %s%n", ((useSCL)
+                        ? "SystemClassLoader"
+                        : "Automatic modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s -m mc/c.TestClient",
+                    autoModCloc, separator, regCLloc, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+                System.out.printf("Case:- Modular Client and %s %s%n", ((useSCL)
+                        ? "SystemClassLoader"
+                        : "Unknown modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s -cp %s %s %s %s -m mc/c.TestClient",
+                    autoModCloc, regCLloc, LOCALE, clVmArg, sMArg),
+                    "FAIL MissingModule"});
+
+                // AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED
+                System.out.printf("Case:- Automated modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+                    regCloc, separator, modCLloc, addmodArg, LOCALE, clVmArg,
+                    sMArg), expectedResult});
+                System.out.printf("Case:- Automated modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Automatic modular CustomClassLoader"),
+                        smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+                    regCloc, separator, regCLloc, autoAddModArg, LOCALE,
+                    clVmArg, sMArg), expectedResult});
+                System.out.printf("Case:- Automated modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Unknown modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s -cp %s %s %s %s -m c/c.TestClient",
+                    regCloc, regCLloc, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+
+                // UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED
+                System.out.printf("Case:- Unknown modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "-cp %s --module-path %s %s %s %s %s c.TestClient",
+                    regCloc, modCLloc, addmodArg, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+                System.out.printf("Case:- Unknown modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Automatic modular CustomClassLoader"),
+                        smMsg);
+                execute(new String[]{String.format(
+                    "-cp %s --module-path %s %s %s %s %s c.TestClient",
+                    regCloc, regCLloc, autoAddModArg, LOCALE, clVmArg, sMArg),
+                    expectedResult});
+                System.out.printf("Case:- Unknown modular Client and %s %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Unknown modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "-cp %s%s%s %s %s %s c.TestClient", regCloc, separator,
+                    regCLloc, LOCALE, clVmArg, sMArg), expectedResult});
+
+                // Regular jars in module-path and Modular jars in class-path.
+                System.out.printf("Case:- Regular Client and %s "
+                        + "inside --module-path %s.%n", ((useSCL)
+                                ? "SystemClassLoader"
+                                : "Unknown modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+                    regCloc, separator, regCLloc, autoAddModArg, LOCALE,
+                    clVmArg, sMArg), expectedResult});
+                System.out.printf("Case:- Modular Client and %s in -cp %s%n",
+                        ((useSCL) ? "SystemClassLoader"
+                                : "Modular CustomClassLoader"), smMsg);
+                execute(new String[]{String.format(
+                    "-cp %s%s%s %s %s %s c.TestClient", modCloc, separator,
+                    modCLloc, LOCALE, clVmArg, sMArg), expectedResult});
+            }
+        }
+    }
+
+    /**
+     * Execute with command arguments and process the result.
+     */
+    private static void execute(String[] args) throws Exception {
+
+        String status = null;
+        String msgKey = null;
+        if ((args != null && args.length > 1)) {
+            String[] secArgs = args[1].split("\\s+");
+            status = (secArgs.length > 0) ? secArgs[0] : null;
+            msgKey = (secArgs.length > 1) ? secArgs[1] : null;
+        }
+        String out = ProcessTools.executeTestJvm(args[0].split("\\s+"))
+                .getOutput();
+        // Handle response.
+        if ((status != null && "PASS".equals(status) && msgKey != null
+                && out.contains(MSG_MAP.get(msgKey)))) {
+            System.out.printf("PASS: Expected Result: %s.%n",
+                    MSG_MAP.get(msgKey));
+        } else if ((status != null && "FAIL".equals(status) && msgKey != null
+                && out.contains(MSG_MAP.get(msgKey)))) {
+            System.out.printf("PASS: Expected Failure: %s.%n",
+                    MSG_MAP.get(msgKey));
+        } else if (out.contains("Exception") || out.contains("Error")) {
+            System.out.printf("OUTPUT: %s", out);
+            throw new RuntimeException("FAIL: Unknown Exception.");
+        } else {
+            System.out.printf("OUTPUT: %s", out);
+            throw new RuntimeException("FAIL: Unknown Test case found");
+        }
+    }
+
+    /**
+     * Creates regular/modular jar files for TestClient and TestClassLoader.
+     */
+    private static void setUp() throws Exception {
+
+        boolean compiled = CompilerUtils.compile(CL_SRC, CL_BIN);
+        compiled &= CompilerUtils.compile(C_SRC, C_BIN);
+        if (!compiled) {
+            throw new RuntimeException("Test Setup failed.");
+        }
+        // Generate regular jar files for TestClient and TestClassLoader
+        JarUtils.createJarFile(CL_JAR, CL_BIN);
+        JarUtils.createJarFile(C_JAR, C_BIN);
+        // Generate modular jar files for TestClient and TestClassLoader with
+        // their corresponding ModuleDescriptor.
+        Files.copy(CL_JAR, MCL_JAR, StandardCopyOption.REPLACE_EXISTING);
+        updateModuleDescr(MCL_JAR, ModuleDescriptor.newModule("mcl")
+                .exports("cl").requires("java.base").build());
+        Files.copy(C_JAR, MC_JAR, StandardCopyOption.REPLACE_EXISTING);
+        updateModuleDescr(MC_JAR, ModuleDescriptor.newModule("mc")
+                .exports("c").requires("java.base").requires("mcl").build());
+        Files.copy(C_JAR, AMC_JAR, StandardCopyOption.REPLACE_EXISTING);
+        updateModuleDescr(AMC_JAR, ModuleDescriptor.newModule("mc")
+                .exports("c").requires("java.base").requires("cl").build());
+    }
+
+    /**
+     * Update regular jars and include module-info.class inside it to make
+     * modular jars.
+     */
+    private static void updateModuleDescr(Path jar, ModuleDescriptor mDescr)
+            throws Exception {
+        if (mDescr != null) {
+            Path dir = Files.createTempDirectory("tmp");
+            Path mi = dir.resolve("module-info.class");
+            try (OutputStream out = Files.newOutputStream(mi)) {
+                ModuleInfoWriter.write(mDescr, out);
+            }
+            System.out.format("Adding 'module-info.class' to jar '%s'%n", jar);
+            JarUtils.updateJarFile(jar, dir);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/TestClassLoader.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, 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 cl;
+
+public class TestClassLoader extends ClassLoader {
+
+    /**
+     * This constructor is used to set the parent ClassLoader
+     */
+    public TestClassLoader(ClassLoader parent) {
+        super(parent);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/TestClient.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, 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 c;
+
+public class TestClient {
+
+    public static void main(String[] args) {
+
+        // Initialize policy file.
+        System.getProperty("test.src");
+        System.out.printf("ContextClassLoader: %s%n",
+                Thread.currentThread().getContextClassLoader().toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/malformed.policy	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,4 @@
+grant {
+    xyz;
+    permission java.util.PropertyPermission "test.src", "read";
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/valid.policy	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,4 @@
+grant codeBase "file:./jars/*" {
+    permission java.lang.RuntimePermission "createClassLoader";
+    permission java.util.PropertyPermission "test.src", "read";
+};
\ No newline at end of file
--- a/jdk/test/java/lang/StackWalker/Basic.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/StackWalker/Basic.java	Fri Feb 10 08:57:42 2017 -0800
@@ -23,18 +23,21 @@
 
 /*
  * @test
- * @bug 8140450
+ * @bug 8140450 8173898
  * @summary Basic test for the StackWalker::walk method
  * @run testng Basic
  */
 
 import java.lang.StackWalker.StackFrame;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import static java.lang.StackWalker.Option.*;
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
+import static org.testng.Assert.*;
 
 public class Basic {
     private static boolean verbose = false;
@@ -60,6 +63,17 @@
         }
     }
 
+    @Test
+    public static void testWalkFromConstructor() throws Exception {
+        System.out.println("testWalkFromConstructor:");
+        List<String> found = ((ConstructorNewInstance)ConstructorNewInstance.class.getMethod("create")
+                             .invoke(null)).collectedFrames();
+        assertEquals(List.of(ConstructorNewInstance.class.getName()+"::<init>",
+                             ConstructorNewInstance.class.getName()+"::create",
+                             Basic.class.getName()+"::testWalkFromConstructor"),
+                     found);
+    }
+
     private final int depth;
     Basic(int depth) {
         this.depth = depth;
@@ -77,6 +91,47 @@
         assertEquals(limit, frames.size());
     }
 
+    static class ConstructorNewInstance {
+        static final StackWalker walker =
+            StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+        List<String> testFramesOrReflectionFrames;
+        public ConstructorNewInstance() {
+            testFramesOrReflectionFrames = walker.walk(this::parse);
+        }
+        public List<String> collectedFrames() {
+            return testFramesOrReflectionFrames;
+        }
+        public boolean accept(StackFrame f) {
+            // Frames whose class names don't contain "."
+            // are our own test frames. These are the ones
+            // we expect.
+            // Frames whose class names contain ".reflect."
+            // are reflection frames. None should be present,
+            // since they are supposed to be filtered by
+            // by StackWalker. If we find any, we want to fail.
+            if (!f.getClassName().contains(".")
+                || f.getClassName().contains(".reflect.")) {
+                System.out.println("    " + f);
+                return true;
+            }
+            // Filter out all other frames (in particular
+            // those from the test framework) in order to
+            // have predictable results.
+            return false;
+        }
+        public String frame(StackFrame f) {
+            return f.getClassName() + "::" + f.getMethodName();
+        }
+        List<String> parse(Stream<StackFrame> s) {
+            return s.filter(this::accept)
+                    .map(this::frame)
+                    .collect(Collectors.toList());
+        }
+        public static ConstructorNewInstance create() throws Exception {
+            return ConstructorNewInstance.class.getConstructor().newInstance();
+        }
+    }
+
     class StackBuilder {
         private final int stackDepth;
         private final int limit;
@@ -131,9 +186,4 @@
         }
     }
 
-    static void assertEquals(int x, int y) {
-        if (x != y) {
-            throw new RuntimeException(x + " != " + y);
-        }
-    }
 }
--- a/jdk/test/java/lang/StackWalker/CallerFromMain.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/StackWalker/CallerFromMain.java	Fri Feb 10 08:57:42 2017 -0800
@@ -51,7 +51,7 @@
         try {
             Class<?> c = sw.getCallerClass();
             throw new RuntimeException("UOE not thrown. Caller: " + c);
-        } catch (IllegalStateException e) {}
+        } catch (IllegalCallerException e) {}
 
         // StackWalker::getCallerClass
         // Runnable::run
--- a/jdk/test/java/lang/StackWalker/CountLocalSlots.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * 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 8147039
- * @summary Confirm locals[] always has expected length, even for "dead" locals
- * @modules java.base/java.lang:open
- * @compile LocalsAndOperands.java
- * @run testng/othervm -Xcomp CountLocalSlots
- */
-
-import org.testng.annotations.Test;
-import java.lang.StackWalker.StackFrame;
-
-public class CountLocalSlots {
-    final static boolean debug = true;
-
-    @Test(dataProvider = "provider", dataProviderClass = LocalsAndOperands.class)
-    public void countLocalSlots(StackFrame... frames) {
-        for (StackFrame frame : frames) {
-            if (debug) {
-                System.out.println("Running countLocalSlots");
-                LocalsAndOperands.dumpStackWithLocals(frames);
-            }
-            // Confirm expected number of locals
-            String methodName = frame.getMethodName();
-            Integer expectedObj = (Integer) LocalsAndOperands.Tester.NUM_LOCALS.get(methodName);
-            if (expectedObj == null) {
-                if (!debug) { LocalsAndOperands.dumpStackWithLocals(frames); }
-                throw new RuntimeException("No NUM_LOCALS entry for " +
-                        methodName + "().  Update test?");
-            }
-            Object[] locals = (Object[]) LocalsAndOperands.invokeGetLocals(frame);
-            if (locals.length != expectedObj) {
-                if (!debug) { LocalsAndOperands.dumpStackWithLocals(frames); }
-                throw new RuntimeException(methodName + "(): number of locals (" +
-                        locals.length + ") did not match expected (" + expectedObj + ")");
-            }
-        }
-    }
-}
--- a/jdk/test/java/lang/StackWalker/LocalsAndOperands.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,33 +23,54 @@
 
 /*
  * @test
- * @bug 8020968 8147039
+ * @bug 8020968 8147039 8156073
  * @summary Tests for locals and operands
  * @modules java.base/java.lang:open
- * @run testng LocalsAndOperands
+ * @run testng/othervm -Xint -DtestUnused=true LocalsAndOperands
+ * @run testng/othervm -Xcomp LocalsAndOperands
+ * @run testng/othervm -Xcomp -XX:-TieredCompilation LocalsAndOperands
  */
 
 import org.testng.annotations.*;
+import static org.testng.Assert.*;
 import java.lang.StackWalker.StackFrame;
+import static java.lang.StackWalker.Option.*;
 import java.lang.reflect.*;
 import java.util.*;
 import java.util.stream.*;
 
 public class LocalsAndOperands {
-    static final boolean debug = true;
+    static final boolean debug = false;
+    static final boolean is32bit;
+    static final boolean testUnused;
 
     static Class<?> liveStackFrameClass;
-    static Class<?> primitiveValueClass;
+    static Class<?> primitiveSlotClass;
+    static Class<?> primitiveSlot32Class;
+    static Class<?> primitiveSlot64Class;
+
     static StackWalker extendedWalker;
     static Method getLocals;
     static Method getOperands;
     static Method getMonitors;
-    static Method primitiveType;
+    static Method primitiveSize;
+    static Method primitiveLongValue;
+    static Method primitiveIntValue;
+    static Method getExtendedWalker;
+
+    private static final long LOWER_LONG_VAL = 4L; // Lower bits
+    private static final long UPPER_LONG_VAL = 0x123400000000L; // Upper bits
+    private static final long NEG_LONG_VAL = Long.MIN_VALUE;
+
+    private static final double LOWER_DOUBLE_VAL = Double.longBitsToDouble(0xABCDL);
+    private static final double UPPER_DOUBLE_VAL = Double.longBitsToDouble(0x432100000000L);
 
     static {
         try {
             liveStackFrameClass = Class.forName("java.lang.LiveStackFrame");
-            primitiveValueClass = Class.forName("java.lang.LiveStackFrame$PrimitiveValue");
+            primitiveSlotClass = Class.forName("java.lang.LiveStackFrame$PrimitiveSlot");
+            primitiveSlot32Class = Class.forName("java.lang.LiveStackFrameInfo$PrimitiveSlot32");
+            primitiveSlot64Class = Class.forName("java.lang.LiveStackFrameInfo$PrimitiveSlot64");
 
             getLocals = liveStackFrameClass.getDeclaredMethod("getLocals");
             getLocals.setAccessible(true);
@@ -60,12 +81,31 @@
             getMonitors = liveStackFrameClass.getDeclaredMethod("getMonitors");
             getMonitors.setAccessible(true);
 
-            primitiveType = primitiveValueClass.getDeclaredMethod("type");
-            primitiveType.setAccessible(true);
+            primitiveSize = primitiveSlotClass.getDeclaredMethod("size");
+            primitiveSize.setAccessible(true);
+
+            primitiveLongValue = primitiveSlotClass.getDeclaredMethod("longValue");
+            primitiveLongValue.setAccessible(true);
+
+            primitiveIntValue = primitiveSlotClass.getDeclaredMethod("intValue");
+            primitiveIntValue.setAccessible(true);
 
-            Method method = liveStackFrameClass.getMethod("getStackWalker");
-            method.setAccessible(true);
-            extendedWalker = (StackWalker) method.invoke(null);
+            getExtendedWalker = liveStackFrameClass.getMethod("getStackWalker", Set.class);
+            getExtendedWalker.setAccessible(true);
+            extendedWalker = (StackWalker) getExtendedWalker.invoke(null,
+                    EnumSet.noneOf(StackWalker.Option.class));
+
+            String dataModel = System.getProperty("sun.arch.data.model");
+            if ("32".equals(dataModel)) {
+                is32bit = true;
+            } else if ("64".equals(dataModel)) {
+                is32bit= false;
+            } else {
+                throw new RuntimeException("Weird data model:" + dataModel);
+            }
+            System.out.println("VM bits: " + dataModel);
+
+            testUnused = System.getProperty("testUnused") != null;
         } catch (Throwable t) { throw new RuntimeException(t); }
     }
 
@@ -80,47 +120,17 @@
      * DataProviders *
      *****************/
 
-    /** Calls testLocals() and provides LiveStackFrames for testLocals* methods */
-    @DataProvider
-    public static StackFrame[][] provider() {
-        return new StackFrame[][] {
-            new Tester().testLocals()
-        };
-    }
-
-    /**
-     * Calls testLocalsKeepAlive() and provides LiveStackFrames for testLocals* methods.
-     * Local variables in testLocalsKeepAlive() are ensured to not become dead.
-     */
+    /** Calls KnownLocalsTester.testLocals* and provides LiveStackFrames */
     @DataProvider
-    public static StackFrame[][] keepAliveProvider() {
-        return new StackFrame[][] {
-            new Tester().testLocalsKeepAlive()
-        };
-    }
-
-    /**
-     * Provides StackFrames from a StackWalker without the LOCALS_AND_OPERANDS
-     * option.
-     */
-    @DataProvider
-    public static StackFrame[][] noLocalsProvider() {
-        // Use default StackWalker
-        return new StackFrame[][] {
-            new Tester(StackWalker.getInstance(), true).testLocals()
-        };
-    }
-
-    /**
-     * Calls testLocals() and provides LiveStackFrames for *all* called methods,
-     * including test infrastructure (jtreg, testng, etc)
-     *
-     */
-    @DataProvider
-    public static StackFrame[][] unfilteredProvider() {
-        return new StackFrame[][] {
-            new Tester(extendedWalker, false).testLocals()
-        };
+    public static StackFrame[][] knownLocalsProvider() {
+        List<StackFrame[]> list = new ArrayList<>(3);
+        list.add(new KnownLocalsTester().testLocalsKeepAlive());
+        list.add(new KnownLocalsTester().testLocalsKeepAliveArgs(0xA, 'z',
+                "himom", 0x3FF00000000L + 0xFFFF, Math.PI));
+        if (testUnused) {
+            list.add(new KnownLocalsTester().testLocalsUnused());
+        }
+        return list.toArray(new StackFrame[1][1]);
     }
 
     /****************
@@ -128,135 +138,123 @@
      ****************/
 
     /**
-     * Check for expected local values and types in the LiveStackFrame
+     * Check for expected local values in the LiveStackFrame
      */
-    @Test(dataProvider = "keepAliveProvider")
+    @Test(dataProvider = "knownLocalsProvider")
     public static void checkLocalValues(StackFrame... frames) {
-        if (debug) {
-            System.out.println("Running checkLocalValues");
-            dumpStackWithLocals(frames);
-        }
-        Arrays.stream(frames).filter(f -> f.getMethodName()
-                                           .equals("testLocalsKeepAlive"))
-                                           .forEach(
-            f -> {
-                Object[] locals = invokeGetLocals(f);
-                for (int i = 0; i < locals.length; i++) {
-                    // Value
-                    String expected = Tester.LOCAL_VALUES[i];
-                    Object observed = locals[i];
-                    if (expected != null /* skip nulls in golden values */ &&
-                            !expected.equals(observed.toString())) {
-                        System.err.println("Local value mismatch:");
-                        if (!debug) { dumpStackWithLocals(frames); }
-                        throw new RuntimeException("local " + i + " value is " +
-                                observed + ", expected " + expected);
-                    }
-
-                    // Type
-                    expected = Tester.LOCAL_TYPES[i];
-                    observed = type(locals[i]);
-                    if (expected != null /* skip nulls in golden values */ &&
-                            !expected.equals(observed)) {
-                        System.err.println("Local type mismatch:");
-                        if (!debug) { dumpStackWithLocals(frames); }
-                        throw new RuntimeException("local " + i + " type is " +
-                                observed + ", expected " + expected);
-                    }
-                }
-            }
-        );
+        dumpFramesIfDebug(frames);
+        try {
+            Stream.of(frames)
+                  .filter(f -> KnownLocalsTester.TEST_METHODS.contains(f.getMethodName()))
+                  .forEach(LocalsAndOperands::checkFrameLocals);
+        } catch (Exception e) { dumpFramesIfNotDebug(frames); throw e; }
     }
 
     /**
-     * Basic sanity check for locals and operands
+     * Check the locals in the given StackFrame against the expected values.
      */
-    @Test(dataProvider = "provider")
-    public static void sanityCheck(StackFrame... frames) {
-        if (debug) {
-            System.out.println("Running sanityCheck");
-        }
-        try {
-            Stream<StackFrame> stream = Arrays.stream(frames);
-            if (debug) {
-                stream.forEach(LocalsAndOperands::printLocals);
+    private static void checkFrameLocals(StackFrame f) {
+        Object[] expectedArray = KnownLocalsTester.LOCAL_VALUES;
+        Object[] locals = invokeGetLocals(f);
+
+        for (int i = 0; i < locals.length; i++) {
+            Object expected = expectedArray[i];
+            Object observed = locals[i];
+
+            if (expected == null) { /* skip nulls in golden values */
+                continue;
+            } else if (expected instanceof KnownLocalsTester.TwoSlotValue) {
+                // confirm integrity of expected values
+                assertEquals(expectedArray[i+1], null,
+                        "Malformed array of expected values - slot after TwoSlotValue should be null");
+                assertLongIsInSlots(locals[i], locals[i+1],
+                        ((KnownLocalsTester.TwoSlotValue)expected).value);
+                i++; // skip following slot
+            } else if (primitiveSlotClass.isInstance(observed)) { // single slot primitive
+                assertTrue(primitiveValueEquals(observed, expected),
+                        "Local value mismatch: local " + i + " value is " +
+                          observed + ", expected " + expected);
+            } else if (expected instanceof Class) {
+                assertTrue(((Class)expected).isInstance(observed),
+                        "Local value mismatch: local " + i + " expected instancof " +
+                          expected + " but got " + observed);
+            } else if (expected instanceof String) {
+                assertEquals(expected, observed, "Local value mismatch: local " +
+                        i + " value is " + observed + ", expected " + expected);
             } else {
-                System.out.println(stream.count() + " frames");
+                throw new RuntimeException("Unrecognized expected local value " +
+                        i + ": " + expected);
             }
-        } catch (Throwable t) {
-            dumpStackWithLocals(frames);
-            throw t;
         }
     }
 
     /**
      * Sanity check for locals and operands, including testng/jtreg frames
+     * using all StackWalker options.
      */
-    @Test(dataProvider = "unfilteredProvider")
-    public static void unfilteredSanityCheck(StackFrame... frames) {
+    @Test
+    public synchronized void fullStackSanityCheck() throws Throwable {
         if (debug) {
-            System.out.println("Running unfilteredSanityCheck");
+            System.out.println("Running fullStackSanityCheck");
         }
-        try {
-            Stream<StackFrame> stream = Arrays.stream(frames);
+        StackWalker sw = (StackWalker) getExtendedWalker.invoke(null,
+                EnumSet.of(SHOW_HIDDEN_FRAMES, SHOW_REFLECT_FRAMES,
+                           RETAIN_CLASS_REFERENCE));
+        sw.forEach(f -> {
             if (debug) {
-                stream.forEach(f -> { System.out.println(f + ": " +
-                        invokeGetLocals(f).length + " locals"); } );
+                printLocals(f);
             } else {
-                System.out.println(stream.count() + " frames");
+                try {
+                    System.out.println("    " + f + ": " +
+                      ((Object[]) getLocals.invoke(f)).length + " locals, " +
+                      ((Object[]) getOperands.invoke(f)).length + " operands, " +
+                      ((Object[]) getMonitors.invoke(f)).length + " monitors");
+                } catch (IllegalAccessException|InvocationTargetException t) {
+                    throw new RuntimeException(t);
+                }
             }
-        } catch (Throwable t) {
-            dumpStackWithLocals(frames);
-            throw t;
-        }
+        });
     }
 
     /**
      * Test that LiveStackFrames are not provided with the default StackWalker
      * options.
      */
-    @Test(dataProvider = "noLocalsProvider")
-    public static void withoutLocalsAndOperands(StackFrame... frames) {
-        for (StackFrame frame : frames) {
-            if (liveStackFrameClass.isInstance(frame)) {
-                throw new RuntimeException("should not be LiveStackFrame");
-            }
-        }
+    @Test
+    public static void noLocalsSanityCheck() {
+        StackWalker sw = StackWalker.getInstance();
+        sw.forEach(f -> {
+            assertFalse(liveStackFrameClass.isInstance(f),
+                        "should not be LiveStackFrame");
+        });
     }
 
-    static class Tester {
+    /**
+     * Class stack-walking methods with a known set of methods and local variables.
+     */
+    static class KnownLocalsTester {
         private StackWalker walker;
-        private boolean filter = true; // Filter out testng/jtreg/etc frames?
 
-        Tester() {
+        KnownLocalsTester() {
             this.walker = extendedWalker;
         }
 
-        Tester(StackWalker walker, boolean filter) {
-            this.walker = walker;
-            this.filter = filter;
-        }
-
         /**
          * Perform stackwalk without keeping local variables alive and return an
          * array of the collected StackFrames
          */
-        private synchronized StackFrame[] testLocals() {
+        private synchronized StackFrame[] testLocalsUnused() {
             // Unused local variables will become dead
-            int x = 10;
-            char c = 'z';
+            int x = 0xA;
+            char c = 'z'; // 0x7A
             String hi = "himom";
-            long l = 1000000L;
-            double d =  3.1415926;
+            long l = 0x3FF00000000L + 0xFFFFL;
+            double d =  Math.PI;
 
-            if (filter) {
-                return walker.walk(s -> s.filter(f -> TEST_METHODS.contains(f
-                        .getMethodName())).collect(Collectors.toList()))
-                        .toArray(new StackFrame[0]);
-            } else {
-                return walker.walk(s -> s.collect(Collectors.toList()))
-                        .toArray(new StackFrame[0]);
-            }
+            return walker.walk(s ->
+                s.filter(f -> TEST_METHODS.contains(f.getMethodName()))
+                 .toArray(StackFrame[]::new)
+            );
         }
 
         /**
@@ -264,64 +262,153 @@
          * the collected StackFrames
          */
         private synchronized StackFrame[] testLocalsKeepAlive() {
-            int x = 10;
-            char c = 'z';
+            int x = 0xA;
+            char c = 'z'; // 0x7A
             String hi = "himom";
-            long l = 1000000L;
-            double d =  3.1415926;
+            long l = 0x3FF00000000L + 0xFFFFL;
+            double d =  Math.PI;
 
-            List<StackWalker.StackFrame> frames;
-            if (filter) {
-                frames = walker.walk(s -> s.filter(f -> TEST_METHODS.contains(f
-                        .getMethodName())).collect(Collectors.toList()));
-            } else {
-                frames = walker.walk(s -> s.collect(Collectors.toList()));
-            }
+            StackFrame[] frames = walker.walk(s ->
+                s.filter(f -> TEST_METHODS.contains(f.getMethodName()))
+                 .toArray(StackFrame[]::new)
+            );
 
             // Use local variables so they stay alive
-            System.out.println("Stayin' alive: "+x+" "+c+" "+hi+" "+l+" "+d);
-            return frames.toArray(new StackFrame[0]); // FIXME: convert to Array here
+            System.out.println("Stayin' alive: "+this+" "+x+" "+c+" "+hi+" "+l+" "+d);
+            return frames;
+        }
+
+        /**
+         * Perform stackwalk, keeping method arguments alive, and return a list of
+         * the collected StackFrames
+         */
+        private synchronized StackFrame[] testLocalsKeepAliveArgs(int x, char c,
+                                                                  String hi, long l,
+                                                                  double d) {
+            StackFrame[] frames = walker.walk(s ->
+                s.filter(f -> TEST_METHODS.contains(f.getMethodName()))
+                 .toArray(StackFrame[]::new)
+            );
+
+            // Use local variables so they stay alive
+            System.out.println("Stayin' alive: "+this+" "+x+" "+c+" "+hi+" "+l+" "+d);
+            return frames;
+        }
+
+        // An expected two-slot local (i.e. long or double)
+        static class TwoSlotValue {
+            public long value;
+            public TwoSlotValue(long value) { this.value = value; }
         }
 
-        // Expected values for locals in testLocals() & testLocalsKeepAlive()
-        // TODO: use real values instead of Strings, rebuild doubles & floats, etc
-        private final static String[] LOCAL_VALUES = new String[] {
-            null, // skip, LocalsAndOperands$Tester@XXX identity is different each run
-            "10",
-            "122",
+        // Expected values for locals in KnownLocalsTester.testLocals* methods
+        private final static Object[] LOCAL_VALUES = new Object[] {
+            LocalsAndOperands.KnownLocalsTester.class,
+            Integer.valueOf(0xA),
+            Integer.valueOf(0x7A),
             "himom",
-            "0",
-            null, // skip, fix in 8156073
-            null, // skip, fix in 8156073
-            null, // skip, fix in 8156073
-            "0"
+            new TwoSlotValue(0x3FF00000000L + 0xFFFFL),
+            null, // 2nd slot
+            new TwoSlotValue(Double.doubleToRawLongBits(Math.PI)),
+            null, // 2nd slot
+            Integer.valueOf(0)
         };
 
-        // Expected types for locals in testLocals() & testLocalsKeepAlive()
-        // TODO: use real types
-        private final static String[] LOCAL_TYPES = new String[] {
-            null, // skip
-            "I",
-            "I",
-            "java.lang.String",
-            "I",
-            "I",
-            "I",
-            "I",
-            "I"
-        };
+        private final static List<String> TEST_METHODS =
+                List.of("testLocalsUnused",
+                        "testLocalsKeepAlive",
+                        "testLocalsKeepAliveArgs");
+    }
+
+    /* Simpler tests of long & double arguments */
+
+    @Test
+    public static void testUsedLongArg() throws Exception {
+        usedLong(LOWER_LONG_VAL);
+        usedLong(UPPER_LONG_VAL);
+        usedLong(NEG_LONG_VAL);
+    }
+
+    private static void usedLong(long longArg) throws Exception {
+        StackFrame[] frames = extendedWalker.walk(s ->
+            s.filter(f -> "usedLong".equals(f.getMethodName()))
+             .toArray(StackFrame[]::new)
+        );
+        try {
+            dumpFramesIfDebug(frames);
+
+            Object[] locals = (Object[]) getLocals.invoke(frames[0]);
+            assertLongIsInSlots(locals[0], locals[1], longArg);
+            System.out.println("Stayin' alive: " + longArg);
+        } catch (Exception t) {
+            dumpFramesIfNotDebug(frames);
+            throw t;
+        }
+    }
+
+    @Test
+    public static void testUnusedLongArg() throws Exception {
+        if (testUnused) {
+            unusedLong(NEG_LONG_VAL);
+        }
+    }
 
-        final static Map NUM_LOCALS = Map.of("testLocals", 8,
-                                             "testLocalsKeepAlive",
-                                             LOCAL_VALUES.length);
-        private final static Collection<String> TEST_METHODS = NUM_LOCALS.keySet();
+    private static void unusedLong(long longArg) throws Exception {
+        StackFrame[] frames = extendedWalker.walk(s ->
+            s.filter(f -> "unusedLong".equals(f.getMethodName()))
+             .toArray(StackFrame[]::new)
+        );
+        try {
+            dumpFramesIfDebug(frames);
+
+            final Object[] locals = (Object[]) getLocals.invoke(frames[0]);
+            assertLongIsInSlots(locals[0], locals[1], NEG_LONG_VAL);
+        } catch (Exception t) {
+            dumpFramesIfNotDebug(frames);
+            throw t;
+        }
+    }
+
+    @Test
+    public static void testUsedDoubleArg() throws Exception {
+        usedDouble(LOWER_DOUBLE_VAL);
+        usedDouble(UPPER_DOUBLE_VAL);
     }
 
+    private static void usedDouble(double doubleArg) throws Exception {
+        StackFrame[] frames = extendedWalker.walk(s ->
+            s.filter(f -> "usedDouble".equals(f.getMethodName()))
+             .toArray(StackFrame[]::new)
+        );
+        try {
+            dumpFramesIfDebug(frames);
+
+            Object[] locals = (Object[]) getLocals.invoke(frames[0]);
+            assertDoubleIsInSlots(locals[0], locals[1], doubleArg);
+            System.out.println("Stayin' alive: " + doubleArg);
+        } catch (Exception t) {
+            dumpFramesIfNotDebug(frames);
+            throw t;
+        }
+    }
+
+    /*******************
+     * Utility Methods *
+     *******************/
+
     /**
      * Print stack trace with locals
      */
     public static void dumpStackWithLocals(StackFrame...frames) {
-        Arrays.stream(frames).forEach(LocalsAndOperands::printLocals);
+        Stream.of(frames).forEach(LocalsAndOperands::printLocals);
+    }
+
+    public static void dumpFramesIfDebug(StackFrame...frames) {
+        if (debug) { dumpStackWithLocals(frames); }
+    }
+
+    public static void dumpFramesIfNotDebug(StackFrame...frames) {
+        if (!debug) { dumpStackWithLocals(frames); }
     }
 
     /**
@@ -329,10 +416,21 @@
      */
     public static void printLocals(StackWalker.StackFrame frame) {
         try {
-            System.out.println(frame);
+            System.out.println("Locals for: " + frame);
             Object[] locals = (Object[]) getLocals.invoke(frame);
             for (int i = 0; i < locals.length; i++) {
-                System.out.format("  local %d: %s type %s\n", i, locals[i], type(locals[i]));
+                String localStr = null;
+
+                if (primitiveSlot64Class.isInstance(locals[i])) {
+                    localStr = String.format("0x%X",
+                            (Long)primitiveLongValue.invoke(locals[i]));
+                } else if (primitiveSlot32Class.isInstance(locals[i])) {
+                    localStr = String.format("0x%X",
+                            (Integer)primitiveIntValue.invoke(locals[i]));
+                } else if (locals[i] != null) {
+                    localStr = locals[i].toString();
+                }
+                System.out.format("  local %d: %s type %s\n", i, localStr, type(locals[i]));
             }
 
             Object[] operands = (Object[]) getOperands.invoke(frame);
@@ -352,12 +450,87 @@
         try {
             if (o == null) {
                 return "null";
-            } else if (primitiveValueClass.isInstance(o)) {
-                char c = (char)primitiveType.invoke(o);
-                return String.valueOf(c);
+            } else if (primitiveSlotClass.isInstance(o)) {
+                int s = (int)primitiveSize.invoke(o);
+                return s + "-byte primitive";
             } else {
                 return o.getClass().getName();
             }
         } catch(Exception e) { throw new RuntimeException(e); }
     }
+
+    /*
+     * Check if the PrimitiveValue "primVal" contains the specified value,
+     * either a Long or an Integer.
+     */
+    static boolean primitiveValueEquals(Object primVal, Object expectedVal) {
+        try {
+            if (expectedVal instanceof Long) {
+                assertFalse(is32bit);
+                assertTrue(primitiveSlot64Class.isInstance(primVal));
+                assertTrue(8 == (int)primitiveSize.invoke(primVal));
+                return Objects.equals(primitiveLongValue.invoke(primVal), expectedVal);
+            } else if (expectedVal instanceof Integer) {
+                int expectedInt = (Integer)expectedVal;
+                if (is32bit) {
+                    assertTrue(primitiveSlot32Class.isInstance(primVal),
+                            "expected a PrimitiveSlot32 on 32-bit VM");
+                    assertTrue(4 == (int)primitiveSize.invoke(primVal));
+                    return expectedInt == (int)primitiveIntValue.invoke(primVal);
+                } else {
+                    assertTrue(primitiveSlot64Class.isInstance(primVal),
+                            "expected a PrimitiveSlot64 on 64-bit VM");
+                    assertTrue(8 == (int)primitiveSize.invoke(primVal));
+                    // Look for int expectedVal in high- or low-order 32 bits
+                    long primValLong = (long)primitiveLongValue.invoke(primVal);
+                    return (int)(primValLong & 0x00000000FFFFFFFFL) == expectedInt ||
+                           (int)(primValLong >>> 32) == expectedInt;
+                }
+            } else {
+                throw new RuntimeException("Called with non-Integer/Long: " + expectedVal);
+            }
+        } catch (IllegalAccessException|InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    /*
+     * Assert that the expected 2-slot long value is stored somewhere in the
+     * pair of slots.
+     * Throw exception if long value isn't in the two slots given.
+     * Accounts for 32 vs 64 bit, but is lax on endianness (accepts either)
+     */
+    static void assertLongIsInSlots(Object primVal0, Object primVal1, long expected) {
+        try {
+            if (is32bit) {
+                int upper = (int)(expected & 0xFFFFFFFFL);
+                int lower = (int)(expected >> 32);
+
+                if (!((primitiveValueEquals(primVal0, upper) &&
+                       primitiveValueEquals(primVal1, lower)) ||
+                      (primitiveValueEquals(primVal0, lower) &&
+                       primitiveValueEquals(primVal1, upper)))) {
+                    throw new RuntimeException(String.format("0x%X and 0x%X of 0x%016X not found in 0x%X and 0x%X",
+                            upper, lower, expected,
+                            (int)primitiveIntValue.invoke(primVal0),
+                            (int)primitiveIntValue.invoke(primVal1)));
+                }
+            } else {
+                if (!(primitiveValueEquals(primVal0, expected) ||
+                      primitiveValueEquals(primVal1, expected))) {
+                    throw new RuntimeException(String.format("0x%016X not found in 0x%016X or 0x%016X",
+                            expected,
+                            (long)primitiveLongValue.invoke(primVal0),
+                            (long)primitiveLongValue.invoke(primVal1)));
+                }
+            }
+        } catch (IllegalAccessException|InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static void assertDoubleIsInSlots(Object primVal0, Object primVal1, double expected) {
+        assertLongIsInSlots(primVal0, primVal1, Double.doubleToRawLongBits(expected));
+    }
 }
--- a/jdk/test/java/lang/StackWalker/LocalsCrash.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * 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 8147039
- * @summary Test for -Xcomp crash that happened before 8147039 fix
- * @modules java.base/java.lang:open
- * @run testng/othervm -Xcomp LocalsCrash
- */
-
-import org.testng.annotations.*;
-import java.lang.reflect.*;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class LocalsCrash {
-    static Class<?> liveStackFrameClass;
-    static Method getStackWalker;
-
-    static {
-        try {
-            liveStackFrameClass = Class.forName("java.lang.LiveStackFrame");
-            getStackWalker = liveStackFrameClass.getMethod("getStackWalker");
-            getStackWalker.setAccessible(true);
-        } catch (Throwable t) { throw new RuntimeException(t); }
-    }
-
-    private StackWalker walker;
-
-    LocalsCrash() {
-        try {
-            walker = (StackWalker) getStackWalker.invoke(null);
-        } catch (Exception e) { throw new RuntimeException(e); }
-    }
-
-    @Test
-    public void test00() { doStackWalk(); }
-
-    @Test
-    public void test01() { doStackWalk(); }
-
-    private synchronized List<StackWalker.StackFrame> doStackWalk() {
-        try {
-            // Unused local variables will become dead
-            int x = 10;
-            char c = 'z';
-            String hi = "himom";
-            long l = 1000000L;
-            double d =  3.1415926;
-
-            return walker.walk(s -> s.collect(Collectors.toList()));
-        } catch (Exception e) { throw new RuntimeException(e); }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/ReflectionFrames.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,842 @@
+/*
+ * Copyright (c) 2017, 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 8173898
+ * @summary Basic test for checking filtering of reflection frames
+ * @run testng ReflectionFrames
+ */
+
+import java.lang.StackWalker.StackFrame;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static java.lang.StackWalker.Option.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class ReflectionFrames {
+    final static boolean verbose = false;
+
+    /**
+     * This test invokes new StackInspector() directly from
+     * the caller StackInspector.Caller.create method.
+     * It checks that the caller is StackInspector.Caller.
+     * It also checks the expected frames collected
+     * by walking the stack from the default StackInspector()
+     * constructor.
+     * This is done twice, once using a default StackWalker
+     * that hides reflection frames, once using a StackWalker
+     * configured to show reflection frames.
+     */
+    @Test
+    public static void testNewStackInspector() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes new StackInspector() directly.
+        // No reflection frame should appear.
+        System.out.println("testNewStackInspector: create");
+
+        StackInspector obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes new StackInspector() directly.
+        // No reflection frame should appear.
+        System.out.println("testNewStackInspector: reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // a MethodHandle.
+        // The create method invokes new StackInspector() directly.
+        // No reflection frame should appear.
+        System.out.println("testNewStackInspector: handle");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes new StackInspector() directly.
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewStackInspector: create: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes new StackInspector() directly.
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewStackInspector: reflect: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // MethodHandle.
+        // The create method invokes new StackInspector() directly.
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewStackInspector: handle: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.NEW));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             // MethodHandle::invoke remains hidden
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewStackInspector"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+    }
+
+   /**
+     * This test invokes Constructor.newInstance() from
+     * the caller StackInspector.Caller.create method.
+     * It checks that the caller is StackInspector.Caller.
+     * It also checks the expected frames collected
+     * by walking the stack from the default StackInspector()
+     * constructor.
+     * This is done twice, once using a default StackWalker
+     * that hides reflection frames, once using a StackWalker
+     * configured to show reflection frames.
+     */
+    @Test
+    public static void testConstructor() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes Constructor.newInstance().
+        // No reflection frame should appear.
+        System.out.println("testConstructor: create");
+
+        StackInspector obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes Constructor.newInstance().
+        // No reflection frame should appear.
+        System.out.println("testConstructor: reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // MethodHandle.
+        // The create method invokes Constructor.newInstance().
+        // No reflection frame should appear.
+        System.out.println("testConstructor: handle");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertEquals(obj.filtered, 0);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes Constructor.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testConstructor: create: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes Constructor.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testConstructor: reflect: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // MethodHandle.
+        // The create method invokes Constructor.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testConstructor: handle: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.CONSTRUCTOR));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             // MethodHandle::invoke remains hidden
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testConstructor"));
+        assertEquals(obj.cls, StackInspector.Caller.class);
+        assertNotEquals(obj.filtered, 0);
+    }
+
+   /**
+     * This test invokes StackInspector.class.newInstance() from
+     * the caller StackInspector.Caller.create method. Because
+     * Class.newInstance() is not considered as a
+     * reflection frame, the the caller returned by
+     * getCallerClass() should appear to be java.lang.Class
+     * and not StackInspector.Caller.
+     * It also checks the expected frames collected
+     * by walking the stack from the default StackInspector()
+     * constructor.
+     * This is done twice, once using a default StackWalker
+     * that hides reflection frames, once using a StackWalker
+     * configured to show reflection frames.
+     */
+    @Test
+    public static void testNewInstance() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes StackInspector.class.newInstance().
+        // No reflection frame should appear, except
+        // Class::newInstance which is not considered as
+        // a reflection frame.
+        System.out.println("testNewInstance: create");
+
+        StackInspector obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes StackInspector.class.newInstance().
+        // No reflection frame should appear, except
+        // Class::newInstance which is not considered as
+        // a reflection frame.
+        System.out.println("testNewInstance: reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // reflection.
+        // The create method invokes StackInspector.class.newInstance().
+        // No reflection frame should appear, except
+        // Class::newInstance which is not considered as
+        // a reflection frame.
+        System.out.println("testNewInstance: handle");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertEquals(obj.filtered, 0);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        // Calls the StackInspector.create method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The create method invokes StackInspector.class.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewInstance: create: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("create", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.reflect method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The reflect method invokes the create method through
+        // reflection.
+        // The create method invokes StackInspector.class.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewInstance: reflect: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("reflect", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             Method.class.getName()
+                                 +"::invoke",
+                             StackInspector.Caller.class.getName()
+                                 +"::reflect",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertNotEquals(obj.filtered, 0);
+
+        // Calls the StackInspector.handle method through reflection
+        // and check the frames collected in the StackInspector
+        // default constructor.
+        // The handle method invokes the create method using
+        // MethodHandle.
+        // The create method invokes StackInspector.class.newInstance().
+        // We should see all reflection frames, except the
+        // jdk.internal.reflect frames which we are filtering
+        // out in StackInspector::filter.
+        System.out.println("testNewInstance: handle: show reflect");
+
+        obj = ((StackInspector)StackInspector.Caller.class
+                             .getMethod("handle", How.class)
+                             .invoke(null, How.CLASS));
+        assertEquals(obj.collectedFrames,
+                     List.of(StackInspector.class.getName()
+                                 +"::<init>",
+                             Constructor.class.getName()
+                                 +"::newInstance",
+                             Class.class.getName()
+                                 +"::newInstance",
+                             StackInspector.Caller.class.getName()
+                                 +"::create",
+                             // MethodHandle::invoke remains hidden
+                             StackInspector.Caller.class.getName()
+                                 +"::handle",
+                             Method.class.getName()
+                                 +"::invoke",
+                             ReflectionFrames.class.getName()
+                                 +"::testNewInstance"));
+
+        // Because Class.newInstance is not filtered, then the
+        // caller is Class.class
+        assertEquals(obj.cls, Class.class);
+        assertNotEquals(obj.filtered, 0);
+    }
+
+    @Test
+    public static void testGetCaller() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        assertEquals(StackInspector.getCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),
+                     ReflectionFrames.class);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        assertEquals(StackInspector.getCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),
+                     ReflectionFrames.class);
+    }
+
+    @Test
+    public static void testReflectCaller() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),
+                     ReflectionFrames.class);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),
+                     ReflectionFrames.class);
+    }
+
+    @Test
+    public static void testSupplyCaller() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),
+                     ReflectionFrames.class);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),
+                     ReflectionFrames.class);
+    }
+
+    @Test
+    public static void testHandleCaller() throws Exception {
+        // Sets the default walker which hides reflection
+        // frames.
+        StackInspector.walker.set(StackInspector.walkerHide);
+
+        assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),
+                     ReflectionFrames.class);
+
+        // Sets a non-default walker configured to show
+        // reflection frames
+        StackInspector.walker.set(StackInspector.walkerShow);
+
+        assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);
+        assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),
+                     ReflectionFrames.class);
+    }
+
+    static enum How { NEW, CONSTRUCTOR, CLASS};
+
+    /**
+     * An object that collect stack frames by walking the stack
+     * (and calling getCallerClass()) from within its constructor.
+     * For the purpose of this test, StackInspector objects are
+     * always created from the nested StackInspector.Caller class,
+     * which should therefore appear as the caller of the
+     * StackInspector constructor.
+     */
+    static class StackInspector {
+        static final StackWalker walkerHide =
+            StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+        static final StackWalker walkerShow =
+            StackWalker.getInstance(EnumSet.of(
+                           StackWalker.Option.RETAIN_CLASS_REFERENCE,
+                           StackWalker.Option.SHOW_REFLECT_FRAMES));
+        final static ThreadLocal<StackWalker> walker = new ThreadLocal<>() {
+             protected StackWalker initialValue() {
+                 return walkerHide;
+             }
+        };
+
+        List<String> collectedFrames;
+        Class<?> cls = null;
+        boolean stop;
+        int filtered;
+        final boolean filterImplFrames;
+
+        public StackInspector() {
+            stop = false;
+            // if reflection frames are not hidden, we want to
+            // filter implementation frames before collecting
+            // to avoid depending on internal details.
+            filterImplFrames = walker.get() == walkerShow;
+            collectedFrames = walker.get().walk(this::parse);
+            cls = walker.get().getCallerClass();
+        }
+
+        public List<String> collectedFrames() {
+            return collectedFrames;
+        }
+
+        // The takeWhile method arrange for stopping frame collection
+        // as soon as a frame from ReflectionFrames.class is reached.
+        // The first such frame encountered is still included in the
+        // collected frames, but collection stops right after.
+        // This makes it possible to filter out anything above the
+        // the test method frame, such as frames from the test
+        // framework.
+        public boolean takeWhile(StackFrame f) {
+            if (stop) return false;
+            if (verbose) System.out.println("    " + f);
+            stop = stop || f.getDeclaringClass() == ReflectionFrames.class;
+            return true;
+        }
+
+        // filter out implementation frames to avoid depending
+        // on implementation details. If present, Class::newInstance,
+        // Method::invoke and Constructor::newInstance will
+        // still appear in the collected frames, which is
+        // sufficient for the purpose of the test.
+        // In the case where the StackWalker itself is supposed to
+        // filter the reflection frames, then this filter will always
+        // return true. This way, if such a reflection frame appears when
+        // it sjould have been filtered by StackWalker, it will make the
+        // test fail.
+        public boolean filter(StackFrame f) {
+            if (filterImplFrames &&
+                f.getClassName().startsWith("jdk.internal.reflect.")) {
+                filtered++;
+                return false;
+            }
+            if (!verbose) System.out.println("    " + f);
+            return true;
+        }
+
+        public String frame(StackFrame f) {
+            return f.getClassName() + "::" + f.getMethodName();
+        }
+
+        List<String> parse(Stream<StackFrame> s) {
+            return s.takeWhile(this::takeWhile)
+                    .filter(this::filter)
+                    .map(this::frame)
+                    .collect(Collectors.toList());
+        }
+
+        /**
+         * The Caller class is used to create instances of
+         * StackInspector, either direcltly, or throug reflection.
+         */
+        public static class Caller {
+            public static StackInspector create(How how) throws Exception {
+                switch(how) {
+                    case NEW: return new StackInspector();
+                    case CONSTRUCTOR: return StackInspector.class
+                        .getConstructor().newInstance();
+                    case CLASS: return StackInspector.class.newInstance();
+                    default: throw new AssertionError(String.valueOf(how));
+                }
+            }
+            public static StackInspector reflect(How how) throws Exception {
+                return (StackInspector) Caller.class.getMethod("create", How.class)
+                      .invoke(null, how);
+            }
+            public static StackInspector handle(How how) throws Exception {
+                Lookup lookup = MethodHandles.lookup();
+                MethodHandle mh = lookup.findStatic(Caller.class, "create",
+                        MethodType.methodType(StackInspector.class, How.class));
+                try {
+                    return (StackInspector) mh.invoke(how);
+                } catch (Error | Exception x) {
+                    throw x;
+                } catch(Throwable t) {
+                    throw new AssertionError(t);
+                }
+            }
+        }
+
+        public static Class<?> getCaller() throws Exception {
+            return walker.get().getCallerClass();
+        }
+
+        public static Class<?> reflectCaller() throws Exception {
+            return (Class<?>)StackWalker.class.getMethod("getCallerClass")
+                .invoke(walker.get());
+        }
+
+        public static Class<?> supplyCaller() throws Exception {
+            return ((Supplier<Class<?>>)StackInspector.walker.get()::getCallerClass).get();
+        }
+
+        public static Class<?> handleCaller() throws Exception {
+            Lookup lookup = MethodHandles.lookup();
+            MethodHandle mh = lookup.findVirtual(StackWalker.class, "getCallerClass",
+                    MethodType.methodType(Class.class));
+            try {
+                return (Class<?>) mh.invoke(walker.get());
+            } catch (Error | Exception x) {
+                throw x;
+            } catch(Throwable t) {
+                throw new AssertionError(t);
+            }
+        }
+    }
+}
--- a/jdk/test/java/lang/invoke/AccessControlTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/invoke/AccessControlTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -118,6 +118,8 @@
                 suffix = "/noaccess";
             else if (lookupModes == PUBLIC)
                 suffix = "/public";
+             else if (lookupModes == (PUBLIC|UNCONDITIONAL))
+                suffix = "/publicLookup";
             else if (lookupModes == (PUBLIC|MODULE))
                 suffix = "/module";
             else if (lookupModes == (PUBLIC|MODULE|PACKAGE))
@@ -140,23 +142,24 @@
          * [A2] However, the resulting {@code Lookup} object is guaranteed
          * to have no more access capabilities than the original.
          * In particular, access capabilities can be lost as follows:<ul>
-         * <li>[A3] If the new lookup class differs from the old one,
-         * protected members will not be accessible by virtue of inheritance.
+         * <li> [A3] If the old lookup class is in a named module, and the new
+         * lookup class is in a different module {@code M}, then no members, not
+         * even public members in {@code M}'s exported packages, will be accessible.
+         * The exception to this is when this lookup is publicLookup, in which case
+         * public access is not lost.
+         * <li> [A4] If the old lookup class is in an unnamed module, and the new
+         * lookup class is a different module then module access is lost.
+         * <li> [A5] If the new lookup class differs from the old one then UNCONDITIONAL
+         * is lost. If the new lookup class is not within the same package member as the
+         * old one, protected members will not be accessible by virtue of inheritance.
          * (Protected members may continue to be accessible because of package sharing.)
-         * <li>[A4] If the new lookup class is in a different package
-         * than the old one, protected and default (package) members will not be accessible.
-         * <li>[A5] If the new lookup class is not within the same package member
+         * <li> [A6] If the new lookup class is in a different package than the old one,
+         * protected and default (package) members will not be accessible.
+         * <li> [A7] If the new lookup class is not within the same package member
          * as the old one, private members will not be accessible.
-         * <li>[A6] If the new lookup class is not accessible to the old lookup class,
-         * using the original access modes,
+         * <li> [A8] If the new lookup class is not accessible to the old lookup class,
          * then no members, not even public members, will be accessible.
-         * <li>[A7] If the new lookup class for this {@code Lookup} is in the unnamed module,
-         * and the new lookup class is in a named module {@code M}, then no members in
-         * {@code M}'s non-exported packages will be accessible.
-         * <li>[A8] If the lookup for this {@code Lookup} is in a named module, and the
-         * new lookup class is in a different module, then no members, not even
-         * public members in {@code M}'s exported packages, will be accessible.
-         * [A8] (In all other cases, public members will continue to be accessible.)
+         * <li> [A9] (In all other cases, public members will continue to be accessible.)
          * </ul>
          * Other than the above cases, the new lookup will have the same
          * access capabilities as the original. [A10]
@@ -171,36 +174,35 @@
             boolean sameModule = (c1.getModule() == c2.getModule()) ||
                                  (!c1.getModule().isNamed() && !c2.getModule().isNamed());
             boolean samePackage = (c1.getClassLoader() == c2.getClassLoader() &&
-                                   packagePrefix(c1).equals(packagePrefix(c2)));
+                                   c1.getPackageName().equals(c2.getPackageName()));
             boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2));
             boolean sameClass = (c1 == c2);
             assert(samePackage  || !sameTopLevel);
             assert(sameTopLevel || !sameClass);
-            boolean accessible = sameClass;  // [A6]
+            boolean accessible = sameClass;
             if ((m1 & PACKAGE) != 0)  accessible |= samePackage;
             if ((m1 & PUBLIC ) != 0)  accessible |= (c2.getModifiers() & PUBLIC) != 0;
             if (!sameModule) {
-                if (c1.getModule().isNamed()) {
-                    accessible = false;  // [A8]
+                if (c1.getModule().isNamed() && (m1 & UNCONDITIONAL) == 0) {
+                    accessible = false;  // [A3]
                 } else {
-                    // Different module; loose MODULE and lower access.
-                    changed |= (MODULE|PACKAGE|PRIVATE|PROTECTED);  // [A7]
+                    changed |= (MODULE|PACKAGE|PRIVATE|PROTECTED);    // [A3] [A4]
                 }
             }
             if (!accessible) {
                 // Different package and no access to c2; lose all access.
-                changed |= (PUBLIC|MODULE|PACKAGE|PRIVATE|PROTECTED);  // [A6]
+                changed |= (PUBLIC|MODULE|PACKAGE|PRIVATE|PROTECTED);  // [A8]
             }
             if (!samePackage) {
                 // Different package; loose PACKAGE and lower access.
-                changed |= (PACKAGE|PRIVATE|PROTECTED);  // [A4]
+                changed |= (PACKAGE|PRIVATE|PROTECTED);  // [A6]
             }
             if (!sameTopLevel) {
-                // Different top-level class.  Lose PRIVATE and lower access.
-                changed |= (PRIVATE|PROTECTED);  // [A5]
+                // Different top-level class.  Lose PRIVATE and PROTECTED access.
+                changed |= (PRIVATE|PROTECTED);  // [A5] [A7]
             }
             if (!sameClass) {
-                changed |= (PROTECTED);     // [A3]
+                changed |= (UNCONDITIONAL);     // [A5]
             } else {
                 assert(changed == 0);       // [A10] (no deprivation if same class)
             }
@@ -228,11 +230,10 @@
             Class<?> c1 = lookupClass();
             Class<?> c2 = m.getDeclaringClass();
 
-            // if the lookup class is in a loose module with PUBLIC access then
-            // public members of public types in all unnamed modules can be accessed
-            if (isLooseModule(c1.getModule())
+            // publicLookup has access to all public types/members of types in unnamed modules
+            if ((lookupModes & UNCONDITIONAL) != 0
                 && (lookupModes & PUBLIC) != 0
-                && (!c2.getModule().isNamed())
+                && !c2.getModule().isNamed()
                 && Modifier.isPublic(c2.getModifiers())
                 && Modifier.isPublic(m.getModifiers()))
                 return true;
@@ -261,17 +262,12 @@
             if (load && c2.getClassLoader() != null) {
                 if (c1.getClassLoader() == null) {
                     // not visible
-                return false;
-            }
-                if (c1 == publicLookup().lookupClass()) {
-                    // not visible as lookup class is defined by child of the boot loader
                     return false;
                 }
             }
 
-            // if the lookup class is in a loose module with PUBLIC access then
-            // public types in all unnamed modules can be accessed
-            if (isLooseModule(c1.getModule())
+            // publicLookup has access to all public types/members of types in unnamed modules
+            if ((lookupModes & UNCONDITIONAL) != 0
                 && (lookupModes & PUBLIC) != 0
                 && (!c2.getModule().isNamed())
                 && Modifier.isPublic(c2.getModifiers()))
@@ -295,11 +291,6 @@
             }
             return r;
         }
-
-        private boolean isLooseModule(Module m) {
-            ClassLoader cl = new ClassLoader() { };
-            return m.canRead(cl.getUnnamedModule());
-        }
     }
 
     private static Class<?> topLevelClass(Class<?> cls) {
@@ -311,14 +302,6 @@
         return c;
     }
 
-    private static String packagePrefix(Class<?> c) {
-        while (c.isArray())  c = c.getComponentType();
-        String s = c.getName();
-        assert(s.indexOf('/') < 0);
-        return s.substring(0, s.lastIndexOf('.')+1);
-    }
-
-
     private final TreeSet<LookupCase> CASES = new TreeSet<>();
     private final TreeMap<LookupCase,TreeSet<LookupCase>> CASE_EDGES = new TreeMap<>();
     private final ArrayList<ClassLoader> LOADERS = new ArrayList<>();
--- a/jdk/test/java/lang/invoke/DropLookupModeTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/invoke/DropLookupModeTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -65,6 +65,10 @@
         lookup = fullPowerLookup.dropLookupMode(PUBLIC);
         assertTrue(lookup.lookupClass() == lc);
         assertTrue(lookup.lookupModes() == 0);
+
+        lookup = fullPowerLookup.dropLookupMode(UNCONDITIONAL);
+        assertTrue(lookup.lookupClass() == lc);
+        assertTrue(lookup.lookupModes() == (PUBLIC|MODULE|PACKAGE|PRIVATE));
     }
 
     /**
@@ -108,7 +112,7 @@
     public void testPublicLookup() {
         final Lookup publicLookup = MethodHandles.publicLookup();
         final Class<?> lc = publicLookup.lookupClass();
-        assertTrue(publicLookup.lookupModes() == PUBLIC);
+        assertTrue(publicLookup.lookupModes() == (PUBLIC|UNCONDITIONAL));
 
         Lookup lookup = publicLookup.dropLookupMode(PRIVATE);
         assertTrue(lookup.lookupClass() == lc);
@@ -129,6 +133,10 @@
         lookup = publicLookup.dropLookupMode(PUBLIC);
         assertTrue(lookup.lookupClass() == lc);
         assertTrue(lookup.lookupModes() == 0);
+
+        lookup = publicLookup.dropLookupMode(UNCONDITIONAL);
+        assertTrue(lookup.lookupClass() == lc);
+        assertTrue(lookup.lookupModes() == PUBLIC);
     }
 
     @DataProvider(name = "badInput")
--- a/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/Driver.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/Driver.java	Fri Feb 10 08:57:42 2017 -0800
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @build test/* m1/* m2/* m3/*
+ * @build test/* m1/* m2/* m3/* Unnamed
  * @run testng/othervm test/p.PrivateLookupInTests
  * @summary Unit tests for MethodHandles.privateLookupIn
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/Unnamed.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+public class Unnamed { }
--- a/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/test/p/PrivateLookupInTests.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/test/p/PrivateLookupInTests.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -126,6 +126,26 @@
         Object obj = mh.invokeExact();
     }
 
+    // test target class in unnamed module
+    public void testTargetClassInUnnamedModule() throws Throwable {
+        Class<?> clazz = Class.forName("Unnamed");
+        assertFalse(clazz.getModule().isNamed());
+
+        // thisModule does not read the unnamed module
+        Module thisModule = getClass().getModule();
+        assertFalse(thisModule.canRead(clazz.getModule()));
+        try {
+            MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        // thisModule reads the unnamed module
+        thisModule.addReads(clazz.getModule());
+        Lookup lookup = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+        assertTrue(lookup.lookupClass() == clazz);
+        assertTrue(lookup.hasPrivateAccess());
+    }
+
     // test does not read m2, m2 opens p2 to test
     @Test(expectedExceptions = {IllegalAccessException.class})
     public void testCallerDoesNotRead() throws Throwable {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/MetafactoryDescriptorTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2017, 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 8035776 8173587
+ * @summary metafactory should fail if instantiatedMethodType does not match sam/bridge descriptors
+ */
+import java.lang.invoke.*;
+import java.util.*;
+
+public class MetafactoryDescriptorTest {
+
+    static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+    static MethodType mt(Class<?> ret, Class<?>... params) {
+        return MethodType.methodType(ret, params);
+    }
+
+    public interface I {}
+
+    public static class C {
+        public static void m_void(String arg) {}
+        public static boolean m_boolean(String arg) { return true; }
+        public static char m_char(String arg) { return 'x'; }
+        public static byte m_byte(String arg) { return 12; }
+        public static short m_short(String arg) { return 12; }
+        public static int m_int(String arg) { return 12; }
+        public static long m_long(String arg) { return 12; }
+        public static float m_float(String arg) { return 12; }
+        public static double m_double(String arg) { return 12; }
+        public static String m_String(String arg) { return ""; }
+        public static Integer m_Integer(String arg) { return 23; }
+        public static Object m_Object(String arg) { return new Object(); }
+
+        public static String n_boolean(boolean arg) { return ""; }
+        public static String n_char(char arg) { return ""; }
+        public static String n_byte(byte arg) { return ""; }
+        public static String n_short(short arg) { return ""; }
+        public static String n_int(int arg) { return ""; }
+        public static String n_long(long arg) { return ""; }
+        public static String n_float(float arg) { return ""; }
+        public static String n_double(double arg) { return ""; }
+        public static String n_String(String arg) { return ""; }
+        public static String n_Integer(Integer arg) { return ""; }
+        public static String n_Object(Object arg) { return ""; }
+
+        public static MethodHandle getM(Class<?> c) {
+            try {
+                return lookup.findStatic(C.class, "m_" + c.getSimpleName(), mt(c, String.class));
+            }
+            catch (NoSuchMethodException | IllegalAccessException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public static MethodHandle getN(Class<?> c) {
+            if (c == void.class) return null;
+            try {
+                return lookup.findStatic(C.class, "n_" + c.getSimpleName(), mt(String.class, c));
+            }
+            catch (NoSuchMethodException | IllegalAccessException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+    }
+
+    public static void main(String... args) {
+        Class<?>[] t = { void.class, boolean.class, char.class,
+                         byte.class, short.class, int.class, long.class, float.class, double.class,
+                         String.class, Integer.class, Object.class };
+
+        for (int i = 0; i < t.length; i++) {
+            MethodHandle m = C.getM(t[i]);
+            MethodHandle n = C.getN(t[i]); // null for void.class
+            for (int j = 0; j < t.length; j++) {
+                boolean correctRet = t[j].isAssignableFrom(t[i]) || conversions.contains(t[i], t[j]);
+                test(correctRet, m, mt(t[i], String.class), mt(t[j], String.class));
+                testBridge(correctRet, m, mt(t[i], String.class), mt(t[i], String.class),
+                           mt(t[j], Object.class));
+                testBridge(correctRet, m, mt(t[i], String.class), mt(t[i], String.class),
+                           mt(t[i], CharSequence.class), mt(t[j], Object.class));
+
+                if (t[i] != void.class && t[j] != void.class) {
+                    boolean correctParam = t[j].isAssignableFrom(t[i]);
+                    test(correctParam, n, mt(String.class, t[i]), mt(String.class, t[j]));
+                    testBridge(correctParam, n, mt(String.class, t[i]), mt(String.class, t[i]),
+                            mt(Object.class, t[j]));
+                    testBridge(correctParam, n, mt(String.class, t[i]), mt(String.class, t[i]),
+                            mt(CharSequence.class, t[i]), mt(Object.class, t[j]));
+                }
+
+            }
+        }
+    }
+
+    static void test(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
+        tryMetafactory(correct, mh, instMT, samMT);
+        tryAltMetafactory(correct, mh, instMT, samMT);
+    }
+
+    static void testBridge(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
+        tryAltMetafactory(correct, mh, instMT, samMT, bridgeMTs);
+    }
+
+    static void tryMetafactory(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
+        try {
+            LambdaMetafactory.metafactory(lookup, "run", mt(I.class),
+                                          samMT, mh, instMT);
+            if (!correct) {
+                throw new AssertionError("Unexpected linkage without error:" +
+                                         " impl=" + mh +
+                                         ", inst=" + instMT +
+                                         ", sam=" + samMT);
+            }
+        }
+        catch (LambdaConversionException e) {
+            if (correct) {
+                throw new AssertionError("Unexpected linkage error:" +
+                                         " e=" + e +
+                                         ", impl=" + mh +
+                                         ", inst=" + instMT +
+                                         ", sam=" + samMT);
+            }
+        }
+    }
+
+    static void tryAltMetafactory(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT,
+                                  MethodType... bridgeMTs) {
+        boolean bridge = bridgeMTs.length > 0;
+        Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
+        args[0] = samMT;
+        args[1] = mh;
+        args[2] = instMT;
+        args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
+        if (bridge) {
+            args[4] = bridgeMTs.length;
+            for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
+        }
+        try {
+            LambdaMetafactory.altMetafactory(lookup, "run", mt(I.class), args);
+            if (!correct) {
+                throw new AssertionError("Unexpected linkage without error:" +
+                                         " impl=" + mh +
+                                         ", inst=" + instMT +
+                                         ", sam=" + samMT +
+                                         ", bridges=" + Arrays.toString(bridgeMTs));
+            }
+        }
+        catch (LambdaConversionException e) {
+            if (correct) {
+                throw new AssertionError("Unexpected linkage error:" +
+                                         " e=" + e +
+                                         ", impl=" + mh +
+                                         ", inst=" + instMT +
+                                         ", sam=" + samMT +
+                                         ", bridges=" + Arrays.toString(bridgeMTs));
+            }
+        }
+    }
+
+    private static class ConversionTable {
+        private final Map<Class<?>, Set<Class<?>>> pairs = new HashMap<>();
+
+        public void put(Class<?> from, Class<?> to) {
+            Set<Class<?>> set = pairs.computeIfAbsent(from, f -> new HashSet<>());
+            set.add(to);
+        }
+
+        public boolean contains(Class<?> from, Class<?> to) {
+            return pairs.containsKey(from) && pairs.get(from).contains(to);
+        }
+    }
+
+    private static ConversionTable conversions = new ConversionTable();
+    static {
+        conversions.put(char.class, int.class);
+        conversions.put(char.class, long.class);
+        conversions.put(char.class, float.class);
+        conversions.put(char.class, double.class);
+        conversions.put(char.class, Character.class);
+        conversions.put(char.class, Object.class);
+        conversions.put(Character.class, char.class);
+        conversions.put(Character.class, int.class);
+        conversions.put(Character.class, long.class);
+        conversions.put(Character.class, float.class);
+        conversions.put(Character.class, double.class);
+
+        conversions.put(byte.class, short.class);
+        conversions.put(byte.class, int.class);
+        conversions.put(byte.class, long.class);
+        conversions.put(byte.class, float.class);
+        conversions.put(byte.class, double.class);
+        conversions.put(byte.class, Byte.class);
+        conversions.put(byte.class, Object.class);
+        conversions.put(Byte.class, byte.class);
+        conversions.put(Byte.class, short.class);
+        conversions.put(Byte.class, int.class);
+        conversions.put(Byte.class, long.class);
+        conversions.put(Byte.class, float.class);
+        conversions.put(Byte.class, double.class);
+
+        conversions.put(short.class, int.class);
+        conversions.put(short.class, long.class);
+        conversions.put(short.class, float.class);
+        conversions.put(short.class, double.class);
+        conversions.put(short.class, Short.class);
+        conversions.put(short.class, Object.class);
+        conversions.put(Short.class, short.class);
+        conversions.put(Short.class, int.class);
+        conversions.put(Short.class, long.class);
+        conversions.put(Short.class, float.class);
+        conversions.put(Short.class, double.class);
+
+        conversions.put(int.class, long.class);
+        conversions.put(int.class, float.class);
+        conversions.put(int.class, double.class);
+        conversions.put(int.class, Integer.class);
+        conversions.put(int.class, Object.class);
+        conversions.put(Integer.class, int.class);
+        conversions.put(Integer.class, long.class);
+        conversions.put(Integer.class, float.class);
+        conversions.put(Integer.class, double.class);
+
+        conversions.put(long.class, float.class);
+        conversions.put(long.class, double.class);
+        conversions.put(long.class, Long.class);
+        conversions.put(long.class, Object.class);
+        conversions.put(Long.class, long.class);
+        conversions.put(Long.class, float.class);
+        conversions.put(Long.class, double.class);
+
+        conversions.put(float.class, double.class);
+        conversions.put(float.class, Float.class);
+        conversions.put(float.class, Object.class);
+        conversions.put(Float.class, float.class);
+        conversions.put(Float.class, double.class);
+
+        conversions.put(double.class, Double.class);
+        conversions.put(double.class, Object.class);
+        conversions.put(Double.class, double.class);
+
+        conversions.put(boolean.class, Boolean.class);
+        conversions.put(boolean.class, Object.class);
+        conversions.put(Boolean.class, boolean.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/MetafactoryMethodNameTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2017, 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 8173587
+ * @summary metafactory should fail if the method name is not legal
+ */
+import java.lang.invoke.*;
+import java.util.*;
+
+public class MetafactoryMethodNameTest {
+
+    public static void main(String... args) {
+        goodName("x");
+        goodName("xy");
+
+        goodName("]");
+        goodName("x]");
+        goodName("]y");
+        goodName("x]y");
+
+        goodName("&");
+        goodName("x&");
+        goodName("&y");
+        goodName("x&y");
+
+        badName(".");
+        badName("x.");
+        badName(".y");
+        badName("x.y");
+
+        badName(";");
+        badName("x;");
+        badName(";y");
+        badName("x;y");
+
+        badName("[");
+        badName("x[");
+        badName("[y");
+        badName("x[y");
+
+        badName("/");
+        badName("x/");
+        badName("/y");
+        badName("x/y");
+
+        badName("<");
+        badName("x<");
+        badName("<y");
+        badName("x<y");
+
+        badName(">");
+        badName("x>");
+        badName(">y");
+        badName("x>y");
+
+        badName("");
+        badName("<init>");
+        badName("<clinit>");
+    }
+
+    static MethodType mt(Class<?> ret, Class<?>... params) {
+        return MethodType.methodType(ret, params);
+    }
+
+    static MethodHandle smh(Class<?> c, String name, MethodType desc) {
+        try {
+            return MethodHandles.lookup().findStatic(c, name, desc);
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static Object[] arr(Object... args) {
+        return args;
+    }
+
+    public static class C {
+        public static void m() {}
+    }
+
+    public interface I {}
+
+    private static MethodHandles.Lookup lookup = MethodHandles.lookup();
+    private static MethodType toI = mt(I.class);
+    private static MethodType toVoid = mt(void.class);
+    private static MethodHandle mh = smh(C.class, "m", toVoid);
+    private static Class<?> lce = LambdaConversionException.class;
+
+    static void goodName(String name) {
+        succeedMFLinkage(lookup, name, toI, toVoid, mh, toVoid);
+        succeedAltMFLinkage(lookup, name, toI, arr(toVoid, mh, toVoid, LambdaMetafactory.FLAG_SERIALIZABLE));
+    }
+
+    static void badName(String name) {
+        failMFLinkage(lookup, name, toI, toVoid, mh, toVoid, lce);
+        failAltMFLinkage(lookup, name, toI, arr(toVoid, mh, toVoid, LambdaMetafactory.FLAG_SERIALIZABLE), lce);
+    }
+
+    static CallSite succeedMFLinkage(MethodHandles.Lookup lookup,
+                                    String name,
+                                    MethodType capType,
+                                    MethodType desc,
+                                    MethodHandle impl,
+                                    MethodType checked) {
+        try {
+            return LambdaMetafactory.metafactory(lookup, name, capType, desc, impl, checked);
+        } catch (Throwable t) {
+            String msg = String.format("Unexpected exception during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+                    lookup, name, capType, desc, impl, checked);
+            throw new AssertionError(msg, t);
+        }
+    }
+
+    static void failMFLinkage(MethodHandles.Lookup lookup,
+                              String name,
+                              MethodType capType,
+                              MethodType desc,
+                              MethodHandle impl,
+                              MethodType checked,
+                              Class<?> expectedExceptionType) {
+        try {
+            LambdaMetafactory.metafactory(lookup, name, capType, desc, impl, checked);
+        } catch (Throwable t) {
+            if (expectedExceptionType.isInstance(t)) {
+                return;
+            } else {
+                String msg = String.format("Unexpected exception: expected %s during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+                        expectedExceptionType.getName(),
+                        lookup, name, capType, desc, impl, checked);
+                throw new AssertionError(msg, t);
+            }
+        }
+        String msg = String.format("Unexpected success: expected %s during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+                expectedExceptionType.getName(),
+                lookup, name, capType, desc, impl, checked);
+        throw new AssertionError(msg);
+    }
+
+    static CallSite succeedAltMFLinkage(MethodHandles.Lookup lookup,
+                                        String name,
+                                        MethodType capType,
+                                        Object[] args) {
+        try {
+            return LambdaMetafactory.altMetafactory(lookup, name, capType, args);
+        } catch (Throwable t) {
+            String msg = String.format("Unexpected exception during linkage for metafactory(%s, %s, %s, %s)",
+                    lookup, name, capType, Arrays.asList(args));
+            throw new AssertionError(msg, t);
+        }
+    }
+
+    static void failAltMFLinkage(MethodHandles.Lookup lookup,
+                                 String name,
+                                 MethodType capType,
+                                 Object[] args,
+                                 Class<?> expectedExceptionType) {
+        try {
+            LambdaMetafactory.altMetafactory(lookup, name, capType, args);
+        } catch (Throwable t) {
+            if (expectedExceptionType.isInstance(t)) {
+                return;
+            } else {
+                String msg = String.format("Unexpected exception: expected %s during linkage for metafactory(%s, %s, %s, %s)",
+                        expectedExceptionType.getName(),
+                        lookup, name, capType, Arrays.asList(args));
+                throw new AssertionError(msg, t);
+            }
+        }
+        String msg = String.format("Unexpected success: expected %s during linkage for metafactory(%s, %s, %s, %s)",
+                expectedExceptionType.getName(),
+                lookup, name, capType, Arrays.asList(args));
+        throw new AssertionError(msg);
+    }
+
+}
--- a/jdk/test/java/lang/invoke/lambda/MetafactorySamReturnTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8035776
- * @summary metafactory should fail if impl return does not match sam/bridge returns
- */
-import java.lang.invoke.*;
-import java.util.Arrays;
-import static java.lang.invoke.MethodType.methodType;
-
-public class MetafactorySamReturnTest {
-
-    static final MethodHandles.Lookup lookup = MethodHandles.lookup();
-
-    public interface I {}
-
-    public static class C {
-        public static void m_void(String arg) {}
-        public static boolean m_boolean(String arg) { return true; }
-        public static char m_char(String arg) { return 'x'; }
-        public static byte m_byte(String arg) { return 12; }
-        public static short m_short(String arg) { return 12; }
-        public static int m_int(String arg) { return 12; }
-        public static long m_long(String arg) { return 12; }
-        public static float m_float(String arg) { return 12; }
-        public static double m_double(String arg) { return 12; }
-        public static String m_String(String arg) { return ""; }
-        public static Integer m_Integer(String arg) { return 23; }
-        public static Object m_Object(String arg) { return new Object(); }
-
-        public static MethodHandle getMH(Class<?> c) {
-            try {
-                return lookup.findStatic(C.class, "m_" + c.getSimpleName(), methodType(c, String.class));
-            }
-            catch (NoSuchMethodException | IllegalAccessException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-
-    public static void main(String... args) {
-        Class<?>[] t = { void.class, boolean.class, char.class,
-                         byte.class, short.class, int.class, long.class, float.class, double.class,
-                         String.class, Integer.class, Object.class };
-
-        for (int i = 0; i < t.length; i++) {
-            MethodHandle mh = C.getMH(t[i]);
-            for (int j = 0; j < t.length; j++) {
-                // TEMPORARY EXCEPTIONS
-                if (t[j] == void.class) continue;
-                if (t[i].isPrimitive() && t[j] == Object.class) continue;
-                if (t[i] == char.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == byte.class && (t[j] == short.class || t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == short.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == int.class && (t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == long.class && (t[j] == float.class || t[j] == double.class)) continue;
-                if (t[i] == float.class && t[j] == double.class) continue;
-                if (t[i] == int.class && t[j] == Integer.class) continue;
-                if (t[i] == Integer.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
-                // END TEMPORARY EXCEPTIONS
-                boolean correct = (t[i].isPrimitive() || t[j].isPrimitive())
-                                  ? t[i] == t[j]
-                                  : t[j].isAssignableFrom(t[i]);
-                MethodType mti = methodType(t[i], String.class);
-                MethodType mtiCS = methodType(t[i], CharSequence.class);
-                MethodType mtj = methodType(t[j], String.class);
-                MethodType mtjObj = methodType(t[j], Object.class);
-                test(correct, mh, mti, mtj);
-                testBridge(correct, mh, mti, mti, mtjObj);
-                testBridge(correct, mh, mti, mti, mtiCS, mtjObj);
-            }
-        }
-    }
-
-    static void test(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
-        tryMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
-        tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
-    }
-
-    static void testBridge(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
-        tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT, bridgeMTs);
-    }
-
-    static void tryMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
-                               MethodType instMT, MethodType samMT) {
-        try {
-            LambdaMetafactory.metafactory(lookup, "run", methodType(I.class, captured),
-                                          samMT, mh, instMT);
-            if (!correct) {
-                throw new AssertionError("Uncaught linkage error:" +
-                                         " impl=" + mh +
-                                         ", captured=" + Arrays.toString(captured) +
-                                         ", inst=" + instMT +
-                                         ", sam=" + samMT);
-            }
-        }
-        catch (LambdaConversionException e) {
-            if (correct) {
-                throw new AssertionError("Unexpected linkage error:" +
-                                         " e=" + e +
-                                         ", impl=" + mh +
-                                         ", captured=" + Arrays.toString(captured) +
-                                         ", inst=" + instMT +
-                                         ", sam=" + samMT);
-            }
-        }
-    }
-
-    static void tryAltMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
-                                  MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
-        boolean bridge = bridgeMTs.length > 0;
-        Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
-        args[0] = samMT;
-        args[1] = mh;
-        args[2] = instMT;
-        args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
-        if (bridge) {
-            args[4] = bridgeMTs.length;
-            for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
-        }
-        try {
-            LambdaMetafactory.altMetafactory(lookup, "run", methodType(I.class, captured), args);
-            if (!correct) {
-                throw new AssertionError("Uncaught linkage error:" +
-                                         " impl=" + mh +
-                                         ", captured=" + Arrays.toString(captured) +
-                                         ", inst=" + instMT +
-                                         ", sam=" + samMT +
-                                         ", bridges=" + Arrays.toString(bridgeMTs));
-            }
-        }
-        catch (LambdaConversionException e) {
-            if (correct) {
-                throw new AssertionError("Unexpected linkage error:" +
-                                         " e=" + e +
-                                         ", impl=" + mh +
-                                         ", captured=" + Arrays.toString(captured) +
-                                         ", inst=" + instMT +
-                                         ", sam=" + samMT +
-                                         ", bridges=" + Arrays.toString(bridgeMTs));
-            }
-        }
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/Driver.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, 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
+ * @build m1/* m2/* Unnamed
+ * @run testng/othervm m1/p1.Main
+ * @summary Basic test case for module access checks and Lookup.in.
+ */
--- a/jdk/test/java/lang/invoke/modules/ModuleAccessControlTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- */
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.List;
-
-import static jdk.testlibrary.ProcessTools.executeTestJava;
-
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
-import static org.testng.Assert.*;
-
-/**
- * @test
- * @library /lib/testlibrary
- * @modules jdk.compiler
- * @build CompilerUtils jdk.testlibrary.*
- * @run testng ModuleAccessControlTest
- * @summary Driver for testing module access checking by MethodHandles.Lookup
- */
-
-public class ModuleAccessControlTest {
-
-    private static final String TEST_SRC = System.getProperty("test.src");
-
-    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
-    private static final Path MODS_DIR = Paths.get("mods");
-
-    // the names of the modules in this test
-    private static List<String> modules = Arrays.asList("m1", "m2");
-
-
-    /**
-     * Compiles all modules used by the test
-     */
-    @BeforeTest
-    public void compileAll() throws Exception {
-        for (String mn : modules) {
-            Path msrc = SRC_DIR.resolve(mn);
-            assertTrue(CompilerUtils
-                .compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
-        }
-    }
-
-    /**
-     * Launch the test
-     */
-    @Test
-    public void runTest() throws Exception {
-        int exitValue = executeTestJava("--module-path", MODS_DIR.toString(),
-                                        "-m", "m1/p1.Main")
-                .outputTo(System.out)
-                .errorTo(System.out)
-                .getExitValue();
-
-        assertTrue(exitValue == 0);
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/Unnamed.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+public class Unnamed { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m1/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+module m1 {
+    requires m2;
+    requires testng;
+    exports p1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m1/p1/Main.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2015, 2017, 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 p1;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+
+import static java.lang.invoke.MethodHandles.Lookup.*;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/**
+ * Basic test case for module access checks and Lookup.in.
+ */
+
+@Test
+public class Main {
+
+    private Class<?> p1_Type1;        // m1, exported
+    private Class<?> p2_Type2;        // m1, not exported
+    private Class<?> q1_Type1;        // m2, exported
+    private Class<?> q2_Type2;        // m2, not exported
+    private Class<?> x500NameClass;   // java.base, not exported
+    private Class<?> unnamedClass;    // class in unnamed module
+
+    @BeforeTest
+    public void setup() throws Exception {
+        try {
+            p1_Type1 = Class.forName("p1.Type1");
+            p2_Type2 = Class.forName("p2.Type2");
+            q1_Type1 = Class.forName("q1.Type1");
+            q2_Type2 = Class.forName("q2.Type2");
+            x500NameClass = Class.forName("sun.security.x509.X500Name");
+            unnamedClass = Class.forName("Unnamed");
+        } catch (ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+
+        // check setup
+        Module m1 = Layer.boot().findModule("m1").orElse(null);
+        assertNotNull(m1);
+        assertTrue(p1_Type1.getModule() == m1);
+        assertTrue(p2_Type2.getModule() == m1);
+        assertTrue(m1.isExported("p1"));
+        assertFalse(m1.isExported("p2"));
+
+        Module m2 = Layer.boot().findModule("m2").orElse(null);
+        assertNotNull(m2);
+        assertTrue(q1_Type1.getModule() == m2);
+        assertTrue(q2_Type2.getModule() == m2);
+        assertTrue(m2.isExported("q1"));
+        assertFalse(m2.isExported("q2"));
+
+        Module unnamedModule = unnamedClass.getModule();
+        assertFalse(unnamedModule.isNamed());
+
+        // m1 needs to read unnamed module
+        Main.class.getModule().addReads(unnamedModule);
+    }
+
+    /**
+     * MethodHandles.lookup()
+     *
+     * [A0] has module access
+     * [A1] can access all public types in m1
+     * [A2] can access public types in packages exported by modules that m1 reads
+     * [A3] cannot access public types in non-exported modules of modules that m1 reads
+     */
+    public void testLookup() throws Exception {
+        Lookup lookup = MethodHandles.lookup();
+        assertTrue((lookup.lookupModes() & MODULE) == MODULE); // [A0]
+
+        // m1
+        findConstructor(lookup, p1_Type1, void.class); // [A1]
+        findConstructor(lookup, p2_Type2, void.class); // [A1]
+
+        // m2
+        findConstructor(lookup, q1_Type1, void.class); // [A2]
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A3]
+
+        // java.base
+        findConstructor(lookup, Object.class, void.class); // [A2]
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class); // [A3]
+
+        // unnamed
+        findConstructor(lookup, unnamedClass, void.class);  // [A3]
+    }
+
+    /**
+     * Hop to lookup class in the same module
+     *
+     * [A0] module and public access is not lost
+     */
+    public void testToSameModule() throws Exception {
+        Lookup lookup = MethodHandles.lookup().in(p2_Type2);
+        assertTrue(lookup.lookupModes() == (MODULE|PUBLIC)); // [A0]
+
+        // m1
+        findConstructor(lookup, p1_Type1, void.class);
+        findConstructor(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructor(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructor(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructor(lookup, unnamedClass, void.class);
+    }
+
+    /**
+     * Hop to lookup class in another named module
+     *
+     * [A0] has no access
+     */
+    public void testFromNamedToNamedModule() throws Exception {
+        Lookup lookup = MethodHandles.lookup().in(q1_Type1);
+        assertTrue(lookup.lookupModes() == 0); // [A0]
+
+        // m1
+        findConstructorExpectingIAE(lookup, p1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructorExpectingIAE(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructorExpectingIAE(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructorExpectingIAE(lookup, unnamedClass, void.class);
+    }
+
+    /**
+     * Hop to lookup class in an unnamed module
+     *
+     * [A0] has no access
+     */
+    public void testFromNamedToUnnamedModule() throws Exception {
+        Lookup lookup = MethodHandles.lookup().in(unnamedClass);
+        assertTrue(lookup.lookupModes() == 0); // [A0]
+
+        // m1
+        findConstructorExpectingIAE(lookup, p1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructorExpectingIAE(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructorExpectingIAE(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructorExpectingIAE(lookup, unnamedClass, void.class);
+    }
+
+    /**
+     * Hop from unnamed to named module.
+     *
+     * [A0] retains PUBLIC access
+     */
+    public void testFromUnnamedToNamedModule() throws Exception {
+        Lookup lookup = MethodHandles.lookup();
+        lookup = MethodHandles.privateLookupIn(unnamedClass, lookup).in(p1_Type1);
+        assertTrue(lookup.lookupModes() == PUBLIC); // A0
+
+        // m1
+        findConstructor(lookup, p1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructor(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructor(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructor(lookup, unnamedClass, void.class);
+    }
+
+    /**
+     * MethodHandles.publicLookup()
+     *
+     * [A0] has PUBLIC|UNCONDITIONAL access
+     */
+    public void testPublicLookup() throws Exception {
+        Lookup lookup = MethodHandles.publicLookup();
+        assertTrue(lookup.lookupModes() == (PUBLIC|UNCONDITIONAL)); // A0
+
+        // m1
+        findConstructor(lookup, p1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructor(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructor(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructor(lookup, unnamedClass, void.class);
+    }
+
+    /**
+     * Hop from publicLookup to accessible type in java.base
+     */
+    public void testPublicLookupToBaseModule() throws Exception {
+        Lookup lookup = MethodHandles.publicLookup().in(String.class);
+        assertTrue(lookup.lookupModes() == PUBLIC); // A0
+
+        // m1
+        findConstructorExpectingIAE(lookup, p1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructorExpectingIAE(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructor(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructorExpectingIAE(lookup, unnamedClass, void.class);
+    }
+
+
+    /**
+     * Hop from publicLookup to accessible type in named module.
+     *
+     * [A0] has PUBLIC access
+     */
+    public void testPublicLookupToAccessibleTypeInNamedModule() throws Exception {
+        Lookup lookup = MethodHandles.publicLookup().in(p1_Type1);
+        assertTrue(lookup.lookupModes() == PUBLIC); // A0
+
+        // m1
+        findConstructor(lookup, p1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructor(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructor(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructor(lookup, unnamedClass, void.class);
+    }
+
+    /**
+     * Teleport from publicLookup to inaccessible type in named module.
+     *
+     * [A0] has no access
+     */
+    public void testPublicLookupToInaccessibleTypeInNamedModule() throws Exception {
+        Lookup lookup = MethodHandles.publicLookup().in(p2_Type2);
+        assertTrue(lookup.lookupModes() == 0); // A0
+
+        // m1
+        findConstructorExpectingIAE(lookup, p1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructorExpectingIAE(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructorExpectingIAE(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructorExpectingIAE(lookup, unnamedClass, void.class);
+    }
+
+    /**
+     * Teleport from publicLookup to public type in unnamed module
+     *
+     * [A0] has PUBLIC access
+     */
+    public void testPublicLookupToUnnamedModule() throws Exception {
+        Lookup lookup = MethodHandles.publicLookup().in(unnamedClass);
+        assertTrue(lookup.lookupModes() == PUBLIC); // A0
+
+        // m1
+        findConstructor(lookup, p1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+        // m2
+        findConstructor(lookup, q1_Type1, void.class);
+        findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+        // java.base
+        findConstructor(lookup, Object.class, void.class);
+        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+        // unnamed
+        findConstructor(lookup, unnamedClass, void.class);
+    }
+
+    /**
+     * Invokes Lookup findConstructor with a method type constructored from the
+     * given return and parameter types, expecting IllegalAccessException to be
+     * thrown.
+     */
+    static void findConstructorExpectingIAE(Lookup lookup,
+                                            Class<?> clazz,
+                                            Class<?> rtype,
+                                            Class<?>... ptypes) throws Exception {
+        try {
+            findConstructor(lookup, clazz, rtype, ptypes);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+    }
+
+    /**
+     * Invokes Lookup findConstructor with a method type constructored from the
+     * given return and parameter types.
+     */
+    static MethodHandle findConstructor(Lookup lookup,
+                                        Class<?> clazz,
+                                        Class<?> rtype,
+                                        Class<?>... ptypes) throws Exception {
+        MethodType mt = MethodType.methodType(rtype, ptypes);
+        return lookup.findConstructor(clazz, mt);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m1/p1/Type1.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, 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 p1;
+
+public class Type1 {
+    public Type1() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m1/p2/Type2.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, 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 p2;
+
+public class Type2 {
+    public Type2() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m2/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+module m2 {
+    exports q1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m2/q1/Type1.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, 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 q1;
+
+public class Type1 {
+    public Type1() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m2/q2/Type2.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, 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 q2;
+
+public class Type2 {
+    public Type2() { }
+}
--- a/jdk/test/java/lang/invoke/modules/src/m1/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- */
-module m1 {
-    requires m2;
-    exports p1;
-}
--- a/jdk/test/java/lang/invoke/modules/src/m1/p1/Main.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,225 +0,0 @@
-/*
- * Copyright (c) 2015, 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 p1;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.invoke.MethodType;
-
-/**
- * Basic test case for module access check, supplements AccessControlTest.
- *
- * The tests consists of two modules:
- *
- * module m1 { requires m2; exports p1; }
- * module m2 { exports q1; }
- *
- * Both modules read java.base (as every module reads java.base)
- *
- * module m1 has public types in packages p1 and p2, p2 is not exported.
- * module m2 has public types in packages q1 and q2, q2 is not exported.
- */
-
-public class Main {
-
-    static final int MODULE = Lookup.MODULE;
-
-    // Use Class.forName to get classes for test because some
-    // are not accessible at compile-time
-
-    static final Class<?> p1_Type1;        // m1, exported
-    static final Class<?> p2_Type2;        // m1, not exported
-    static final Class<?> q1_Type1;        // m2, exported, m1 reads m2
-    static final Class<?> q2_Type2;        // m2, not exported, m1 reads m2
-    static final Class<?> x500NameClass;   // java.base, not exported
-
-    static {
-        try {
-            p1_Type1 = Class.forName("p1.Type1");
-            p2_Type2 = Class.forName("p2.Type2");
-            q1_Type1 = Class.forName("q1.Type1");
-            q2_Type2 = Class.forName("q2.Type2");
-            x500NameClass = Class.forName("sun.security.x509.X500Name");
-        } catch (ClassNotFoundException e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        Lookup lookup, lookup2;
-
-        /**
-         * MethodHandles.lookup()
-         * has module access [A0]
-         * can access all public types in m1 [A1]
-         * can access public types in packages exported by modules that m1 reads [A2]
-         * cannot access public types in non-exported modules of modules that m1 reads [A3]
-         */
-        lookup = MethodHandles.lookup();
-        assertTrue((lookup.lookupModes() & MODULE) == MODULE); // [A0]
-        findConstructor(lookup, p1_Type1, void.class); // [A1]
-        findConstructor(lookup, p2_Type2, void.class); // [A1]
-        findConstructor(lookup, q1_Type1, void.class); // [A2]
-        findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A3]
-        findConstructor(lookup, Object.class, void.class); // [A2]
-        findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class); // [A3]
-
-        /**
-         * Teleport from MethodHandles.lookup() to lookup class in the same module
-         * module access is retained [A0]
-         * can access all public types in m1 [A1]
-         * can access public types in packages exported by modules that m1 reads [A2]
-         * cannot access public types in non-exported modules of modules that m1 reads [A3]
-         */
-        lookup2 = lookup.in(p2_Type2);
-        assertTrue((lookup2.lookupModes() & MODULE) == MODULE); // [A0]
-        findConstructor(lookup2, p1_Type1, void.class); // [A1]
-        findConstructor(lookup2, p2_Type2, void.class); // [A1]
-        findConstructor(lookup2, q1_Type1, void.class); // [A2]
-        findConstructorExpectingIAE(lookup2, q2_Type2, void.class); // [A3]
-        findConstructor(lookup2, Object.class, void.class); // [A2]
-        findConstructorExpectingIAE(lookup2, x500NameClass, void.class, String.class); // [A3]
-
-        /**
-         * Teleport from MethodHandles.lookup() to lookup class in another named module
-         * has no access [A0]
-         */
-        lookup2 = lookup.in(Object.class);
-        assertTrue(lookup2.lookupModes() == 0); // [A0]
-        findConstructorExpectingIAE(lookup2, Object.class, void.class);  // [A0]
-
-        /**
-         * Teleport from MethodHandles.lookup() to lookup class in an unnamed module
-         * has no access [A0]
-         */
-        Class<?> c = MethodHandles.publicLookup().lookupClass();
-        assertTrue(!c.getModule().isNamed());
-        lookup2 = lookup.in(c);
-        assertTrue(lookup2.lookupModes() == 0); // [A0]
-        findConstructorExpectingIAE(lookup2, Object.class, void.class);
-
-        /**
-         * MethodHandles.publicLookup()
-         * has no module access [A0]
-         * can access public types in exported packages [A1]
-         * cannot access public types in non-exported packages [A2]
-         */
-        lookup = MethodHandles.publicLookup();
-        assertTrue((lookup.lookupModes() & MODULE) == 0); // [A0]
-        findConstructor(lookup, p1_Type1, void.class); // [A1]
-        findConstructorExpectingIAE(lookup, p2_Type2, void.class); // [A1]
-        findConstructor(lookup, q1_Type1, void.class); // [A1]
-        findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A2]
-        findConstructor(lookup, Object.class, void.class); // [A1]
-        findConstructorExpectingIAE(lookup, x500NameClass, void.class); // [A2]
-
-        /**
-         * Teleport from MethodHandles.publicLookup() to lookup class in java.base
-         * has no module access [A0]
-         * can access public types in packages exported by java.base [A1]
-         * cannot access public types in non-exported packages [A2]
-         * no access to types in other named modules [A3]
-         */
-        lookup2 = lookup.in(Object.class);
-        assertTrue((lookup2.lookupModes() & MODULE) == 0); // [A0]
-        findConstructor(lookup2, String.class, void.class); // [A1]
-        findConstructorExpectingIAE(lookup2, x500NameClass, void.class, String.class); // [A2]
-        findConstructorExpectingIAE(lookup2, p1_Type1, void.class); // [A3]
-        findConstructorExpectingIAE(lookup2, q1_Type1, void.class); // [A3]
-
-        /**
-         * Teleport from MethodHandles.publicLookup() to lookup class in m1
-         * has no module access [A0]
-         * can access public types in packages exported by m1, m2 and java.base [A1]
-         * cannot access public types is non-exported packages [A2]
-         */
-        lookup2 = lookup.in(p1_Type1);
-        assertTrue((lookup2.lookupModes() & MODULE) == 0); // [A0]
-        findConstructor(lookup2, p1_Type1, void.class);  // [A1]
-        findConstructor(lookup2, q1_Type1, void.class);  // [A1]
-        findConstructor(lookup2, Object.class, void.class);  // [A1]
-        findConstructorExpectingIAE(lookup, p2_Type2, void.class); // [A2]
-        findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A2]
-        findConstructorExpectingIAE(lookup2, x500NameClass, void.class, String.class); // [A2]
-
-        /**
-         * Teleport from MethodHandles.publicLookup() to lookup class in m2
-         * has no module access [A0]
-         * can access public types in packages exported by m2 and java.base [A1]
-         * cannot access public types is non-exported packages or modules that m2 does
-         *   not read [A2]
-         */
-        lookup2 = lookup.in(q1_Type1);
-        assertTrue((lookup2.lookupModes() & MODULE) == 0); // [A0]
-        findConstructor(lookup2, q1_Type1, void.class); // [A1]
-        findConstructor(lookup2, Object.class, void.class); // [A1]
-        findConstructorExpectingIAE(lookup2, p1_Type1, void.class); // [A2]
-        findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A2]
-        findConstructorExpectingIAE(lookup2, x500NameClass, void.class, String.class);  // [A2]
-
-        /**
-         * Teleport from MethodHandles.publicLookup() to lookup class that is not
-         * in an exported package, should get no access [A0]
-         */
-        lookup2 = lookup.in(p2_Type2);
-        assertTrue(lookup2.lookupModes()  == 0); // [A0]
-        findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A0]
-    }
-
-    /**
-     * Invokes Lookup findConstructor with a method type constructored from the
-     * given return and parameter types, expecting IllegalAccessException to be
-     * thrown.
-     */
-    static MethodHandle findConstructorExpectingIAE(Lookup lookup,
-                                                    Class<?> clazz,
-                                                    Class<?> rtype,
-                                                    Class<?>... ptypes) throws Exception {
-        try {
-            findConstructor(lookup, clazz, rtype, ptypes);
-            throw new RuntimeException("IllegalAccessError expected");
-        } catch (IllegalAccessException expected) {
-            return null;
-        }
-    }
-
-    /**
-     * Invokes Lookup findConstructor with a method type constructored from the
-     * given return and parameter types.
-     */
-    static MethodHandle findConstructor(Lookup lookup,
-                                        Class<?> clazz,
-                                        Class<?> rtype,
-                                        Class<?>... ptypes) throws Exception {
-        MethodType mt = MethodType.methodType(rtype, ptypes);
-        return lookup.findConstructor(clazz, mt);
-    }
-
-    static void assertTrue(boolean condition) {
-        if (!condition)
-            throw new RuntimeException();
-    }
-
-}
--- a/jdk/test/java/lang/invoke/modules/src/m1/p1/Type1.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, 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 p1;
-
-public class Type1 {
-    public Type1() { }
-}
--- a/jdk/test/java/lang/invoke/modules/src/m1/p2/Type2.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, 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 p2;
-
-public class Type2 {
-    public Type2() { }
-}
--- a/jdk/test/java/lang/invoke/modules/src/m2/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- */
-module m2 {
-    exports q1;
-}
--- a/jdk/test/java/lang/invoke/modules/src/m2/q1/Type1.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, 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 q1;
-
-public class Type1 {
-    public Type1() { }
-}
--- a/jdk/test/java/lang/invoke/modules/src/m2/q2/Type2.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015, 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 q2;
-
-public class Type2 {
-    public Type2() { }
-}
--- a/jdk/test/java/lang/module/AutomaticModulesTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/module/AutomaticModulesTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -33,10 +33,10 @@
 import java.lang.module.Configuration;
 import java.lang.module.FindException;
 import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Exports;
 import java.lang.module.ModuleDescriptor.Requires.Modifier;
 import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReference;
+import java.lang.module.ResolutionException;
 import java.lang.module.ResolvedModule;
 import java.lang.reflect.Layer;
 import java.lang.reflect.Module;
@@ -137,6 +137,7 @@
         assertTrue(mref.isPresent(), mn + " not found");
 
         ModuleDescriptor descriptor = mref.get().descriptor();
+        assertTrue(descriptor.isAutomatic());
         assertEquals(descriptor.name(), mn);
         if (vs == null) {
             assertFalse(descriptor.version().isPresent());
@@ -175,17 +176,14 @@
         assertTrue(mref.isPresent(), "m not found");
 
         ModuleDescriptor descriptor = mref.get().descriptor();
+        assertTrue(descriptor.isAutomatic());
 
         assertTrue(descriptor.packages().size() == 2);
         assertTrue(descriptor.packages().contains("p"));
         assertTrue(descriptor.packages().contains("q"));
 
-        Set<String> exports = descriptor.exports().stream()
-                .map(Exports::source)
-                .collect(Collectors.toSet());
-        assertTrue(exports.size() == 2);
-        assertTrue(exports.contains("p"));
-        assertTrue(exports.contains("q"));
+        assertTrue(descriptor.exports().isEmpty());
+        assertTrue(descriptor.opens().isEmpty());
     }
 
     /**
@@ -201,15 +199,13 @@
         assertTrue(mref.isPresent(), "m not found");
 
         ModuleDescriptor descriptor = mref.get().descriptor();
+        assertTrue(descriptor.isAutomatic());
 
         assertTrue(descriptor.packages().size() == 1);
         assertTrue(descriptor.packages().contains("p"));
 
-        Set<String> exports = descriptor.exports().stream()
-                .map(Exports::source)
-                .collect(Collectors.toSet());
-        assertTrue(exports.size() == 1);
-        assertTrue(exports.contains("p"));
+        assertTrue(descriptor.exports().isEmpty());
+        assertTrue(descriptor.opens().isEmpty());
     }
 
     /**
@@ -229,10 +225,10 @@
         assertTrue(mref.isPresent(), "m not found");
 
         ModuleDescriptor descriptor = mref.get().descriptor();
+        assertTrue(descriptor.isAutomatic());
 
-        assertTrue(descriptor.packages().size() == 2);
+        assertTrue(descriptor.packages().size() == 1);
         assertTrue(descriptor.packages().contains("p"));
-        assertTrue(descriptor.packages().contains("p.resources"));
     }
 
     /**
@@ -254,9 +250,17 @@
         String provider = "p.S1";
 
         Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp");
+
+        // provider class
+        Path providerClass = tmpdir.resolve(provider.replace('.', '/') + ".class");
+        Files.createDirectories(providerClass.getParent());
+        Files.createFile(providerClass);
+
+        // services configuration file
         Path services = tmpdir.resolve("META-INF").resolve("services");
         Files.createDirectories(services);
         Files.write(services.resolve(service), Set.of(provider));
+
         Path dir = Files.createTempDirectory(USER_DIR, "mods");
         JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir);
 
@@ -314,7 +318,7 @@
 
                 // service type         provider type
                 { "p.S",                "-" },
-                { "p.S",                ".S1" },
+                { "p.S",                "p..S1" },
                 { "p.S",                "S1." },
         };
     }
@@ -324,13 +328,41 @@
      * values or names.
      */
     @Test(dataProvider = "badproviders", expectedExceptions = FindException.class)
-    public void testBadProvideNames(String service, String provider)
+    public void testBadProviderNames(String service, String provider)
         throws IOException
     {
         Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp");
+
+        // provider class
+        Path providerClass = tmpdir.resolve(provider.replace('.', '/') + ".class");
+        Files.createDirectories(providerClass.getParent());
+        Files.createFile(providerClass);
+
+        // services configuration file
         Path services = tmpdir.resolve("META-INF").resolve("services");
         Files.createDirectories(services);
         Files.write(services.resolve(service), Set.of(provider));
+
+        Path dir = Files.createTempDirectory(USER_DIR, "mods");
+        JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir);
+
+        // should throw FindException
+        ModuleFinder.of(dir).findAll();
+    }
+
+    /**
+     * Test JAR file with META-INF/services configuration file listing a
+     * provider that is not in the module.
+     */
+    @Test(expectedExceptions = FindException.class)
+    public void testMissingProviderPackage() throws IOException {
+        Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp");
+
+        // services configuration file
+        Path services = tmpdir.resolve("META-INF").resolve("services");
+        Files.createDirectories(services);
+        Files.write(services.resolve("p.S"), Set.of("q.P"));
+
         Path dir = Files.createTempDirectory(USER_DIR, "mods");
         JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir);
 
@@ -352,7 +384,8 @@
         attrs.put(Attributes.Name.MAIN_CLASS, mainClass);
 
         Path dir = Files.createTempDirectory(USER_DIR, "mods");
-        createDummyJarFile(dir.resolve("m.jar"), man);
+        String entry = mainClass.replace('.', '/') + ".class";
+        createDummyJarFile(dir.resolve("m.jar"), man, entry);
 
         ModuleFinder finder = ModuleFinder.of(dir);
 
@@ -366,20 +399,21 @@
     }
 
 
-    // Main-Class files that do not map to a legal Java identifier
+    // Main-Class files that do not map to a legal qualified type name
     @DataProvider(name = "badmainclass")
     public Object[][] createBadMainClass() {
         return new Object[][]{
 
+            { "Main",        null },
+            { "p..Main",     null },
             { "p-.Main",     null },
-            { ".Main",       null }
 
         };
     }
 
     /**
-     * Test that a JAR file with a Main-Class attribute that is not a valid
-     * Java identifier
+     * Test that a JAR file with a Main-Class attribute that is not a qualified
+     * type name.
      */
     @Test(dataProvider = "badmainclass", expectedExceptions = FindException.class)
     public void testBadMainClass(String mainClass, String ignore) throws IOException {
@@ -389,6 +423,24 @@
         attrs.put(Attributes.Name.MAIN_CLASS, mainClass);
 
         Path dir = Files.createTempDirectory(USER_DIR, "mods");
+        String entry = mainClass.replace('.', '/') + ".class";
+        createDummyJarFile(dir.resolve("m.jar"), man, entry);
+
+        // should throw FindException
+        ModuleFinder.of(dir).findAll();
+    }
+
+    /**
+     * Test that a JAR file with a Main-Class attribute that is not in the module
+     */
+    @Test(expectedExceptions = FindException.class)
+    public void testMissingMainClassPackage() throws IOException {
+        Manifest man = new Manifest();
+        Attributes attrs = man.getMainAttributes();
+        attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
+        attrs.put(Attributes.Name.MAIN_CLASS, "p.Main");
+
+        Path dir = Files.createTempDirectory(USER_DIR, "mods");
         createDummyJarFile(dir.resolve("m.jar"), man);
 
         // should throw FindException
@@ -405,7 +457,7 @@
      */
     public void testConfiguration1() throws Exception {
         ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("a")
+            = ModuleDescriptor.newModule("a")
                 .requires("b")
                 .requires("c")
                 .requires("java.base")
@@ -465,13 +517,13 @@
      */
     public void testInConfiguration2() throws IOException {
         ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("a")
+            = ModuleDescriptor.newModule("a")
                 .requires("b")
                 .requires("java.base")
                 .build();
 
         ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("b")
+            = ModuleDescriptor.newModule("b")
                 .requires("c")
                 .requires("java.base")
                 .build();
@@ -538,13 +590,13 @@
      */
     public void testInConfiguration3() throws IOException {
         ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("a")
+            = ModuleDescriptor.newModule("a")
                 .requires("b")
                 .requires("java.base")
                 .build();
 
         ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("b")
+            = ModuleDescriptor.newModule("b")
                 .requires(Set.of(Modifier.TRANSITIVE), "c")
                 .requires("java.base")
                 .build();
@@ -609,11 +661,67 @@
 
 
     /**
+     * Basic test of a configuration created with automatic modules
+     *   a requires b* and c*
+     *   b* contains p
+     *   c* contains p
+     */
+    @Test(expectedExceptions = { ResolutionException.class })
+    public void testDuplicateSuppliers1() throws IOException {
+        ModuleDescriptor descriptor
+            = ModuleDescriptor.newModule("a")
+                .requires("b")
+                .requires("c")
+                .build();
+
+        // c and d are automatic modules with the same package
+        Path dir = Files.createTempDirectory(USER_DIR, "mods");
+        createDummyJarFile(dir.resolve("b.jar"), "p/T.class");
+        createDummyJarFile(dir.resolve("c.jar"), "p/T.class");
+
+        // module finder locates 'a' and the modules in the directory
+        ModuleFinder finder
+            = ModuleFinder.compose(ModuleUtils.finderOf(descriptor),
+                                   ModuleFinder.of(dir));
+
+        Configuration parent = Layer.boot().configuration();
+        resolve(parent, finder, "a");
+    }
+
+
+    /**
+     * Basic test of a configuration created with automatic modules
+     *   a contains p, requires b*
+     *   b* contains p
+     */
+    @Test(expectedExceptions = { ResolutionException.class })
+    public void testDuplicateSuppliers2() throws IOException {
+        ModuleDescriptor descriptor
+            = ModuleDescriptor.newModule("a")
+                .packages(Set.of("p"))
+                .requires("b")
+                .build();
+
+        // c and d are automatic modules with the same package
+        Path dir = Files.createTempDirectory(USER_DIR, "mods");
+        createDummyJarFile(dir.resolve("b.jar"), "p/T.class");
+
+        // module finder locates 'a' and the modules in the directory
+        ModuleFinder finder
+            = ModuleFinder.compose(ModuleUtils.finderOf(descriptor),
+                                   ModuleFinder.of(dir));
+
+        Configuration parent = Layer.boot().configuration();
+        resolve(parent, finder, "a");
+    }
+
+
+    /**
      * Basic test of Layer containing automatic modules
      */
     public void testInLayer() throws IOException {
         ModuleDescriptor descriptor
-            = ModuleDescriptor.module("a")
+            = ModuleDescriptor.newModule("a")
                 .requires("b")
                 .requires("c")
                 .build();
@@ -664,7 +772,7 @@
 
         // test miscellaneous methods
         assertTrue(m.isAutomatic());
-        assertFalse(m.isSynthetic());
+        assertFalse(m.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC));
         assertFalse(m.osName().isPresent());
         assertFalse(m.osArch().isPresent());
         assertFalse(m.osVersion().isPresent());
@@ -672,12 +780,12 @@
 
 
     /**
-     * Invokes parent.resolveRequires to resolve the given root modules.
+     * Invokes parent.resolve to resolve the given root modules.
      */
     static Configuration resolve(Configuration parent,
                                  ModuleFinder finder,
                                  String... roots) {
-        return parent.resolveRequires(finder, ModuleFinder.of(), Set.of(roots));
+        return parent.resolve(finder, ModuleFinder.of(), Set.of(roots));
     }
 
     /**
--- a/jdk/test/java/lang/module/ConfigurationTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/module/ConfigurationTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -24,23 +24,26 @@
 /**
  * @test
  * @library /lib/testlibrary
+ * @modules java.base/jdk.internal.misc
  * @build ConfigurationTest ModuleUtils
  * @run testng ConfigurationTest
  * @summary Basic tests for java.lang.module.Configuration
  */
 
 import java.lang.module.Configuration;
+import java.lang.module.FindException;
 import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Builder;
 import java.lang.module.ModuleDescriptor.Requires;
 import java.lang.module.ModuleFinder;
 import java.lang.module.ResolutionException;
 import java.lang.module.ResolvedModule;
 import java.lang.reflect.Layer;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 
+import jdk.internal.misc.SharedSecrets;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
@@ -48,30 +51,35 @@
 @Test
 public class ConfigurationTest {
 
+    /**
+     * Creates a "non-strict" builder for building a module. This allows the
+     * test the create ModuleDescriptor objects that do not require java.base.
+     */
+    private static ModuleDescriptor.Builder newBuilder(String mn) {
+        return SharedSecrets.getJavaLangModuleAccess()
+                .newModuleBuilder(mn, false, Set.of());
+    }
 
     /**
      * Basic test of resolver
      *     m1 requires m2, m2 requires m3
      */
     public void testBasic() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m3")
                 .build();
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .build();
 
         ModuleFinder finder
             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 3);
 
@@ -110,24 +118,21 @@
      */
     public void testRequiresTransitive1() {
         // m1 requires m2, m2 requires transitive m3
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m3")
                 .build();
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .build();
 
         ModuleFinder finder
             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 3);
 
@@ -167,18 +172,16 @@
 
         // cf1: m1 and m2, m2 requires transitive m1
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf1 = resolveRequires(finder1, "m2");
+        Configuration cf1 = resolve(finder1, "m2");
 
         assertTrue(cf1.modules().size() == 2);
         assertTrue(cf1.findModule("m1").isPresent());
@@ -196,14 +199,13 @@
 
         // cf2: m3, m3 requires m2
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+        Configuration cf2 = resolve(cf1, finder2, "m3");
 
         assertTrue(cf2.modules().size() == 1);
         assertTrue(cf2.findModule("m1").isPresent());  // in parent
@@ -231,13 +233,11 @@
 
         // cf1: m1
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder1, "m1");
+        Configuration cf1 = resolve(finder1, "m1");
 
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m1").isPresent());
@@ -250,19 +250,17 @@
 
         // cf2: m2, m3: m2 requires transitive m1, m3 requires m2
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+        Configuration cf2 = resolve(cf1, finder2, "m3");
 
         assertTrue(cf2.modules().size() == 2);
         assertTrue(cf2.findModule("m1").isPresent());   // in parent
@@ -297,13 +295,11 @@
 
         // cf1: m1
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder1, "m1");
+        Configuration cf1 = resolve(finder1, "m1");
 
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m1").isPresent());
@@ -316,14 +312,13 @@
 
         // cf2: m2 requires transitive m1
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m2");
+        Configuration cf2 = resolve(cf1, finder2, "m2");
 
         assertTrue(cf2.modules().size() == 1);
         assertTrue(cf2.findModule("m1").isPresent());  // in parent
@@ -340,14 +335,13 @@
 
         // cf3: m3 requires m2
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);
 
-        Configuration cf3 = resolveRequires(cf2, finder3, "m3");
+        Configuration cf3 = resolve(cf2, finder3, "m3");
 
         assertTrue(cf3.modules().size() == 1);
         assertTrue(cf3.findModule("m1").isPresent());  // in parent
@@ -376,18 +370,16 @@
 
         // cf1: m1, m2 requires transitive m1
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf1 = resolveRequires(finder1, "m2");
+        Configuration cf1 = resolve(finder1, "m2");
 
         assertTrue(cf1.modules().size() == 2);
         assertTrue(cf1.findModule("m1").isPresent());
@@ -408,20 +400,18 @@
 
         // cf2: m3 requires transitive m2, m4 requires m3
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")
                 .build();
 
-        ModuleDescriptor descriptor4
-            = ModuleDescriptor.module("m4")
+        ModuleDescriptor descriptor4 = newBuilder("m4")
                 .requires("m3")
                 .build();
 
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3", "m4");
+        Configuration cf2 = resolve(cf1, finder2, "m3", "m4");
 
         assertTrue(cf2.modules().size() == 2);
         assertTrue(cf2.findModule("m1").isPresent());   // in parent
@@ -456,28 +446,24 @@
      * - Configuration cf3(cf1,cf2): m4 requires m2, m3
      */
     public void testRequiresTransitive6() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
-        ModuleDescriptor descriptor4
-            = ModuleDescriptor.module("m4")
+        ModuleDescriptor descriptor4 = newBuilder("m4")
                 .requires("m2")
                 .requires("m3")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
-        Configuration cf1 = resolveRequires(finder1, "m2");
+        Configuration cf1 = resolve(finder1, "m2");
         assertTrue(cf1.modules().size() == 2);
         assertTrue(cf1.findModule("m1").isPresent());
         assertTrue(cf1.findModule("m2").isPresent());
@@ -485,7 +471,7 @@
         assertTrue(cf1.parents().get(0) == Configuration.empty());
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
-        Configuration cf2 = resolveRequires(finder2, "m3");
+        Configuration cf2 = resolve(finder2, "m3");
         assertTrue(cf2.modules().size() == 2);
         assertTrue(cf2.findModule("m3").isPresent());
         assertTrue(cf2.findModule("m1").isPresent());
@@ -493,7 +479,7 @@
         assertTrue(cf2.parents().get(0) == Configuration.empty());
 
         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4);
-        Configuration cf3 = Configuration.resolveRequires(finder3,
+        Configuration cf3 = Configuration.resolve(finder3,
                 List.of(cf1, cf2),
                 ModuleFinder.of(),
                 Set.of("m4"));
@@ -522,14 +508,13 @@
      *     resolve m1
      */
     public void testRequiresStatic1() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 1);
 
@@ -545,18 +530,16 @@
      *     resolve m1
      */
     public void testRequiresStatic2() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 1);
 
@@ -572,18 +555,16 @@
      *     resolve m1, m2
      */
     public void testRequiresStatic3() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf = resolveRequires(finder, "m1", "m2");
+        Configuration cf = resolve(finder, "m1", "m2");
 
         assertTrue(cf.modules().size() == 2);
 
@@ -604,25 +585,22 @@
      *     m3
      */
     public void testRequiresStatic4() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
                 .requires("m3")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.STATIC), "m3")
                 .build();
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .build();
 
         ModuleFinder finder
-                = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
-
-        Configuration cf = resolveRequires(finder, "m1");
+            = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
+
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 3);
 
@@ -648,31 +626,28 @@
      * - Configuration cf2: m3 requires m1, requires static m2
      */
     public void testRequiresStatic5() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf1 = resolveRequires(finder1, "m1", "m2");
+        Configuration cf1 = resolve(finder1, "m1", "m2");
 
         assertTrue(cf1.modules().size() == 2);
         assertTrue(cf1.findModule("m1").isPresent());
         assertTrue(cf1.findModule("m2").isPresent());
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m1")
                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+        Configuration cf2 = resolve(cf1, finder2, "m3");
 
         assertTrue(cf2.modules().size() == 1);
         assertTrue(cf2.findModule("m3").isPresent());
@@ -694,26 +669,24 @@
      * - Configuration cf2: m3 requires m1, requires static m2
      */
     public void testRequiresStatic6() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder1, "m1");
+        Configuration cf1 = resolve(finder1, "m1");
 
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m1").isPresent());
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m1")
                 .requires(Set.of(Requires.Modifier.STATIC), "m2")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+        Configuration cf2 = resolve(cf1, finder2, "m3");
 
         assertTrue(cf2.modules().size() == 1);
         assertTrue(cf2.findModule("m3").isPresent());
@@ -735,21 +708,19 @@
     public void testRequiresStatic7() {
         ModuleDescriptor descriptor1 = null;  // not observable
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE,
                                 Requires.Modifier.STATIC),
                          "m1")
                 .build();
 
-        ModuleDescriptor descriptor3
-                = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor2, descriptor3);
 
-        Configuration cf = resolveRequires(finder, "m3");
+        Configuration cf = resolve(finder, "m3");
 
         assertTrue(cf.modules().size() == 2);
         assertTrue(cf.findModule("m2").isPresent());
@@ -770,8 +741,7 @@
     public void testRequiresStatic8() {
         ModuleDescriptor descriptor1 = null;  // not observable
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE,
                                 Requires.Modifier.STATIC),
                         "m1")
@@ -779,21 +749,20 @@
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2);
 
-        Configuration cf1 = resolveRequires(finder1, "m2");
+        Configuration cf1 = resolve(finder1, "m2");
 
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m2").isPresent());
         ResolvedModule m2 = cf1.findModule("m2").get();
         assertTrue(m2.reads().isEmpty());
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+        Configuration cf2 = resolve(cf1, finder2, "m3");
 
         assertTrue(cf2.modules().size() == 1);
         assertTrue(cf2.findModule("m3").isPresent());
@@ -810,22 +779,19 @@
      */
     public void testServiceBinding1() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .exports("p")
                 .uses("p.S")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
-                .contains("q")
-                .provides("p.S", "q.T")
+                .provides("p.S", List.of("q.T"))
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf = resolveRequiresAndUses(finder, "m1");
+        Configuration cf = resolveAndBind(finder, "m1");
 
         assertTrue(cf.modules().size() == 2);
         assertTrue(cf.findModule("m1").isPresent());
@@ -853,31 +819,26 @@
      */
     public void testServiceBinding2() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .exports("p")
                 .uses("p.S1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
                 .uses("p.S2")
-                .contains("q")
-                .provides("p.S1", "q.Service1Impl")
+                .provides("p.S1", List.of("q.Service1Impl"))
                 .build();
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m1")
-                .contains("q")
-                .provides("p.S2", "q.Service2Impl")
+                .provides("p.S2", List.of("q.Service2Impl"))
                 .build();
 
         ModuleFinder finder
             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 
-        Configuration cf = resolveRequiresAndUses(finder, "m1");
+        Configuration cf = resolveAndBind(finder, "m1");
 
         assertTrue(cf.modules().size() == 3);
         assertTrue(cf.findModule("m1").isPresent());
@@ -912,29 +873,26 @@
      */
     public void testServiceBindingWithConfigurations1() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .exports("p")
                 .uses("p.S")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder1, "m1");
+        Configuration cf1 = resolve(finder1, "m1");
 
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m1").isPresent());
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
-                .contains("q")
-                .provides("p.S", "q.T")
+                .provides("p.S", List.of("q.T"))
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 
-        Configuration cf2 = resolveRequiresAndUses(cf1, finder2); // no roots
+        Configuration cf2 = resolveAndBind(cf1, finder2); // no roots
 
         assertTrue(cf2.parents().size() == 1);
         assertTrue(cf2.parents().get(0) == cf1);
@@ -961,47 +919,39 @@
      */
     public void testServiceBindingWithConfigurations2() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .exports("p")
                 .uses("p.S")
-                .contains("p1")
-                .provides("p.S", "p1.ServiceImpl")
+                .provides("p.S", List.of("p1.ServiceImpl"))
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
-                .contains("p2")
-                .provides("p.S", "p2.ServiceImpl")
+                .provides("p.S", List.of("p2.ServiceImpl"))
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf1 = resolveRequiresAndUses(finder1, "m1");
+        Configuration cf1 = resolveAndBind(finder1, "m1");
 
         assertTrue(cf1.modules().size() == 2);
         assertTrue(cf1.findModule("m1").isPresent());
         assertTrue(cf1.findModule("m2").isPresent());
 
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m1")
-                .contains("p3")
-                .provides("p.S", "p3.ServiceImpl")
+                .provides("p.S", List.of("p3.ServiceImpl"))
                 .build();
 
-        ModuleDescriptor descriptor4
-            = ModuleDescriptor.module("m4")
+        ModuleDescriptor descriptor4 = newBuilder("m4")
                 .requires("m1")
-                .contains("p4")
-                .provides("p.S", "p4.ServiceImpl")
+                .provides("p.S", List.of("p4.ServiceImpl"))
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 
-        Configuration cf2 = resolveRequiresAndUses(cf1, finder2); // no roots
+        Configuration cf2 = resolveAndBind(cf1, finder2); // no roots
 
         assertTrue(cf2.parents().size() == 1);
         assertTrue(cf2.parents().get(0) == cf1);
@@ -1037,22 +987,19 @@
      */
     public void testServiceBindingWithConfigurations3() {
 
-        ModuleDescriptor service
-            = ModuleDescriptor.module("s")
+        ModuleDescriptor service = newBuilder("s")
                 .exports("p")
                 .build();
 
-        ModuleDescriptor provider_v1
-            = ModuleDescriptor.module("p")
+        ModuleDescriptor provider_v1 = newBuilder("p")
                 .version("1.0")
                 .requires("s")
-                .contains("q")
-                .provides("p.S", "q.T")
+                .provides("p.S", List.of("q.T"))
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(service, provider_v1);
 
-        Configuration cf1 = resolveRequires(finder1, "p");
+        Configuration cf1 = resolve(finder1, "p");
 
         assertTrue(cf1.modules().size() == 2);
         assertTrue(cf1.findModule("s").isPresent());
@@ -1063,18 +1010,15 @@
         assertEquals(p.reference().descriptor(), provider_v1);
 
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("s")
                 .uses("p.S")
                 .build();
 
-        ModuleDescriptor provider_v2
-            = ModuleDescriptor.module("p")
+        ModuleDescriptor provider_v2 = newBuilder("p")
                 .version("2.0")
                 .requires("s")
-                .contains("q")
-                .provides("p.S", "q.T")
+                .provides("p.S", List.of("q.T"))
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, provider_v2);
@@ -1082,7 +1026,7 @@
 
         // finder2 is the before ModuleFinder and so p@2.0 should be located
 
-        Configuration cf2 = resolveRequiresAndUses(cf1, finder2, "m1");
+        Configuration cf2 = resolveAndBind(cf1, finder2, "m1");
 
         assertTrue(cf2.parents().size() == 1);
         assertTrue(cf2.parents().get(0) == cf1);
@@ -1097,7 +1041,7 @@
         // finder2 is the after ModuleFinder and so p@2.0 should not be located
         // as module p is in parent configuration.
 
-        cf2 = resolveRequiresAndUses(cf1, ModuleFinder.of(), finder2, "m1");
+        cf2 = resolveAndBind(cf1, ModuleFinder.of(), finder2, "m1");
 
         assertTrue(cf2.parents().size() == 1);
         assertTrue(cf2.parents().get(0) == cf1);
@@ -1117,25 +1061,22 @@
      */
     public void testWithTwoFinders1() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
                 .build();
 
-        ModuleDescriptor descriptor2_v1
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2_v1 = newBuilder("m2")
                 .version("1.0")
                 .build();
 
-        ModuleDescriptor descriptor2_v2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2_v2 = newBuilder("m2")
                 .version("2.0")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2_v1);
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2_v2);
 
-        Configuration cf = resolveRequires(finder1, finder2, "m1");
+        Configuration cf = resolve(finder1, finder2, "m1");
 
         assertTrue(cf.modules().size() == 2);
         assertTrue(cf.findModule("m1").isPresent());
@@ -1157,30 +1098,25 @@
      */
     public void testWithTwoFinders2() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .exports("p")
                 .uses("p.S")
                 .build();
 
-        ModuleDescriptor descriptor2_v1
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2_v1 = newBuilder("m2")
                 .requires("m1")
-                .contains("q")
-                .provides("p.S", "q.T")
+                .provides("p.S", List.of("q.T"))
                 .build();
 
-        ModuleDescriptor descriptor2_v2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2_v2 = newBuilder("m2")
                 .requires("m1")
-                .contains("q")
-                .provides("p.S", "q.T")
+                .provides("p.S", List.of("q.T"))
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2_v1);
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2_v2);
 
-        Configuration cf = resolveRequiresAndUses(finder1, finder2, "m1");
+        Configuration cf = resolveAndBind(finder1, finder2, "m1");
 
         assertTrue(cf.modules().size() == 2);
         assertTrue(cf.findModule("m1").isPresent());
@@ -1200,18 +1136,17 @@
      */
     public void testResolvedInParent1() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder, "m1");
+        Configuration cf1 = resolve(finder, "m1");
 
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m1").isPresent());
 
-        Configuration cf2 = resolveRequires(cf1, finder, "m1");
+        Configuration cf2 = resolve(cf1, finder, "m1");
 
         assertTrue(cf2.modules().size() == 1);
     }
@@ -1223,26 +1158,23 @@
      */
     public void testResolvedInParent2() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder1, "m1");
+        Configuration cf1 = resolve(finder1, "m1");
 
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m1").isPresent());
 
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 
-        Configuration cf2 = resolveRequires(cf1, ModuleFinder.of(), finder2, "m2");
+        Configuration cf2 = resolve(cf1, ModuleFinder.of(), finder2, "m2");
 
         assertTrue(cf2.modules().size() == 1);
         assertTrue(cf2.findModule("m2").isPresent());
@@ -1268,29 +1200,28 @@
     public void testResolvedInMultipleParents1() {
 
         // Configuration cf1: m1
-        ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
-        Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
+        Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
         assertEquals(cf1.parents(), List.of(Configuration.empty()));
         assertTrue(cf1.findModule("m1").isPresent());
         ResolvedModule m1 = cf1.findModule("m1").get();
         assertTrue(m1.configuration() == cf1);
 
         // Configuration cf2: m2
-        ModuleDescriptor descriptor2 = ModuleDescriptor.module("m2").build();
-        Configuration cf2 = resolveRequires(ModuleUtils.finderOf(descriptor2), "m2");
+        ModuleDescriptor descriptor2 = newBuilder("m2").build();
+        Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");
         assertEquals(cf2.parents(), List.of(Configuration.empty()));
         assertTrue(cf2.findModule("m2").isPresent());
         ResolvedModule m2 = cf2.findModule("m2").get();
         assertTrue(m2.configuration() == cf2);
 
         // Configuration cf3(cf1,cf2): m3 requires m1 and m2
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m1")
                 .requires("m2")
                 .build();
         ModuleFinder finder = ModuleUtils.finderOf(descriptor3);
-        Configuration cf3 = Configuration.resolveRequires(
+        Configuration cf3 = Configuration.resolve(
                 finder,
                 List.of(cf1, cf2),  // parents
                 ModuleFinder.of(),
@@ -1319,19 +1250,18 @@
      */
     public void testResolvedInMultipleParents2() {
         // Configuration cf1: m1
-        ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
-        Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
+        Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
         assertEquals(cf1.parents(), List.of(Configuration.empty()));
         assertTrue(cf1.findModule("m1").isPresent());
         ResolvedModule m1 = cf1.findModule("m1").get();
         assertTrue(m1.configuration() == cf1);
 
         // Configuration cf2(cf1): m2 requires m1
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
                 .build();
-        Configuration cf2 = Configuration.resolveRequires(
+        Configuration cf2 = Configuration.resolve(
                 ModuleUtils.finderOf(descriptor2),
                 List.of(cf1),  // parents
                 ModuleFinder.of(),
@@ -1342,11 +1272,10 @@
         assertTrue(m2.configuration() == cf2);
 
         // Configuration cf3(cf1): m3 requires m1
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m1")
                 .build();
-        Configuration cf3 = Configuration.resolveRequires(
+        Configuration cf3 = Configuration.resolve(
                 ModuleUtils.finderOf(descriptor3),
                 List.of(cf1),  // parents
                 ModuleFinder.of(),
@@ -1357,13 +1286,12 @@
         assertTrue(m3.configuration() == cf3);
 
         // Configuration cf4(cf2,cf3): m4 requires m1,m2,m3
-        ModuleDescriptor descriptor4
-            = ModuleDescriptor.module("m4")
+        ModuleDescriptor descriptor4 = newBuilder("m4")
                 .requires("m1")
                 .requires("m2")
                 .requires("m3")
                 .build();
-        Configuration cf4 = Configuration.resolveRequires(
+        Configuration cf4 = Configuration.resolve(
                 ModuleUtils.finderOf(descriptor4),
                 List.of(cf2, cf3),  // parents
                 ModuleFinder.of(),
@@ -1395,35 +1323,34 @@
         ModuleDescriptor descriptor1, descriptor2, descriptor3;
 
         // Configuration cf1: m1@1
-        descriptor1 = ModuleDescriptor.module("m1").version("1").build();
-        Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
+        descriptor1 = newBuilder("m1").version("1").build();
+        Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
         assertEquals(cf1.parents(), List.of(Configuration.empty()));
 
         // Configuration cf2: m1@2, m2@2
-        descriptor1 = ModuleDescriptor.module("m1").version("2").build();
-        descriptor2 = ModuleDescriptor.module("m2").version("2").build();
-        Configuration cf2 = resolveRequires(
+        descriptor1 = newBuilder("m1").version("2").build();
+        descriptor2 = newBuilder("m2").version("2").build();
+        Configuration cf2 = resolve(
                 ModuleUtils.finderOf(descriptor1, descriptor2),
                 "m1", "m2");
         assertEquals(cf2.parents(), List.of(Configuration.empty()));
 
         // Configuration cf3: m1@3, m2@3, m3@3
-        descriptor1 = ModuleDescriptor.module("m1").version("3").build();
-        descriptor2 = ModuleDescriptor.module("m2").version("3").build();
-        descriptor3 = ModuleDescriptor.module("m3").version("3").build();
-        Configuration cf3 = resolveRequires(
+        descriptor1 = newBuilder("m1").version("3").build();
+        descriptor2 = newBuilder("m2").version("3").build();
+        descriptor3 = newBuilder("m3").version("3").build();
+        Configuration cf3 = resolve(
                 ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3),
                 "m1", "m2", "m3");
         assertEquals(cf3.parents(), List.of(Configuration.empty()));
 
         // Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m3
-        ModuleDescriptor descriptor4
-                = ModuleDescriptor.module("m4")
+        ModuleDescriptor descriptor4 = newBuilder("m4")
                 .requires("m1")
                 .requires("m2")
                 .requires("m3")
                 .build();
-        Configuration cf4 = Configuration.resolveRequires(
+        Configuration cf4 = Configuration.resolve(
                 ModuleUtils.finderOf(descriptor4),
                 List.of(cf1, cf2, cf3),  // parents
                 ModuleFinder.of(),
@@ -1470,17 +1397,15 @@
      * configuration.
      */
     public void testOverriding1() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder, "m1");
+        Configuration cf1 = resolve(finder, "m1");
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m1").isPresent());
 
-        Configuration cf2 = resolveRequires(cf1, finder, "m1");
+        Configuration cf2 = resolve(cf1, finder, "m1");
         assertTrue(cf2.modules().size() == 1);
         assertTrue(cf2.findModule("m1").isPresent());
     }
@@ -1490,24 +1415,24 @@
      * configuration.
      */
     public void testOverriding2() {
-        ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
-        Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
+        Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
         assertTrue(cf1.modules().size() == 1);
         assertTrue(cf1.findModule("m1").isPresent());
 
-        ModuleDescriptor descriptor2 = ModuleDescriptor.module("m2").build();
-        Configuration cf2 = resolveRequires(ModuleUtils.finderOf(descriptor2), "m2");
+        ModuleDescriptor descriptor2 = newBuilder("m2").build();
+        Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");
         assertTrue(cf2.modules().size() == 1);
         assertTrue(cf2.findModule("m2").isPresent());
 
-        ModuleDescriptor descriptor3 = ModuleDescriptor.module("m3").build();
-        Configuration cf3 = resolveRequires(ModuleUtils.finderOf(descriptor3), "m3");
+        ModuleDescriptor descriptor3 = newBuilder("m3").build();
+        Configuration cf3 = resolve(ModuleUtils.finderOf(descriptor3), "m3");
         assertTrue(cf3.modules().size() == 1);
         assertTrue(cf3.findModule("m3").isPresent());
 
         // override m2, m1 and m3 should be found in parent configurations
         ModuleFinder finder = ModuleUtils.finderOf(descriptor2);
-        Configuration cf4 = Configuration.resolveRequires(
+        Configuration cf4 = Configuration.resolve(
                 finder,
                 List.of(cf1, cf2, cf3),
                 ModuleFinder.of(),
@@ -1530,18 +1455,16 @@
      */
     public void testOverriding3() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf1 = resolveRequires(finder1, "m2");
+        Configuration cf1 = resolve(finder1, "m2");
 
         assertTrue(cf1.modules().size() == 2);
         assertTrue(cf1.findModule("m1").isPresent());
@@ -1549,14 +1472,13 @@
 
         // cf2: m3 requires m2, m1
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m1", "m3");
+        Configuration cf2 = resolve(cf1, finder2, "m1", "m3");
 
         assertTrue(cf2.parents().size() == 1);
         assertTrue(cf2.parents().get(0) == cf1);
@@ -1585,64 +1507,58 @@
     /**
      * Root module not found
      */
-    @Test(expectedExceptions = { ResolutionException.class })
+    @Test(expectedExceptions = { FindException.class })
     public void testRootNotFound() {
-        resolveRequires(ModuleFinder.of(), "m1");
+        resolve(ModuleFinder.of(), "m1");
     }
 
 
     /**
      * Direct dependency not found
      */
-    @Test(expectedExceptions = { ResolutionException.class })
+    @Test(expectedExceptions = { FindException.class })
     public void testDirectDependencyNotFound() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1").requires("m2").build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
-        resolveRequires(finder, "m1");
+        resolve(finder, "m1");
     }
 
 
     /**
      * Transitive dependency not found
      */
-    @Test(expectedExceptions = { ResolutionException.class })
+    @Test(expectedExceptions = { FindException.class })
     public void testTransitiveDependencyNotFound() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1").requires("m2").build();
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2").requires("m3").build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
+        ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
-        resolveRequires(finder, "m1");
+        resolve(finder, "m1");
     }
 
 
     /**
      * Service provider dependency not found
      */
-    @Test(expectedExceptions = { ResolutionException.class })
+    @Test(expectedExceptions = { FindException.class })
     public void testServiceProviderDependencyNotFound() {
 
         // service provider dependency (on m3) not found
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .exports("p")
                 .uses("p.S")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
                 .requires("m3")
-                .contains("q")
-                .provides("p.S", "q.T")
+                .provides("p.S", List.of("q.T"))
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         // should throw ResolutionException because m3 is not found
-        Configuration cf = resolveRequiresAndUses(finder, "m1");
+        Configuration cf = resolveAndBind(finder, "m1");
     }
 
 
@@ -1651,15 +1567,12 @@
      */
     @Test(expectedExceptions = { ResolutionException.class })
     public void testSimpleCycle() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1").requires("m2").build();
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2").requires("m3").build();
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3").requires("m1").build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
+        ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();
+        ModuleDescriptor descriptor3 = newBuilder("m3").requires("m1").build();
         ModuleFinder finder
             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
-        resolveRequires(finder, "m1");
+        resolve(finder, "m1");
     }
 
     /**
@@ -1668,20 +1581,16 @@
     @Test(expectedExceptions = { ResolutionException.class })
     public void testCycleInProvider() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .exports("p")
                 .uses("p.S")
                 .build();
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
                 .requires("m3")
-                .contains("q")
-                .provides("p.S", "q.T")
+                .provides("p.S", List.of("q.T"))
                 .build();
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
@@ -1689,7 +1598,7 @@
             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 
         // should throw ResolutionException because of the m2 <--> m3 cycle
-        resolveRequiresAndUses(finder, "m1");
+        resolveAndBind(finder, "m1");
     }
 
 
@@ -1699,19 +1608,16 @@
     @Test(expectedExceptions = { ResolutionException.class })
     public void testPackageSuppliedByTwoOthers() {
 
-        ModuleDescriptor descriptor1
-            =  ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
                 .requires("m3")
                 .build();
 
-        ModuleDescriptor descriptor2
-            =  ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .exports("p")
                 .build();
 
-        ModuleDescriptor descriptor3
-            =  ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .exports("p", Set.of("m1"))
                 .build();
 
@@ -1719,7 +1625,7 @@
             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 
         // m2 and m3 export package p to module m1
-        resolveRequires(finder, "m1");
+        resolve(finder, "m1");
     }
 
 
@@ -1730,21 +1636,19 @@
     @Test(expectedExceptions = { ResolutionException.class })
     public void testPackageSuppliedBySelfAndOther() {
 
-        ModuleDescriptor descriptor1
-            =  ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
-                .contains("p")
+                .packages(Set.of("p"))
                 .build();
 
-        ModuleDescriptor descriptor2
-            =  ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .exports("p")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         // m1 contains package p, module m2 exports package p to m1
-        resolveRequires(finder, "m1");
+        resolve(finder, "m1");
     }
 
 
@@ -1753,20 +1657,18 @@
      * a module that also contains a package p.
      */
     public void testContainsPackageInSelfAndOther() {
-        ModuleDescriptor descriptor1
-            =  ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
-                .contains("p")
+                .packages(Set.of("p"))
                 .build();
 
-        ModuleDescriptor descriptor2
-            =  ModuleDescriptor.module("m2")
-                .contains("p")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
+                .packages(Set.of("p"))
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 2);
         assertTrue(cf.findModule("m1").isPresent());
@@ -1787,8 +1689,7 @@
      */
     @Test(expectedExceptions = { ResolutionException.class })
     public void testExportSamePackageAsBootLayer() {
-        ModuleDescriptor descriptor
-            =  ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor = newBuilder("m1")
                 .requires("java.base")
                 .exports("java.lang")
                 .build();
@@ -1798,7 +1699,7 @@
         Configuration bootConfiguration = Layer.boot().configuration();
 
         // m1 contains package java.lang, java.base exports package java.lang to m1
-        resolveRequires(bootConfiguration, finder, "m1");
+        resolve(bootConfiguration, finder, "m1");
     }
 
 
@@ -1806,15 +1707,14 @@
      * Test "uses p.S" where p is contained in the same module.
      */
     public void testContainsService1() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .contains("p")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
+                .packages(Set.of("p"))
                 .uses("p.S")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 1);
         assertTrue(cf.findModule("m1").isPresent());
@@ -1826,13 +1726,11 @@
      */
     @Test(expectedExceptions = { ResolutionException.class })
     public void testContainsService2() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .contains("p")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
+                .packages(Set.of("p"))
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
                 .uses("p.S")
                 .build();
@@ -1840,7 +1738,7 @@
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         // m2 does not read a module that exports p
-        resolveRequires(finder, "m2");
+        resolve(finder, "m2");
     }
 
 
@@ -1848,16 +1746,14 @@
      * Test "provides p.S" where p is contained in the same module.
      */
     public void testContainsService3() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .contains("p")
-                .contains("q")
-                .provides("p.S", "q.S1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
+                .packages(Set.of("p", "q"))
+                .provides("p.S", List.of("q.S1"))
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 1);
         assertTrue(cf.findModule("m1").isPresent());
@@ -1869,22 +1765,19 @@
      */
     @Test(expectedExceptions = { ResolutionException.class })
     public void testContainsService4() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .contains("p")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
+                .packages(Set.of("p"))
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m1")
-                .contains("q")
-                .provides("p.S", "q.S1")
+                .provides("p.S", List.of("q.S1"))
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         // m2 does not read a module that exports p
-        resolveRequires(finder, "m2");
+        resolve(finder, "m2");
     }
 
 
@@ -1893,15 +1786,14 @@
      */
     @Test(expectedExceptions = { ResolutionException.class })
     public void testServiceTypePackageNotExported1() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .uses("p.S")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
         // m1 does not read a module that exports p
-        resolveRequires(finder, "m1");
+        resolve(finder, "m1");
     }
 
 
@@ -1910,40 +1802,14 @@
      */
     @Test(expectedExceptions = { ResolutionException.class })
     public void testServiceTypePackageNotExported2() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .contains("q")
-                .provides("p.S", "q.T")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
+                .provides("p.S", List.of("q.T"))
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
         // m1 does not read a module that exports p
-        resolveRequires(finder, "m1");
-    }
-
-
-    /**
-     * Test "provides p.S with q.T" where q.T is not local
-     */
-    @Test(expectedExceptions = { ResolutionException.class })
-    public void testProviderPackageNotLocal() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .exports("p")
-                .exports("q")
-                .build();
-
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
-                .requires("m1")
-                .provides("p.S", "q.T")
-                .build();
-
-        ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
-
-        // q.T not in module m2
-        resolveRequires(finder, "m2");
+        resolve(finder, "m1");
     }
 
 
@@ -2007,34 +1873,17 @@
     @Test(dataProvider = "platformmatch")
     public void testPlatformMatch(String s1, String s2) {
 
-        ModuleDescriptor.Builder builder
-            = ModuleDescriptor.module("m1").requires("m2");
-
-        String[] s = s1.split("-");
-        if (!s[0].equals("*"))
-            builder.osName(s[0]);
-        if (!s[1].equals("*"))
-            builder.osArch(s[1]);
-        if (!s[2].equals("*"))
-            builder.osVersion(s[2]);
-
+        Builder builder = newBuilder("m1").requires("m2");
+        addPlatformConstraints(builder, s1);
         ModuleDescriptor descriptor1 = builder.build();
 
-        builder = ModuleDescriptor.module("m2");
-
-        s = s2.split("-");
-        if (!s[0].equals("*"))
-            builder.osName(s[0]);
-        if (!s[1].equals("*"))
-            builder.osArch(s[1]);
-        if (!s[2].equals("*"))
-            builder.osVersion(s[2]);
-
+        builder = newBuilder("m2");
+        addPlatformConstraints(builder, s2);
         ModuleDescriptor descriptor2 = builder.build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         assertTrue(cf.modules().size() == 2);
         assertTrue(cf.findModule("m1").isPresent());
@@ -2046,7 +1895,7 @@
      * platforms.
      */
     @Test(dataProvider = "platformmismatch",
-          expectedExceptions = ResolutionException.class )
+          expectedExceptions = FindException.class )
     public void testPlatformMisMatch(String s1, String s2) {
         testPlatformMatch(s1, s2);
     }
@@ -2057,16 +1906,67 @@
     @Test(expectedExceptions = { IllegalArgumentException.class })
     public void testResolveRequiresWithNoParents() {
         ModuleFinder empty = ModuleFinder.of();
-        Configuration.resolveRequires(empty, List.of(), empty, Set.of());
+        Configuration.resolve(empty, List.of(), empty, Set.of());
     }
 
     @Test(expectedExceptions = { IllegalArgumentException.class })
     public void testResolveRequiresAndUsesWithNoParents() {
         ModuleFinder empty = ModuleFinder.of();
-        Configuration.resolveRequiresAndUses(empty, List.of(), empty, Set.of());
+        Configuration.resolveAndBind(empty, List.of(), empty, Set.of());
     }
 
 
+    // parents with modules for specific platforms
+
+    @Test(dataProvider = "platformmatch")
+    public void testResolveRequiresWithCompatibleParents(String s1, String s2) {
+        Builder builder = newBuilder("m1");
+        addPlatformConstraints(builder, s1);
+        ModuleDescriptor descriptor1 = builder.build();
+
+        builder = newBuilder("m2");
+        addPlatformConstraints(builder, s2);
+        ModuleDescriptor descriptor2 = builder.build();
+
+        ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
+        Configuration cf1 = resolve(finder1, "m1");
+
+        ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
+        Configuration cf2 = resolve(finder2, "m2");
+
+        Configuration cf3 = Configuration.resolve(ModuleFinder.of(),
+                                                  List.of(cf1, cf2),
+                                                  ModuleFinder.of(),
+                                                  Set.of());
+        assertTrue(cf3.parents().size() == 2);
+    }
+
+    @Test(dataProvider = "platformmismatch",
+          expectedExceptions = IllegalArgumentException.class )
+    public void testResolveRequiresWithConflictingParents(String s1, String s2) {
+        Builder builder = newBuilder("m1");
+        addPlatformConstraints(builder, s1);
+        ModuleDescriptor descriptor1 = builder.build();
+
+        builder = newBuilder("m2");
+        addPlatformConstraints(builder, s2);
+        ModuleDescriptor descriptor2 = builder.build();
+
+        ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
+        Configuration cf1 = resolve(finder1, "m1");
+
+        ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
+        Configuration cf2 = resolve(finder2, "m2");
+
+        // should throw IAE
+        Configuration.resolve(ModuleFinder.of(),
+                              List.of(cf1, cf2),
+                              ModuleFinder.of(),
+                              Set.of());
+    }
+
+
+
     // null handling
 
     // finder1, finder2, roots
@@ -2074,72 +1974,72 @@
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresWithNull1() {
-        resolveRequires((ModuleFinder)null, ModuleFinder.of());
+        resolve((ModuleFinder)null, ModuleFinder.of());
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresWithNull2() {
-        resolveRequires(ModuleFinder.of(), (ModuleFinder)null);
+        resolve(ModuleFinder.of(), (ModuleFinder)null);
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresWithNull3() {
         Configuration empty = Configuration.empty();
-        Configuration.resolveRequires(null, List.of(empty),  ModuleFinder.of(), Set.of());
+        Configuration.resolve(null, List.of(empty),  ModuleFinder.of(), Set.of());
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresWithNull4() {
         ModuleFinder empty = ModuleFinder.of();
-        Configuration.resolveRequires(empty, null, empty, Set.of());
+        Configuration.resolve(empty, null, empty, Set.of());
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresWithNull5() {
         Configuration cf = Layer.boot().configuration();
-        Configuration.resolveRequires(ModuleFinder.of(), List.of(cf), null, Set.of());
+        Configuration.resolve(ModuleFinder.of(), List.of(cf), null, Set.of());
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresWithNull6() {
         ModuleFinder empty = ModuleFinder.of();
         Configuration cf = Layer.boot().configuration();
-        Configuration.resolveRequires(empty, List.of(cf), empty, null);
+        Configuration.resolve(empty, List.of(cf), empty, null);
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresAndUsesWithNull1() {
-        resolveRequiresAndUses((ModuleFinder) null, ModuleFinder.of());
+        resolveAndBind((ModuleFinder) null, ModuleFinder.of());
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresAndUsesWithNull2() {
-        resolveRequiresAndUses(ModuleFinder.of(), (ModuleFinder) null);
+        resolveAndBind(ModuleFinder.of(), (ModuleFinder) null);
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresAndUsesWithNull3() {
         Configuration empty = Configuration.empty();
-        Configuration.resolveRequiresAndUses(null, List.of(empty), ModuleFinder.of(), Set.of());
+        Configuration.resolveAndBind(null, List.of(empty), ModuleFinder.of(), Set.of());
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresAndUsesWithNull4() {
         ModuleFinder empty = ModuleFinder.of();
-        Configuration.resolveRequiresAndUses(empty, null, empty, Set.of());
+        Configuration.resolveAndBind(empty, null, empty, Set.of());
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresAndUsesWithNull5() {
         Configuration cf = Layer.boot().configuration();
-        Configuration.resolveRequiresAndUses(ModuleFinder.of(), List.of(cf), null, Set.of());
+        Configuration.resolveAndBind(ModuleFinder.of(), List.of(cf), null, Set.of());
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testResolveRequiresAndUsesWithNull6() {
         ModuleFinder empty = ModuleFinder.of();
         Configuration cf = Layer.boot().configuration();
-        Configuration.resolveRequiresAndUses(empty, List.of(cf), empty, null);
+        Configuration.resolveAndBind(empty, List.of(cf), empty, null);
     }
 
     @Test(expectedExceptions = { NullPointerException.class })
@@ -2165,58 +2065,58 @@
 
 
     /**
-     * Invokes parent.resolveRequires(...)
+     * Invokes parent.resolve(...)
      */
-    private Configuration resolveRequires(Configuration parent,
-                                          ModuleFinder before,
-                                          ModuleFinder after,
-                                          String... roots) {
-        return parent.resolveRequires(before, after, Set.of(roots));
+    private Configuration resolve(Configuration parent,
+                                  ModuleFinder before,
+                                  ModuleFinder after,
+                                  String... roots) {
+        return parent.resolve(before, after, Set.of(roots));
     }
 
-    private Configuration resolveRequires(Configuration parent,
-                                          ModuleFinder before,
-                                          String... roots) {
-        return resolveRequires(parent, before, ModuleFinder.of(), roots);
+    private Configuration resolve(Configuration parent,
+                                  ModuleFinder before,
+                                  String... roots) {
+        return resolve(parent, before, ModuleFinder.of(), roots);
     }
 
-    private Configuration resolveRequires(ModuleFinder before,
-                                          ModuleFinder after,
-                                          String... roots) {
-        return resolveRequires(Configuration.empty(), before, after, roots);
+    private Configuration resolve(ModuleFinder before,
+                                  ModuleFinder after,
+                                  String... roots) {
+        return resolve(Configuration.empty(), before, after, roots);
     }
 
-    private Configuration resolveRequires(ModuleFinder before,
-                                          String... roots) {
-        return resolveRequires(Configuration.empty(), before, roots);
+    private Configuration resolve(ModuleFinder before,
+                                  String... roots) {
+        return resolve(Configuration.empty(), before, roots);
     }
 
 
     /**
-     * Invokes parent.resolveRequiresAndUses(...)
+     * Invokes parent.resolveAndBind(...)
      */
-    private Configuration resolveRequiresAndUses(Configuration parent,
-                                                 ModuleFinder before,
-                                                 ModuleFinder after,
-                                                 String... roots) {
-        return parent.resolveRequiresAndUses(before, after, Set.of(roots));
+    private Configuration resolveAndBind(Configuration parent,
+                                         ModuleFinder before,
+                                         ModuleFinder after,
+                                         String... roots) {
+        return parent.resolveAndBind(before, after, Set.of(roots));
     }
 
-    private Configuration resolveRequiresAndUses(Configuration parent,
-                                                 ModuleFinder before,
-                                                 String... roots) {
-        return resolveRequiresAndUses(parent, before, ModuleFinder.of(), roots);
+    private Configuration resolveAndBind(Configuration parent,
+                                         ModuleFinder before,
+                                         String... roots) {
+        return resolveAndBind(parent, before, ModuleFinder.of(), roots);
     }
 
-    private Configuration resolveRequiresAndUses(ModuleFinder before,
-                                                 ModuleFinder after,
-                                                 String... roots) {
-        return resolveRequiresAndUses(Configuration.empty(), before, after, roots);
+    private Configuration resolveAndBind(ModuleFinder before,
+                                         ModuleFinder after,
+                                         String... roots) {
+        return resolveAndBind(Configuration.empty(), before, after, roots);
     }
 
-    private Configuration resolveRequiresAndUses(ModuleFinder before,
-                                                 String... roots) {
-        return resolveRequiresAndUses(Configuration.empty(), before, roots);
+    private Configuration resolveAndBind(ModuleFinder before,
+                                         String... roots) {
+        return resolveAndBind(Configuration.empty(), before, roots);
     }
 
 
@@ -2234,5 +2134,17 @@
                 .anyMatch(mn2::equals);
     }
 
-
+    /**
+     * Decodes the platform string and calls the builder osName/osArch/osVersion
+     * methods to set the platform constraints.
+     */
+    static void addPlatformConstraints(Builder builder, String platformString) {
+        String[] s = platformString.split("-");
+        if (!s[0].equals("*"))
+            builder.osName(s[0]);
+        if (!s[1].equals("*"))
+            builder.osArch(s[1]);
+        if (!s[2].equals("*"))
+            builder.osVersion(s[2]);
+    }
 }
--- a/jdk/test/java/lang/module/ModuleDescriptorTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/module/ModuleDescriptorTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -24,6 +24,7 @@
 /**
  * @test
  * @modules java.base/jdk.internal.module
+ *          java.base/jdk.internal.misc
  * @run testng ModuleDescriptorTest
  * @summary Basic test for java.lang.module.ModuleDescriptor and its builder
  */
@@ -42,14 +43,19 @@
 import java.lang.module.ModuleDescriptor.Version;
 import java.lang.reflect.Module;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
 
+import jdk.internal.misc.SharedSecrets;
 import jdk.internal.module.ModuleInfoWriter;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
@@ -84,21 +90,27 @@
     // requires
 
     private Requires requires(Set<Modifier> mods, String mn) {
-        return ModuleDescriptor.module("m")
-            .requires(mods, mn)
-            .build()
-            .requires()
-            .iterator()
-            .next();
+        return requires(mods, mn, null);
     }
 
     private Requires requires(Set<Modifier> mods, String mn, Version v) {
-        return ModuleDescriptor.module("m")
-            .requires(mods, mn, v)
-            .build()
-            .requires()
-            .iterator()
-            .next();
+        Builder builder = ModuleDescriptor.newModule("m");
+        if (v == null) {
+            builder.requires(mods, mn);
+        } else {
+            builder.requires(mods, mn, v);
+        }
+        Set<Requires> requires = builder.build().requires();
+        assertTrue(requires.size() == 2);
+        Iterator<Requires> iterator = requires.iterator();
+        Requires r = iterator.next();
+        if (r.name().equals("java.base")) {
+            r = iterator.next();
+        } else {
+            Requires other = iterator.next();
+            assertEquals(other.name(), "java.base");
+        }
+        return r;
     }
 
     private Requires requires(String mn) {
@@ -107,7 +119,7 @@
 
     public void testRequiresWithRequires() {
         Requires r1 = requires("foo");
-        ModuleDescriptor descriptor = ModuleDescriptor.module("m").requires(r1).build();
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").requires(r1).build();
         Requires r2 = descriptor.requires().iterator().next();
         assertEquals(r1, r2);
     }
@@ -162,28 +174,28 @@
     @Test(expectedExceptions = IllegalStateException.class)
     public void testRequiresWithDuplicatesRequires() {
         Requires r = requires("foo");
-        ModuleDescriptor.module("m").requires(r).requires(r);
+        ModuleDescriptor.newModule("m").requires(r).requires(r);
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testRequiresSelfWithRequires() {
         Requires r = requires("foo");
-        ModuleDescriptor.module("foo").requires(r);
+        ModuleDescriptor.newModule("foo").requires(r);
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testRequiresSelfWithNoModifier() {
-        ModuleDescriptor.module("m").requires("m");
+        ModuleDescriptor.newModule("m").requires("m");
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testRequiresSelfWithOneModifier() {
-        ModuleDescriptor.module("m").requires(Set.of(TRANSITIVE), "m");
+        ModuleDescriptor.newModule("m").requires(Set.of(TRANSITIVE), "m");
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testRequiresSelfWithAllModifiers() {
-        ModuleDescriptor.module("m").requires(EnumSet.allOf(Modifier.class), "m");
+        ModuleDescriptor.newModule("m").requires(EnumSet.allOf(Modifier.class), "m");
     }
 
     @Test(dataProvider = "invalidjavaidentifiers",
@@ -194,17 +206,17 @@
 
     @Test(expectedExceptions = NullPointerException.class)
     public void testRequiresWithNullRequires() {
-        ModuleDescriptor.module("m").requires((Requires) null);
+        ModuleDescriptor.newModule("m").requires((Requires) null);
     }
 
     @Test(expectedExceptions = NullPointerException.class)
     public void testRequiresWithNullModifiers() {
-        ModuleDescriptor.module("m").requires(null, "foo");
+        ModuleDescriptor.newModule("m").requires(null, "foo");
     }
 
     @Test(expectedExceptions = NullPointerException.class)
     public void testRequiresWithNullVersion() {
-        ModuleDescriptor.module("m").requires(Set.of(), "foo", null);
+        ModuleDescriptor.newModule("m").requires(Set.of(), "foo", null);
     }
 
     public void testRequiresCompare() {
@@ -284,7 +296,7 @@
     // exports
 
     private Exports exports(Set<Exports.Modifier> mods, String pn) {
-        return ModuleDescriptor.module("foo")
+        return ModuleDescriptor.newModule("foo")
             .exports(mods, pn)
             .build()
             .exports()
@@ -297,7 +309,7 @@
     }
 
     private Exports exports(Set<Exports.Modifier> mods, String pn, String target) {
-        return ModuleDescriptor.module("foo")
+        return ModuleDescriptor.newModule("foo")
             .exports(mods, pn, Set.of(target))
             .build()
             .exports()
@@ -312,7 +324,7 @@
 
     public void testExportsExports() {
         Exports e1 = exports("p");
-        ModuleDescriptor descriptor = ModuleDescriptor.module("m").exports(e1).build();
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").exports(e1).build();
         Exports e2 = descriptor.exports().iterator().next();
         assertEquals(e1, e2);
     }
@@ -341,7 +353,7 @@
         targets.add("bar");
         targets.add("gus");
         Exports e
-            = ModuleDescriptor.module("foo")
+            = ModuleDescriptor.newModule("foo")
                 .exports("p", targets)
                 .build()
                 .exports()
@@ -380,69 +392,80 @@
     @Test(expectedExceptions = IllegalStateException.class)
     public void testExportsWithDuplicate1() {
         Exports e = exports("p");
-        ModuleDescriptor.module("foo").exports(e).exports(e);
+        ModuleDescriptor.newModule("foo").exports(e).exports(e);
     }
 
     @Test(expectedExceptions = IllegalStateException.class)
     public void testExportsWithDuplicate2() {
-        ModuleDescriptor.module("foo").exports("p").exports("p");
-    }
-
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void testExportsOnContainedPackage() {
-        ModuleDescriptor.module("foo").contains("p").exports("p");
-    }
-
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void testExportsToTargetOnContainedPackage() {
-        ModuleDescriptor.module("foo").contains("p").exports("p", Set.of("bar"));
+        ModuleDescriptor.newModule("foo").exports("p").exports("p");
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class )
     public void testExportsWithEmptySet() {
-        ModuleDescriptor.module("foo").exports("p", Collections.emptySet());
+        ModuleDescriptor.newModule("foo").exports("p", Collections.emptySet());
     }
 
     @Test(dataProvider = "invalidjavaidentifiers",
           expectedExceptions = IllegalArgumentException.class )
     public void testExportsWithBadName(String pn, String ignore) {
-        ModuleDescriptor.module("foo").exports(pn);
+        ModuleDescriptor.newModule("foo").exports(pn);
     }
 
     @Test(expectedExceptions = NullPointerException.class )
     public void testExportsWithNullExports() {
-        ModuleDescriptor.module("foo").exports((Exports) null);
+        ModuleDescriptor.newModule("foo").exports((Exports) null);
     }
 
     @Test(expectedExceptions = NullPointerException.class )
     public void testExportsWithNullTargets() {
-        ModuleDescriptor.module("foo").exports("p", (Set<String>) null);
+        ModuleDescriptor.newModule("foo").exports("p", (Set<String>) null);
     }
 
-    public void testExportsEqualsAndHashCode() {
-        Exports e1, e2;
+    public void testExportsCompare() {
+        Exports e1 = exports("p");
+        Exports e2 = exports("p");
+        assertEquals(e1, e2);
+        assertTrue(e1.hashCode() == e2.hashCode());
+        assertTrue(e1.compareTo(e2) == 0);
+        assertTrue(e2.compareTo(e1) == 0);
+    }
 
-        e1 = exports("p");
-        e2 = exports("p");
+    public void testExportsCompareWithSameModifiers() {
+        Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
+        Exports e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
         assertEquals(e1, e2);
         assertTrue(e1.hashCode() == e2.hashCode());
+        assertTrue(e1.compareTo(e2) == 0);
+        assertTrue(e2.compareTo(e1) == 0);
+    }
 
-        e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
-        e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
+    public void testExportsCompareWithDifferentModifiers() {
+        Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
+        Exports e2 = exports("p");
+        assertNotEquals(e1, e2);
+        assertTrue(e1.compareTo(e2) == 1);
+        assertTrue(e2.compareTo(e1) == -1);
+    }
+
+    public void testExportsCompareWithSameTargets() {
+        Exports e1 = exports("p", "x");
+        Exports e2 = exports("p", "x");
         assertEquals(e1, e2);
         assertTrue(e1.hashCode() == e2.hashCode());
+        assertTrue(e1.compareTo(e2) == 0);
+        assertTrue(e2.compareTo(e1) == 0);
+    }
 
-        e1 = exports("p");
-        e2 = exports("q");
+    public void testExportsCompareWithDifferentTargets() {
+        Exports e1 = exports("p", "y");
+        Exports e2 = exports("p", "x");
         assertNotEquals(e1, e2);
-
-        e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
-        e2 = exports(Set.of(), "p");
-        assertNotEquals(e1, e2);
+        assertTrue(e1.compareTo(e2) == 1);
+        assertTrue(e2.compareTo(e1) == -1);
     }
 
     public void testExportsToString() {
-        String s = ModuleDescriptor.module("foo")
+        String s = ModuleDescriptor.newModule("foo")
             .exports("p1", Set.of("bar"))
             .build()
             .exports()
@@ -457,7 +480,7 @@
     // opens
 
     private Opens opens(Set<Opens.Modifier> mods, String pn) {
-        return ModuleDescriptor.module("foo")
+        return ModuleDescriptor.newModule("foo")
                 .opens(mods, pn)
                 .build()
                 .opens()
@@ -470,7 +493,7 @@
     }
 
     private Opens opens(Set<Opens.Modifier> mods, String pn, String target) {
-        return ModuleDescriptor.module("foo")
+        return ModuleDescriptor.newModule("foo")
                 .opens(mods, pn, Set.of(target))
                 .build()
                 .opens()
@@ -484,7 +507,7 @@
 
     public void testOpensOpens() {
         Opens o1 = opens("p");
-        ModuleDescriptor descriptor = ModuleDescriptor.module("m").opens(o1).build();
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").opens(o1).build();
         Opens o2 = descriptor.opens().iterator().next();
         assertEquals(o1, o2);
     }
@@ -513,7 +536,7 @@
         Set<String> targets = new HashSet<>();
         targets.add("bar");
         targets.add("gus");
-        Opens o = ModuleDescriptor.module("foo")
+        Opens o = ModuleDescriptor.newModule("foo")
                 .opens("p", targets)
                 .build()
                 .opens()
@@ -528,98 +551,83 @@
         assertTrue(o.targets().contains("gus"));
     }
 
-    /*
-
-    public void testOpensToAllWithModifier() {
-        Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
-        assertEquals(e, e);
-        assertTrue(e.modifiers().size() == 1);
-        assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
-        assertEquals(e.source(), "p");
-        assertFalse(e.isQualified());
-        assertTrue(e.targets().isEmpty());
-    }
-
-    public void testOpensToTargetWithModifier() {
-        Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", Set.of("bar"));
-        assertEquals(e, e);
-        assertTrue(e.modifiers().size() == 1);
-        assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
-        assertEquals(e.source(), "p");
-        assertTrue(e.isQualified());
-        assertTrue(e.targets().size() == 1);
-        assertTrue(e.targets().contains("bar"));
-    }
-
-
-    */
-
     @Test(expectedExceptions = IllegalStateException.class)
     public void testOpensWithDuplicate1() {
         Opens o = opens("p");
-        ModuleDescriptor.module("foo").opens(o).opens(o);
+        ModuleDescriptor.newModule("foo").opens(o).opens(o);
     }
 
     @Test(expectedExceptions = IllegalStateException.class)
     public void testOpensWithDuplicate2() {
-        ModuleDescriptor.module("foo").opens("p").opens("p");
-    }
-
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void testOpensOnContainedPackage() {
-        ModuleDescriptor.module("foo").contains("p").opens("p");
-    }
-
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void testOpensToTargetOnContainedPackage() {
-        ModuleDescriptor.module("foo").contains("p").opens("p", Set.of("bar"));
+        ModuleDescriptor.newModule("foo").opens("p").opens("p");
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class )
     public void testOpensWithEmptySet() {
-        ModuleDescriptor.module("foo").opens("p", Collections.emptySet());
+        ModuleDescriptor.newModule("foo").opens("p", Collections.emptySet());
     }
 
     @Test(dataProvider = "invalidjavaidentifiers",
             expectedExceptions = IllegalArgumentException.class )
     public void testOpensWithBadName(String pn, String ignore) {
-        ModuleDescriptor.module("foo").opens(pn);
+        ModuleDescriptor.newModule("foo").opens(pn);
     }
 
     @Test(expectedExceptions = NullPointerException.class )
     public void testOpensWithNullExports() {
-        ModuleDescriptor.module("foo").opens((Opens) null);
+        ModuleDescriptor.newModule("foo").opens((Opens) null);
     }
 
     @Test(expectedExceptions = NullPointerException.class )
     public void testOpensWithNullTargets() {
-        ModuleDescriptor.module("foo").opens("p", (Set<String>) null);
+        ModuleDescriptor.newModule("foo").opens("p", (Set<String>) null);
+    }
+
+    public void testOpensCompare() {
+        Opens o1 = opens("p");
+        Opens o2 = opens("p");
+        assertEquals(o1, o2);
+        assertTrue(o1.hashCode() == o2.hashCode());
+        assertTrue(o1.compareTo(o2) == 0);
+        assertTrue(o2.compareTo(o1) == 0);
+    }
+
+    public void testOpensCompareWithSameModifiers() {
+        Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
+        Opens o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
+        assertEquals(o1, o2);
+        assertTrue(o1.hashCode() == o2.hashCode());
+        assertTrue(o1.compareTo(o2) == 0);
+        assertTrue(o2.compareTo(o1) == 0);
     }
 
-    public void testOpensEqualsAndHashCode() {
-        Opens o1, o2;
+    public void testOpensCompareWithDifferentModifiers() {
+        Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
+        Opens o2 = opens("p");
+        assertNotEquals(o1, o2);
+        assertTrue(o1.compareTo(o2) == 1);
+        assertTrue(o2.compareTo(o1) == -1);
+    }
 
-        o1 = opens("p");
-        o2 = opens("p");
-        assertEquals(o1, o2);
-        assertTrue(o1.hashCode() == o1.hashCode());
-
-        o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
-        o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
+    public void testOpensCompareWithSameTargets() {
+        Opens o1 = opens("p", "x");
+        Opens o2 = opens("p", "x");
         assertEquals(o1, o2);
         assertTrue(o1.hashCode() == o2.hashCode());
+        assertTrue(o1.compareTo(o2) == 0);
+        assertTrue(o2.compareTo(o1) == 0);
+    }
 
-        o1 = opens("p");
-        o2 = opens("q");
+    public void testOpensCompareWithDifferentTargets() {
+        Opens o1 = opens("p", "y");
+        Opens o2 = opens("p", "x");
         assertNotEquals(o1, o2);
-
-        o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
-        o2 = opens(Set.of(), "p");
-        assertNotEquals(o1, o2);
+        assertTrue(o1.compareTo(o2) == 1);
+        assertTrue(o2.compareTo(o1) == -1);
     }
 
     public void testOpensToString() {
-        String s = ModuleDescriptor.module("foo")
+        String s = ModuleDescriptor.newModule("foo")
                 .opens("p1", Set.of("bar"))
                 .build()
                 .opens()
@@ -635,7 +643,7 @@
 
     public void testUses() {
         Set<String> uses
-            = ModuleDescriptor.module("foo")
+            = ModuleDescriptor.newModule("foo")
                 .uses("p.S")
                 .uses("q.S")
                 .build()
@@ -647,30 +655,44 @@
 
     @Test(expectedExceptions = IllegalStateException.class)
     public void testUsesWithDuplicate() {
-        ModuleDescriptor.module("foo").uses("p.S").uses("p.S");
+        ModuleDescriptor.newModule("foo").uses("p.S").uses("p.S");
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testUsesWithSimpleIdentifier() {
+        ModuleDescriptor.newModule("foo").uses("S");
     }
 
     @Test(dataProvider = "invalidjavaidentifiers",
           expectedExceptions = IllegalArgumentException.class )
     public void testUsesWithBadName(String service, String ignore) {
-        ModuleDescriptor.module("foo").uses(service);
+        ModuleDescriptor.newModule("foo").uses(service);
     }
 
 
     // provides
 
     private Provides provides(String st, String pc) {
-        return ModuleDescriptor.module("foo")
-            .provides(st, pc)
+        return ModuleDescriptor.newModule("foo")
+            .provides(st, List.of(pc))
             .build()
             .provides()
             .iterator()
             .next();
     }
 
+    private Provides provides(String st, List<String> pns) {
+        return ModuleDescriptor.newModule("foo")
+                .provides(st, pns)
+                .build()
+                .provides()
+                .iterator()
+                .next();
+    }
+
     public void testProvidesWithProvides() {
         Provides p1 = provides("p.S", "q.S1");
-        ModuleDescriptor descriptor = ModuleDescriptor.module("m")
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule("m")
                 .provides(p1)
                 .build();
         Provides p2 = descriptor.provides().iterator().next();
@@ -679,7 +701,7 @@
 
 
     public void testProvides() {
-        Set<Provides> set = ModuleDescriptor.module("foo")
+        Set<Provides> set = ModuleDescriptor.newModule("foo")
                 .provides("p.S", List.of("q.P1", "q.P2"))
                 .build()
                 .provides();
@@ -696,59 +718,86 @@
     @Test(expectedExceptions = IllegalStateException.class )
     public void testProvidesWithDuplicateProvides() {
         Provides p = provides("p.S", "q.S2");
-        ModuleDescriptor.module("m").provides("p.S", "q.S1").provides(p);
+        ModuleDescriptor.newModule("m").provides("p.S", List.of("q.S1")).provides(p);
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class )
     public void testProvidesWithEmptySet() {
-        ModuleDescriptor.module("foo").provides("p.Service", Collections.emptyList());
+        ModuleDescriptor.newModule("foo").provides("p.Service", Collections.emptyList());
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class )
+    public void testProvidesWithSimpleIdentifier1() {
+        ModuleDescriptor.newModule("foo").provides("S", List.of("q.P"));
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class )
+    public void testProvidesWithSimpleIdentifier2() {
+        ModuleDescriptor.newModule("foo").provides("p.S", List.of("P"));
     }
 
     @Test(dataProvider = "invalidjavaidentifiers",
           expectedExceptions = IllegalArgumentException.class )
     public void testProvidesWithBadService(String service, String ignore) {
-        ModuleDescriptor.module("foo").provides(service, "p.Provider");
+        ModuleDescriptor.newModule("foo").provides(service, List.of("p.Provider"));
     }
 
     @Test(dataProvider = "invalidjavaidentifiers",
           expectedExceptions = IllegalArgumentException.class )
     public void testProvidesWithBadProvider(String provider, String ignore) {
-        ModuleDescriptor.module("foo").provides("p.Service", provider);
+        List<String> names = new ArrayList<>(); // allows nulls
+        names.add(provider);
+        ModuleDescriptor.newModule("foo").provides("p.Service", names);
     }
 
     @Test(expectedExceptions = NullPointerException.class )
     public void testProvidesWithNullProvides() {
-        ModuleDescriptor.module("foo").provides((Provides) null);
+        ModuleDescriptor.newModule("foo").provides((Provides) null);
     }
 
     @Test(expectedExceptions = NullPointerException.class )
     public void testProvidesWithNullProviders() {
-        ModuleDescriptor.module("foo").provides("p.S", (List<String>) null);
+        ModuleDescriptor.newModule("foo").provides("p.S", (List<String>) null);
     }
 
-    public void testProvidesEqualsAndHashCode() {
-        Provides p1, p2;
-
-        p1 = provides("p.S", "q.S1");
-        p2 = provides("p.S", "q.S1");
+    public void testProvidesCompare() {
+        Provides p1 = provides("p.S", "q.S1");
+        Provides p2 = provides("p.S", "q.S1");
         assertEquals(p1, p2);
         assertTrue(p1.hashCode() == p2.hashCode());
+        assertTrue(p1.compareTo(p2) == 0);
+        assertTrue(p2.compareTo(p1) == 0);
+    }
 
-        p1 = provides("p.S", "q.S1");
-        p2 = provides("p.S", "q.S2");
+    public void testProvidesCompareWithDifferentService() {
+        Provides p1 = provides("p.S2", "q.S1");
+        Provides p2 = provides("p.S1", "q.S1");
         assertNotEquals(p1, p2);
-
-        p1 = provides("p.S", "q.S1");
-        p2 = provides("p.S2", "q.S1");
-        assertNotEquals(p1, p2);
+        assertTrue(p1.compareTo(p2) == 1);
+        assertTrue(p2.compareTo(p1) == -1);
     }
 
-    // contains
+    public void testProvidesCompareWithDifferentProviders1() {
+        Provides p1 = provides("p.S", "q.S2");
+        Provides p2 = provides("p.S", "q.S1");
+        assertNotEquals(p1, p2);
+        assertTrue(p1.compareTo(p2) == 1);
+        assertTrue(p2.compareTo(p1) == -1);
+    }
 
-    public void testContains() {
-        Set<String> packages = ModuleDescriptor.module("foo")
-                .contains("p")
-                .contains("q")
+    public void testProvidesCompareWithDifferentProviders2() {
+        Provides p1 = provides("p.S", List.of("q.S1", "q.S2"));
+        Provides p2 = provides("p.S", "q.S1");
+        assertNotEquals(p1, p2);
+        assertTrue(p1.compareTo(p2) == 1);
+        assertTrue(p2.compareTo(p1) == -1);
+    }
+
+    // packages
+
+    public void testPackages1() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .packages(Set.of("p", "q"))
                 .build()
                 .packages();
         assertTrue(packages.size() == 2);
@@ -756,37 +805,10 @@
         assertTrue(packages.contains("q"));
     }
 
-    public void testContainsWithEmptySet() {
-        Set<String> packages = ModuleDescriptor.module("foo")
-                .contains(Collections.emptySet())
-                .build()
-                .packages();
-        assertTrue(packages.size() == 0);
-    }
-
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void testContainsWithDuplicate() {
-        ModuleDescriptor.module("foo").contains("p").contains("p");
-    }
-
-    @Test(expectedExceptions = IllegalStateException.class)
-    public void testContainsWithExportedPackage() {
-        ModuleDescriptor.module("foo").exports("p").contains("p");
-    }
-
-    @Test(dataProvider = "invalidjavaidentifiers",
-          expectedExceptions = IllegalArgumentException.class )
-    public void testContainsWithBadName(String pn, String ignore) {
-        ModuleDescriptor.module("foo").contains(pn);
-    }
-
-
-    // packages
-
-    public void testPackages() {
-        Set<String> packages = ModuleDescriptor.module("foo")
-                .exports("p")
-                .contains("q")
+    public void testPackages2() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .packages(Set.of("p"))
+                .packages(Set.of("q"))
                 .build()
                 .packages();
         assertTrue(packages.size() == 2);
@@ -795,17 +817,135 @@
     }
 
 
+    public void testPackagesWithEmptySet() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .packages(Collections.emptySet())
+                .build()
+                .packages();
+        assertTrue(packages.size() == 0);
+    }
+
+    public void testPackagesDuplicate() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .packages(Set.of("p"))
+                .packages(Set.of("p"))
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndExportsPackage1() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .packages(Set.of("p"))
+                .exports("p")
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndExportsPackage2() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .exports("p")
+                .packages(Set.of("p"))
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndOpensPackage1() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .packages(Set.of("p"))
+                .opens("p")
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndOpensPackage2() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .opens("p")
+                .packages(Set.of("p"))
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndProvides1() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .packages(Set.of("p"))
+                .provides("q.S", List.of("p.T"))
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndProvides2() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .provides("q.S", List.of("p.T"))
+                .packages(Set.of("p"))
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndMainClass1() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .packages(Set.of("p"))
+                .mainClass("p.Main")
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndMainClass2() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .mainClass("p.Main")
+                .packages(Set.of("p"))
+                .build()
+                .packages();
+        assertTrue(packages.size() == 1);
+        assertTrue(packages.contains("p"));
+    }
+
+    public void testPackagesAndAll() {
+        Set<String> packages = ModuleDescriptor.newModule("foo")
+                .exports("p1")
+                .opens("p2")
+                .packages(Set.of("p3"))
+                .provides("q.S", List.of("p4.T"))
+                .mainClass("p5.Main")
+                .build()
+                .packages();
+        assertTrue(Objects.equals(packages, Set.of("p1", "p2", "p3", "p4", "p5")));
+    }
+
+    @Test(dataProvider = "invalidjavaidentifiers",
+          expectedExceptions = IllegalArgumentException.class )
+    public void testPackagesWithBadName(String pn, String ignore) {
+        Set<String> pkgs = new HashSet<>();  // allows nulls
+        pkgs.add(pn);
+        ModuleDescriptor.newModule("foo").packages(pkgs);
+    }
+
     // name
 
     public void testModuleName() {
-        String mn = ModuleDescriptor.module("foo").build().name();
+        String mn = ModuleDescriptor.newModule("foo").build().name();
         assertEquals(mn, "foo");
     }
 
     @Test(dataProvider = "invalidjavaidentifiers",
           expectedExceptions = IllegalArgumentException.class )
     public void testBadModuleName(String mn, String ignore) {
-        ModuleDescriptor.module(mn);
+        ModuleDescriptor.newModule(mn);
     }
 
 
@@ -813,7 +953,7 @@
 
     public void testVersion1() {
         Version v1 = Version.parse("1.0");
-        Version v2 = ModuleDescriptor.module("foo")
+        Version v2 = ModuleDescriptor.newModule("foo")
                 .version(v1)
                 .build()
                 .version()
@@ -823,7 +963,7 @@
 
     public void testVersion2() {
         String vs = "1.0";
-        Version v1 = ModuleDescriptor.module("foo")
+        Version v1 = ModuleDescriptor.newModule("foo")
                 .version(vs)
                 .build()
                 .version()
@@ -834,86 +974,178 @@
 
     @Test(expectedExceptions = NullPointerException.class )
     public void testNullVersion1() {
-        ModuleDescriptor.module("foo").version((Version) null);
+        ModuleDescriptor.newModule("foo").version((Version) null);
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class )
     public void testNullVersion2() {
-        ModuleDescriptor.module("foo").version((String) null);
+        ModuleDescriptor.newModule("foo").version((String) null);
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class )
     public void testEmptyVersion() {
-        ModuleDescriptor.module("foo").version("");
+        ModuleDescriptor.newModule("foo").version("");
     }
 
 
     // toNameAndVersion
 
     public void testToNameAndVersion() {
-        ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
+        ModuleDescriptor md1 = ModuleDescriptor.newModule("foo").build();
         assertEquals(md1.toNameAndVersion(), "foo");
 
-        ModuleDescriptor md2 = ModuleDescriptor.module("foo").version("1.0").build();
+        ModuleDescriptor md2 = ModuleDescriptor.newModule("foo").version("1.0").build();
         assertEquals(md2.toNameAndVersion(), "foo@1.0");
     }
 
 
     // open modules
 
-    public void testOpenModules() {
-        ModuleDescriptor descriptor = ModuleDescriptor.openModule("m")
-                .requires("java.base")
-                .contains("p")
+    public void testOpenModule() {
+        ModuleDescriptor descriptor = ModuleDescriptor.newOpenModule("foo")
+                .requires("bar")
+                .exports("p")
+                .provides("p.Service", List.of("q.ServiceImpl"))
                 .build();
+
+        // modifiers
+        assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.OPEN));
         assertTrue(descriptor.isOpen());
-        assertTrue(descriptor.packages().size() == 1);
-        assertTrue(descriptor.packages().contains("p"));
-        assertTrue(descriptor.exports().isEmpty());
+
+        // requires
+        assertTrue(descriptor.requires().size() == 2);
+        Set<String> names = descriptor.requires()
+                .stream()
+                .map(Requires::name)
+                .collect(Collectors.toSet());
+        assertEquals(names, Set.of("bar", "java.base"));
+
+        // packages
+        assertEquals(descriptor.packages(), Set.of("p", "q"));
+
+        // exports
+        assertTrue(descriptor.exports().size() == 1);
+        names = descriptor.exports()
+                .stream()
+                .map(Exports::source)
+                .collect(Collectors.toSet());
+        assertEquals(names, Set.of("p"));
+
+        // opens
+        assertTrue(descriptor.opens().isEmpty());
     }
 
     @Test(expectedExceptions = IllegalStateException.class)
-    public void testOpensOnWeakModule1() {
-        ModuleDescriptor.openModule("foo").opens("p");
+    public void testOpensOnOpenModule1() {
+        ModuleDescriptor.newOpenModule("foo").opens("p");
     }
 
     @Test(expectedExceptions = IllegalStateException.class)
-    public void testOpensOnWeakModule2() {
-        ModuleDescriptor.openModule("foo").opens("p", Set.of("bar"));
+    public void testOpensOnOpenModule2() {
+        ModuleDescriptor.newOpenModule("foo").opens("p", Set.of("bar"));
     }
 
     public void testIsOpen() {
-        assertFalse(ModuleDescriptor.module("m").build().isOpen());
-        assertFalse(ModuleDescriptor.automaticModule("m").build().isOpen());
-        assertTrue(ModuleDescriptor.openModule("m").build().isOpen());
+        assertFalse(ModuleDescriptor.newModule("m").build().isOpen());
+        assertFalse(ModuleDescriptor.newAutomaticModule("m").build().isOpen());
+        assertTrue(ModuleDescriptor.newOpenModule("m").build().isOpen());
     }
 
 
     // automatic modules
 
+    public void testAutomaticModule() {
+        ModuleDescriptor descriptor = ModuleDescriptor.newAutomaticModule("foo")
+                .packages(Set.of("p"))
+                .provides("p.Service", List.of("q.ServiceImpl"))
+                .build();
+
+        // modifiers
+        assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.AUTOMATIC));
+        assertTrue(descriptor.isAutomatic());
+
+        // requires
+        assertTrue(descriptor.requires().size() == 1);
+        Set<String> names = descriptor.requires()
+                .stream()
+                .map(Requires::name)
+                .collect(Collectors.toSet());
+        assertEquals(names, Set.of("java.base"));
+
+        // packages
+        assertEquals(descriptor.packages(), Set.of("p", "q"));
+        assertTrue(descriptor.exports().isEmpty());
+        assertTrue(descriptor.opens().isEmpty());
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testRequiresOnAutomaticModule() {
+        ModuleDescriptor.newAutomaticModule("foo").requires("java.base");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testExportsOnAutomaticModule1() {
+        ModuleDescriptor.newAutomaticModule("foo").exports("p");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testExportsOnAutomaticModule2() {
+        ModuleDescriptor.newAutomaticModule("foo").exports("p", Set.of("bar"));
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testOpensOnAutomaticModule1() {
+        ModuleDescriptor.newAutomaticModule("foo").opens("p");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testOpensOnAutomaticModule2() {
+        ModuleDescriptor.newAutomaticModule("foo").opens("p", Set.of("bar"));
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class)
+    public void testUsesOnAutomaticModule() {
+        ModuleDescriptor.newAutomaticModule("foo").uses("p.Service");
+    }
+
     public void testIsAutomatic() {
-        ModuleDescriptor descriptor1 = ModuleDescriptor.module("foo").build();
+        ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("foo").build();
         assertFalse(descriptor1.isAutomatic());
 
-        ModuleDescriptor descriptor2 = ModuleDescriptor.openModule("foo").build();
+        ModuleDescriptor descriptor2 = ModuleDescriptor.newOpenModule("foo").build();
         assertFalse(descriptor2.isAutomatic());
 
-        ModuleDescriptor descriptor3 = ModuleDescriptor.automaticModule("foo").build();
+        ModuleDescriptor descriptor3 = ModuleDescriptor.newAutomaticModule("foo").build();
         assertTrue(descriptor3.isAutomatic());
     }
 
-    // isSynthetic
-    public void testIsSynthetic() {
-        assertFalse(Object.class.getModule().getDescriptor().isSynthetic());
+
+    // newModule with modifiers
+
+    public void testNewModuleToBuildAutomaticModule() {
+        Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC);
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build();
+        assertTrue(descriptor.modifiers().equals(ms));
+        assertTrue(descriptor.isAutomatic());
+    }
 
-        ModuleDescriptor descriptor1 = ModuleDescriptor.module("foo").build();
-        assertFalse(descriptor1.isSynthetic());
+    public void testNewModuleToBuildOpenModule() {
+        Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.OPEN);
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build();
+        assertTrue(descriptor.modifiers().equals(ms));
+        assertTrue(descriptor.isOpen());
 
-        ModuleDescriptor descriptor2 = ModuleDescriptor.openModule("foo").build();
-        assertFalse(descriptor2.isSynthetic());
+        ms = Set.of(ModuleDescriptor.Modifier.OPEN, ModuleDescriptor.Modifier.SYNTHETIC);
+        descriptor = ModuleDescriptor.newModule("foo", ms).build();
+        assertTrue(descriptor.modifiers().equals(ms));
+        assertTrue(descriptor.isOpen());
+    }
 
-        ModuleDescriptor descriptor3 = ModuleDescriptor.automaticModule("foo").build();
-        assertFalse(descriptor3.isSynthetic());
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testNewModuleToBuildAutomaticAndOpenModule() {
+        Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC,
+                                                   ModuleDescriptor.Modifier.OPEN);
+        ModuleDescriptor.newModule("foo", ms);
     }
 
 
@@ -921,14 +1153,19 @@
 
     public void testMainClass() {
         String mainClass
-            = ModuleDescriptor.module("foo").mainClass("p.Main").build().mainClass().get();
+            = ModuleDescriptor.newModule("foo").mainClass("p.Main").build().mainClass().get();
         assertEquals(mainClass, "p.Main");
     }
 
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testMainClassWithSimpleIdentifier() {
+        ModuleDescriptor.newModule("foo").mainClass("Main");
+    }
+
     @Test(dataProvider = "invalidjavaidentifiers",
           expectedExceptions = IllegalArgumentException.class )
     public void testMainClassWithBadName(String mainClass, String ignore) {
-        Builder builder = ModuleDescriptor.module("foo");
+        Builder builder = ModuleDescriptor.newModule("foo");
         builder.mainClass(mainClass);
     }
 
@@ -936,54 +1173,54 @@
     // osName
 
     public void testOsName() {
-        String osName = ModuleDescriptor.module("foo").osName("Linux").build().osName().get();
+        String osName = ModuleDescriptor.newModule("foo").osName("Linux").build().osName().get();
         assertEquals(osName, "Linux");
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testNullOsName() {
-        ModuleDescriptor.module("foo").osName(null);
+        ModuleDescriptor.newModule("foo").osName(null);
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testEmptyOsName() {
-        ModuleDescriptor.module("foo").osName("");
+        ModuleDescriptor.newModule("foo").osName("");
     }
 
 
     // osArch
 
     public void testOsArch() {
-        String osArch = ModuleDescriptor.module("foo").osName("arm").build().osName().get();
+        String osArch = ModuleDescriptor.newModule("foo").osName("arm").build().osName().get();
         assertEquals(osArch, "arm");
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testNullOsArch() {
-        ModuleDescriptor.module("foo").osArch(null);
+        ModuleDescriptor.newModule("foo").osArch(null);
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testEmptyOsArch() {
-        ModuleDescriptor.module("foo").osArch("");
+        ModuleDescriptor.newModule("foo").osArch("");
     }
 
 
     // osVersion
 
     public void testOsVersion() {
-        String osVersion = ModuleDescriptor.module("foo").osName("11.2").build().osName().get();
+        String osVersion = ModuleDescriptor.newModule("foo").osName("11.2").build().osName().get();
         assertEquals(osVersion, "11.2");
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testNullOsVersion() {
-        ModuleDescriptor.module("foo").osVersion(null);
+        ModuleDescriptor.newModule("foo").osVersion(null);
     }
 
     @Test(expectedExceptions = IllegalArgumentException.class)
     public void testEmptyOsVersion() {
-        ModuleDescriptor.module("foo").osVersion("");
+        ModuleDescriptor.newModule("foo").osVersion("");
     }
 
     // reads
@@ -1023,7 +1260,7 @@
      * Test ModuleDescriptor with a packager finder
      */
     public void testReadsWithPackageFinder() throws Exception {
-        ModuleDescriptor descriptor = ModuleDescriptor.module("foo")
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
                 .requires("java.base")
                 .build();
 
@@ -1044,7 +1281,7 @@
      */
     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
     public void testReadsWithBadPackageFinder() throws Exception {
-        ModuleDescriptor descriptor = ModuleDescriptor.module("foo")
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
                 .requires("java.base")
                 .exports("p")
                 .build();
@@ -1077,7 +1314,7 @@
     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
     public void testReadOfJavaBaseWithRequires() {
         ModuleDescriptor descriptor
-            = ModuleDescriptor.module("java.base")
+            = ModuleDescriptor.newModule("java.base")
                 .requires("other")
                 .build();
         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
@@ -1087,7 +1324,8 @@
     // The requires table must have an entry for java.base
     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
     public void testReadWithEmptyRequires() {
-        ModuleDescriptor descriptor = ModuleDescriptor.module("m1").build();
+        ModuleDescriptor descriptor = SharedSecrets.getJavaLangModuleAccess()
+                .newModuleBuilder("m1", false, Set.of()).build();
         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
         ModuleDescriptor.read(bb);
     }
@@ -1095,10 +1333,8 @@
     // The requires table must have an entry for java.base
     @Test(expectedExceptions = InvalidModuleDescriptorException.class)
     public void testReadWithNoRequiresBase() {
-        ModuleDescriptor descriptor
-            = ModuleDescriptor.module("m1")
-                .requires("m2")
-                .build();
+        ModuleDescriptor descriptor = SharedSecrets.getJavaLangModuleAccess()
+                .newModuleBuilder("m1", false, Set.of()).requires("m2").build();
         ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
         ModuleDescriptor.read(bb);
     }
@@ -1138,22 +1374,50 @@
     // equals/hashCode/compareTo/toString
 
     public void testEqualsAndHashCode() {
-        ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
-        ModuleDescriptor md2 = ModuleDescriptor.module("foo").build();
+        ModuleDescriptor md1 = ModuleDescriptor.newModule("m").build();
+        ModuleDescriptor md2 = ModuleDescriptor.newModule("m").build();
         assertEquals(md1, md1);
         assertEquals(md1.hashCode(), md2.hashCode());
+        assertTrue(md1.compareTo(md2) == 0);
+        assertTrue(md2.compareTo(md1) == 0);
     }
 
-    public void testCompare() {
-        ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
-        ModuleDescriptor md2 = ModuleDescriptor.module("bar").build();
-        int n = "foo".compareTo("bar");
-        assertTrue(md1.compareTo(md2) == n);
-        assertTrue(md2.compareTo(md1) == -n);
+    @DataProvider(name = "sortedModuleDescriptors")
+    public Object[][] sortedModuleDescriptors() {
+        return new Object[][]{
+
+            { ModuleDescriptor.newModule("m2").build(),
+              ModuleDescriptor.newModule("m1").build()
+            },
+
+            { ModuleDescriptor.newModule("m").version("2").build(),
+              ModuleDescriptor.newModule("m").version("1").build()
+            },
+
+            { ModuleDescriptor.newModule("m").version("1").build(),
+              ModuleDescriptor.newModule("m").build()
+            },
+
+            { ModuleDescriptor.newOpenModule("m").build(),
+              ModuleDescriptor.newModule("m").build()
+            },
+
+        };
+    }
+
+    @Test(dataProvider = "sortedModuleDescriptors")
+    public void testCompare(ModuleDescriptor md1, ModuleDescriptor md2) {
+        assertNotEquals(md1, md2);
+        assertTrue(md1.compareTo(md2) == 1);
+        assertTrue(md2.compareTo(md1) == -1);
     }
 
     public void testToString() {
-        String s = ModuleDescriptor.module("m1").requires("m2").exports("p1").build().toString();
+        String s = ModuleDescriptor.newModule("m1")
+                .requires("m2")
+                .exports("p1")
+                .build()
+                .toString();
         assertTrue(s.contains("m1"));
         assertTrue(s.contains("m2"));
         assertTrue(s.contains("p1"));
--- a/jdk/test/java/lang/module/ModuleFinderTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/module/ModuleFinderTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -471,37 +471,11 @@
      * Test ModuleFinder.of with a file path to a directory containing a file
      * that will not be recognized as a module.
      */
-    public void testOfWithUnrecognizedEntryInDirectory() throws Exception {
+    public void testOfWithUnrecognizedEntryInDirectory1() throws Exception {
         Path dir = Files.createTempDirectory(USER_DIR, "mods");
         Files.createTempFile(dir, "m", ".junk");
 
         ModuleFinder finder = ModuleFinder.of(dir);
-        try {
-            finder.find("java.rhubarb");
-            assertTrue(false);
-        } catch (FindException e) {
-            // expected
-        }
-
-        finder = ModuleFinder.of(dir);
-        try {
-            finder.findAll();
-            assertTrue(false);
-        } catch (FindException e) {
-            // expected
-        }
-    }
-
-
-    /**
-     * Test ModuleFinder.of with a file path to a directory containing a file
-     * starting with ".", the file should be ignored.
-     */
-    public void testOfWithHiddenEntryInDirectory() throws Exception {
-        Path dir = Files.createTempDirectory(USER_DIR, "mods");
-        Files.createTempFile(dir, ".marker", "");
-
-        ModuleFinder finder = ModuleFinder.of(dir);
         assertFalse(finder.find("java.rhubarb").isPresent());
 
         finder = ModuleFinder.of(dir);
@@ -510,6 +484,24 @@
 
 
     /**
+     * Test ModuleFinder.of with a file path to a directory containing a file
+     * that will not be recognized as a module.
+     */
+    public void testOfWithUnrecognizedEntryInDirectory2() throws Exception {
+        Path dir = Files.createTempDirectory(USER_DIR, "mods");
+        createModularJar(dir.resolve("m1.jar"), "m1");
+        Files.createTempFile(dir, "m2", ".junk");
+
+        ModuleFinder finder = ModuleFinder.of(dir);
+        assertTrue(finder.find("m1").isPresent());
+        assertFalse(finder.find("m2").isPresent());
+
+        finder = ModuleFinder.of(dir);
+        assertTrue(finder.findAll().size() == 1);
+    }
+
+
+    /**
      * Test ModuleFinder.of with a directory that contains two
      * versions of the same module
      */
@@ -748,7 +740,7 @@
             vs = mid.substring(i+1);
         }
         ModuleDescriptor.Builder builder
-            = ModuleDescriptor.module(mn).requires("java.base");
+            = ModuleDescriptor.newModule(mn).requires("java.base");
         if (vs != null)
             builder.version(vs);
         return builder.build();
--- a/jdk/test/java/lang/module/ModuleNamesTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/module/ModuleNamesTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -235,7 +235,7 @@
      */
     private Builder newBuilder(String mn) {
         return SharedSecrets.getJavaLangModuleAccess()
-                            .newModuleBuilder(mn, false, false, false);
+                            .newModuleBuilder(mn, false, Set.of());
     }
 
     /**
--- a/jdk/test/java/lang/module/ModuleReader/ModuleReaderTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/module/ModuleReader/ModuleReaderTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -79,14 +79,52 @@
         "java/lang/Object.class"
     };
 
+    // resource names that should not be found in the base module
+    private static final String[] BAD_BASE_RESOURCES = {
+        "NotFound",
+        "java",
+        "/java",
+        "//java",
+        "java/",
+        "java/lang",
+        "/java/lang",
+        "//java/lang",
+        "java/lang/",
+        "java//lang",
+        "/java/lang/Object.class",
+        "//java/lang/Object.class",
+        "java/lang/Object.class/",
+        "java//lang//Object.class",
+        "./java/lang/Object.class",
+        "java/./lang/Object.class",
+        "java/lang/./Object.class",
+        "../java/lang/Object.class",
+        "java/../lang/Object.class",
+        "java/lang/../Object.class",
+    };
+
     // resources in test module (can't use module-info.class as a test
     // resource as it will be modified by the jmod tool)
     private static final String[] TEST_RESOURCES = {
         "p/Main.class"
     };
 
-    // a resource that is not in the base or test module
-    private static final String NOT_A_RESOURCE = "NotAResource";
+    // resource names that should not be found in the test module
+    private static final String[] BAD_TEST_RESOURCES = {
+        "NotFound",
+        "p",
+        "/p",
+        "//p",
+        "p/",
+        "/p/Main.class",
+        "//p/Main.class",
+        "p/Main.class/",
+        "p//Main.class",
+        "./p/Main.class",
+        "p/./Main.class",
+        "../p/Main.class",
+        "p/../p/Main.class"
+    };
 
 
     @BeforeTest
@@ -126,10 +164,11 @@
             }
 
             // test "not found"
-            assertFalse(reader.find(NOT_A_RESOURCE).isPresent());
-            assertFalse(reader.open(NOT_A_RESOURCE).isPresent());
-            assertFalse(reader.read(NOT_A_RESOURCE).isPresent());
-
+            for (String name : BAD_BASE_RESOURCES) {
+                assertFalse(reader.find(name).isPresent());
+                assertFalse(reader.open(name).isPresent());
+                assertFalse(reader.read(name).isPresent());
+            }
 
             // test nulls
             try {
@@ -216,7 +255,7 @@
      */
     void test(Path mp) throws IOException {
 
-        ModuleFinder finder = new ModulePath(Runtime.version(), true, mp);
+        ModuleFinder finder = ModulePath.of(Runtime.version(), true, mp);
         ModuleReference mref = finder.find(TEST_MODULE).get();
         ModuleReader reader = mref.open();
 
@@ -236,9 +275,11 @@
             }
 
             // test "not found"
-            assertFalse(reader.find(NOT_A_RESOURCE).isPresent());
-            assertFalse(reader.open(NOT_A_RESOURCE).isPresent());
-            assertFalse(reader.read(NOT_A_RESOURCE).isPresent());
+            for (String name : BAD_TEST_RESOURCES) {
+                assertFalse(reader.find(name).isPresent());
+                assertFalse(reader.open(name).isPresent());
+                assertFalse(reader.read(name).isPresent());
+            }
 
             // test nulls
             try {
--- a/jdk/test/java/lang/module/ModuleReferenceTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/module/ModuleReferenceTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -31,6 +31,7 @@
 import java.lang.module.ModuleReader;
 import java.lang.module.ModuleReference;
 import java.net.URI;
+import java.util.Set;
 
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
@@ -49,10 +50,10 @@
 
     public void testBasic() throws Exception {
         ModuleDescriptor descriptor
-            = ModuleDescriptor.module("m")
+            = ModuleDescriptor.newModule("m")
                 .exports("p")
                 .exports("q")
-                .contains("p.internal")
+                .packages(Set.of("p.internal"))
                 .build();
 
         URI uri = URI.create("module:/m");
@@ -71,7 +72,7 @@
 
     public void testNullLocation() {
         ModuleDescriptor descriptor
-            = ModuleDescriptor.module("m")
+            = ModuleDescriptor.newModule("m")
                 .exports("p")
                 .build();
         ModuleReference mref = newModuleReference(descriptor, null);
--- a/jdk/test/java/lang/module/MultiReleaseJarTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/module/MultiReleaseJarTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -65,7 +65,7 @@
 
     private static final String MODULE_INFO = "module-info.class";
 
-    private static final int RELEASE = Runtime.version().major();
+    private static final int VERSION = Runtime.version().major();
 
     // are multi-release JARs enabled?
     private static final boolean MULTI_RELEASE;
@@ -80,7 +80,7 @@
     public void testBasic() throws Exception {
         String name = "m1";
 
-        ModuleDescriptor descriptor = ModuleDescriptor.module(name)
+        ModuleDescriptor descriptor = ModuleDescriptor.newModule(name)
                 .requires("java.base")
                 .build();
 
@@ -88,8 +88,8 @@
                 .moduleInfo("module-info.class", descriptor)
                 .resource("p/Main.class")
                 .resource("p/Helper.class")
-                .resource("META-INF/versions/9/p/Helper.class")
-                .resource("META-INF/versions/9/p/internal/Helper9.class")
+                .resource("META-INF/versions/" + VERSION + "/p/Helper.class")
+                .resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
                 .build();
 
         // find the module
@@ -117,12 +117,12 @@
     public void testModuleInfoInVersionedSection() throws Exception {
         String name = "m1";
 
-        ModuleDescriptor descriptor1 = ModuleDescriptor.module(name)
+        ModuleDescriptor descriptor1 = ModuleDescriptor.newModule(name)
                 .requires("java.base")
                 .build();
 
         // module descriptor for versioned section
-        ModuleDescriptor descriptor2 = ModuleDescriptor.module(name)
+        ModuleDescriptor descriptor2 = ModuleDescriptor.newModule(name)
                 .requires("java.base")
                 .requires("jdk.unsupported")
                 .build();
@@ -131,9 +131,9 @@
                 .moduleInfo(MODULE_INFO, descriptor1)
                 .resource("p/Main.class")
                 .resource("p/Helper.class")
-                .moduleInfo("META-INF/versions/9/" + MODULE_INFO, descriptor2)
-                .resource("META-INF/versions/9/p/Helper.class")
-                .resource("META-INF/versions/9/p/internal/Helper9.class")
+                .moduleInfo("META-INF/versions/" + VERSION + "/" + MODULE_INFO, descriptor2)
+                .resource("META-INF/versions/" + VERSION + "/p/Helper.class")
+                .resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
                 .build();
 
         // find the module
@@ -161,8 +161,8 @@
         Path jar = new JarBuilder(name)
                 .resource("p/Main.class")
                 .resource("p/Helper.class")
-                .resource("META-INF/versions/9/p/Helper.class")
-                .resource("META-INF/versions/9/p/internal/Helper9.class")
+                .resource("META-INF/versions/" + VERSION + "/p/Helper.class")
+                .resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
                 .build();
 
         // find the module
@@ -188,19 +188,19 @@
     public void testModuleReader() throws Exception {
         String name = "m1";
 
-        ModuleDescriptor descriptor1 = ModuleDescriptor.module(name)
+        ModuleDescriptor descriptor1 = ModuleDescriptor.newModule(name)
                 .requires("java.base")
                 .build();
 
         // module descriptor for versioned section
-        ModuleDescriptor descriptor2 = ModuleDescriptor.module(name)
+        ModuleDescriptor descriptor2 = ModuleDescriptor.newModule(name)
                 .requires("java.base")
                 .requires("jdk.unsupported")
                 .build();
 
         Path jar = new JarBuilder(name)
                 .moduleInfo(MODULE_INFO, descriptor1)
-                .moduleInfo("META-INF/versions/9/" + MODULE_INFO, descriptor2)
+                .moduleInfo("META-INF/versions/" + VERSION + "/" + MODULE_INFO, descriptor2)
                 .build();
 
         // find the module
@@ -243,7 +243,7 @@
 
             String expectedTail = "!/";
             if (MULTI_RELEASE)
-                expectedTail += "META-INF/versions/" + RELEASE + "/";
+                expectedTail += "META-INF/versions/" + VERSION + "/";
             expectedTail += MODULE_INFO;
             assertTrue(uri.toString().endsWith(expectedTail));
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessibleObject/CanAccessTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2017, 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
+ * @build CanAccessTest
+ * @modules java.base/jdk.internal.misc:+open
+ * @run testng CanAccessTest
+ * @summary Test AccessibleObject::canAccess method
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.SecureClassLoader;
+
+import jdk.internal.misc.Unsafe;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test
+public class CanAccessTest {
+    private static Unsafe INSTANCE = Unsafe.getUnsafe();
+
+    /**
+     * null object parameter for Constructor
+     */
+    public void testConstructor() throws Exception {
+        Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
+        assertFalse(ctor.canAccess(null));
+        assertTrue(ctor.trySetAccessible());
+
+        try {
+            // non-null object parameter
+            ctor.canAccess(INSTANCE);
+            assertTrue(false);
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    /**
+     * Test protected constructors
+     */
+    public void testProtectedConstructor() throws Exception {
+        TestLoader.testProtectedConstructorNonOpenedPackage();
+
+        Constructor<?> ctor = TestLoader.class.getDeclaredConstructor();
+        assertTrue(ctor.canAccess(null));
+    }
+
+    /**
+     * null object parameter  for static members
+     */
+    public void testStaticMember() throws Exception {
+        Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
+        assertFalse(m.canAccess(null));
+        assertTrue(m.trySetAccessible());
+
+        try {
+            // non-null object parameter
+            m.canAccess(INSTANCE);
+            assertTrue(false);
+        } catch (IllegalArgumentException expected) { }
+    }
+
+    /**
+     * Test protected static
+     */
+    public void testProtectedStatic() throws Exception {
+        Method m = TestLoader.testProtectedStatic();
+        assertFalse(m.canAccess(null));
+    }
+
+    /**
+     * the specified object must be an instance of the declaring class
+     * for instance members
+     */
+    public void testInstanceMethod() throws Exception {
+        Method m = Unsafe.class.getDeclaredMethod("addressSize0");
+        assertFalse(m.canAccess(INSTANCE));
+
+        try {
+            m.canAccess(null);
+            assertTrue(false);
+        } catch (IllegalArgumentException expected) { }
+    }
+
+    /**
+     * the specified object must be an instance of the declaring class
+     * for instance members
+     */
+    public void testInvalidInstanceObject() throws Exception {
+        Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+        Method m = clazz.getDeclaredMethod("size");
+
+        try {
+            m.canAccess(INSTANCE);
+            assertTrue(false);
+        } catch (IllegalArgumentException expected) { }
+    }
+
+
+    static class TestLoader extends SecureClassLoader {
+        public static Method testProtectedStatic() throws Exception {
+            Method m = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable");
+            assertTrue(m.canAccess(null));
+            return m;
+        }
+
+        protected TestLoader() throws Exception {
+            Constructor<?> ctor = SecureClassLoader.class.getDeclaredConstructor();
+            assertFalse(ctor.canAccess(null));
+            assertFalse(ctor.trySetAccessible());
+        }
+
+        public static void testProtectedConstructorNonOpenedPackage() throws Exception {
+            new TestLoader();
+        }
+    }
+}
--- a/jdk/test/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -30,7 +30,6 @@
  * @summary Test java.lang.reflect.AccessibleObject with modules
  */
 
-import java.lang.module.ModuleDescriptor;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2017, 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
+ * @build TrySetAccessibleTest
+ * @modules java.base/java.lang:open
+ *          java.base/jdk.internal.perf
+ *          java.base/jdk.internal.misc:+open
+ * @run testng TrySetAccessibleTest
+ * @summary Test AccessibleObject::trySetAccessible method
+ */
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import jdk.internal.misc.Unsafe;
+import jdk.internal.perf.Perf;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test
+public class TrySetAccessibleTest {
+    /**
+     * Invoke a private constructor on a public class in an exported package
+     */
+    public void testPrivateConstructorInExportedPackage() throws Exception {
+        Constructor<?> ctor = Perf.class.getDeclaredConstructor();
+
+        try {
+            ctor.newInstance();
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        assertFalse(ctor.trySetAccessible());
+        assertFalse(ctor.canAccess(null));
+    }
+
+    /**
+     * Invoke a private constructor on a public class in an open package
+     */
+    public void testPrivateConstructorInOpenedPackage() throws Exception {
+        Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
+
+        try {
+            ctor.newInstance();
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        assertTrue(ctor.trySetAccessible());
+        assertTrue(ctor.canAccess(null));
+        Unsafe unsafe = (Unsafe) ctor.newInstance();
+    }
+
+    /**
+     * Invoke a private method on a public class in an exported package
+     */
+    public void testPrivateMethodInExportedPackage() throws Exception {
+        Method m = Perf.class.getDeclaredMethod("getBytes", String.class);
+        try {
+            m.invoke(null);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        assertFalse(m.trySetAccessible());
+        assertFalse(m.canAccess(null));
+    }
+
+
+    /**
+     * Invoke a private method on a public class in an open package
+     */
+    public void testPrivateMethodInOpenedPackage() throws Exception {
+        Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
+        assertFalse(m.canAccess(null));
+
+        try {
+            m.invoke(null);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        assertTrue(m.trySetAccessible());
+        assertTrue(m.canAccess(null));
+        try {
+            m.invoke(null);
+            assertTrue(false);
+        } catch (InvocationTargetException e) {
+            // thrown by throwIllegalAccessError
+            assertTrue(e.getCause() instanceof IllegalAccessError);
+        }
+    }
+
+    /**
+     * Invoke a private method on a public class in an exported package
+     */
+    public void testPrivateFieldInExportedPackage() throws Exception {
+        Field f = Perf.class.getDeclaredField("instance");
+        try {
+            f.get(null);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        assertFalse(f.trySetAccessible());
+        assertFalse(f.canAccess(null));
+        try {
+            f.get(null);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) {}
+    }
+
+    /**
+     * Access a private field in a public class that is an exported package
+     */
+    public void testPrivateFieldInOpenedPackage() throws Exception {
+        Field f = Unsafe.class.getDeclaredField("theUnsafe");
+
+        try {
+            f.get(null);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        assertTrue(f.trySetAccessible());
+        assertTrue(f.canAccess(null));
+        Unsafe unsafe = (Unsafe) f.get(null);
+    }
+
+
+    /**
+     * Invoke a public constructor on a public class in a non-exported package
+     */
+    public void testPublicConstructorInNonExportedPackage() throws Exception {
+        Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+        Constructor<?> ctor = clazz.getConstructor(String.class);
+
+        try {
+            ctor.newInstance("cn=duke");
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        assertFalse(ctor.trySetAccessible());
+        assertFalse(ctor.canAccess(null));
+        assertTrue(ctor.trySetAccessible() == ctor.isAccessible());
+    }
+
+
+    /**
+     * Access a public field in a public class that in a non-exported package
+     */
+    public void testPublicFieldInNonExportedPackage() throws Exception {
+        Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+        Field f = clazz.getField("SERIALNUMBER_OID");
+
+        try {
+            f.get(null);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        assertFalse(f.trySetAccessible());
+        assertFalse(f.canAccess(null));
+    }
+
+
+    /**
+     * Test that the Class constructor cannot be make accessible.
+     */
+    public void testJavaLangClass() throws Exception {
+
+        // non-public constructor
+        Constructor<?> ctor
+            = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class);
+        AccessibleObject[] ctors = { ctor };
+
+        assertFalse(ctor.trySetAccessible());
+        assertFalse(ctor.canAccess(null));
+    }
+
+}
--- a/jdk/test/java/lang/reflect/Layer/BasicLayerTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/Layer/BasicLayerTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -24,6 +24,7 @@
 /**
  * @test
  * @library /lib/testlibrary
+ * @modules java.base/jdk.internal.misc
  * @build BasicLayerTest ModuleUtils
  * @compile layertest/Test.java
  * @run testng BasicLayerTest
@@ -43,6 +44,7 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import jdk.internal.misc.SharedSecrets;
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 
@@ -50,6 +52,15 @@
 public class BasicLayerTest {
 
     /**
+     * Creates a "non-strict" builder for building a module. This allows the
+     * test the create ModuleDescriptor objects that do not require java.base.
+     */
+    private static ModuleDescriptor.Builder newBuilder(String mn) {
+        return SharedSecrets.getJavaLangModuleAccess()
+                .newModuleBuilder(mn, false, Set.of());
+    }
+
+    /**
      * Exercise Layer.empty()
      */
     public void testEmpty() {
@@ -109,25 +120,22 @@
      * Exercise Layer defineModules, created with empty layer as parent
      */
     public void testLayerOnEmpty() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
                 .exports("p1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("m3")
                 .build();
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .build();
 
         ModuleFinder finder
             = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         // map each module to its own class loader for this test
         ClassLoader loader1 = new ClassLoader() { };
@@ -191,15 +199,13 @@
      * Exercise Layer defineModules, created with boot layer as parent
      */
     public void testLayerOnBoot() {
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("m2")
                 .requires("java.base")
                 .exports("p1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires("java.base")
                 .build();
 
@@ -207,7 +213,7 @@
             = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         Configuration parent = Layer.boot().configuration();
-        Configuration cf = resolveRequires(parent, finder, "m1");
+        Configuration cf = resolve(parent, finder, "m1");
 
         ClassLoader loader = new ClassLoader() { };
 
@@ -256,21 +262,19 @@
      * have the same module-private package.
      */
     public void testPackageContainedInSelfAndOther() {
-        ModuleDescriptor descriptor1
-            =  ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 =  newBuilder("m1")
                 .requires("m2")
-                .contains("p")
+                .packages(Set.of("p"))
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
-                .contains("p")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
+                .packages(Set.of("p"))
                 .build();
 
         ModuleFinder finder
             = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
         assertTrue(cf.modules().size() == 2);
 
         // one loader per module, should be okay
@@ -292,22 +296,18 @@
     public void testSameExportInPartitionedGraph() {
 
         // m1 reads m2, m2 exports p to m1
-        ModuleDescriptor descriptor1
-            =  ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 =  newBuilder("m1")
                 .requires("m2")
                 .build();
-        ModuleDescriptor descriptor2
-            =  ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 =  newBuilder("m2")
                 .exports("p", Set.of("m1"))
                 .build();
 
         // m3 reads m4, m4 exports p to m3
-        ModuleDescriptor descriptor3
-            =  ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m4")
                 .build();
-        ModuleDescriptor descriptor4
-            =  ModuleDescriptor.module("m4")
+        ModuleDescriptor descriptor4 = newBuilder("m4")
                 .exports("p", Set.of("m3"))
                 .build();
 
@@ -317,7 +317,7 @@
                                    descriptor3,
                                    descriptor4);
 
-        Configuration cf = resolveRequires(finder, "m1", "m3");
+        Configuration cf = resolve(finder, "m1", "m3");
         assertTrue(cf.modules().size() == 4);
 
         // one loader per module
@@ -353,16 +353,15 @@
         ModuleDescriptor base = Object.class.getModule().getDescriptor();
         assertTrue(base.packages().contains("sun.launcher"));
 
-        ModuleDescriptor descriptor
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor = newBuilder("m1")
                .requires("java.base")
-               .contains("sun.launcher")
+               .packages(Set.of("sun.launcher"))
                .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 
         Configuration parent = Layer.boot().configuration();
-        Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+        Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
         assertTrue(cf.modules().size() == 1);
 
         ClassLoader loader = new ClassLoader() { };
@@ -382,18 +381,16 @@
 
         // cf1: m1 and m2, m2 requires transitive m1
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf1 = resolveRequires(finder1, "m2");
+        Configuration cf1 = resolve(finder1, "m2");
 
         ClassLoader cl1 = new ClassLoader() { };
         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
@@ -401,14 +398,13 @@
 
         // cf2: m3, m3 requires m2
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+        Configuration cf2 = resolve(cf1, finder2, "m3");
 
         ClassLoader cl2 = new ClassLoader() { };
         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
@@ -456,13 +452,11 @@
 
         // cf1: m1
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder1, "m1");
+        Configuration cf1 = resolve(finder1, "m1");
 
         ClassLoader cl1 = new ClassLoader() { };
         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
@@ -470,19 +464,17 @@
 
         // cf2: m2, m3: m2 requires transitive m1, m3 requires m2
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+        Configuration cf2 = resolve(cf1, finder2, "m3");
 
         ClassLoader cl2 = new ClassLoader() { };
         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
@@ -527,13 +519,11 @@
 
         // cf1: m1
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .build();
+        ModuleDescriptor descriptor1 = newBuilder("m1").build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf1 = resolveRequires(finder1, "m1");
+        Configuration cf1 = resolve(finder1, "m1");
 
         ClassLoader cl1 = new ClassLoader() { };
         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
@@ -541,14 +531,13 @@
 
         // cf2: m2 requires transitive m1
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m2");
+        Configuration cf2 = resolve(cf1, finder2, "m2");
 
         ClassLoader cl2 = new ClassLoader() { };
         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
@@ -556,14 +545,13 @@
 
         // cf3: m3 requires m2
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires("m2")
                 .build();
 
         ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);
 
-        Configuration cf3 = resolveRequires(cf2, finder3, "m3");
+        Configuration cf3 = resolve(cf2, finder3, "m3");
 
         ClassLoader cl3 = new ClassLoader() { };
         Layer layer3 = layer2.defineModules(cf3, mn -> cl3);
@@ -610,18 +598,16 @@
 
         // cf1: m1, m2 requires transitive m1
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
-        ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+        ModuleDescriptor descriptor2 = newBuilder("m2")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
                 .build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
-        Configuration cf1 = resolveRequires(finder1, "m2");
+        Configuration cf1 = resolve(finder1, "m2");
 
         ClassLoader cl1 = new ClassLoader() { };
         Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
@@ -629,20 +615,18 @@
 
         // cf2: m3 requires transitive m2, m4 requires m3
 
-        ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3")
+        ModuleDescriptor descriptor3 = newBuilder("m3")
                 .requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")
                 .build();
 
-        ModuleDescriptor descriptor4
-            = ModuleDescriptor.module("m4")
+        ModuleDescriptor descriptor4 = newBuilder("m4")
                 .requires("m3")
                 .build();
 
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 
-        Configuration cf2 = resolveRequires(cf1, finder2, "m3", "m4");
+        Configuration cf2 = resolve(cf1, finder2, "m3", "m4");
 
         ClassLoader cl2 = new ClassLoader() { };
         Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
@@ -693,8 +677,7 @@
     @Test(expectedExceptions = { LayerInstantiationException.class })
     public void testModuleAlreadyDefinedToLoader() {
 
-        ModuleDescriptor md
-            = ModuleDescriptor.module("m")
+        ModuleDescriptor md = newBuilder("m")
                 .requires("java.base")
                 .build();
 
@@ -702,7 +685,7 @@
 
         Configuration parent = Layer.boot().configuration();
 
-        Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m"));
+        Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));
 
         ClassLoader loader = new ClassLoader() { };
 
@@ -722,15 +705,13 @@
     @Test(expectedExceptions = { LayerInstantiationException.class })
     public void testPackageAlreadyInNamedModule() {
 
-        ModuleDescriptor md1
-            = ModuleDescriptor.module("m1")
-                .contains("p")
+        ModuleDescriptor md1 = newBuilder("m1")
+                .packages(Set.of("p"))
                 .requires("java.base")
                 .build();
 
-        ModuleDescriptor md2
-            = ModuleDescriptor.module("m2")
-                .contains("p")
+        ModuleDescriptor md2 = newBuilder("m2")
+                .packages(Set.of("p"))
                 .requires("java.base")
                 .build();
 
@@ -742,13 +723,13 @@
 
         Configuration parent = Layer.boot().configuration();
 
-        Configuration cf1 = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+        Configuration cf1 = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
 
         Layer layer1 = Layer.boot().defineModules(cf1, mn -> loader);
 
         // attempt to define m2 containing package p to class loader
 
-        Configuration cf2 = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m2"));
+        Configuration cf2 = parent.resolve(finder, ModuleFinder.of(), Set.of("m2"));
 
         // should throw exception because p already in m1
         Layer layer2 = Layer.boot().defineModules(cf2, mn -> loader);
@@ -767,16 +748,15 @@
         Class<?> c = layertest.Test.class;
         assertFalse(c.getModule().isNamed());  // in unnamed module
 
-        ModuleDescriptor md
-            = ModuleDescriptor.module("m")
-                .contains(c.getPackageName())
+        ModuleDescriptor md = newBuilder("m")
+                .packages(Set.of(c.getPackageName()))
                 .requires("java.base")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(md);
 
         Configuration parent = Layer.boot().configuration();
-        Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m"));
+        Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));
 
         Layer.boot().defineModules(cf, mn -> c.getClassLoader());
     }
@@ -786,8 +766,7 @@
      * Attempt to create a Layer with a module named "java.base".
      */
     public void testLayerWithJavaBase() {
-        ModuleDescriptor descriptor
-            = ModuleDescriptor.module("java.base")
+        ModuleDescriptor descriptor = newBuilder("java.base")
                 .exports("java.lang")
                 .build();
 
@@ -795,7 +774,7 @@
 
         Configuration cf = Layer.boot()
             .configuration()
-            .resolveRequires(finder, ModuleFinder.of(), Set.of("java.base"));
+            .resolve(finder, ModuleFinder.of(), Set.of("java.base"));
         assertTrue(cf.modules().size() == 1);
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -824,16 +803,15 @@
      */
     @Test(enabled = false)
     public void testLayerWithJavaPackage() {
-        ModuleDescriptor descriptor
-            = ModuleDescriptor.module("foo")
-                .contains("java.foo")
+        ModuleDescriptor descriptor = newBuilder("foo")
+                .packages(Set.of("java.foo"))
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 
         Configuration cf = Layer.boot()
                 .configuration()
-                .resolveRequires(finder, ModuleFinder.of(), Set.of("foo"));
+                .resolve(finder, ModuleFinder.of(), Set.of("foo"));
         assertTrue(cf.modules().size() == 1);
 
         ClassLoader pcl = ClassLoader.getPlatformClassLoader();
@@ -870,15 +848,14 @@
      */
     @Test(expectedExceptions = { LayerInstantiationException.class })
     public void testLayerWithBootLoader() {
-        ModuleDescriptor descriptor
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor = newBuilder("m1")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor);
 
         Configuration cf = Layer.boot()
             .configuration()
-            .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+            .resolve(finder, ModuleFinder.of(), Set.of("m1"));
         assertTrue(cf.modules().size() == 1);
 
         Layer.boot().defineModules(cf, mn -> null );
@@ -891,15 +868,14 @@
     @Test(expectedExceptions = { IllegalArgumentException.class })
     public void testIncorrectParent1() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .requires("java.base")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
         Configuration parent = Layer.boot().configuration();
-        Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+        Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
 
         ClassLoader loader = new ClassLoader() { };
         Layer.empty().defineModules(cf, mn -> loader);
@@ -912,13 +888,12 @@
     @Test(expectedExceptions = { IllegalArgumentException.class })
     public void testIncorrectParent2() {
 
-        ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
+        ModuleDescriptor descriptor1 = newBuilder("m1")
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
 
-        Configuration cf = resolveRequires(finder, "m1");
+        Configuration cf = resolve(finder, "m1");
 
         ClassLoader loader = new ClassLoader() { };
         Layer.boot().defineModules(cf, mn -> loader);
@@ -935,7 +910,7 @@
 
     @Test(expectedExceptions = { NullPointerException.class })
     public void testCreateWithNull2() {
-        Configuration cf = resolveRequires(Layer.boot().configuration(), ModuleFinder.of());
+        Configuration cf = resolve(Layer.boot().configuration(), ModuleFinder.of());
         Layer.boot().defineModules(cf, null);
     }
 
@@ -975,14 +950,14 @@
      * Resolve the given modules, by name, and returns the resulting
      * Configuration.
      */
-    private static Configuration resolveRequires(Configuration cf,
-                                                 ModuleFinder finder,
-                                                 String... roots) {
-        return cf.resolveRequires(finder, ModuleFinder.of(), Set.of(roots));
+    private static Configuration resolve(Configuration cf,
+                                         ModuleFinder finder,
+                                         String... roots) {
+        return cf.resolve(finder, ModuleFinder.of(), Set.of(roots));
     }
 
-    private static Configuration resolveRequires(ModuleFinder finder,
-                                                 String... roots) {
-        return resolveRequires(Configuration.empty(), finder, roots);
+    private static Configuration resolve(ModuleFinder finder,
+                                         String... roots) {
+        return resolve(Configuration.empty(), finder, roots);
     }
 }
--- a/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -81,7 +81,7 @@
      */
     public void testWithOneLoader() throws Exception {
 
-        Configuration cf = resolveRequires("m1");
+        Configuration cf = resolve("m1");
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
 
@@ -110,7 +110,7 @@
      */
     public void testWithManyLoaders() throws Exception {
 
-        Configuration cf = resolveRequires("m1");
+        Configuration cf = resolve("m1");
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
 
@@ -145,7 +145,7 @@
      */
     public void testServicesWithOneLoader() throws Exception {
 
-        Configuration cf = resolveRequiresAndUses("m1");
+        Configuration cf = resolveAndBind("m1");
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
 
@@ -186,7 +186,7 @@
      */
     public void testServicesWithManyLoaders() throws Exception {
 
-        Configuration cf = resolveRequiresAndUses("m1");
+        Configuration cf = resolveAndBind("m1");
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
 
@@ -233,7 +233,7 @@
      */
     public void testDelegationToParent() throws Exception {
 
-        Configuration cf = resolveRequires("m1");
+        Configuration cf = resolve("m1");
 
         ClassLoader parent = this.getClass().getClassLoader();
         String cn = this.getClass().getName();
@@ -267,16 +267,16 @@
     public void testOverlappingPackages() {
 
         ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1").exports("p").build();
+            = ModuleDescriptor.newModule("m1").exports("p").build();
 
         ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2").exports("p").build();
+            = ModuleDescriptor.newModule("m2").exports("p").build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         Configuration cf = Layer.boot()
             .configuration()
-            .resolveRequires(finder, ModuleFinder.of(), Set.of("m1", "m2"));
+            .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
 
         // cannot define both module m1 and m2 to the same class loader
         try {
@@ -301,29 +301,29 @@
     public void testSplitDelegation() {
 
         ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1").exports("p").build();
+            = ModuleDescriptor.newModule("m1").exports("p").build();
 
         ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2").exports("p").build();
+            = ModuleDescriptor.newModule("m2").exports("p").build();
 
         ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
 
         Configuration cf1 = Layer.boot()
             .configuration()
-            .resolveRequires(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
+            .resolve(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
 
         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
         checkLayer(layer1, "m1", "m2");
 
         ModuleDescriptor descriptor3
-            = ModuleDescriptor.module("m3").requires("m1").build();
+            = ModuleDescriptor.newModule("m3").requires("m1").build();
 
         ModuleDescriptor descriptor4
-            = ModuleDescriptor.module("m4").requires("m2").build();
+            = ModuleDescriptor.newModule("m4").requires("m2").build();
 
         ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
 
-        Configuration cf2 = cf1.resolveRequires(finder2, ModuleFinder.of(),
+        Configuration cf2 = cf1.resolve(finder2, ModuleFinder.of(),
                                                 Set.of("m3", "m4"));
 
         // package p cannot be supplied by two class loaders
@@ -349,13 +349,13 @@
      */
     public void testOverriding1() throws Exception {
 
-        Configuration cf1 = resolveRequires("m1");
+        Configuration cf1 = resolve("m1");
 
         Layer layer1 = Layer.boot().defineModulesWithOneLoader(cf1, null);
         checkLayer(layer1, "m1", "m2", "m3");
 
         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
-        Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
+        Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
                                                 Set.of("m1"));
 
         Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
@@ -398,13 +398,13 @@
      */
     public void testOverriding2() throws Exception {
 
-        Configuration cf1 = resolveRequires("m1");
+        Configuration cf1 = resolve("m1");
 
         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
         checkLayer(layer1, "m1", "m2", "m3");
 
         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
-        Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
+        Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
                                                 Set.of("m1"));
 
         Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
@@ -492,14 +492,14 @@
      */
     public void testOverriding3() throws Exception {
 
-        Configuration cf1 = resolveRequires("m1");
+        Configuration cf1 = resolve("m1");
 
         Layer layer1 = Layer.boot().defineModulesWithOneLoader(cf1, null);
         checkLayer(layer1, "m1", "m2", "m3");
 
         ModuleFinder finder = finderFor("m1", "m3");
 
-        Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
+        Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
                                                 Set.of("m1"));
 
         Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
@@ -529,14 +529,14 @@
      */
     public void testOverriding4() throws Exception {
 
-        Configuration cf1 = resolveRequires("m1");
+        Configuration cf1 = resolve("m1");
 
         Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
         checkLayer(layer1, "m1", "m2", "m3");
 
         ModuleFinder finder = finderFor("m1", "m3");
 
-        Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
+        Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
                                                 Set.of("m1"));
 
         Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
@@ -577,7 +577,7 @@
      * Layer.defineModulesWithOneLoader.
      */
     public void testResourcesOneLoader() throws Exception {
-        Configuration cf = resolveRequires("m1");
+        Configuration cf = resolve("m1");
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
         ClassLoader loader = layer.findLoader("m1");
@@ -589,7 +589,7 @@
      * Layer.defineModulesWithOneLoader.
      */
     public void testResourcesManyLoaders() throws Exception {
-        Configuration cf = resolveRequires("m1");
+        Configuration cf = resolve("m1");
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
         ClassLoader loader = layer.findLoader("m1");
@@ -621,22 +621,22 @@
      * Resolve the given modules, by name, and returns the resulting
      * Configuration.
      */
-    private static Configuration resolveRequires(String... roots) {
+    private static Configuration resolve(String... roots) {
         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
         return Layer.boot()
             .configuration()
-            .resolveRequires(finder, ModuleFinder.of(), Set.of(roots));
+            .resolve(finder, ModuleFinder.of(), Set.of(roots));
     }
 
     /**
      * Resolve the given modules, by name, and returns the resulting
      * Configuration.
      */
-    private static Configuration resolveRequiresAndUses(String... roots) {
+    private static Configuration resolveAndBind(String... roots) {
         ModuleFinder finder = ModuleFinder.of(MODS_DIR);
         return Layer.boot()
             .configuration()
-            .resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of(roots));
+            .resolveAndBind(finder, ModuleFinder.of(), Set.of(roots));
     }
 
 
--- a/jdk/test/java/lang/reflect/Layer/LayerControllerTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/Layer/LayerControllerTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -50,22 +50,22 @@
      */
     private Layer.Controller createTestLayer() {
         ModuleDescriptor descriptor1
-            = ModuleDescriptor.module("m1")
-                .contains("p1")
+            = ModuleDescriptor.newModule("m1")
+                .packages(Set.of("p1"))
                 .requires("java.base")
                 .build();
 
         ModuleDescriptor descriptor2
-            = ModuleDescriptor.module("m2")
+            = ModuleDescriptor.newModule("m2")
                 .requires("java.base")
-                .contains("p2")
+                .packages(Set.of("p2"))
                 .build();
 
         ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
         Layer bootLayer = Layer.boot();
 
         Configuration cf = bootLayer.configuration()
-                .resolveRequires(finder, ModuleFinder.of(), Set.of("m1", "m2"));
+                .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
 
@@ -193,4 +193,4 @@
             assertTrue(false);
         } catch (NullPointerException expected) { }
     }
-}
\ No newline at end of file
+}
--- a/jdk/test/java/lang/reflect/Module/AnnotationsTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/Module/AnnotationsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -144,7 +144,7 @@
         Layer bootLayer = Layer.boot();
 
         Configuration cf = bootLayer.configuration()
-                .resolveRequires(finder, ModuleFinder.of(), Set.of(name));
+                .resolve(finder, ModuleFinder.of(), Set.of(name));
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
--- a/jdk/test/java/lang/reflect/Module/BasicModuleTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/Module/BasicModuleTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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,8 +25,10 @@
 import java.lang.module.ResolvedModule;
 import java.lang.reflect.Layer;
 import java.lang.reflect.Module;
+import java.nio.file.spi.FileSystemProvider;  // service type in java.base
 import java.util.function.Predicate;
 import java.util.stream.Stream;
+import javax.print.PrintServiceLookup;        // service type in java.desktop
 
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
@@ -170,6 +172,14 @@
 
         // canRead
         assertTrue(base.canRead(base));
+        assertFalse(base.canRead(thisModule));
+
+        // addReads
+        try {
+            base.addReads(thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        assertFalse(base.canRead(thisModule));
 
         // isExported
         assertTrue(base.isExported("java.lang"));
@@ -182,6 +192,18 @@
         assertFalse(base.isExported("java.wombat", thisModule));
         assertFalse(base.isExported("java.wombat", base));
 
+        // addExports
+        try {
+            base.addExports("java.lang", thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        try {
+            base.addExports("jdk.internal.misc", thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        assertFalse(base.isExported("jdk.internal.misc"));
+        assertFalse(base.isExported("jdk.internal.misc", thisModule));
+
         // isOpen
         assertFalse(base.isOpen("java.lang"));
         assertFalse(base.isOpen("java.lang", thisModule));
@@ -192,6 +214,29 @@
         assertFalse(base.isOpen("java.wombat"));
         assertFalse(base.isOpen("java.wombat", thisModule));
         assertFalse(base.isOpen("java.wombat", base));
+
+        // addOpens
+        try {
+            base.addOpens("jdk.internal.misc", thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        assertFalse(base.isOpen("jdk.internal.misc"));
+        assertFalse(base.isOpen("jdk.internal.misc", thisModule));
+
+        // canUse
+        assertTrue(base.canUse(FileSystemProvider.class));
+        assertFalse(base.canUse(Thread.class));
+
+        // addUses
+        try {
+            base.addUses(FileSystemProvider.class);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        try {
+            base.addUses(Thread.class);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        assertFalse(base.canUse(Thread.class));
     }
 
 
@@ -226,26 +271,68 @@
         assertTrue(desktop.canRead(base));
         assertTrue(desktop.canRead(xml));
 
+        // addReads
+        try {
+            desktop.addReads(thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        assertFalse(desktop.canRead(thisModule));
+
         // isExported
         assertTrue(desktop.isExported("java.awt"));
         assertTrue(desktop.isExported("java.awt", thisModule));
+        assertFalse(desktop.isExported("sun.awt"));
+        assertFalse(desktop.isExported("sun.awt", thisModule));
+        assertTrue(desktop.isExported("sun.awt", desktop));
         assertFalse(desktop.isExported("java.wombat"));
         assertFalse(desktop.isExported("java.wombat", thisModule));
+        assertFalse(desktop.isExported("java.wombat", base));
+
+        // addExports
+        try {
+            desktop.addExports("java.awt", thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        try {
+            desktop.addExports("sun.awt", thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        assertFalse(desktop.isExported("sun.awt"));
+        assertFalse(desktop.isExported("sun.awt", thisModule));
+
+        // isOpen
+        assertFalse(desktop.isOpen("java.awt"));
+        assertFalse(desktop.isOpen("java.awt", thisModule));
+        assertTrue(desktop.isOpen("java.awt", desktop));
+        assertFalse(desktop.isOpen("sun.awt"));
+        assertFalse(desktop.isOpen("sun.awt", thisModule));
+        assertTrue(desktop.isOpen("sun.awt", desktop));
+        assertFalse(desktop.isOpen("java.wombat"));
+        assertFalse(desktop.isOpen("java.wombat", thisModule));
+        assertFalse(desktop.isOpen("java.wombat", desktop));
+
+        // addOpens
+        try {
+            base.addOpens("sun.awt", thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        assertFalse(desktop.isOpen("sun.awt"));
+        assertFalse(desktop.isOpen("sun.awt", thisModule));
+
+        // canUse
+        assertTrue(base.canUse(FileSystemProvider.class));
+        assertFalse(base.canUse(Thread.class));
+
+        // addUses
+        try {
+            desktop.addUses(PrintServiceLookup.class);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        try {
+            desktop.addUses(Thread.class);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+        assertFalse(desktop.canUse(Thread.class));
     }
 
-
-    @Test(expectedExceptions = { NullPointerException.class })
-    public void testIsExportedNull() {
-        Module thisModule = this.getClass().getModule();
-        thisModule.isExported(null, thisModule);
-    }
-
-
-    @Test(expectedExceptions = { NullPointerException.class })
-    public void testIsExportedToNull() {
-        Module thisModule = this.getClass().getModule();
-        thisModule.isExported("", null);
-    }
-
-
 }
--- a/jdk/test/java/lang/reflect/Module/WithSecurityManager.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/Module/WithSecurityManager.java	Fri Feb 10 08:57:42 2017 -0800
@@ -126,7 +126,7 @@
         Layer bootLayer = Layer.boot();
         Configuration cf = bootLayer
             .configuration()
-            .resolveRequires(finder, ModuleFinder.of(), Set.of(ANOTHER_MODULE));
+            .resolve(finder, ModuleFinder.of(), Set.of(ANOTHER_MODULE));
         Layer layer = bootLayer.defineModulesWithOneLoader(cf, null);
 
         Optional<Module> om = layer.findModule(mn);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/Driver.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, 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
+ * @build test/* m1/* m2/* m3/* m4/*
+ * @run testng/othervm test/test.Main
+ * @summary Basic test case for Module::addXXX methods
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m1/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+module m1 {
+    exports p1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m1/p1/C.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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 p1;
+
+public class C {
+    public C() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m2/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+module m2 {
+    exports p2;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m2/p2/C.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017, 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 p2;
+
+import java.lang.reflect.Module;
+
+public class C {
+
+    public static void export(String pn, Module m) {
+        C.class.getModule().addExports(pn, m);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m2/p2/internal/C.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, 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 p2.internal;
+
+public class C {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m3/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+module m3 {
+    exports p3 to test;
+    opens p3 to test;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m3/p3/C.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, 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 p3;
+
+public class C {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m4/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+module m4 {
+    exports p4;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m4/p4/C.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017, 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 p4;
+
+import java.lang.reflect.Constructor;
+
+public class C {
+    public static Object tryNewInstance(Class<?> clazz) throws Exception {
+        Constructor<?> ctor = clazz.getDeclaredConstructor();
+        return ctor.newInstance();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/test/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+module test {
+    exports test to testng;
+
+    requires m2;
+    requires m3;
+    requires m4;
+    requires testng;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/test/test/C.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, 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 test;
+
+public class C { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/test/test/Main.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2017, 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 test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Module;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/**
+ * Basic test case for Module::addXXXX methods
+ */
+
+@Test
+public class Main {
+
+    /**
+     * Test Module::addReads
+     *
+     *     module test { }
+     *
+     *     module m1 {
+     *         exports p1;
+     *     }
+     */
+    public void testAddReads() throws Throwable {
+        Module thisModule = Main.class.getModule();
+        Class<?> clazz = Class.forName("p1.C");
+        Module m1 = clazz.getModule();
+
+        // test does not read m1
+        assertFalse(thisModule.canRead(m1));
+        MethodHandles.Lookup lookup = MethodHandles.lookup();
+        MethodType mt = MethodType.methodType(void.class);
+        try {
+            lookup.findConstructor(clazz, mt);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        // update test to read m1
+        Module result = thisModule.addReads(m1);
+        assertTrue(result== thisModule);
+        assertTrue(thisModule.canRead(m1));
+        MethodHandle mh = lookup.findConstructor(clazz, mt);
+        Object obj = mh.invoke();
+
+        // attempt to update m1 to read test
+        try {
+            m1.addReads(thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+    }
+
+
+    /**
+     * Test Module::addExports
+     *
+     *     module test {
+     *         requires m2;
+     *     }
+     *     module m2 {
+     *         exports p2;
+     *         contains package p2.internal;
+     *     }
+     */
+    public void testAddExports() throws Exception {
+        Module thisModule = Main.class.getModule();
+        Module m2 = p2.C.class.getModule();
+        Class<?> targetClass = Class.forName("p2.internal.C");
+        String p2Internal = targetClass.getPackageName();
+        assertTrue(targetClass.getModule() == m2);
+
+        // m2 does not export p2.internal to test
+        assertFalse(m2.isExported(p2Internal, thisModule));
+        Constructor<?> ctor = targetClass.getDeclaredConstructor();
+        try {
+            ctor.newInstance();
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        // update m2 to export p2.internal to test
+        p2.C.export(p2Internal, thisModule);
+        assertTrue(m2.isExported(p2Internal, thisModule));
+        ctor.newInstance(); // should succeed
+
+        // attempt to update m2 to export a package to test
+        try {
+            m2.addExports("p2.other", thisModule);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+    }
+
+    /**
+     * Test Module::addOpens
+     *
+     *     module test {
+     *         requires m3;
+     *         requires m4;
+     *     }
+     *
+     *     module m3 {
+     *         exports p3 to test;
+     *         opens p3 to test;
+     *     }
+     *
+     *     module m4 {
+     *         exports p4;
+     *     }
+     */
+    public void testAddOpens() throws Exception {
+        Module thisModule = Main.class.getModule();
+        Module m3 = p3.C.class.getModule();
+        Module m4 = p4.C.class.getModule();
+
+        // test does not open package test to m4
+        assertFalse(thisModule.isOpen("test", m4));
+        try {
+            p4.C.tryNewInstance(test.C.class);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+        // open test to m4
+        thisModule.addOpens("test", m4);
+        p4.C.tryNewInstance(test.C.class);  // should succeed
+
+
+        // m3 does not open p3 to m4
+        assertFalse(m3.isOpen("p3", m4));
+        try {
+            p4.C.tryNewInstance(p3.C.class);
+            assertTrue(false);
+        } catch (IllegalAccessException expected) { }
+
+
+        // m3 opens p3 to test => test allowed to open m3/p3 to m4
+        assertTrue(m3.isOpen("p3", thisModule));
+        m3.addOpens("p3", m4);
+        assertTrue(m3.isOpen("p3", m4));
+        p4.C.tryNewInstance(p3.C.class);   // should succeed
+
+
+        // attempt to update m4 to open package to m3
+        try {
+            m4.addOpens("p4", m3);
+            assertTrue(false);
+        } catch (IllegalCallerException expected) { }
+    }
+
+
+    /**
+     * Test Module::addUses
+     */
+    public void testAddUses() {
+        Module thisModule = Main.class.getModule();
+
+        assertFalse(thisModule.canUse(Service.class));
+        try {
+            ServiceLoader.load(Service.class);
+            assertTrue(false);
+        } catch (ServiceConfigurationError expected) { }
+
+        Module result = thisModule.addUses(Service.class);
+        assertTrue(result== thisModule);
+
+        assertTrue(thisModule.canUse(Service.class));
+        ServiceLoader.load(Service.class); // no exception
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/test/test/Service.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, 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 test;
+
+/**
+ * Simple service type
+ */
+public interface Service { }
--- a/jdk/test/java/lang/reflect/Proxy/ProxyClassAccessTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/Proxy/ProxyClassAccessTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -91,7 +91,7 @@
         Layer bootLayer = Layer.boot();
         Configuration cf = bootLayer
                 .configuration()
-                .resolveRequiresAndUses(ModuleFinder.of(), finder, modules);
+                .resolveAndBind(ModuleFinder.of(), finder, modules);
         ClassLoader parentLoader = this.getClass().getClassLoader();
         Layer layer = bootLayer.defineModulesWithOneLoader(cf, parentLoader);
 
--- a/jdk/test/java/lang/reflect/Proxy/ProxyLayerTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/lang/reflect/Proxy/ProxyLayerTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -79,7 +79,7 @@
         Layer bootLayer = Layer.boot();
         Configuration cf = bootLayer
                 .configuration()
-                .resolveRequiresAndUses(ModuleFinder.of(), finder, Arrays.asList(modules));
+                .resolveAndBind(ModuleFinder.of(), finder, Arrays.asList(modules));
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
 
@@ -113,7 +113,7 @@
         Layer bootLayer = Layer.boot();
         Configuration cf = bootLayer
                 .configuration()
-                .resolveRequiresAndUses(ModuleFinder.of(), finder, Arrays.asList(modules));
+                .resolveAndBind(ModuleFinder.of(), finder, Arrays.asList(modules));
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
 
@@ -143,7 +143,7 @@
         Layer bootLayer = Layer.boot();
         Configuration cf = bootLayer
                 .configuration()
-                .resolveRequiresAndUses(ModuleFinder.of(), finder, Arrays.asList(modules));
+                .resolveAndBind(ModuleFinder.of(), finder, Arrays.asList(modules));
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
 
--- a/jdk/test/java/net/httpclient/security/Driver.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/net/httpclient/security/Driver.java	Fri Feb 10 08:57:42 2017 -0800
@@ -127,6 +127,7 @@
             cmd.add("-Dtest.src=" + testSrc);
             cmd.add("-Dtest.classes=" + testClasses);
             cmd.add("-Djava.security.manager");
+            cmd.add("--add-modules=jdk.incubator.httpclient");
             cmd.add("-Djava.security.policy=" + testSrc + sep + policy);
             cmd.add("-Dport.number=" + Integer.toString(Utils.getFreePort()));
             cmd.add("-Dport.number1=" + Integer.toString(Utils.getFreePort()));
--- a/jdk/test/java/nio/channels/FileChannel/Transfer.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/nio/channels/FileChannel/Transfer.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -24,43 +24,53 @@
 /* @test
  * @bug 4434723 4482726 4559072 4638365 4795550 5081340 5103988 6253145
  *   6984545
- * @summary Test FileChannel.transferFrom and transferTo
+ * @summary Test FileChannel.transferFrom and transferTo (use -Dseed=X to set PRNG seed)
  * @library ..
+ * @library /lib/testlibrary/
+ * @build jdk.testlibrary.*
+ * @run testng Transfer
  * @key randomness
  */
 
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.RandomAccessFile;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.NonReadableChannelException;
+import java.nio.channels.Pipe;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
 import java.nio.channels.spi.SelectorProvider;
 import java.nio.file.StandardOpenOption;
 import java.nio.file.FileAlreadyExistsException;
 import java.util.Random;
+import java.util.concurrent.TimeUnit;
 
+import jdk.testlibrary.RandomFactory;
+
+import org.testng.annotations.Test;
 
 public class Transfer {
 
-    private static Random generator = new Random();
-
-    private static int[] testSizes = {
-        0, 10, 1023, 1024, 1025, 2047, 2048, 2049 };
+    private static Random generator = RandomFactory.getRandom();
+    private static PrintStream err = System.err;
+    private static PrintStream out = System.out;
 
-    public static void main(String[] args) throws Exception {
-        testFileChannel();
-        for (int i=0; i<testSizes.length; i++)
-            testReadableByteChannel(testSizes[i]);
-        xferTest02(); // for bug 4482726
-        xferTest03(); // for bug 4559072
-        xferTest04(); // for bug 4638365
-        xferTest05(); // for bug 4638365
-        xferTest06(); // for bug 5081340
-        xferTest07(); // for bug 5103988
-        xferTest08(); // for bug 6253145
-        xferTest09(); // for bug 6984545
-    }
-
-    private static void testFileChannel() throws Exception {
+    @Test
+    public void testFileChannel() throws Exception {
         File source = File.createTempFile("source", null);
         source.deleteOnExit();
         File sink = File.createTempFile("sink", null);
@@ -105,52 +115,58 @@
         sink.delete();
     }
 
-    private static void testReadableByteChannel(int size) throws Exception {
-        SelectorProvider sp = SelectorProvider.provider();
-        Pipe p = sp.openPipe();
-        Pipe.SinkChannel sink = p.sink();
-        Pipe.SourceChannel source = p.source();
-        sink.configureBlocking(false);
+    @Test
+    public void testReadableByteChannel() throws Exception {
+        int[] testSizes = { 0, 10, 1023, 1024, 1025, 2047, 2048, 2049 };
 
-        ByteBuffer outgoingdata = ByteBuffer.allocateDirect(size + 10);
-        byte[] someBytes = new byte[size + 10];
-        generator.nextBytes(someBytes);
-        outgoingdata.put(someBytes);
-        outgoingdata.flip();
+        for (int size : testSizes) {
+            SelectorProvider sp = SelectorProvider.provider();
+            Pipe p = sp.openPipe();
+            Pipe.SinkChannel sink = p.sink();
+            Pipe.SourceChannel source = p.source();
+            sink.configureBlocking(false);
 
-        int totalWritten = 0;
-        while (totalWritten < size + 10) {
-            int written = sink.write(outgoingdata);
-            if (written < 0)
-                throw new Exception("Write failed");
-            totalWritten += written;
-        }
+            ByteBuffer outgoingdata = ByteBuffer.allocateDirect(size + 10);
+            byte[] someBytes = new byte[size + 10];
+            generator.nextBytes(someBytes);
+            outgoingdata.put(someBytes);
+            outgoingdata.flip();
 
-        File f = File.createTempFile("blah"+size, null);
-        f.deleteOnExit();
-        RandomAccessFile raf = new RandomAccessFile(f, "rw");
-        FileChannel fc = raf.getChannel();
-        long oldPosition = fc.position();
+            int totalWritten = 0;
+            while (totalWritten < size + 10) {
+                int written = sink.write(outgoingdata);
+                if (written < 0)
+                    throw new Exception("Write failed");
+                totalWritten += written;
+            }
 
-        long bytesWritten = fc.transferFrom(source, 0, size);
-        fc.force(true);
-        if (bytesWritten != size)
-            throw new RuntimeException("Transfer failed");
+            File f = File.createTempFile("blah"+size, null);
+            f.deleteOnExit();
+            RandomAccessFile raf = new RandomAccessFile(f, "rw");
+            FileChannel fc = raf.getChannel();
+            long oldPosition = fc.position();
 
-        if (fc.position() != oldPosition)
-            throw new RuntimeException("Position changed");
+            long bytesWritten = fc.transferFrom(source, 0, size);
+            fc.force(true);
+            if (bytesWritten != size)
+                throw new RuntimeException("Transfer failed");
 
-        if (fc.size() != size)
-            throw new RuntimeException("Unexpected sink size "+ fc.size());
+            if (fc.position() != oldPosition)
+                throw new RuntimeException("Position changed");
 
-        fc.close();
-        sink.close();
-        source.close();
+            if (fc.size() != size)
+                throw new RuntimeException("Unexpected sink size "+ fc.size());
 
-        f.delete();
+            fc.close();
+            sink.close();
+            source.close();
+
+            f.delete();
+        }
     }
 
-    public static void xferTest02() throws Exception {
+    @Test
+    public void xferTest02() throws Exception { // for bug 4482726
         byte[] srcData = new byte[5000];
         for (int i=0; i<5000; i++)
             srcData[i] = (byte)generator.nextInt();
@@ -187,7 +203,8 @@
         dest.delete();
     }
 
-    public static void xferTest03() throws Exception {
+    @Test
+    public void xferTest03() throws Exception { // for bug 4559072
         byte[] srcData = new byte[] {1,2,3,4} ;
 
         // get filechannel for the source file.
@@ -225,7 +242,8 @@
     }
 
     // Test transferTo with large file
-    public static void xferTest04() throws Exception {
+    @Test
+    public void xferTest04() throws Exception { // for bug 4638365
         // Windows and Linux can't handle the really large file sizes for a
         // truncate or a positional write required by the test for 4563125
         String osName = System.getProperty("os.name");
@@ -264,7 +282,8 @@
     }
 
     // Test transferFrom with large file
-    public static void xferTest05() throws Exception {
+    @Test
+    public void xferTest05() throws Exception { // for bug 4638365
         // Create a source file & large sink file for the test
         File source = File.createTempFile("blech", null);
         source.deleteOnExit();
@@ -294,7 +313,7 @@
                      testSize - 40);
         } catch (IOException e) {
             // Can't set up the test, abort it
-            System.err.println("xferTest05 was aborted.");
+            err.println("xferTest05 was aborted.");
             return;
         } finally {
             fc.close();
@@ -337,7 +356,8 @@
     }
 
     // Test transferFrom asking for more bytes than remain in source
-    public static void xferTest06() throws Exception {
+    @Test
+    public void xferTest06() throws Exception { // for bug 5081340
         String data = "Use the source, Luke!";
 
         File source = File.createTempFile("source", null);
@@ -370,7 +390,8 @@
     }
 
     // Test transferTo to non-blocking socket channel
-    public static void xferTest07() throws Exception {
+    @Test
+    public void xferTest07() throws Exception { // for bug 5103988
         File source = File.createTempFile("source", null);
         source.deleteOnExit();
 
@@ -405,7 +426,8 @@
 
 
     // Test transferTo with file positions larger than 2 and 4GB
-    public static void xferTest08() throws Exception {
+    @Test
+    public void xferTest08() throws Exception { // for bug 6253145
         // Creating a sparse 6GB file on Windows takes too long
         String osName = System.getProperty("os.name");
         if (osName.startsWith("Windows"))
@@ -421,10 +443,15 @@
         RandomAccessFile raf = new RandomAccessFile(file, "rw");
         FileChannel fc = raf.getChannel();
 
+        out.println("  Creating large file...");
+        long t0 = System.nanoTime();
         try {
             fc.write(ByteBuffer.wrap("0123456789012345".getBytes("UTF-8")), 6*G);
+            long t1 = System.nanoTime();
+            out.printf("  Created large file in %d ns (%d ms) %n",
+            t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
         } catch (IOException x) {
-            System.err.println("Unable to create test file:" + x);
+            err.println("  Unable to create test file:" + x);
             fc.close();
             return;
         }
@@ -480,7 +507,10 @@
 
                 // write to file and transfer to echo server
                 fc.write(sendbuf, position);
+                t0 = System.nanoTime();
                 fc.transferTo(position, count, source);
+                out.printf("  transferTo(%d, %2d, source): %d ns%n",
+                    position, count, System.nanoTime() - t0);
 
                 // read from echo server
                 long nread = 0;
@@ -495,7 +525,7 @@
                 readbuf.flip();
                 sendbuf.flip();
                 if (!readbuf.equals(sendbuf))
-                    throw new RuntimeException("Echo'ed bytes do not match!");
+                    throw new RuntimeException("Echoed bytes do not match!");
                 readbuf.clear();
                 sendbuf.clear();
             }
@@ -509,7 +539,8 @@
 
     // Test that transferFrom with FileChannel source that is not readable
     // throws NonReadableChannelException
-    static void xferTest09() throws Exception {
+    @Test
+    public void xferTest09() throws Exception { // for bug 6984545
         File source = File.createTempFile("source", null);
         source.deleteOnExit();
 
--- a/jdk/test/java/nio/channels/Selector/SelectTimeout.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/nio/channels/Selector/SelectTimeout.java	Fri Feb 10 08:57:42 2017 -0800
@@ -30,14 +30,13 @@
  */
 import java.io.IOException;
 import java.nio.channels.Selector;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 
 public class SelectTimeout {
     private static final long BIG_TIMEOUT    = 100_000_001_000L; // 8165000
     private static final long BIGGER_TIMEOUT = 850_000_000_000_000L; // 8172547
-    private static final long SLEEP_MILLIS   = 10000;
-
-    private static volatile Exception theException;
-    private static volatile boolean isTimedOut;
+    private static final long SLEEP_MILLIS   = 10_000;
 
     public static void main(String[] args)
         throws IOException, InterruptedException {
@@ -59,17 +58,18 @@
 
     private static boolean test(final long timeout)
         throws InterruptedException, IOException {
-        theException = null;
+        AtomicReference<Exception> theException =
+            new AtomicReference<>();
+        AtomicBoolean isTimedOut = new AtomicBoolean();
 
         Selector selector = Selector.open();
 
         Thread t = new Thread(() -> {
             try {
-                isTimedOut = false;
                 selector.select(timeout);
-                isTimedOut = true;
+                isTimedOut.set(true);
             } catch (IOException ioe) {
-                theException = ioe;
+                theException.set(ioe);
             }
         });
         t.start();
@@ -77,8 +77,8 @@
         t.join(SLEEP_MILLIS);
 
         boolean result;
-        if (theException == null) {
-            if (timeout > SLEEP_MILLIS && isTimedOut) {
+        if (theException.get() == null) {
+            if (timeout > SLEEP_MILLIS && isTimedOut.get()) {
                 System.err.printf("Test timed out early with timeout %d%n",
                     timeout);
                 result = false;
@@ -88,11 +88,12 @@
             }
         } else {
             System.err.printf("Test failed with timeout %d%n", timeout);
-            theException.printStackTrace();
+            theException.get().printStackTrace();
             result = false;
         }
 
         t.interrupt();
+        selector.close();
 
         return result;
     }
--- a/jdk/test/java/nio/file/FileSystem/Basic.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/nio/file/FileSystem/Basic.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -30,11 +30,18 @@
  */
 
 import java.io.File;
-import java.nio.file.*;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.ProviderNotFoundException;
 import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
 import jdk.testlibrary.FileUtils;
 
 /**
@@ -47,6 +54,44 @@
             throw new RuntimeException(msg);
     }
 
+    static void checkFileStores(String os, FileSystem fs) throws IOException {
+        boolean checkFileStores = true;
+        if (!os.equals("Windows")) {
+            // try to check whether 'df' hangs
+            System.out.println("\n--- Begin df output ---");
+            System.out.flush();
+            Process proc = new ProcessBuilder("df").inheritIO().start();
+            try {
+                proc.waitFor(90, TimeUnit.SECONDS);
+            } catch (InterruptedException ignored) {
+            }
+            System.out.println("--- End df output ---\n");
+            System.out.flush();
+            try {
+                int exitValue = proc.exitValue();
+                if (exitValue != 0) {
+                    System.err.printf("df process exited with %d != 0%n",
+                        exitValue);
+                    checkFileStores = false;
+                }
+            } catch (IllegalThreadStateException ignored) {
+                System.err.println("df command apparently hung");
+                checkFileStores = false;
+            }
+        }
+
+        // sanity check method
+        if (checkFileStores) {
+            System.out.println("\n--- Begin FileStores ---");
+            for (FileStore store: fs.getFileStores()) {
+                System.out.println(store);
+            }
+            System.out.println("--- EndFileStores ---\n");
+        } else {
+            System.err.println("Skipping FileStore check due to df failure");
+        }
+    }
+
     static void checkSupported(FileSystem fs, String... views) {
         for (String view: views) {
             check(fs.supportedFileAttributeViews().contains(view),
@@ -70,7 +115,9 @@
         }
     }
 
-    public static void main(String[] args) throws IOException, URISyntaxException {
+    public static void main(String[] args)
+        throws IOException, URISyntaxException {
+        String os = System.getProperty("os.name");
         FileSystem fs = FileSystems.getDefault();
 
         // close should throw UOE
@@ -85,15 +132,11 @@
         check(fs.provider().getScheme().equals("file"),
             "should use 'file' scheme");
 
-        // santity check method - need to re-visit this in future as I/O errors
-        // are possible
-        for (FileStore store: fs.getFileStores()) {
-            System.out.println(store);
-        }
+        // sanity check FileStores
+        checkFileStores(os, fs);
 
         // sanity check supportedFileAttributeViews
         checkSupported(fs, "basic");
-        String os = System.getProperty("os.name");
         if (os.equals("SunOS"))
             checkSupported(fs, "posix", "unix", "owner", "acl", "user");
         if (os.equals("Linux"))
--- a/jdk/test/java/security/modules/ModularTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/security/modules/ModularTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -164,9 +164,9 @@
         final Builder builder;
         if (moduleType == MODULE_TYPE.EXPLICIT) {
             System.out.format(" %nGenerating ModuleDescriptor object");
-            builder = ModuleDescriptor.module(moduleName).exports(pkg);
+            builder = ModuleDescriptor.newModule(moduleName).exports(pkg);
             if (isService && serviceInterface != null && serviceImpl != null) {
-                builder.provides(serviceInterface, serviceImpl);
+                builder.provides(serviceInterface, List.of(serviceImpl));
             } else {
                 if (serviceInterface != null) {
                     builder.uses(serviceInterface);
--- a/jdk/test/java/time/TEST.properties	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/time/TEST.properties	Fri Feb 10 08:57:42 2017 -0800
@@ -1,6 +1,5 @@
-# Threeten test uses TestNG
+# java.time tests use TestNG
 TestNG.dirs = .
 othervm.dirs = tck/java/time/chrono test/java/time/chrono test/java/time/format
 lib.dirs = ../../lib/testlibrary
 lib.build = jdk.testlibrary.RandomFactory
-modules = java.base/java.time:open java.base/java.time.chrono:open java.base/java.time.zone:open
--- a/jdk/test/java/time/tck/java/time/AbstractTCKTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/time/tck/java/time/AbstractTCKTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -69,14 +69,35 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamConstants;
 import java.io.Serializable;
-import java.lang.reflect.Field;
 import java.util.Formatter;
+import java.util.Map;
 
 /**
  * Base test class.
  */
 public abstract class AbstractTCKTest {
 
+    /**
+     * Map from package name to the serialVersionUID of the .Ser class for the package.
+     */
+    private static Map<String, Long> serialVersionUIDs = Map.of(
+                "java.time",        -7683839454370182990L,
+                "java.time.chrono", -6103370247208168577L,
+                "java.time.zone",   -8885321777449118786L
+                );
+
+    /**
+     * Returns the serialVersionUID for the class.
+     * The SUIDs are defined by the specification for each class.
+     * @param serClass the class to return the SUID of
+     * @return returns the serialVersionUID for the class
+     */
+    public final static long getSUID(Class<?> serClass) {
+        String pkgName = serClass.getPackageName();
+        return serialVersionUIDs.get(pkgName);
+    }
+
+
     protected static boolean isIsoLeap(long year) {
         if (year % 4 != 0) {
             return false;
@@ -111,10 +132,8 @@
 
     protected static void assertSerializedBySer(Object object, byte[] expectedBytes, byte[]... matches) throws Exception {
         String serClass = object.getClass().getPackage().getName() + ".Ser";
-        Class<?> serCls = Class.forName(serClass);
-        Field field = serCls.getDeclaredField("serialVersionUID");
-        field.setAccessible(true);
-        long serVer = (Long) field.get(null);
+        long serVer = getSUID(object.getClass());
+
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) {
             oos.writeObject(object);
@@ -172,9 +191,8 @@
      * @throws Exception if an unexpected condition occurs
      */
     protected static void assertNotSerializable(Class<?> serClass) throws Exception {
-        Field field = serClass.getDeclaredField("serialVersionUID");
-        field.setAccessible(true);
-        long serVer = (Long) field.get(null);
+        long serVer = getSUID(serClass);
+
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream out = new DataOutputStream(baos)) {
             out.writeShort(ObjectStreamConstants.STREAM_MAGIC);
@@ -201,7 +219,6 @@
         fail("Class should not be deserializable " + serClass.getName());
     }
 
-
     /**
      * Utility method to dump a byte array in a java syntax.
      * @param bytes and array of bytes
--- a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -104,8 +104,6 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Duration;
@@ -470,24 +468,12 @@
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=NullPointerException.class)
     public void constructor_nullTime() throws Throwable  {
-        Constructor<OffsetDateTime> con = OffsetDateTime.class.getDeclaredConstructor(LocalDateTime.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(null, OFFSET_PONE);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
+        OffsetDateTime.of(null, OFFSET_PONE);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void constructor_nullOffset() throws Throwable  {
-        Constructor<OffsetDateTime> con = OffsetDateTime.class.getDeclaredConstructor(LocalDateTime.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(LocalDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30)), null);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
+        OffsetDateTime.of(LocalDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30)), null);
     }
 
     //-----------------------------------------------------------------------
--- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -89,8 +89,6 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.time.Clock;
 import java.time.DateTimeException;
 import java.time.Instant;
@@ -465,28 +463,16 @@
     }
 
     //-----------------------------------------------------------------------
-    // constructor
+    // constructor via factory
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=NullPointerException.class)
     public void constructor_nullTime() throws Throwable  {
-        Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(null, OFFSET_PONE);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
+        OffsetTime.of(null, OFFSET_PONE);
     }
 
     @Test(expectedExceptions=NullPointerException.class)
     public void constructor_nullOffset() throws Throwable  {
-        Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
-        con.setAccessible(true);
-        try {
-            con.newInstance(LocalTime.of(11, 30, 0, 0), null);
-        } catch (InvocationTargetException ex) {
-            throw ex.getCause();
-        }
+       OffsetTime.of(LocalTime.of(11, 30, 0, 0), null);
     }
 
     //-----------------------------------------------------------------------
--- a/jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -63,8 +63,11 @@
 import org.testng.annotations.Test;
 import tck.java.time.AbstractTCKTest;
 
-import java.io.*;
-import java.lang.reflect.Field;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamConstants;
 import java.time.DateTimeException;
 import java.time.ZoneId;
 import java.time.zone.ZoneRulesException;
@@ -153,10 +156,8 @@
 
     private ZoneId deserialize(String id) throws Exception {
         String serClass = ZoneId.class.getPackage().getName() + ".Ser";
-        Class<?> serCls = Class.forName(serClass);
-        Field field = serCls.getDeclaredField("serialVersionUID");
-        field.setAccessible(true);
-        long serVer = (Long) field.get(null);
+        long serVer = getSUID(ZoneId.class);
+
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         try (DataOutputStream dos = new DataOutputStream(baos)) {
             dos.writeShort(ObjectStreamConstants.STREAM_MAGIC);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/TEST.properties	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,2 @@
+# java.time test system clock
+modules = java.base/java.time:open
--- a/jdk/test/java/util/ServiceLoader/modules/BadProvidersTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/util/ServiceLoader/modules/BadProvidersTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -90,7 +90,7 @@
         Layer bootLayer = Layer.boot();
 
         Configuration cf = bootLayer.configuration()
-                .resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of(moduleName));
+                .resolveAndBind(finder, ModuleFinder.of(), Set.of(moduleName));
 
         ClassLoader scl = ClassLoader.getSystemClassLoader();
 
--- a/jdk/test/java/util/ServiceLoader/modules/Basic.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/util/ServiceLoader/modules/Basic.java	Fri Feb 10 08:57:42 2017 -0800
@@ -311,17 +311,17 @@
         ModuleFinder finder = ModuleFinder.of(dir);
 
         // layer1
-        Configuration cf1 = cf0.resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of());
+        Configuration cf1 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
         Layer layer1 = bootLayer.defineModulesWithOneLoader(cf1, scl);
         assertTrue(layer1.modules().size() == 1);
 
         // layer2
-        Configuration cf2 = cf0.resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of());
+        Configuration cf2 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
         Layer layer2 = bootLayer.defineModulesWithOneLoader(cf2, scl);
         assertTrue(layer2.modules().size() == 1);
 
         // layer3 with layer1 and layer2 as parents
-        Configuration cf3 = Configuration.resolveRequiresAndUses(finder,
+        Configuration cf3 = Configuration.resolveAndBind(finder,
                 List.of(cf1, cf2),
                 ModuleFinder.of(),
                 Set.of());
@@ -413,7 +413,7 @@
         Collections.addAll(roots, modules);
         Layer bootLayer = Layer.boot();
         Configuration parent = bootLayer.configuration();
-        Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), roots);
+        Configuration cf = parent.resolve(finder, ModuleFinder.of(), roots);
         ClassLoader scl = ClassLoader.getSystemClassLoader();
         Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
         assertTrue(layer.modules().size() == 1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/tck/ForkJoinPool9Test.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Doug Lea and Martin Buchholz with assistance from
+ * members of JCP JSR-166 Expert Group and released to the public
+ * domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.concurrent.CompletableFuture;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ForkJoinPool9Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(ForkJoinPool9Test.class);
+    }
+
+    /**
+     * Check handling of common pool thread context class loader
+     */
+    public void testCommonPoolThreadContextClassLoader() throws Throwable {
+        if (!testImplementationDetails) return;
+        VarHandle CCL =
+            MethodHandles.privateLookupIn(Thread.class, MethodHandles.lookup())
+            .findVarHandle(Thread.class, "contextClassLoader", ClassLoader.class);
+        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+        boolean haveSecurityManager = (System.getSecurityManager() != null);
+        CompletableFuture.runAsync(
+            () -> {
+                assertSame(systemClassLoader,
+                           Thread.currentThread().getContextClassLoader());
+                assertSame(systemClassLoader,
+                           CCL.get(Thread.currentThread()));
+                if (haveSecurityManager)
+                    assertThrows(
+                        SecurityException.class,
+                        () -> System.getProperty("foo"),
+                        () -> Thread.currentThread().setContextClassLoader(null));
+
+                // TODO ?
+//                 if (haveSecurityManager
+//                     && Thread.currentThread().getClass().getSimpleName()
+//                     .equals("InnocuousForkJoinWorkerThread"))
+//                     assertThrows(SecurityException.class, /* ?? */);
+            }).join();
+    }
+
+}
--- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java	Fri Feb 10 08:57:42 2017 -0800
@@ -46,6 +46,7 @@
  * @summary JSR-166 tck tests (whitebox tests allowed)
  * @build *
  * @modules java.base/java.util.concurrent:open
+ *          java.base/java.lang:open
  *          java.management
  * @run junit/othervm/timeout=1000
  *      -Djsr166.testImplementationDetails=true
@@ -59,6 +60,9 @@
  *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=1
  *      -Djava.util.secureRandomSeed=true
  *      JSR166TestCase
+ * @run junit/othervm/timeout=1000/policy=tck.policy
+ *      -Djsr166.testImplementationDetails=true
+ *      JSR166TestCase
  */
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -584,6 +588,7 @@
                 "AtomicReference9Test",
                 "AtomicReferenceArray9Test",
                 "ExecutorCompletionService9Test",
+                "ForkJoinPool9Test",
             };
             addNamedTestClasses(suite, java9TestClassNames);
         }
@@ -594,7 +599,7 @@
     /** Returns list of junit-style test method names in given class. */
     public static ArrayList<String> testMethodNames(Class<?> testClass) {
         Method[] methods = testClass.getDeclaredMethods();
-        ArrayList<String> names = new ArrayList<String>(methods.length);
+        ArrayList<String> names = new ArrayList<>(methods.length);
         for (Method method : methods) {
             if (method.getName().startsWith("test")
                 && Modifier.isPublic(method.getModifiers())
@@ -700,7 +705,7 @@
      * The first exception encountered if any threadAssertXXX method fails.
      */
     private final AtomicReference<Throwable> threadFailure
-        = new AtomicReference<Throwable>(null);
+        = new AtomicReference<>(null);
 
     /**
      * Records an exception so that it can be rethrown later in the test
@@ -1262,7 +1267,7 @@
         }
         public void refresh() {}
         public String toString() {
-            List<Permission> ps = new ArrayList<Permission>();
+            List<Permission> ps = new ArrayList<>();
             for (Enumeration<Permission> e = perms.elements(); e.hasMoreElements();)
                 ps.add(e.nextElement());
             return "AdjustablePolicy with permissions " + ps;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/concurrent/tck/tck.policy	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,15 @@
+grant {
+    // Permissions j.u.c. needs directly
+    permission java.lang.RuntimePermission "modifyThread";
+    permission java.lang.RuntimePermission "getClassLoader";
+    permission java.lang.RuntimePermission "setContextClassLoader";
+    permission java.util.PropertyPermission "*", "read";
+    // Permissions needed to change permissions!
+    permission java.security.SecurityPermission "getPolicy";
+    permission java.security.SecurityPermission "setPolicy";
+    permission java.security.SecurityPermission "setSecurityManager";
+    // Permissions needed by the junit test harness
+    permission java.lang.RuntimePermission "accessDeclaredMembers";
+    permission java.io.FilePermission "<<ALL FILES>>", "read";
+    permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/reflect/CallerSensitive/CheckCSMs.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.jdeps.ClassFileReader;
+import static com.sun.tools.classfile.ConstantPool.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/*
+ * @test
+ * @summary CallerSensitive methods should be static or final instance
+ *          methods except the known list of non-final instance methods
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ *          jdk.jdeps/com.sun.tools.jdeps
+ * @build CheckCSMs
+ * @run main/othervm/timeout=900 CheckCSMs
+ */
+public class CheckCSMs {
+    private static int numThreads = 3;
+    private static boolean listCSMs = false;
+    private final ExecutorService pool;
+
+    // The goal is to remove this list of Non-final instance @CS methods
+    // over time.  Do not add any new one to this list.
+    private static Set<String> KNOWN_NON_FINAL_CSMS =
+      Set.of("java/io/ObjectStreamField#getType ()Ljava/lang/Class;",
+             "java/io/ObjectStreamClass#forClass ()Ljava/lang/Class;",
+             "java/lang/Runtime#load (Ljava/lang/String;)V",
+             "java/lang/Runtime#loadLibrary (Ljava/lang/String;)V",
+             "java/lang/Thread#getContextClassLoader ()Ljava/lang/ClassLoader;",
+             "javax/sql/rowset/serial/SerialJavaObject#getFields ()[Ljava/lang/reflect/Field;"
+      );
+
+    public static void main(String[] args) throws Exception {
+        if (args.length > 0 && args[0].equals("--list")) {
+            listCSMs = true;
+        }
+
+        CheckCSMs checkCSMs = new CheckCSMs();
+        Set<String> result = checkCSMs.run(getPlatformClasses());
+        if (!KNOWN_NON_FINAL_CSMS.equals(result)) {
+            Set<String> diff = new HashSet<>(result);
+            diff.removeAll(KNOWN_NON_FINAL_CSMS);
+            throw new RuntimeException("Unexpected non-final instance method: " +
+                result.stream().sorted()
+                      .collect(Collectors.joining("\n", "\n", "")));
+        }
+    }
+
+    private final Set<String> nonFinalCSMs = new ConcurrentSkipListSet<>();
+    private final ReferenceFinder finder;
+    public CheckCSMs() {
+        this.finder = new ReferenceFinder(getFilter(), getVisitor());
+        pool = Executors.newFixedThreadPool(numThreads);
+
+    }
+
+    public Set<String> run(Stream<Path> classes)
+        throws IOException, InterruptedException, ExecutionException,
+               ConstantPoolException
+    {
+        classes.forEach(this::processPath);
+        waitForCompletion();
+        pool.shutdown();
+        return nonFinalCSMs;
+    }
+
+
+    private ReferenceFinder.Filter getFilter() {
+        final String classname = "jdk/internal/reflect/Reflection";
+        final String method = "getCallerClass";
+        return new ReferenceFinder.Filter() {
+            public boolean accept(ConstantPool cpool, CPRefInfo cpref) {
+                try {
+                    CONSTANT_NameAndType_info nat = cpref.getNameAndTypeInfo();
+                    return cpref.getClassName().equals(classname) && nat.getName().equals(method);
+                } catch (ConstantPoolException ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        };
+    }
+
+    private ReferenceFinder.Visitor getVisitor() {
+        return new ReferenceFinder.Visitor() {
+            public void visit(ClassFile cf, Method m,  List<CPRefInfo> refs) {
+                try {
+                    // ignore jdk.unsupported/sun.reflect.Reflection.getCallerClass
+                    // which is a "special" delegate to the internal getCallerClass
+                    if (cf.getName().equals("sun/reflect/Reflection") &&
+                        m.getName(cf.constant_pool).equals("getCallerClass"))
+                        return;
+
+                    String name = String.format("%s#%s %s", cf.getName(),
+                                                m.getName(cf.constant_pool),
+                                                m.descriptor.getValue(cf.constant_pool));
+                    if (!CheckCSMs.isStaticOrFinal(cf, m, cf.constant_pool)) {
+                        System.err.println("Unsupported @CallerSensitive: " + name);
+                        nonFinalCSMs.add(name);
+                    } else {
+                        if (listCSMs) {
+                            System.out.format("@CS  %s%n", name);
+                        }
+                    }
+                } catch (ConstantPoolException ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        };
+    }
+
+    void processPath(Path path) {
+        try {
+            ClassFileReader reader = ClassFileReader.newInstance(path);
+            for (ClassFile cf : reader.getClassFiles()) {
+                if (cf.access_flags.is(AccessFlags.ACC_MODULE))
+                    continue;
+
+                String classFileName = cf.getName();
+                // for each ClassFile
+                //    parse constant pool to find matching method refs
+                //      parse each method (caller)
+                //      - visit and find method references matching the given method name
+                pool.submit(getTask(cf));
+            }
+        } catch (IOException x) {
+            throw new UncheckedIOException(x);
+        } catch (ConstantPoolException x) {
+            throw new RuntimeException(x);
+        }
+    }
+
+    private static final String CALLER_SENSITIVE_ANNOTATION
+        = "Ljdk/internal/reflect/CallerSensitive;";
+
+    private static boolean isCallerSensitive(Method m, ConstantPool cp)
+        throws ConstantPoolException
+    {
+        RuntimeAnnotations_attribute attr =
+            (RuntimeAnnotations_attribute)m.attributes.get(Attribute.RuntimeVisibleAnnotations);
+        if (attr != null) {
+            for (int i = 0; i < attr.annotations.length; i++) {
+                Annotation ann = attr.annotations[i];
+                String annType = cp.getUTF8Value(ann.type_index);
+                if (CALLER_SENSITIVE_ANNOTATION.equals(annType)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static boolean isStaticOrFinal(ClassFile cf, Method m, ConstantPool cp)
+        throws ConstantPoolException
+    {
+        if (!isCallerSensitive(m, cp))
+            return false;
+
+        // either a static method or a final instance method
+        return m.access_flags.is(AccessFlags.ACC_STATIC) ||
+               m.access_flags.is(AccessFlags.ACC_FINAL) ||
+               cf.access_flags.is(AccessFlags.ACC_FINAL);
+    }
+
+    private final List<FutureTask<Void>> tasks = new ArrayList<FutureTask<Void>>();
+    private FutureTask<Void> getTask(final ClassFile cf) {
+        FutureTask<Void> task = new FutureTask<Void>(new Callable<Void>() {
+            public Void call() throws Exception {
+                finder.parse(cf);
+                return null;
+            }
+        });
+        tasks.add(task);
+        return task;
+    }
+
+    private void waitForCompletion() throws InterruptedException, ExecutionException {
+        for (FutureTask<Void> t : tasks) {
+            t.get();
+        }
+        if (tasks.isEmpty()) {
+            throw new RuntimeException("No classes found, or specified.");
+        }
+        System.out.println("Parsed " + tasks.size() + " classfiles");
+    }
+
+    static Stream<Path> getPlatformClasses() throws IOException {
+        Path home = Paths.get(System.getProperty("java.home"));
+
+        // Either an exploded build or an image.
+        File classes = home.resolve("modules").toFile();
+        if (classes.isDirectory()) {
+            return Stream.of(classes.toPath());
+        } else {
+            return jrtPaths();
+        }
+    }
+
+    static Stream<Path> jrtPaths() {
+        FileSystem jrt = FileSystems.getFileSystem(URI.create("jrt:/"));
+        Path root = jrt.getPath("/");
+
+        try {
+            return Files.walk(root)
+                    .filter(p -> p.getNameCount() > 1)
+                    .filter(p -> p.toString().endsWith(".class"));
+        } catch (IOException x) {
+            throw new UncheckedIOException(x);
+        }
+    }
+}
--- a/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java	Fri Feb 10 08:57:42 2017 -0800
@@ -46,7 +46,7 @@
     private static final String JAVA_BASE = "java.base";
 
     private static final ModuleDescriptor BASE
-        = ModuleDescriptor.module(JAVA_BASE).build();
+        = ModuleDescriptor.newModule(JAVA_BASE).build();
 
     private static final Set<ModuleDescriptor> MREFS
             = Layer.boot().modules().stream().map(Module::getDescriptor)
--- a/jdk/test/jdk/modules/scenarios/container/src/container/container/Main.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/jdk/modules/scenarios/container/src/container/container/Main.java	Fri Feb 10 08:57:42 2017 -0800
@@ -71,9 +71,9 @@
         ModuleFinder finder = ModuleFinder.of(paths);
 
         Configuration cf = Layer.boot().configuration()
-            .resolveRequiresAndUses(finder,
-                                    ModuleFinder.of(),
-                                    Set.of(appModuleName));
+            .resolveAndBind(finder,
+                            ModuleFinder.of(),
+                            Set.of(appModuleName));
 
         System.out.println("Resolved");
         cf.modules().stream()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/org/omg/CORBA/OrbPropertiesTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import org.omg.CORBA.ORB;
+
+/*
+ * @test
+ * @bug 8049375
+ * @summary Extend how the org.omg.CORBA.ORB handles the search for orb.properties
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @modules java.corba
+ * @compile OrbPropertiesTest.java TestOrbImpl.java TestSingletonOrbImpl.java
+ * @run main/othervm
+ *    -Djava.naming.provider.url=iiop://localhost:1050
+ *    -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ *    OrbPropertiesTest -port 1049
+ * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy
+ *    -Djava.naming.provider.url=iiop://localhost:3050
+ *    -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ *    OrbPropertiesTest -port 3049
+ */
+public class OrbPropertiesTest {
+
+    public static void main(String[] args) throws Exception {
+        updateOrbPropertiesFile();
+        // create and initialize the ORB
+        ORB orb = ORB.init(args, null);
+        if (!(orb instanceof TestOrbImpl)) {
+            throw new RuntimeException("org.omg.CORBA.ORBClass property not set as expected");
+        }
+        ORB singletonOrb = ORB.init();
+        System.out.println("singletonOrb class == " + singletonOrb.getClass().getName());
+        if (!(singletonOrb instanceof TestSingletonOrbImpl)) {
+            throw new RuntimeException("org.omg.CORBA.ORBSingletonClass property not set as expected");
+        }
+
+    }
+
+    private static void updateOrbPropertiesFile() throws Exception {
+        String orbPropertiesFile = System.getProperty("java.home", ".") + "/conf/orb.properties";
+        String orbClassMapping = "org.omg.CORBA.ORBClass TestOrbImpl";
+        String orbSingletonClassMapping = "org.omg.CORBA.ORBSingletonClass TestSingletonOrbImpl";
+        String orbPropertiesMappings = orbClassMapping + "\n" + orbSingletonClassMapping +"\n";
+        try (PrintWriter hfPWriter = new PrintWriter(new BufferedWriter(
+                new FileWriter(orbPropertiesFile, false)))) {
+            hfPWriter.println(orbPropertiesMappings);
+        } catch (IOException ioEx) {
+            ioEx.printStackTrace();
+            throw ioEx;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/org/omg/CORBA/TestOrbImpl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.applet.Applet;
+import java.util.Properties;
+
+import org.omg.CORBA.Any;
+import org.omg.CORBA.Context;
+import org.omg.CORBA.ContextList;
+import org.omg.CORBA.Environment;
+import org.omg.CORBA.ExceptionList;
+import org.omg.CORBA.NVList;
+import org.omg.CORBA.NamedValue;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.Request;
+import org.omg.CORBA.StructMember;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.TypeCode;
+import org.omg.CORBA.UnionMember;
+import org.omg.CORBA.WrongTransaction;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.portable.OutputStream;
+
+
+public class TestOrbImpl extends ORB{
+
+    @Override
+    protected void set_parameters(String[] args, Properties props) {
+
+    }
+
+    @Override
+    protected void set_parameters(Applet app, Properties props) {
+
+    }
+
+    @Override
+    public String[] list_initial_services() {
+        return null;
+    }
+
+    @Override
+    public Object resolve_initial_references(String object_name)
+            throws InvalidName {
+        return null;
+    }
+
+    @Override
+    public String object_to_string(Object obj) {
+        return null;
+    }
+
+    @Override
+    public Object string_to_object(String str) {
+        return null;
+    }
+
+    @Override
+    public NVList create_list(int count) {
+        return null;
+    }
+
+    @Override
+    public NamedValue create_named_value(String s, Any any, int flags) {
+        return null;
+    }
+
+    @Override
+    public ExceptionList create_exception_list() {
+        return null;
+    }
+
+    @Override
+    public ContextList create_context_list() {
+        return null;
+    }
+
+    @Override
+    public Context get_default_context() {
+        return null;
+    }
+
+    @Override
+    public Environment create_environment() {
+        return null;
+    }
+
+    @Override
+    public OutputStream create_output_stream() {
+        return null;
+    }
+
+    @Override
+    public void send_multiple_requests_oneway(Request[] req) {
+
+    }
+
+    @Override
+    public void send_multiple_requests_deferred(Request[] req) {
+
+    }
+
+    @Override
+    public boolean poll_next_response() {
+        return false;
+    }
+
+    @Override
+    public Request get_next_response() throws WrongTransaction {
+        return null;
+    }
+
+    @Override
+    public TypeCode get_primitive_tc(TCKind tcKind) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_struct_tc(String id, String name,
+            StructMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_union_tc(String id, String name,
+            TypeCode discriminator_type, UnionMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_enum_tc(String id, String name, String[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_alias_tc(String id, String name,
+            TypeCode original_type) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_exception_tc(String id, String name,
+            StructMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_interface_tc(String id, String name) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_string_tc(int bound) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_wstring_tc(int bound) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_sequence_tc(int bound, TypeCode element_type) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_recursive_sequence_tc(int bound, int offset) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_array_tc(int length, TypeCode element_type) {
+        return null;
+    }
+
+    @Override
+    public Any create_any() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/org/omg/CORBA/TestSingletonOrbImpl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+import java.applet.Applet;
+import java.util.Properties;
+
+import org.omg.CORBA.Any;
+import org.omg.CORBA.Context;
+import org.omg.CORBA.ContextList;
+import org.omg.CORBA.Environment;
+import org.omg.CORBA.ExceptionList;
+import org.omg.CORBA.NVList;
+import org.omg.CORBA.NamedValue;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.Request;
+import org.omg.CORBA.StructMember;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.TypeCode;
+import org.omg.CORBA.UnionMember;
+import org.omg.CORBA.WrongTransaction;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.portable.OutputStream;
+
+
+public class TestSingletonOrbImpl extends ORB {
+
+    @Override
+    protected void set_parameters(String[] args, Properties props) {
+
+    }
+
+    @Override
+    protected void set_parameters(Applet app, Properties props) {
+
+    }
+
+    @Override
+    public String[] list_initial_services() {
+        return null;
+    }
+
+    @Override
+    public Object resolve_initial_references(String object_name)
+            throws InvalidName {
+        return null;
+    }
+
+    @Override
+    public String object_to_string(Object obj) {
+        return null;
+    }
+
+    @Override
+    public Object string_to_object(String str) {
+        return null;
+    }
+
+    @Override
+    public NVList create_list(int count) {
+        return null;
+    }
+
+    @Override
+    public NamedValue create_named_value(String s, Any any, int flags) {
+        return null;
+    }
+
+    @Override
+    public ExceptionList create_exception_list() {
+        return null;
+    }
+
+    @Override
+    public ContextList create_context_list() {
+        return null;
+    }
+
+    @Override
+    public Context get_default_context() {
+        return null;
+    }
+
+    @Override
+    public Environment create_environment() {
+        return null;
+    }
+
+    @Override
+    public OutputStream create_output_stream() {
+        return null;
+    }
+
+    @Override
+    public void send_multiple_requests_oneway(Request[] req) {
+
+    }
+
+    @Override
+    public void send_multiple_requests_deferred(Request[] req) {
+
+    }
+
+    @Override
+    public boolean poll_next_response() {
+        return false;
+    }
+
+    @Override
+    public Request get_next_response() throws WrongTransaction {
+        return null;
+    }
+
+    @Override
+    public TypeCode get_primitive_tc(TCKind tcKind) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_struct_tc(String id, String name,
+            StructMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_union_tc(String id, String name,
+            TypeCode discriminator_type, UnionMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_enum_tc(String id, String name, String[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_alias_tc(String id, String name,
+            TypeCode original_type) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_exception_tc(String id, String name,
+            StructMember[] members) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_interface_tc(String id, String name) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_string_tc(int bound) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_wstring_tc(int bound) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_sequence_tc(int bound, TypeCode element_type) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_recursive_sequence_tc(int bound, int offset) {
+        return null;
+    }
+
+    @Override
+    public TypeCode create_array_tc(int length, TypeCode element_type) {
+        return null;
+    }
+
+    @Override
+    public Any create_any() {
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/org/omg/CORBA/jtreg.test.policy	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+grant {
+  permission java.util.PropertyPermission "*", "read";
+  permission java.io.FilePermission "<<ALL FILES>>", "read, write, execute";
+};
+
+grant codeBase "file:${test.classes}/*" {
+  permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve";
+  permission java.lang.RuntimePermission "accessClassInPackage.com.sun.jndi.cosnaming";
+};
--- a/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -27,7 +27,7 @@
  *  @summary Verify a non-zero value is assigned to jmxremote.port
  *           when VM is started with jmxremote.port=0.
  *  @library /lib/testlibrary
- *  @modules java.management/sun.management.jdp
+ *  @modules jdk.management.agent/sun.management.jdp
  *  @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpJmxRemoteDynamicPortTestCase DynamicLauncher
  *  @run main JdpJmxRemoteDynamicPortTest
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2017, 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 8173783
+ * @summary 6u141 IllegalArgumentException: jdk.tls.namedGroups
+ * run main/othervm HelloExtensionsTest
+ * run main/othervm HelloExtensionsTest -Djdk.tls.namedGroups="bug, bug"
+ * run main/othervm HelloExtensionsTest -Djdk.tls.namedGroups="secp521r1"
+ *
+ */
+import javax.crypto.*;
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.nio.*;
+import java.security.*;
+
+public class HelloExtensionsTest {
+
+    private static boolean debug = false;
+    private static boolean proceed = true;
+    private static boolean EcAvailable = isEcAvailable();
+
+    static String pathToStores = "../../../../javax/net/ssl/etc";
+    private static String keyStoreFile = "keystore";
+    private static String trustStoreFile = "truststore";
+    private static String passwd = "passphrase";
+
+    private static String keyFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + keyStoreFile;
+    private static String trustFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+    private static void checkDone(SSLEngine ssle) throws Exception {
+        if (!ssle.isInboundDone()) {
+            throw new Exception("isInboundDone isn't done");
+        }
+        if (!ssle.isOutboundDone()) {
+            throw new Exception("isOutboundDone isn't done");
+        }
+    }
+
+    private static void runTest(SSLEngine ssle) throws Exception {
+
+         /*
+
+         A client hello message captured via wireshark by selecting
+         a TLSv1.2 Client Hello record and clicking through to the
+         TLSv1.2 Record Layer line and then selecting the hex stream
+         via "copy -> bytes -> hex stream".
+
+         For Record purposes, here's the ClientHello :
+
+         *** ClientHello, TLSv1.2
+         RandomCookie:  GMT: 1469560450 bytes = { 108, 140, 12, 202,
+         2, 213, 10, 236, 143, 223, 58, 162, 228, 155, 239, 3, 98,
+         232, 89, 41, 116, 120, 13, 37, 105, 153, 97, 241 }
+         Session ID:  {}
+         Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+         TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256,
+         TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
+         TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+         TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+         TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+         TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+         TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+         TLS_RSA_WITH_AES_128_CBC_SHA,
+         TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+         TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+         TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+         TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+         TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+         TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+         TLS_RSA_WITH_AES_128_GCM_SHA256,
+         TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+         TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+         TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+         TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+         TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+         SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+         TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+         TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+         SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+         SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+         TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
+         Compression Methods:  { 0 }
+         Extension elliptic_curves, curve names: {secp256r1,
+         sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1,
+         sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1,
+         sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1,
+         secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
+         Extension ec_point_formats, formats: [uncompressed]
+         Extension signature_algorithms, signature_algorithms:
+         SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA,
+         SHA256withECDSA, SHA256withRSA, Unknown (hash:0x3, signature:0x3),
+         Unknown (hash:0x3, signature:0x1), SHA1withECDSA,
+         SHA1withRSA, SHA1withDSA
+         Extension server_name, server_name:
+         [host_name: bugs.openjdk.java.net]
+         */
+
+        String hello = "16030300df010000db03035898b7826c8c0cc" +
+            "a02d50aec8fdf3aa2e49bef0362e8592974780d25699961f" +
+            "100003ac023c027003cc025c02900670040c009c013002fc" +
+            "004c00e00330032c02bc02f009cc02dc031009e00a2c008c" +
+            "012000ac003c00d0016001300ff01000078000a003400320" +
+            "0170001000300130015000600070009000a0018000b000c0" +
+            "019000d000e000f001000110002001200040005001400080" +
+            "016000b00020100000d00180016060306010503050104030" +
+            "401030303010203020102020000001a00180000156275677" +
+            "32e6f70656e6a646b2e6a6176612e6e6574";
+
+        byte[] msg_clihello = hexStringToByteArray(hello);
+        ByteBuffer bf_clihello = ByteBuffer.wrap(msg_clihello);
+
+        SSLSession session = ssle.getSession();
+        int appBufferMax = session.getApplicationBufferSize();
+        int netBufferMax = session.getPacketBufferSize();
+
+        ByteBuffer serverIn = ByteBuffer.allocate(appBufferMax + 50);
+        ByteBuffer serverOut = ByteBuffer.wrap("I'm Server".getBytes());
+        ByteBuffer sTOc = ByteBuffer.allocate(netBufferMax);
+
+        ssle.beginHandshake();
+
+        // unwrap the clientHello message.
+        SSLEngineResult result = ssle.unwrap(bf_clihello, serverIn);
+        System.out.println("server unwrap " + result);
+        runDelegatedTasks(result, ssle);
+
+        if (!proceed) {
+            //expected exception occurred. Don't process anymore
+            return;
+        }
+
+        // one more step, ensure the clientHello message is parsed.
+        SSLEngineResult.HandshakeStatus status = ssle.getHandshakeStatus();
+        if ( status == HandshakeStatus.NEED_UNWRAP) {
+            result = ssle.unwrap(bf_clihello, serverIn);
+            System.out.println("server unwrap " + result);
+            runDelegatedTasks(result, ssle);
+        } else if ( status == HandshakeStatus.NEED_WRAP) {
+            result = ssle.wrap(serverOut, sTOc);
+            System.out.println("server wrap " + result);
+            runDelegatedTasks(result, ssle);
+        } else {
+            throw new Exception("unexpected handshake status " + status);
+        }
+
+        // enough, stop
+    }
+
+    /*
+     * If the result indicates that we have outstanding tasks to do,
+     * go ahead and run them in this thread.
+     */
+    private static void runDelegatedTasks(SSLEngineResult result,
+            SSLEngine engine) throws Exception {
+
+        if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+            Runnable runnable;
+            try {
+                while ((runnable = engine.getDelegatedTask()) != null) {
+                    log("\trunning delegated task...");
+                    runnable.run();
+                }
+            } catch (ExceptionInInitializerError e) {
+                String v = System.getProperty("jdk.tls.namedGroups");
+                if (!EcAvailable || v == null) {
+                    // we weren't expecting this if no EC providers
+                    throw new RuntimeException("Unexpected Error :" + e);
+                }
+                if (v != null && v.contains("bug")) {
+                    // OK - we were expecting this Error
+                    log("got expected error for bad jdk.tls.namedGroups");
+                    proceed = false;
+                    return;
+                } else {
+                    System.out.println("Unexpected error. " +
+                        "jdk.tls.namedGroups value: " + v);
+                    throw e;
+                }
+            }
+            HandshakeStatus hsStatus = engine.getHandshakeStatus();
+            if (hsStatus == HandshakeStatus.NEED_TASK) {
+                throw new Exception(
+                    "handshake shouldn't need additional tasks");
+            }
+            log("\tnew HandshakeStatus: " + hsStatus);
+        }
+    }
+
+    private static byte[] hexStringToByteArray(String s) {
+        int len = s.length();
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+                + Character.digit(s.charAt(i+1), 16));
+        }
+        return data;
+    }
+
+    private static boolean isEcAvailable() {
+        try {
+            Signature.getInstance("SHA1withECDSA");
+            Signature.getInstance("NONEwithECDSA");
+            KeyAgreement.getInstance("ECDH");
+            KeyFactory.getInstance("EC");
+            KeyPairGenerator.getInstance("EC");
+            AlgorithmParameters.getInstance("EC");
+        } catch (Exception e) {
+            log("EC not available. Received: " + e);
+            return false;
+        }
+        return true;
+    }
+
+    public static void main(String args[]) throws Exception {
+        SSLEngine ssle = createSSLEngine(keyFilename, trustFilename);
+        runTest(ssle);
+        System.out.println("Test Passed.");
+    }
+
+    /*
+     * Create an initialized SSLContext to use for this test.
+     */
+    static private SSLEngine createSSLEngine(String keyFile, String trustFile)
+            throws Exception {
+
+        SSLEngine ssle;
+
+        KeyStore ks = KeyStore.getInstance("JKS");
+        KeyStore ts = KeyStore.getInstance("JKS");
+
+        char[] passphrase = "passphrase".toCharArray();
+
+        ks.load(new FileInputStream(keyFile), passphrase);
+        ts.load(new FileInputStream(trustFile), passphrase);
+
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+        kmf.init(ks, passphrase);
+
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+        tmf.init(ts);
+
+        SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+        sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+        ssle = sslCtx.createSSLEngine();
+        ssle.setUseClientMode(false);
+
+        return ssle;
+    }
+
+
+    private static void log(String str) {
+        if (debug) {
+            System.out.println(str);
+        }
+    }
+}
--- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java	Fri Feb 10 08:57:42 2017 -0800
@@ -456,7 +456,7 @@
                 .shouldMatch("Timestamp signature algorithm: .*key.*weak");
         verify(file, "-J-Djava.security.debug=jar")
                 .shouldHaveExitValue(0)
-                .shouldMatch("SignatureException:.*Disabled");
+                .shouldMatch("SignatureException:.*disabled");
     }
 
     static void checkHalfWeak(String file) throws Throwable {
--- a/jdk/test/tools/jar/mmrjar/Basic.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/tools/jar/mmrjar/Basic.java	Fri Feb 10 08:57:42 2017 -0800
@@ -331,7 +331,7 @@
         ModuleInfoExtender mie = ModuleInfoExtender.newExtender(
             new ByteArrayInputStream(mdBytes));
 
-        mie.mainClass("foo.main");
+        mie.mainClass("p.Main");
         mie.version(Version.parse("1.0"));
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -345,7 +345,7 @@
 
         // different main-class
         mie = ModuleInfoExtender.newExtender(new ByteArrayInputStream(mdBytes));
-        mie.mainClass("foo.main2");
+        mie.mainClass("p.Main2");
         mie.version(Version.parse("1.0"));
         baos.reset();
         mie.write(baos);
@@ -360,7 +360,7 @@
 
         // different version
         mie = ModuleInfoExtender.newExtender(new ByteArrayInputStream(mdBytes));
-        mie.mainClass("foo.main");
+        mie.mainClass("p.Main");
         mie.version(Version.parse("2.0"));
         baos.reset();
         mie.write(baos);
@@ -395,7 +395,7 @@
         Files.copy(Paths.get("test7-v9", "module-info.class"),
                    Paths.get("test7-v10", "module-info.class"));
 
-        int rc = jar("--create --file mmr.jar --main-class=foo.main -C test7 . --release 9 -C test7-v9 . --release 10 -C test7-v10 .");
+        int rc = jar("--create --file mmr.jar --main-class=p.Main -C test7 . --release 9 -C test7-v9 . --release 10 -C test7-v10 .");
 
 System.out.println("-----------------------");
 System.out.println( new String(errbytes.toByteArray()));
@@ -409,7 +409,7 @@
 System.out.println("-----------------------");
 System.out.println( new String(outbytes.toByteArray()));
 
-        Optional<String> exp = Optional.of("foo.main");
+        Optional<String> exp = Optional.of("p.Main");
         try (ZipFile zf = new ZipFile("mmr.jar")) {
             Assert.assertTrue(zf.getEntry("module-info.class") == null);
 
--- a/jdk/test/tools/jar/modularJar/Basic.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/tools/jar/modularJar/Basic.java	Fri Feb 10 08:57:42 2017 -0800
@@ -328,7 +328,7 @@
             .resultChecker(r -> assertModuleData(r, FOO));
     }
 
-    @Test
+    @Test(enabled = false)
     public void partialUpdateFooMainClass() throws IOException {
         Path mp = Paths.get("partialUpdateFooMainClass");
         createTestDir(mp);
--- a/jdk/test/tools/jlink/JLinkNegativeTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/tools/jlink/JLinkNegativeTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -274,7 +274,7 @@
                 helper.getJmodSrcDir(), helper.getJmodClassesDir(), moduleName2, classNames);
 
         try (OutputStream out = Files.newOutputStream(module2.resolve("module-info.class"))) {
-            ModuleInfoWriter.write(ModuleDescriptor.module(moduleName1)
+            ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName1)
                     .requires("java.base").build(), out);
         }
 
@@ -332,7 +332,7 @@
                 helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName2, classNames);
 
         try (OutputStream out = Files.newOutputStream(module2.resolve("module-info.class"))) {
-            ModuleInfoWriter.write(ModuleDescriptor.module(moduleName1)
+            ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName1)
                     .requires("java.base").build(), out);
         }
 
--- a/jdk/test/tools/jmod/hashes/HashesTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/tools/jmod/hashes/HashesTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -312,9 +312,7 @@
         assertTrue(ht.hashes("m2") == null);
 
         // should not override any JDK packaged modules
-        ModuleFinder finder = new ModulePath(Runtime.version(),
-                                             true,
-                                             mpath);
+        ModuleFinder finder = ModulePath.of(Runtime.version(), true, mpath);
         assertTrue(ht.hashes(finder,"jdk.compiler") == null);
         assertTrue(ht.hashes(finder,"jdk.attach") == null);
     }
@@ -325,9 +323,7 @@
     }
 
     private ModuleHashes hashes(String name) {
-        ModuleFinder finder = new ModulePath(Runtime.version(),
-                                             true,
-                                             lib);
+        ModuleFinder finder = ModulePath.of(Runtime.version(), true, lib);
         return hashes(finder, name);
     }
 
--- a/jdk/test/tools/launcher/ArgsEnvVar.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/tools/launcher/ArgsEnvVar.java	Fri Feb 10 08:57:42 2017 -0800
@@ -40,7 +40,7 @@
     private static File testJar = null;
     private static Map<String, String> env = new HashMap<>();
 
-    private static String JAVA_OPTIONS = "JAVA_OPTIONS";
+    private static String JDK_JAVA_OPTIONS = "JDK_JAVA_OPTIONS";
 
     static void init() throws IOException {
         if  (testJar != null) {
@@ -105,7 +105,7 @@
         File argFile2 = createArgFile("argFile2", List.of("-Darg.file2=TWO"));
         File argFile3 = createArgFile("argFile3", List.of("-Darg.file3=THREE"));
 
-        env.put(JAVA_OPTIONS, "@argFile1\n-Xint\r-cp @@escaped\t@argFile2");
+        env.put(JDK_JAVA_OPTIONS, "@argFile1\n-Xint\r-cp @@escaped\t@argFile2");
 
         TestResult tr = doExec(env, javaCmd, "@argFile3", "-cp", "test.jar", "Foo", "uarg1", "@uarg2");
 
@@ -133,13 +133,13 @@
     }
 
     private TestResult testInEnv(List<String> options) {
-        env.put(JAVA_OPTIONS, String.join(" ", options));
+        env.put(JDK_JAVA_OPTIONS, String.join(" ", options));
         return doExec(env, javaCmd, "-jar", "test.jar");
     }
 
     private TestResult testInEnvAsArgFile(List<String> options) throws IOException {
         File argFile = createArgFile("argFile", options);
-        env.put(JAVA_OPTIONS, "@argFile");
+        env.put(JDK_JAVA_OPTIONS, "@argFile");
         TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
         argFile.delete();
         return tr;
@@ -187,7 +187,7 @@
         File argFile1 = createArgFile("arg File 1", List.of("-Xint"));
         File argFile2 = createArgFile("arg File 2", List.of("-Dprop='value with spaces'"));
         File argFile3 = createArgFile("arg File 3", List.of("-Xmx32m"));
-        env.put(JAVA_OPTIONS, "'@arg File 1' @\"arg File 2\" @'arg File'\" 3\"");
+        env.put(JDK_JAVA_OPTIONS, "'@arg File 1' @\"arg File 2\" @'arg File'\" 3\"");
 
         TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
         List<String> options = new ArrayList<>();
@@ -204,7 +204,7 @@
 
     @Test
     public void openQuoteShouldFail() {
-        env.put(JAVA_OPTIONS, "-Dprop='value missing close quote");
+        env.put(JDK_JAVA_OPTIONS, "-Dprop='value missing close quote");
         TestResult tr = doExec(env, javaCmd, "-version");
         tr.checkNegative();
         if (!tr.testStatus) {
@@ -215,11 +215,11 @@
 
     @Test
     public void noWildcard() {
-        env.put(JAVA_OPTIONS, "-cp *");
+        env.put(JDK_JAVA_OPTIONS, "-cp *");
         TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
         verifyOptions(List.of("-cp", "*", "-jar", "test.jar"), tr);
 
-        env.put(JAVA_OPTIONS, "-p ?");
+        env.put(JDK_JAVA_OPTIONS, "-p ?");
         tr = doExec(env, javaCmd, "-jar", "test.jar", "one", "two");
         verifyOptions(List.of("-p", "?", "-jar", "test.jar", "one", "two"), tr);
     }
--- a/jdk/test/tools/launcher/I18NArgTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/tools/launcher/I18NArgTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -95,21 +95,19 @@
             throw new RuntimeException("test fails");
         }
 
-        // Test via JAVA_OPTIONS
-/*
+        // Test via JDK_JAVA_OPTIONS
         Map<String, String> env = new HashMap<>();
         String cmd = "-Dtest.src=" + TEST_SOURCES_DIR.getAbsolutePath() +
                 " -Dtest.classes=" + TEST_CLASSES_DIR.getAbsolutePath() +
                 " -cp " + TEST_CLASSES_DIR.getAbsolutePath() +
                 " I18NArgTest " + unicodeStr + " " + hexValue;
-        env.put("JAVA_OPTIONS", cmd);
+        env.put("JDK_JAVA_OPTIONS", cmd);
         tr = doExec(env, javaCmd);
         System.out.println(tr.testOutput);
         if (!tr.isOK()) {
             System.err.println(tr);
             throw new RuntimeException("test fails");
         }
-*/
     }
 
     static void testCharacters(String... args) {
--- a/jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModules.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModules.java	Fri Feb 10 08:57:42 2017 -0800
@@ -30,6 +30,8 @@
 public final class SystemModules {
     public static final String[] MODULE_NAMES = new String[0];
 
+    public static int PACKAGES_IN_BOOT_LAYER = 1024;
+
     public static boolean hasSplitPackages() {
         return true;
     }
--- a/langtools/.hgtags	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/.hgtags	Fri Feb 10 08:57:42 2017 -0800
@@ -397,3 +397,4 @@
 5b6f12de6f9167a582fa2c6ac54e69c591b09e68 jdk-9+152
 03f48cd283f5dd6b7153fd7e0cf2df8582b14391 jdk-9+153
 6a9dd3d893b0a493a3e5d8d392815b5ee76a02d9 jdk-9+154
+dfcfdb2db85f1bb434209f56ca557ea6f9830aa8 jdk-9+155
--- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/AbstractProcessor.java	Fri Feb 10 08:57:42 2017 -0800
@@ -83,7 +83,7 @@
         if  (so == null)
             return Collections.emptySet();
         else
-            return arrayToSet(so.value());
+            return arrayToSet(so.value(), false);
     }
 
     /**
@@ -92,21 +92,31 @@
      * same set of strings as the annotation.  If the class is not so
      * annotated, an empty set is returned.
      *
+     * If the {@link ProcessingEvironment#getSourceVersion source
+     * version} does not support modules, in other words if it is less
+     * than or equal to {@link SourceVersion#RELEASE_8 RELEASE_8},
+     * then any leading {@link Processor#getSupportedAnnotationTypes
+     * module prefixes} are stripped from the names.
+     *
      * @return the names of the annotation types supported by this
      * processor, or an empty set if none
      */
     public Set<String> getSupportedAnnotationTypes() {
             SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class);
+            boolean initialized = isInitialized();
             if  (sat == null) {
-                if (isInitialized())
+                if (initialized)
                     processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
                                                              "No SupportedAnnotationTypes annotation " +
                                                              "found on " + this.getClass().getName() +
                                                              ", returning an empty set.");
                 return Collections.emptySet();
+            } else {
+                boolean stripModulePrefixes =
+                        initialized &&
+                        processingEnv.getSourceVersion().compareTo(SourceVersion.RELEASE_8) <= 0;
+                return arrayToSet(sat.value(), stripModulePrefixes);
             }
-            else
-                return arrayToSet(sat.value());
         }
 
     /**
@@ -185,11 +195,18 @@
         return initialized;
     }
 
-    private static Set<String> arrayToSet(String[] array) {
+    private static Set<String> arrayToSet(String[] array,
+                                          boolean stripModulePrefixes) {
         assert array != null;
         Set<String> set = new HashSet<>(array.length);
-        for (String s : array)
+        for (String s : array) {
+            if (stripModulePrefixes) {
+                int index = s.indexOf('/');
+                if (index != -1)
+                    s = s.substring(index + 1);
+            }
             set.add(s);
+        }
         return Collections.unmodifiableSet(set);
     }
 }
--- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/Filer.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/Filer.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -264,7 +264,7 @@
      * @param moduleAndPkg module and/or package relative to which the file
      *           should be named, or the empty string if none
      * @param relativeName final pathname components of the file
-     * @param originatingElements type or package elements causally
+     * @param originatingElements type or package or module elements causally
      * associated with the creation of this file, may be elided or
      * {@code null}
      * @return a {@code FileObject} to write the new resource
--- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/FilerException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/FilerException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -31,7 +31,7 @@
  * Indicates a {@link Filer} detected an attempt to open a file that
  * would violate the guarantees provided by the {@code Filer}.  Those
  * guarantees include not creating the same file more than once, not
- * creating multiple files corresponding to the same type, and not
+ * creating multiple files corresponding to the same type or package, and not
  * creating files for types with invalid names.
  *
  * @author Joseph D. Darcy
--- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/Processor.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -194,7 +194,7 @@
  * <p>The {@link Filer} interface discusses restrictions on how
  * processors can operate on files.
  *
- * <p>Note that implementors of this interface may find it convenient
+ * @apiNote Implementors of this interface may find it convenient
  * to extend {@link AbstractProcessor} rather than implementing this
  * interface directly.
  *
@@ -254,6 +254,14 @@
      * a.B} which reside in different modules. To only support {@code
      * a.B} in the {@code Foo} module, instead use {@code "Foo/a.B"}.
      *
+     * If a module name is included, only an annotation in that module
+     * is matched. In particular, if a module name is given in an
+     * environment where modules are not supported, such as an
+     * annotation processing environment configured for a {@linkplain
+     * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
+     * source version} without modules, then the annotation types with
+     * a module name do <em>not</em> match.
+     *
      * Finally, {@code "*"} by itself represents the set of all
      * annotation types, including the empty set.  Note that a
      * processor should not claim {@code "*"} unless it is actually
@@ -280,6 +288,14 @@
      * where <i>TypeName</i> is as defined in
      * <cite>The Java&trade; Language Specification</cite>.
      *
+     * @apiNote When running in an environment which supports modules,
+     * processors are encouraged to include the module prefix when
+     * describing their supported annotation types. The method {@link
+     * AbstractProcessor.getSupportedAnnotationTypes
+     * AbstractProcessor.getSupportedAnnotationTypes} provides support
+     * for stripping off the module prefix when running in an
+     * environment without modules.
+     *
      * @return the names of the annotation types supported by this processor
      * @see javax.annotation.processing.SupportedAnnotationTypes
      * @jls 3.8 Identifiers
@@ -315,7 +331,7 @@
      * is returned, the annotation types are unclaimed and subsequent
      * processors may be asked to process them.  A processor may
      * always return the same boolean value or may vary the result
-     * based on chosen criteria.
+     * based on its own chosen criteria.
      *
      * <p>The input set will be empty if the processor supports {@code
      * "*"} and the root elements have no annotations.  A {@code
@@ -343,8 +359,8 @@
     * <p>Since incomplete programs are being modeled, some of the
     * parameters may only have partial information or may be {@code
     * null}.  At least one of {@code element} and {@code userText}
-    * must be non-{@code null}.  If {@code element} is non-{@code
-    * null}, {@code annotation} and {@code member} may be {@code
+    * must be non-{@code null}.  If {@code element} is non-{@code null},
+    * {@code annotation} and {@code member} may be {@code
     * null}.  Processors may not throw a {@code NullPointerException}
     * if some parameters are {@code null}; if a processor has no
     * completions to offer based on the provided information, an
--- a/langtools/src/java.compiler/share/classes/javax/annotation/processing/RoundEnvironment.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/annotation/processing/RoundEnvironment.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -65,7 +65,7 @@
     boolean errorRaised();
 
     /**
-     * Returns the root elements for annotation processing generated
+     * Returns the {@linkplain Processor root elements} for annotation processing generated
      * by the prior round.
      *
      * @return the root elements for annotation processing generated
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/AnnotatedConstruct.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/AnnotatedConstruct.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -62,7 +62,7 @@
  *
  * If there are multiple annotations of type <i>AT</i> present on
  * <i>C</i>, then if <i>AT</i> is repeatable annotation type, an
- * annotation of type <i>ATC</i> is implicitly declared on <i>C</i>.
+ * annotation of type <i>ATC</i> is {@linkplain javax.lang.model.util.Elements#getOrigin(AnnotatedConstruct, AnnotationMirror) implicitly declared} on <i>C</i>.
  *
  * <li> A representation of <i>A</i> appears in the executable output
  * for <i>C</i>, such as the {@code RuntimeVisibleAnnotations} or
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/UnknownEntityException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/UnknownEntityException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -32,8 +32,9 @@
  * this exception may be thrown by visitors to indicate that the
  * visitor was created for a prior version of the language.
  *
- * <p>A common superclass for those exceptions allows a single catch
- * block to have code handling them uniformly.
+ * @apiNote A common superclass for exceptions specific to different
+ * kinds of unknown entities allows a single catch block to easily
+ * provide uniform handling of those related conditions.
  *
  * @author Joseph D. Darcy
  * @see javax.lang.model.element.UnknownElementException
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/Element.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/Element.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -37,7 +37,7 @@
 
 
 /**
- * Represents a program element such as a package, class, or method.
+ * Represents a program element such as a module, package, class, or method.
  * Each element represents a static, language-level construct
  * (and not, for example, a runtime construct of the virtual machine).
  *
@@ -139,7 +139,7 @@
      *
      * <li> If this is a {@linkplain
      * PackageElement#getEnclosingElement package}, its module is
-     * returned.
+     * returned if such a module exists. Otherwise, {@code null} is returned.
      *
      * <li> If this is a {@linkplain
      * TypeParameterElement#getEnclosingElement type parameter},
@@ -176,11 +176,14 @@
      * A {@linkplain ModuleElement#getEnclosedElements module}
      * encloses packages within it.
      *
+     * Enclosed elements may include implicitly declared {@linkplain
+     * Elements.Origin#MANDATED mandated} elements.
+     *
      * Other kinds of elements are not currently considered to enclose
      * any elements; however, that may change as this API or the
      * programming language evolves.
      *
-     * <p>Note that elements of certain kinds can be isolated using
+     * @apiNote Elements of certain kinds can be isolated using
      * methods in {@link ElementFilter}.
      *
      * @return the enclosed elements, or an empty list if none
@@ -197,7 +200,7 @@
      * Returns {@code true} if the argument represents the same
      * element as {@code this}, or {@code false} otherwise.
      *
-     * <p>Note that the identity of an element involves implicit state
+     * @apiNote The identity of an element involves implicit state
      * not directly accessible from the element's methods, including
      * state about the presence of unrelated types.  Element objects
      * created by different implementations of these interfaces should
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java	Fri Feb 10 08:57:42 2017 -0800
@@ -37,17 +37,18 @@
 public interface ModuleElement extends Element, QualifiedNameable {
 
     /**
-     * Returns the fully qualified name of this module.
+     * Returns the fully qualified name of this module.  For an
+     * {@linkplain #isUnnamed() unnamed module}, an empty name is returned.
      *
-     * @return the qualified name of this module, or an
+     * @return the fully qualified name of this module, or an
      * empty name if this is an unnamed module
      */
     @Override
     Name getQualifiedName();
 
     /**
-     * Returns the simple name of this module.  For an unnamed
-     * module, an empty name is returned.
+     * Returns the simple name of this module.  For an {@linkplain
+     * #isUnnamed() unnamed module}, an empty name is returned.
      *
      * @return the simple name of this module or an empty name if
      * this is an unnamed module
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/NestingKind.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/NestingKind.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -89,25 +89,29 @@
 
     /**
      * A type that is a named member of another type.
+     * @jls 8.5 Member Type Declarations
      */
     MEMBER,
 
     /**
      * A named type declared within a construct other than a type.
+     * @jls 14.3 Local Class Declarations
      */
     LOCAL,
 
     /**
      * A type without a name.
+     * @jls 15.9.5 Anonymous Class Declarations
      */
     ANONYMOUS;
 
     /**
      * Does this constant correspond to a nested type element?
      * A <i>nested</i> type element is any that is not top-level.
-     * An <i>inner</i> type element is any nested type element that
+     * More specifically, an <i>inner</i> type element is any nested type element that
      * is not {@linkplain Modifier#STATIC static}.
      * @return whether or not the constant is nested
+     * @jls 14.3 Inner Classes and Enclosing Instances
      */
     public boolean isNested() {
         return this != TOP_LEVEL;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/PackageElement.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/PackageElement.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -42,6 +42,7 @@
     /**
      * Returns the fully qualified name of this package.
      * This is also known as the package's <i>canonical</i> name.
+     * For an {@linkplain #isUnnamed() unnamed package}, an empty name is returned.
      *
      * @return the fully qualified name of this package, or an
      * empty name if this is an unnamed package
@@ -50,8 +51,8 @@
     Name getQualifiedName();
 
     /**
-     * Returns the simple name of this package.  For an unnamed
-     * package, an empty name is returned.
+     * Returns the simple name of this package.  For an {@linkplain
+     * #isUnnamed() unnamed package}, an empty name is returned.
      *
      * @return the simple name of this package or an empty name if
      * this is an unnamed package
@@ -82,9 +83,16 @@
     boolean isUnnamed();
 
     /**
-     * Returns the enclosing module.
+     * Returns the enclosing module if such a module exists; otherwise
+     * returns {@code null}.
      *
-     * @return the enclosing module
+     * One situation where a module does not exist for a package is if
+     * the environment does not include modules, such as an annotation
+     * processing environment configured for a {@linkplain
+     * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
+     * source version} without modules.
+     *
+     * @return the enclosing module or {@code null} if no such module exists
      */
     @Override
     Element getEnclosingElement();
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/Parameterizable.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/Parameterizable.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -35,7 +35,7 @@
  */
 public interface Parameterizable extends Element {
     /**
-     * Returns the formal type parameters of the type element in
+     * Returns the formal type parameters of an element in
      * declaration order.
      *
      * @return the formal type parameters, or an empty list
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/TypeElement.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -63,21 +63,25 @@
      * Returns the fields, methods, constructors, and member types
      * that are directly declared in this class or interface.
      *
-     * This includes any (implicit) default constructor and
-     * the implicit {@code values} and {@code valueOf} methods of an
-     * enum type.
+     * This includes any {@linkplain Elements.Origin#MANDATED
+     * mandated} elements such as the (implicit) default constructor
+     * and the implicit {@code values} and {@code valueOf} methods of
+     * an enum type.
      *
-     * <p> Note that as a particular instance of the {@linkplain
+     * @apiNote As a particular instance of the {@linkplain
      * javax.lang.model.element general accuracy requirements} and the
      * ordering behavior required of this interface, the list of
      * enclosed elements will be returned in the natural order for the
      * originating source of information about the type.  For example,
      * if the information about the type is originating from a source
      * file, the elements will be returned in source code order.
-     * (However, in that case the the ordering of synthesized
-     * elements, such as a default constructor, is not specified.)
+     * (However, in that case the the ordering of elements, such as a
+     * default constructor, is not specified.)
      *
      * @return the enclosed elements in proper order, or an empty list if none
+     *
+     * @jls 8.8.9 Default Constructor
+     * @jls 8.9.3 Enum Members
      */
     @Override
     List<? extends Element> getEnclosedElements();
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/UnknownAnnotationValueException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/UnknownAnnotationValueException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -79,7 +79,7 @@
     /**
      * Returns the additional argument.
      *
-     * @return the additional argument
+     * @return the additional argument, or {@code null} if unavailable
      */
     public Object getArgument() {
         return parameter;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/UnknownElementException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/UnknownElementException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -77,7 +77,7 @@
     /**
      * Returns the additional argument.
      *
-     * @return the additional argument
+     * @return the additional argument, or {@code null} if unavailable
      */
     public Object getArgument() {
         return parameter;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/package-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/package-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -87,14 +87,14 @@
  * If a program is syntactically valid but erroneous in some other
  * fashion, any returned model must have no less information than if
  * all the method bodies in the program were replaced by {@code "throw
- * new RuntimeException();"}.  If a program refers to a missing type XYZ,
+ * new RuntimeException();"}.  If a program refers to a missing type Xyz,
  * the returned model must contain no less information than if the
- * declaration of type XYZ were assumed to be {@code "class XYZ {}"},
- * {@code "interface XYZ {}"}, {@code "enum XYZ {}"}, or {@code
- * "@interface XYZ {}"}. If a program refers to a missing type {@code
- * XYZ<K1, ... ,Kn>}, the returned model must contain no less
- * information than if the declaration of XYZ were assumed to be
- * {@code "class XYZ<T1, ... ,Tn> {}"} or {@code "interface XYZ<T1,
+ * declaration of type Xyz were assumed to be {@code "class Xyz {}"},
+ * {@code "interface Xyz {}"}, {@code "enum Xyz {}"}, or {@code
+ * "@interface Xyz {}"}. If a program refers to a missing type {@code
+ * Xyz<K1, ... ,Kn>}, the returned model must contain no less
+ * information than if the declaration of Xyz were assumed to be
+ * {@code "class Xyz<T1, ... ,Tn> {}"} or {@code "interface Xyz<T1,
  * ... ,Tn> {}"}
  *
  * <p> Unless otherwise specified in a particular implementation, the
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/IntersectionType.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/IntersectionType.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -33,14 +33,12 @@
  * <p>An intersection type can be either implicitly or explicitly
  * declared in a program. For example, the bound of the type parameter
  * {@code <T extends Number & Runnable>} is an (implicit) intersection
- * type.  As of {@link javax.lang.model.SourceVersion#RELEASE_8
- * RELEASE_8}, this is represented by an {@code IntersectionType} with
+ * type.  This is represented by an {@code IntersectionType} with
  * {@code Number} and {@code Runnable} as its bounds.
  *
- * @implNote Also as of {@link
- * javax.lang.model.SourceVersion#RELEASE_8 RELEASE_8}, in the
- * reference implementation an {@code IntersectionType} is used to
- * model the explicit target type of a cast expression.
+ * @implNote In the reference implementation an {@code
+ * IntersectionType} is used to model the explicit target type of a
+ * cast expression.
  *
  * @since 1.8
  */
@@ -49,7 +47,7 @@
     /**
      * Return the bounds comprising this intersection type.
      *
-     * @return the bounds of this intersection types.
+     * @return the bounds of this intersection type
      */
     List<? extends TypeMirror> getBounds();
 }
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/NoType.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/NoType.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -34,6 +34,7 @@
  * <ul>
  * <li>{@link TypeKind#VOID VOID} - corresponds to the keyword {@code void}.
  * <li>{@link TypeKind#PACKAGE PACKAGE} - the pseudo-type of a package element.
+ * <li>{@link TypeKind#MODULE MODULE} - the pseudo-type of a module element.
  * <li>{@link TypeKind#NONE NONE} - used in other cases
  *   where no actual type is appropriate; for example, the superclass
  *   of {@code java.lang.Object}.
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/UnionType.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/UnionType.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -30,9 +30,8 @@
 /**
  * Represents a union type.
  *
- * As of the {@link javax.lang.model.SourceVersion#RELEASE_7
- * RELEASE_7} source version, union types can appear as the type
- * of a multi-catch exception parameter.
+ * Union types can appear as the type of a multi-catch exception
+ * parameter.
  *
  * @since 1.7
  */
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/UnknownTypeException.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/UnknownTypeException.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -77,7 +77,7 @@
     /**
      * Returns the additional argument.
      *
-     * @return the additional argument
+     * @return the additional argument, or {@code null} if unavailable
      */
     public Object getArgument() {
         return parameter;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -55,15 +55,6 @@
  * arguments to methods in this class, a {@code NullPointerException}
  * will be thrown.
  *
- * <p>Note that a <i>static import</i> statement can make the text of
- * calls to the methods in this class more concise; for example:
- *
- * <blockquote><pre>
- *     import static javax.lang.model.util.ElementFilter.*;
- *     ...
- *         {@code List<VariableElement>} fs = fieldsIn(someClass.getEnclosedElements());
- * </pre></blockquote>
- *
  * @author Joseph D. Darcy
  * @author Scott Seligman
  * @author Peter von der Ah&eacute;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -59,12 +59,17 @@
     /**
      * Returns a package given its fully qualified name, as seen from the given module.
      *
+     * @implSpec The default implementation of this method returns
+     * {@code null}.
+     *
      * @param name  fully qualified package name, or an empty string for an unnamed package
      * @param module module relative to which the lookup should happen
      * @return the specified package, or {@code null} if it cannot be found
      * @since 9
      */
-    PackageElement getPackageElement(ModuleElement module, CharSequence name);
+    default PackageElement getPackageElement(ModuleElement module, CharSequence name) {
+        return null;
+    }
 
     /**
      * Returns a type element given its canonical name if the type element is unique in the environment.
@@ -79,12 +84,17 @@
     /**
      * Returns a type element given its canonical name, as seen from the given module.
      *
+     * @implSpec The default implementation of this method returns
+     * {@code null}.
+     *
      * @param name  the canonical name
      * @param module module relative to which the lookup should happen
      * @return the named type element, or {@code null} if it cannot be found
      * @since 9
      */
-    TypeElement getTypeElement(ModuleElement module, CharSequence name);
+    default TypeElement getTypeElement(ModuleElement module, CharSequence name) {
+        return null;
+    }
 
     /**
      * Returns a module element given its fully qualified name.
@@ -95,11 +105,16 @@
      * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
      * source version} without modules.
      *
+     * @implSpec The default implementation of this method returns
+     * {@code null}.
+     *
      * @param name  the name
      * @return the named module element, or {@code null} if it cannot be found
      * @since 9
      */
-    ModuleElement getModuleElement(CharSequence name);
+    default ModuleElement getModuleElement(CharSequence name) {
+        return null;
+    }
 
     /**
      * Returns the values of an annotation's elements, including defaults.
@@ -267,6 +282,7 @@
          * multiple annotations of a repeatable annotation type.
          *
          * @jls 8.8.9 Default Constructor
+         * @jls 8.9.3 Enum Members
          * @jls 9.6.3 Repeatable Annotation Types
          * @jls 9.7.5 Multiple Annotations of the Same Type
          */
@@ -337,18 +353,23 @@
      * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
      * source version} without modules.
      *
+     * @implSpec The default implementation of this method returns
+     * {@code null}.
+     *
      * @param type the element being examined
      * @return the module of an element
      * @since 9
      */
-    ModuleElement getModuleOf(Element type);
+    default ModuleElement getModuleOf(Element type) {
+        return null;
+    }
 
     /**
      * Returns all members of a type element, whether inherited or
      * declared directly.  For a class the result also includes its
      * constructors, but not local or anonymous classes.
      *
-     * <p>Note that elements of certain kinds can be isolated using
+     * @apiNote Elements of certain kinds can be isolated using
      * methods in {@link ElementFilter}.
      *
      * @param type  the type being examined
--- a/langtools/src/jdk.compiler/share/classes/com/sun/source/tree/ImportTree.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/source/tree/ImportTree.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -26,7 +26,7 @@
 package com.sun.source.tree;
 
 /**
- * A tree node for an import statement.
+ * A tree node for an import declaration.
  *
  * For example:
  * <pre>
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -118,6 +118,7 @@
             if (source.compareTo(Source.JDK1_9) >= 0) {
                 values.add(LintCategory.DEP_ANN);
             }
+            values.add(LintCategory.OPENS);
             values.add(LintCategory.MODULE);
             values.add(LintCategory.REMOVAL);
         }
@@ -211,6 +212,11 @@
         MODULE("module"),
 
         /**
+         * Warn about issues regarding module opens.
+         */
+        OPENS("opens"),
+
+        /**
          * Warn about issues relating to use of command line options
          */
         OPTIONS("options"),
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Feb 10 08:57:42 2017 -0800
@@ -2947,6 +2947,14 @@
                 return;
             }
 
+            if (!env.info.isSpeculative && that.getMode() == JCMemberReference.ReferenceMode.NEW) {
+                Type enclosingType = exprType.getEnclosingType();
+                if (enclosingType != null && enclosingType.hasTag(CLASS)) {
+                    // Check for the existence of an apropriate outer instance
+                    rs.resolveImplicitThis(that.pos(), env, exprType);
+                }
+            }
+
             if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
 
                 if (that.getMode() == ReferenceMode.INVOKE &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Fri Feb 10 08:57:42 2017 -0800
@@ -3876,4 +3876,14 @@
         }
     }
 
+    void checkPackageExistsForOpens(final DiagnosticPosition pos, PackageSymbol packge) {
+        if (packge.members().isEmpty() &&
+            ((packge.flags() & Flags.HAS_RESOURCE) == 0)) {
+            deferredLintHandler.report(() -> {
+                if (lint.isEnabled(LintCategory.OPENS))
+                    log.warning(pos, Warnings.PackageEmptyOrNotFound(packge));
+            });
+        }
+    }
+
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Fri Feb 10 08:57:42 2017 -0800
@@ -165,6 +165,7 @@
     private final boolean lintOptions;
 
     private Set<ModuleSymbol> rootModules = null;
+    private final Set<ModuleSymbol> warnedMissing = new HashSet<>();
 
     public static Modules instance(Context context) {
         Modules instance = context.get(Modules.class);
@@ -525,7 +526,6 @@
             ModuleSymbol msym = moduleFinder.findModule((ModuleSymbol) sym);
 
             if (msym.kind == ERR) {
-                log.error(Errors.ModuleNotFound(msym));
                 //make sure the module is initialized:
                 msym.directives = List.nil();
                 msym.exports = List.nil();
@@ -674,6 +674,7 @@
             ModuleSymbol msym = lookupModule(tree.moduleName);
             if (msym.kind != MDL) {
                 log.error(tree.moduleName.pos(), Errors.ModuleNotFound(msym));
+                warnedMissing.add(msym);
             } else if (allRequires.contains(msym)) {
                 log.error(tree.moduleName.pos(), Errors.DuplicateRequires(msym));
             } else {
@@ -695,9 +696,6 @@
             PackageSymbol packge = syms.enterPackage(sym, name);
             attr.setPackageSymbols(tree.qualid, packge);
 
-            if (tree.hasTag(Tag.OPENS) && sym.flags.contains(ModuleFlags.OPEN)) {
-                log.error(tree.pos(), Errors.NoOpensUnlessStrong);
-            }
             List<ExportsDirective> exportsForPackage = allExports.computeIfAbsent(packge, p -> List.nil());
             for (ExportsDirective d : exportsForPackage) {
                 reportExportsConflict(tree, packge);
@@ -898,10 +896,7 @@
 
         @Override
         public void visitOpens(JCOpens tree) {
-            if (tree.directive.packge.members().isEmpty() &&
-                ((tree.directive.packge.flags() & Flags.HAS_RESOURCE) == 0)) {
-                log.error(tree.qualid.pos(), Errors.PackageEmptyOrNotFound(tree.directive.packge));
-            }
+            chk.checkPackageExistsForOpens(tree.qualid, tree.directive.packge);
             msym.directives = msym.directives.prepend(tree.directive);
         }
 
@@ -931,6 +926,9 @@
         public void visitProvides(JCProvides tree) {
             Type st = attr.attribType(tree.serviceName, env, syms.objectType);
             ClassSymbol service = (ClassSymbol) st.tsym;
+            if (allProvides.containsKey(service)) {
+                log.error(tree.serviceName.pos(), Errors.RepeatedProvidesForService(service));
+            }
             ListBuffer<ClassSymbol> impls = new ListBuffer<>();
             for (JCExpression implName : tree.implNames) {
                 Type it = attr.attribType(implName, env, syms.objectType);
@@ -959,8 +957,6 @@
                     }
                 }
                 if (it.hasTag(CLASS)) {
-                    // For now, we just check the pair (service-type, impl-type) is unique
-                    // TODO, check only one provides per service type as well
                     if (allProvides.computeIfAbsent(service, s -> new HashSet<>()).add(impl)) {
                         impls.append(impl);
                     } else {
@@ -1183,26 +1179,44 @@
         return allModules == null || allModules.contains(msym);
     }
 
-    private Set<ModuleSymbol> computeTransitiveClosure(Iterable<? extends ModuleSymbol> base, Set<ModuleSymbol> observable) {
-        List<ModuleSymbol> todo = List.nil();
+    private Set<ModuleSymbol> computeTransitiveClosure(Set<? extends ModuleSymbol> base, Set<ModuleSymbol> observable) {
+        List<ModuleSymbol> primaryTodo = List.nil();
+        List<ModuleSymbol> secondaryTodo = List.nil();
 
         for (ModuleSymbol ms : base) {
-            todo = todo.prepend(ms);
+            primaryTodo = primaryTodo.prepend(ms);
         }
 
         Set<ModuleSymbol> result = new LinkedHashSet<>();
         result.add(syms.java_base);
 
-        while (todo.nonEmpty()) {
-            ModuleSymbol current = todo.head;
-            todo = todo.tail;
+        while (primaryTodo.nonEmpty() || secondaryTodo.nonEmpty()) {
+            ModuleSymbol current;
+            boolean isPrimaryTodo;
+            if (primaryTodo.nonEmpty()) {
+                current = primaryTodo.head;
+                primaryTodo = primaryTodo.tail;
+                isPrimaryTodo = true;
+            } else {
+                current = secondaryTodo.head;
+                secondaryTodo = secondaryTodo.tail;
+                isPrimaryTodo = false;
+            }
             if (observable != null && !observable.contains(current))
                 continue;
             if (!result.add(current) || current == syms.unnamedModule || ((current.flags_field & Flags.AUTOMATIC_MODULE) != 0))
                 continue;
             current.complete();
+            if (current.kind == ERR && isPrimaryTodo && warnedMissing.add(current)) {
+                log.error(Errors.ModuleNotFound(current));
+            }
             for (RequiresDirective rd : current.requires) {
-                todo = todo.prepend(rd.module);
+                if (rd.module == syms.java_base) continue;
+                if ((rd.isTransitive() && isPrimaryTodo) || base.contains(current)) {
+                    primaryTodo = primaryTodo.prepend(rd.module);
+                } else {
+                    secondaryTodo = secondaryTodo.prepend(rd.module);
+                }
             }
         }
 
@@ -1582,5 +1596,6 @@
     public void newRound() {
         rootModules = null;
         allModules = null;
+        warnedMissing.clear();
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Fri Feb 10 08:57:42 2017 -0800
@@ -502,7 +502,7 @@
     private final class ArchiveContainer implements Container {
         private final Path archivePath;
         private final FileSystem fileSystem;
-        private final Map<RelativePath, Path> pathCache = new HashMap<>();
+        private final Map<RelativePath, Path> packages;
 
         public ArchiveContainer(Path archivePath) throws IOException, ProviderNotFoundException, SecurityException {
             this.archivePath = archivePath;
@@ -514,6 +514,21 @@
             } else {
                 this.fileSystem = FileSystems.newFileSystem(archivePath, null);
             }
+            packages = new HashMap<>();
+            for (Path root : fileSystem.getRootDirectories()) {
+                Files.walkFileTree(root, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE,
+                        new SimpleFileVisitor<Path>() {
+                            @Override
+                            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
+                                if (isValid(dir.getFileName())) {
+                                    packages.put(new RelativeDirectory(root.relativize(dir).toString()), dir);
+                                    return FileVisitResult.CONTINUE;
+                                } else {
+                                    return FileVisitResult.SKIP_SUBTREE;
+                                }
+                            }
+                        });
+            }
         }
 
         /**
@@ -526,7 +541,7 @@
                          Set<JavaFileObject.Kind> fileKinds,
                          boolean recurse,
                          ListBuffer<JavaFileObject> resultList) throws IOException {
-            Path resolvedSubdirectory = resolvePath(subdirectory);
+            Path resolvedSubdirectory = packages.get(subdirectory);
 
             if (resolvedSubdirectory == null)
                 return ;
@@ -544,18 +559,6 @@
                             }
                         }
 
-                        boolean isValid(Path fileName) {
-                            if (fileName == null) {
-                                return true;
-                            } else {
-                                String name = fileName.toString();
-                                if (name.endsWith("/")) {
-                                    name = name.substring(0, name.length() - 1);
-                                }
-                                return SourceVersion.isIdentifier(name);
-                            }
-                        }
-
                         @Override
                         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                             if (attrs.isRegularFile() && fileKinds.contains(getKind(file.getFileName().toString()))) {
@@ -569,27 +572,29 @@
 
         }
 
-        @Override
-        public JavaFileObject getFileObject(Path userPath, RelativeFile name) throws IOException {
-            Path p = resolvePath(name);
-            if (p != null)
-                return PathFileObject.forJarPath(JavacFileManager.this, p, userPath);
-
-            return null;
+        private boolean isValid(Path fileName) {
+            if (fileName == null) {
+                return true;
+            } else {
+                String name = fileName.toString();
+                if (name.endsWith("/")) {
+                    name = name.substring(0, name.length() - 1);
+                }
+                return SourceVersion.isIdentifier(name);
+            }
         }
 
-        private synchronized Path resolvePath(RelativePath path) {
-            if (!pathCache.containsKey(path)) {
-                Path relativePath = path.resolveAgainst(fileSystem);
-
-                if (!Files.exists(relativePath)) {
-                    relativePath = null;
+        @Override
+        public JavaFileObject getFileObject(Path userPath, RelativeFile name) throws IOException {
+            RelativeDirectory root = name.dirname();
+            Path packagepath = packages.get(root);
+            if (packagepath != null) {
+                Path relpath = packagepath.resolve(name.basename());
+                if (Files.exists(relpath)) {
+                    return PathFileObject.forJarPath(JavacFileManager.this, relpath, userPath);
                 }
-
-                pathCache.put(path, relativePath);
-                return relativePath;
             }
-            return pathCache.get(path);
+            return null;
         }
 
         @Override
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Fri Feb 10 08:57:42 2017 -0800
@@ -43,6 +43,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.ProviderNotFoundException;
+import java.nio.file.spi.FileSystemProvider;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -1119,8 +1120,12 @@
                 }
 
                 if (p.getFileName().toString().endsWith(".jar") && fsInfo.exists(p)) {
-                    URI uri = URI.create("jar:" + p.toUri());
-                    try (FileSystem fs = FileSystems.newFileSystem(uri, fsEnv, null)) {
+                    FileSystemProvider jarFSProvider = fsInfo.getJarFSProvider();
+                    if (jarFSProvider == null) {
+                        log.error(Errors.NoZipfsForArchive(p));
+                        return null;
+                    }
+                    try (FileSystem fs = jarFSProvider.newFileSystem(p, fsEnv)) {
                         Path moduleInfoClass = fs.getPath("module-info.class");
                         if (Files.exists(moduleInfoClass)) {
                             String moduleName = readModuleName(moduleInfoClass);
@@ -1132,9 +1137,6 @@
                     } catch (IOException e) {
                         log.error(Errors.LocnCantReadFile(p));
                         return null;
-                    } catch (ProviderNotFoundException e) {
-                        log.error(Errors.NoZipfsForArchive(p));
-                        return null;
                     }
 
                     //automatic module:
@@ -1177,8 +1179,12 @@
                         // workaround for now
                         FileSystem fs = fileSystems.get(p);
                         if (fs == null) {
-                            URI uri = URI.create("jar:" + p.toUri());
-                            fs = FileSystems.newFileSystem(uri, Collections.emptyMap(), null);
+                            FileSystemProvider jarFSProvider = fsInfo.getJarFSProvider();
+                            if (jarFSProvider == null) {
+                                log.error(Errors.LocnCantReadFile(p));
+                                return null;
+                            }
+                            fs = jarFSProvider.newFileSystem(p, Collections.emptyMap());
                             try {
                                 Path moduleInfoClass = fs.getPath("classes/module-info.class");
                                 String moduleName = readModuleName(moduleInfoClass);
@@ -1194,7 +1200,7 @@
                         }
                     } catch (ModuleNameReader.BadClassFile e) {
                         log.error(Errors.LocnBadModuleInfo(p));
-                    } catch (IOException | ProviderNotFoundException e) {
+                    } catch (IOException e) {
                         log.error(Errors.LocnCantReadFile(p));
                         return null;
                     }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Fri Feb 10 08:57:42 2017 -0800
@@ -45,6 +45,7 @@
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
 import javax.tools.StandardLocation;
 
 import com.sun.source.util.TaskEvent;
@@ -623,7 +624,8 @@
                 keepComments = true;
                 genEndPos = true;
             }
-            Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, lineDebugInfo);
+            Parser parser = parserFactory.newParser(content, keepComments(), genEndPos,
+                                lineDebugInfo, filename.isNameCompatible("module-info", Kind.SOURCE));
             tree = parser.parseCompilationUnit();
             if (verbose) {
                 log.printVerbose("parsing.done", Long.toString(elapsed(msec)));
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Fri Feb 10 08:57:42 2017 -0800
@@ -288,7 +288,9 @@
                                    List<JCAnnotation> trees) {
         for (Attribute.Compound anno : annos) {
             for (JCAnnotation tree : trees) {
-                JCTree match = matchAnnoToTree(findme, anno, tree);
+                if (tree.type.tsym != anno.type.tsym)
+                    continue;
+                JCTree match = matchAttributeToTree(findme, anno, tree);
                 if (match != null)
                     return match;
             }
@@ -297,15 +299,15 @@
     }
 
     /**
-     * Returns the tree for an annotation given an Attribute to
-     * search (recursively) and its corresponding tree.
+     * Returns the tree for an attribute given an enclosing attribute to
+     * search (recursively) and the enclosing attribute's corresponding tree.
      * Returns null if the tree cannot be found.
      */
-    private JCTree matchAnnoToTree(final Attribute.Compound findme,
-                                   final Attribute attr,
-                                   final JCTree tree) {
+    private JCTree matchAttributeToTree(final Attribute findme,
+                                        final Attribute attr,
+                                        final JCTree tree) {
         if (attr == findme)
-            return (tree.type.tsym == findme.type.tsym) ? tree : null;
+            return tree;
 
         class Vis implements Attribute.Visitor {
             JCTree result = null;
@@ -317,7 +319,7 @@
                 for (Pair<MethodSymbol, Attribute> pair : anno.values) {
                     JCExpression expr = scanForAssign(pair.fst, tree);
                     if (expr != null) {
-                        JCTree match = matchAnnoToTree(findme, pair.snd, expr);
+                        JCTree match = matchAttributeToTree(findme, pair.snd, expr);
                         if (match != null) {
                             result = match;
                             return;
@@ -326,16 +328,19 @@
                 }
             }
             public void visitArray(Attribute.Array array) {
-                if (tree.hasTag(NEWARRAY) &&
-                        types.elemtype(array.type).tsym == findme.type.tsym) {
-                    List<JCExpression> elems = ((JCNewArray) tree).elems;
+                if (tree.hasTag(NEWARRAY)) {
+                    List<JCExpression> elems = ((JCNewArray)tree).elems;
                     for (Attribute value : array.values) {
-                        if (value == findme) {
-                            result = elems.head;
+                        JCTree match = matchAttributeToTree(findme, value, elems.head);
+                        if (match != null) {
+                            result = match;
                             return;
                         }
                         elems = elems.tail;
                     }
+                } else if (array.values.length == 1) {
+                    // the tree may not be a NEWARRAY for single-element array initializers
+                    result = matchAttributeToTree(findme, array.values[0], tree);
                 }
             }
             public void visitEnum(Attribute.Enum e) {
@@ -710,10 +715,15 @@
         if (annoTree == null)
             return elemTreeTop;
 
-        // 6388543: if v != null, we should search within annoTree to find
-        // the tree matching v. For now, we ignore v and return the tree of
-        // the annotation.
-        return new Pair<>(annoTree, elemTreeTop.snd);
+        if (v == null)
+            return new Pair<>(annoTree, elemTreeTop.snd);
+
+        JCTree valueTree = matchAttributeToTree(
+                cast(Attribute.class, v), cast(Attribute.class, a), annoTree);
+        if (valueTree == null)
+            return new Pair<>(annoTree, elemTreeTop.snd);
+
+        return new Pair<>(valueTree, elemTreeTop.snd);
     }
 
     /**
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Feb 10 08:57:42 2017 -0800
@@ -70,6 +70,10 @@
      */
     private static final int infixPrecedenceLevels = 10;
 
+    /** Is the parser instantiated to parse a module-info file ?
+     */
+    private final boolean parseModuleInfo;
+
     /** The scanner used for lexical analysis.
      */
     protected Lexer S;
@@ -138,10 +142,21 @@
     /** Construct a parser from a given scanner, tree factory and log.
      */
     protected JavacParser(ParserFactory fac,
+                          Lexer S,
+                          boolean keepDocComments,
+                          boolean keepLineMap,
+                          boolean keepEndPositions) {
+        this(fac, S, keepDocComments, keepLineMap, keepEndPositions, false);
+
+    }
+    /** Construct a parser from a given scanner, tree factory and log.
+     */
+    protected JavacParser(ParserFactory fac,
                      Lexer S,
                      boolean keepDocComments,
                      boolean keepLineMap,
-                     boolean keepEndPositions) {
+                     boolean keepEndPositions,
+                     boolean parseModuleInfo) {
         this.S = S;
         nextToken(); // prime the pump
         this.F = fac.F;
@@ -165,6 +180,7 @@
         this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier();
         this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods();
         this.keepDocComments = keepDocComments;
+        this.parseModuleInfo = parseModuleInfo;
         docComments = newDocCommentTable(keepDocComments, fac);
         this.keepLineMap = keepLineMap;
         this.errorTree = F.Erroneous();
@@ -3347,8 +3363,13 @@
             } else {
                 errs = List.of(mods);
             }
-            return toP(F.Exec(syntaxError(pos, errs, "expected3",
-                                          CLASS, INTERFACE, ENUM)));
+            final JCErroneous erroneousTree;
+            if (parseModuleInfo) {
+                erroneousTree = syntaxError(pos, errs, "expected.module.or.open");
+            } else {
+                erroneousTree = syntaxError(pos, errs, "expected3", CLASS, INTERFACE, ENUM);
+            }
+            return toP(F.Exec(erroneousTree));
         }
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Fri Feb 10 08:57:42 2017 -0800
@@ -81,7 +81,11 @@
     }
 
     public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
+        return newParser(input, keepDocComments, keepEndPos, keepLineMap, false);
+    }
+
+    public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap, boolean parseModuleInfo) {
         Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
-        return new JavacParser(this, lexer, keepDocComments, keepLineMap, keepEndPos);
+        return new JavacParser(this, lexer, keepDocComments, keepLineMap, keepEndPos, parseModuleInfo);
     }
 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1671,14 +1671,14 @@
             if (s.equals("*")) {
                 return MatchingUtils.validImportStringToPattern(s);
             }
-            module = ".*/";
+            module = allowModules ? ".*/" : "";
             pkg = s;
         } else {
             module = Pattern.quote(s.substring(0, slash + 1));
             pkg = s.substring(slash + 1);
         }
         if (MatchingUtils.isValidImportString(pkg)) {
-            return Pattern.compile((allowModules ? module : "") + MatchingUtils.validImportStringToPatternString(pkg));
+            return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg));
         } else {
             log.warning("proc.malformed.supported.string", s, p.getClass().getName());
             return noMatches; // won't match any valid identifier
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Feb 10 08:57:42 2017 -0800
@@ -1895,6 +1895,9 @@
 compiler.err.expected.module=\
     ''module'' expected
 
+compiler.err.expected.module.or.open=\
+    ''module'' or ''open'' expected
+
 compiler.err.dot.class.expected=\
     ''.class'' expected
 
@@ -2882,6 +2885,10 @@
 compiler.err.no.opens.unless.strong=\
     ''opens'' only allowed in strong modules
 
+# 0: symbol
+compiler.err.repeated.provides.for.service=\
+    multiple ''provides'' for service {0}
+
 # 0: symbol, 1: symbol
 compiler.err.duplicate.provides=\
     duplicate provides: service {0}, implementation {1}
@@ -2921,6 +2928,10 @@
 compiler.err.package.empty.or.not.found=\
     package is empty or does not exist: {0}
 
+# 0: symbol
+compiler.warn.package.empty.or.not.found=\
+    package is empty or does not exist: {0}
+
 compiler.err.no.output.dir=\
     no class output directory specified
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Fri Feb 10 08:57:42 2017 -0800
@@ -204,6 +204,9 @@
 javac.opt.Xlint.desc.module=\
     Warn about module system related issues.
 
+javac.opt.Xlint.desc.opens=\
+    Warn about issues regarding module opens.
+
 javac.opt.Xlint.desc.options=\
     Warn about issues relating to use of command line options.
 
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -1723,9 +1723,29 @@
                     break main;
                 ch = text.charAt(currPos);
             }
-            if (ch == '>' && blockTags.contains(StringUtils.toLowerCase(text.substring(tagPos, currPos)))) {
+            String tagFound = StringUtils.toLowerCase(text.substring(tagPos, currPos));
+            if (blockTags.contains(tagFound)) {
                 result.append(text, startPos, lessThanPos);
+                currPos = tagPos + tagFound.length();
+                boolean foundGT = false;
+                Character quoteKind = null;
+                while (!foundGT) {
+                    if (ch == '\"' || ch == '\'') {
+                        if (quoteKind == null) {
+                            quoteKind = ch;
+                        } else if (quoteKind == ch) {
+                            quoteKind = null;
+                        }
+                    }
+                    if (ch == '>' && quoteKind == null) {
+                        foundGT = true;
+                    }
+                    if (++currPos == len)
+                        break;
+                    ch = text.charAt(currPos);
+                }
                 startPos = currPos + 1;
+                currPos = startPos;
             }
             lessThanPos = text.indexOf('<', currPos);
         }
@@ -1740,6 +1760,10 @@
                 ('1' <= ch && ch <= '6');
     }
 
+    private static boolean isWhitespace(char ch) {
+        return Character.isWhitespace(ch);
+    }
+
     /**
      * Add a link to the stylesheet file.
      *
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FrameOutputWriter.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -29,10 +29,12 @@
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
 import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
 import jdk.javadoc.internal.doclets.toolkit.Content;
 import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
 import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
 import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
+import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
 
 
 /**
@@ -92,6 +94,15 @@
         Content frame = getFrameDetails();
         HtmlTree body = new HtmlTree(HtmlTag.BODY);
         body.addAttr(HtmlAttr.ONLOAD, "loadFrames()");
+        String topFilePath = configuration.topFile.getPath();
+        String javaScriptRefresh = "\nif (targetPage == \"\" || targetPage == \"undefined\")\n" +
+                "     window.location.replace('" + topFilePath + "');\n";
+        RawHtml scriptContent = new RawHtml(javaScriptRefresh.replace("\n", DocletConstants.NL));
+        HtmlTree scriptTree = HtmlTree.SCRIPT();
+        scriptTree.addContent(scriptContent);
+        body.addContent(scriptTree);
+        Content noScript = HtmlTree.NOSCRIPT(contents.noScriptMessage);
+        body.addContent(noScript);
         if (configuration.allowTag(HtmlTag.MAIN)) {
             HtmlTree main = HtmlTree.MAIN(frame);
             body.addContent(main);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, 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
@@ -74,6 +74,11 @@
         return memberTree;
     }
 
+    @Override
+    public boolean showTabs() {
+        return false;
+    }
+
     /**
      * {@inheritDoc}
      */
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, 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
@@ -1773,14 +1773,14 @@
     /**
      * Returns a Comparator for index file presentations, and are sorted as follows.
      *  If comparing modules then simply compare the simple names,
-     *  comparing packages then simply compare the qualified names, otherwise
-     *  1. if equal, then compare the ElementKind ex: Module, Package, Interface etc.
-     *  2. sort on simple names of entities
-     *  3a. if equal and if the type is of ExecutableElement(Constructor, Methods),
+     *  comparing packages then simply compare the qualified names, if comparing a package with a
+     *  module/type/member then compare the FullyQualifiedName of the package
+     *  with the SimpleName of the entity, otherwise
+     *  1. compare the ElementKind ex: Module, Package, Interface etc.
+     *  2a. if equal and if the type is of ExecutableElement(Constructor, Methods),
      *      a case insensitive comparison of parameter the type signatures
-     *  3b. if equal, case sensitive comparison of the type signatures
-     *  4. finally, if equal, compare the FQNs of the entities
-     * Iff comparing packages then simply sort on qualified names.
+     *  2b. if equal, case sensitive comparison of the type signatures
+     *  3. finally, if equal, compare the FQNs of the entities
      * @return a comparator for index file use
      */
     public Comparator<Element> makeIndexUseComparator() {
@@ -1788,8 +1788,10 @@
             /**
              * Compare two given elements, if comparing two modules, return the
              * comparison of SimpleName, if comparing two packages, return the
-             * comparison of FullyQualifiedName, first sort on kinds, then on the
-             * names, then on the parameters only if the type is an ExecutableElement,
+             * comparison of FullyQualifiedName, if comparing a package with a
+             * module/type/member then compare the FullyQualifiedName of the package
+             * with the SimpleName of the entity, then sort on the kinds, then on
+             * the parameters only if the type is an ExecutableElement,
              * the parameters are compared and finally the qualified names.
              *
              * @param e1 - an element.
@@ -1806,11 +1808,17 @@
                 if (isPackage(e1) && isPackage(e2)) {
                     return compareFullyQualifiedNames(e1, e2);
                 }
-                result = compareElementTypeKinds(e1, e2);
+                if (isPackage(e1) || isPackage(e2)) {
+                    result = (isPackage(e1))
+                            ? compareStrings(getFullyQualifiedName(e1), getSimpleName(e2))
+                            : compareStrings(getSimpleName(e1), getFullyQualifiedName(e2));
+                } else {
+                    result = compareNames(e1, e2);
+                }
                 if (result != 0) {
                     return result;
                 }
-                result = compareNames(e1, e2);
+                result = compareElementTypeKinds(e1, e2);
                 if (result != 0) {
                     return result;
                 }
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties	Fri Feb 10 08:57:42 2017 -0800
@@ -33,16 +33,20 @@
 where options include:
 
 main.opt.public.desc=\
-    Show only public classes and members
+    Show only public types and members. For named modules,\n\
+    show exported packages and the module''s API.
 
 main.opt.protected.desc=\
-    Show protected/public classes and members (default)
+    Show protected/public types and members (default). For\n\
+    named modules, show exported packages and the module''s API.
 
 main.opt.package.desc=\
-    Show package/protected/public classes and members
+    Show package/protected/public types and members. For \n\
+    named modules, show all packages and all module details.
 
 main.opt.private.desc=\
-    Show all classes and members
+    Show all types and members. For named modules,\n\
+    show all packages and all module details.
 
 main.opt.show.members.arg=\
     <value>
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Fri Feb 10 08:57:42 2017 -0800
@@ -390,27 +390,23 @@
     @Override
     public boolean terminalEditorRunning() {
         Terminal terminal = in.getTerminal();
-        if (terminal instanceof JShellUnixTerminal)
-            return ((JShellUnixTerminal) terminal).isRaw();
+        if (terminal instanceof SuspendableTerminal)
+            return ((SuspendableTerminal) terminal).isRaw();
         return false;
     }
 
     @Override
     public void suspend() {
-        try {
-            in.getTerminal().restore();
-        } catch (Exception ex) {
-            throw new IllegalStateException(ex);
-        }
+        Terminal terminal = in.getTerminal();
+        if (terminal instanceof SuspendableTerminal)
+            ((SuspendableTerminal) terminal).suspend();
     }
 
     @Override
     public void resume() {
-        try {
-            in.getTerminal().init();
-        } catch (Exception ex) {
-            throw new IllegalStateException(ex);
-        }
+        Terminal terminal = in.getTerminal();
+        if (terminal instanceof SuspendableTerminal)
+            ((SuspendableTerminal) terminal).resume();
     }
 
     @Override
@@ -666,7 +662,7 @@
         }
     };
 
-    private static final class JShellUnixTerminal extends NoInterruptUnixTerminal {
+    private static final class JShellUnixTerminal extends NoInterruptUnixTerminal implements SuspendableTerminal {
 
         private final StopDetectingInputStream input;
 
@@ -695,9 +691,28 @@
         public void enableInterruptCharacter() {
         }
 
+        @Override
+        public void suspend() {
+            try {
+                getSettings().restore();
+                super.disableInterruptCharacter();
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+
+        @Override
+        public void resume() {
+            try {
+                init();
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+
     }
 
-    private static final class JShellWindowsTerminal extends WindowsTerminal {
+    private static final class JShellWindowsTerminal extends WindowsTerminal implements SuspendableTerminal {
 
         private final StopDetectingInputStream input;
 
@@ -716,6 +731,31 @@
             return input.setInputStream(super.wrapInIfNeeded(in));
         }
 
+        @Override
+        public void suspend() {
+            try {
+                restore();
+                setConsoleMode(getConsoleMode() & ~ConsoleMode.ENABLE_PROCESSED_INPUT.code);
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+
+        @Override
+        public void resume() {
+            try {
+                restore();
+                init();
+            } catch (Exception ex) {
+                throw new IllegalStateException(ex);
+            }
+        }
+
+        @Override
+        public boolean isRaw() {
+            return (getConsoleMode() & ConsoleMode.ENABLE_LINE_INPUT.code) == 0;
+        }
+
     }
 
     private static final class TestTerminal extends TerminalSupport {
@@ -736,6 +776,12 @@
 
     }
 
+    private interface SuspendableTerminal {
+        public void suspend();
+        public void resume();
+        public boolean isRaw();
+    }
+
     private static final class CheckCompletionKeyMap extends KeyMap {
 
         private final KeyMap del;
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java	Fri Feb 10 08:57:42 2017 -0800
@@ -197,7 +197,6 @@
 
     private boolean debug = false;
     public boolean testPrompt = false;
-    private String defaultStartup = null;
     private Startup startup = null;
     private String executionControlSpec = null;
     private EditorSetting editor = BUILT_IN_EDITOR;
@@ -205,9 +204,9 @@
     private static final String[] EDITOR_ENV_VARS = new String[] {
         "JSHELLEDITOR", "VISUAL", "EDITOR"};
 
-    // Commands and snippets which should be replayed
-    private List<String> replayableHistory;
-    private List<String> replayableHistoryPrevious;
+    // Commands and snippets which can be replayed
+    private ReplayableHistory replayableHistory;
+    private ReplayableHistory replayableHistoryPrevious;
 
     static final String STARTUP_KEY  = "STARTUP";
     static final String EDITOR_KEY   = "EDITOR";
@@ -507,6 +506,76 @@
     }
 
     /**
+     * Encapsulate a history of snippets and commands which can be replayed.
+     */
+    private static class ReplayableHistory {
+
+        // the history
+        private List<String> hist;
+
+        // the length of the history as of last save
+        private int lastSaved;
+
+        private ReplayableHistory(List<String> hist) {
+            this.hist = hist;
+            this.lastSaved = 0;
+        }
+
+        // factory for empty histories
+        static ReplayableHistory emptyHistory() {
+            return new ReplayableHistory(new ArrayList<>());
+        }
+
+        // factory for history stored in persistent storage
+        static ReplayableHistory fromPrevious(PersistentStorage prefs) {
+            // Read replay history from last jshell session
+            String prevReplay = prefs.get(REPLAY_RESTORE_KEY);
+            if (prevReplay == null) {
+                return null;
+            } else {
+                return new ReplayableHistory(Arrays.asList(prevReplay.split(RECORD_SEPARATOR)));
+            }
+
+        }
+
+        // store the history in persistent storage
+        void storeHistory(PersistentStorage prefs) {
+            if (hist.size() > lastSaved) {
+                // Prevent history overflow by calculating what will fit, starting
+                // with most recent
+                int sepLen = RECORD_SEPARATOR.length();
+                int length = 0;
+                int first = hist.size();
+                while (length < Preferences.MAX_VALUE_LENGTH && --first >= 0) {
+                    length += hist.get(first).length() + sepLen;
+                }
+                if (first >= 0) {
+                    hist = hist.subList(first + 1, hist.size());
+                }
+                String shist = String.join(RECORD_SEPARATOR, hist);
+                prefs.put(REPLAY_RESTORE_KEY, shist);
+                markSaved();
+            }
+            prefs.flush();
+        }
+
+        // add a snippet or command to the history
+        void add(String s) {
+            hist.add(s);
+        }
+
+        // return history to reloaded
+        Iterable<String> iterable() {
+            return hist;
+        }
+
+        // mark that persistent storage and current history are in sync
+        void markSaved() {
+            lastSaved = hist.size();
+        }
+    }
+
+    /**
      * Is the input/output currently interactive
      *
      * @return true if console
@@ -756,10 +825,7 @@
         // initialize JShell instance
         resetState();
         // Read replay history from last jshell session into previous history
-        String prevReplay = prefs.get(REPLAY_RESTORE_KEY);
-        if (prevReplay != null) {
-            replayableHistoryPrevious = Arrays.asList(prevReplay.split(RECORD_SEPARATOR));
-        }
+        replayableHistoryPrevious = ReplayableHistory.fromPrevious(prefs);
         // load snippet/command files given on command-line
         for (String loadFile : commandLineArgs.nonOptions()) {
             runFile(loadFile, "jshell");
@@ -775,6 +841,13 @@
             if (feedback.shouldDisplayCommandFluff()) {
                 hardmsg("jshell.msg.welcome", version());
             }
+            // Be sure history is always saved so that user code isn't lost
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+                @Override
+                public void run() {
+                    replayableHistory.storeHistory(prefs);
+                }
+            });
             // execute from user input
             try (IOContext in = new ConsoleIOContext(this, cmdin, console)) {
                 start(in);
@@ -868,7 +941,7 @@
 
         // Reset the replayable history, saving the old for restore
         replayableHistoryPrevious = replayableHistory;
-        replayableHistory = new ArrayList<>();
+        replayableHistory = ReplayableHistory.emptyHistory();
         JShell.Builder builder =
                JShell.builder()
                 .in(userin)
@@ -1933,20 +2006,7 @@
     private boolean cmdExit() {
         regenerateOnDeath = false;
         live = false;
-        if (!replayableHistory.isEmpty()) {
-            // Prevent history overflow by calculating what will fit, starting
-            // with most recent
-            int sepLen = RECORD_SEPARATOR.length();
-            int length = 0;
-            int first = replayableHistory.size();
-            while(length < Preferences.MAX_VALUE_LENGTH && --first >= 0) {
-                length += replayableHistory.get(first).length() + sepLen;
-            }
-            String hist =  String.join(RECORD_SEPARATOR,
-                    replayableHistory.subList(first + 1, replayableHistory.size()));
-            prefs.put(REPLAY_RESTORE_KEY, hist);
-        }
-        prefs.flush();
+        replayableHistory.storeHistory(prefs);
         fluffmsg("jshell.msg.goodbye");
         return true;
     }
@@ -2420,7 +2480,7 @@
         if (!parseCommandLineLikeFlags(rawargs, ap)) {
             return false;
         }
-        Iterable<String> history;
+        ReplayableHistory history;
         if (ap.restore()) {
             if (replayableHistoryPrevious == null) {
                 errormsg("jshell.err.reload.no.previous");
@@ -2432,7 +2492,13 @@
             history = replayableHistory;
             fluffmsg("jshell.err.reload.restarting.state");
         }
-        return doReload(history, !ap.quiet());
+        boolean success = doReload(history, !ap.quiet());
+        if (success && ap.restore()) {
+            // if we are restoring from previous, then if nothing was added
+            // before time of exit, there is nothing to save
+            replayableHistory.markSaved();
+        }
+        return success;
     }
 
     private boolean cmdEnv(String rawargs) {
@@ -2460,9 +2526,9 @@
         return doReload(replayableHistory, false);
     }
 
-    private boolean doReload(Iterable<String> history, boolean echo) {
+    private boolean doReload(ReplayableHistory history, boolean echo) {
         resetState();
-        run(new ReloadIOContext(history,
+        run(new ReloadIOContext(history.iterable(),
                 echo ? cmdout : null));
         return true;
     }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Fri Feb 10 08:57:42 2017 -0800
@@ -85,7 +85,7 @@
         try {
             Parser parser = new Parser(
                     () -> new Matched(scannerFactory.newScanner(s, false)),
-                    () -> proc.taskFactory.new ParseTask(s));
+                    () -> proc.taskFactory.parse(s));
             Completeness stat = parser.parseUnit();
             int endPos = stat == Completeness.UNKNOWN
                     ? s.length()
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java	Fri Feb 10 08:57:42 2017 -0800
@@ -155,7 +155,7 @@
         if (compileSource.length() == 0) {
             return Collections.emptyList();
         }
-        ParseTask pt = state.taskFactory.new ParseTask(compileSource);
+        ParseTask pt = state.taskFactory.parse(compileSource);
         List<? extends Tree> units = pt.units();
         if (units.isEmpty()) {
             return compileFailResult(pt, userSource, Kind.ERRONEOUS);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParser.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -39,7 +39,6 @@
 import static com.sun.tools.javac.parser.Tokens.TokenKind.INTERFACE;
 import static com.sun.tools.javac.parser.Tokens.TokenKind.LPAREN;
 import static com.sun.tools.javac.parser.Tokens.TokenKind.MONKEYS_AT;
-import static com.sun.tools.javac.parser.Tokens.TokenKind.PACKAGE;
 import static com.sun.tools.javac.parser.Tokens.TokenKind.SEMI;
 import static com.sun.tools.javac.parser.Tokens.TokenKind.VOID;
 import com.sun.tools.javac.tree.JCTree;
@@ -48,10 +47,8 @@
 import com.sun.tools.javac.tree.JCTree.JCExpression;
 import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
 import com.sun.tools.javac.tree.JCTree.JCModifiers;
-import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
 import com.sun.tools.javac.tree.JCTree.JCStatement;
 import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.tree.JCTree.Tag;
 import static com.sun.tools.javac.tree.JCTree.Tag.IDENT;
 import com.sun.tools.javac.util.List;
@@ -68,12 +65,17 @@
  */
 class ReplParser extends JavacParser {
 
+    // force starting in expression mode
+    private final boolean forceExpression;
+
     public ReplParser(ParserFactory fac,
             com.sun.tools.javac.parser.Lexer S,
             boolean keepDocComments,
             boolean keepLineMap,
-            boolean keepEndPositions) {
+            boolean keepEndPositions,
+            boolean forceExpression) {
         super(fac, S, keepDocComments, keepLineMap, keepEndPositions);
+        this.forceExpression = forceExpression;
     }
 
     /**
@@ -205,7 +207,10 @@
                         nextToken();
                     } else {
                         // return type of method, declared type of variable, or an expression
-                        t = term(EXPR | TYPE);
+                        // unless expression is being forced
+                        t = term(forceExpression
+                                ? EXPR
+                                : EXPR | TYPE);
                     }
                     if (token.kind == COLON && t.hasTag(IDENT)) {
                         // labelled statement
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ReplParserFactory.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -36,24 +36,30 @@
  */
 class ReplParserFactory extends ParserFactory {
 
-    public static ParserFactory instance(Context context) {
-        ParserFactory instance = context.get(parserFactoryKey);
-        if (instance == null) {
-            instance = new ReplParserFactory(context);
-        }
-        return instance;
+    // force starting in expression mode
+    private final boolean forceExpression;
+
+    public static void preRegister(Context context, boolean forceExpression) {
+        context.put(parserFactoryKey, (Context.Factory<ParserFactory>)
+                (c -> new ReplParserFactory(c, forceExpression)));
     }
 
     private final ScannerFactory scannerFactory;
 
-    protected ReplParserFactory(Context context) {
+    protected ReplParserFactory(Context context, boolean forceExpression) {
         super(context);
+        this.forceExpression = forceExpression;
         this.scannerFactory = ScannerFactory.instance(context);
     }
 
     @Override
     public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
         com.sun.tools.javac.parser.Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
-        return new ReplParser(this, lexer, keepDocComments, keepLineMap, keepEndPos);
+        return new ReplParser(this, lexer, keepDocComments, keepLineMap, keepEndPos, forceExpression);
+    }
+
+    @Override
+    public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap, boolean parseModuleInfo) {
+        return newParser(input, keepDocComments, keepEndPos, keepLineMap);
     }
 }
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -227,7 +227,7 @@
     }
 
     private Tree.Kind guessKind(String code) {
-        ParseTask pt = proc.taskFactory.new ParseTask(code);
+        ParseTask pt = proc.taskFactory.parse(code);
         List<? extends Tree> units = pt.units();
         if (units.isEmpty()) {
             return Tree.Kind.BLOCK;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -61,6 +61,7 @@
 import javax.tools.FileObject;
 import jdk.jshell.MemoryFileManager.SourceMemoryJavaFileObject;
 import java.lang.Runtime.Version;
+import com.sun.source.tree.Tree.Kind;
 
 /**
  * The primary interface to the compiler API.  Parsing, analysis, and
@@ -100,6 +101,23 @@
         return fileManager;
     }
 
+    // Parse a snippet and return our parse task handler
+    ParseTask parse(final String source) {
+        ParseTask pt = state.taskFactory.new ParseTask(source, false);
+        if (!pt.units().isEmpty()
+                && pt.units().get(0).getKind() == Kind.EXPRESSION_STATEMENT
+                && pt.getDiagnostics().hasOtherThanNotStatementErrors()) {
+            // It failed, it may be an expression being incorrectly
+            // parsed as having a leading type variable, example:   a < b
+            // Try forcing interpretation as an expression
+            ParseTask ept = state.taskFactory.new ParseTask(source, true);
+            if (!ept.getDiagnostics().hasOtherThanNotStatementErrors()) {
+                return ept;
+            }
+        }
+        return pt;
+    }
+
     private interface SourceHandler<T> {
 
         JavaFileObject sourceToFileObject(MemoryFileManager fm, T t);
@@ -179,11 +197,11 @@
         private final Iterable<? extends CompilationUnitTree> cuts;
         private final List<? extends Tree> units;
 
-        ParseTask(final String source) {
+        ParseTask(final String source, final boolean forceExpression) {
             super(Stream.of(source),
                     new StringSourceHandler(),
                     "-XDallowStringFolding=false", "-proc:none");
-            ReplParserFactory.instance(getContext());
+            ReplParserFactory.preRegister(getContext(), forceExpression);
             cuts = parse();
             units = Util.stream(cuts)
                     .flatMap(cut -> {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -28,6 +28,7 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.stream.IntStream;
 import jdk.jshell.spi.ExecutionControl;
 import jdk.jshell.spi.SPIResolutionException;
 
@@ -41,6 +42,23 @@
  */
 public class DirectExecutionControl implements ExecutionControl {
 
+    private static final String[] charRep;
+
+    static {
+        charRep = new String[256];
+        for (int i = 0; i < charRep.length; ++i) {
+            charRep[i] = Character.isISOControl(i)
+                    ? String.format("\\%03o", i)
+                    : "" + (char) i;
+        }
+        charRep['\b'] = "\\b";
+        charRep['\t'] = "\\t";
+        charRep['\n'] = "\\n";
+        charRep['\f'] = "\\f";
+        charRep['\r'] = "\\r";
+        charRep['\\'] = "\\\\";
+    }
+
     private final LoaderDelegate loaderDelegate;
 
     /**
@@ -192,9 +210,26 @@
         if (value == null) {
             return "null";
         } else if (value instanceof String) {
-            return "\"" + (String) value + "\"";
+            return "\"" + ((String) value).codePoints()
+                    .flatMap(cp ->
+                        (cp == '"')
+                            ? "\\\"".codePoints()
+                            : (cp < 256)
+                                ? charRep[cp].codePoints()
+                                : IntStream.of(cp))
+                    .collect(
+                            StringBuilder::new,
+                            StringBuilder::appendCodePoint,
+                            StringBuilder::append)
+                    .toString() + "\"";
         } else if (value instanceof Character) {
-            return "'" + value + "'";
+            char cp = (char) (Character) value;
+            return "'" + (
+                (cp == '\'')
+                    ? "\\\'"
+                    : (cp < 256)
+                            ? charRep[cp]
+                            : String.valueOf(cp)) + "'";
         } else if (value.getClass().isArray()) {
             int dims = 0;
             Class<?> t = value.getClass();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/FailOverExecutionControlProvider.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/FailOverExecutionControlProvider.java	Fri Feb 10 08:57:42 2017 -0800
@@ -111,7 +111,8 @@
                     PrintWriter log = new PrintWriter(writer);
                     log.println("FailOverExecutionControlProvider:");
                     ex.printStackTrace(log);
-                    logger().fine(log.toString());
+                    log.flush();
+                    logger().fine(writer.toString());
                     // only care about the first, and only if they all fail
                     if (thrown == null) {
                         thrown = ex;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java	Fri Feb 10 08:57:42 2017 -0800
@@ -102,7 +102,6 @@
             Process process = jdii.process();
 
             List<Consumer<String>> deathListeners = new ArrayList<>();
-            deathListeners.add(s -> env.closeDown());
             Util.detectJdiExitEvent(vm, s -> {
                 for (Consumer<String> h : deathListeners) {
                     h.accept(s);
@@ -120,7 +119,8 @@
             Map<String, InputStream> input = new HashMap<>();
             input.put("in", env.userIn());
             return remoteInputOutput(socket.getInputStream(), out, outputs, input,
-                    (objIn, objOut) -> new JdiDefaultExecutionControl(objOut, objIn, vm, process, remoteAgent, deathListeners));
+                    (objIn, objOut) -> new JdiDefaultExecutionControl(env,
+                                        objOut, objIn, vm, process, remoteAgent, deathListeners));
         }
     }
 
@@ -130,15 +130,20 @@
      * @param cmdout the output for commands
      * @param cmdin the input for responses
      */
-    private JdiDefaultExecutionControl(ObjectOutput cmdout, ObjectInput cmdin,
+    private JdiDefaultExecutionControl(ExecutionEnv env,
+            ObjectOutput cmdout, ObjectInput cmdin,
             VirtualMachine vm, Process process, String remoteAgent,
             List<Consumer<String>> deathListeners) {
         super(cmdout, cmdin);
         this.vm = vm;
         this.process = process;
         this.remoteAgent = remoteAgent;
+        // We have now succeeded in establishing the connection.
+        // If there is an exit now it propagates all the way up
+        // and the VM should be disposed of.
+        deathListeners.add(s -> env.closeDown());
         deathListeners.add(s -> disposeVM());
-    }
+     }
 
     @Override
     public String invoke(String classname, String methodname)
--- a/langtools/src/jdk.jshell/share/classes/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/src/jdk.jshell/share/classes/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -70,11 +70,10 @@
     uses jdk.jshell.spi.ExecutionControlProvider;
     uses jdk.internal.editor.spi.BuildInEditorProvider;
 
-    provides javax.tools.Tool with jdk.internal.jshell.tool.JShellToolProvider;
-    provides jdk.jshell.spi.ExecutionControlProvider
-        with jdk.jshell.execution.JdiExecutionControlProvider;
+    provides javax.tools.Tool
+        with jdk.internal.jshell.tool.JShellToolProvider;
     provides jdk.jshell.spi.ExecutionControlProvider
-        with jdk.jshell.execution.LocalExecutionControlProvider;
-    provides jdk.jshell.spi.ExecutionControlProvider
-        with jdk.jshell.execution.FailOverExecutionControlProvider;
+        with jdk.jshell.execution.JdiExecutionControlProvider,
+             jdk.jshell.execution.LocalExecutionControlProvider,
+             jdk.jshell.execution.FailOverExecutionControlProvider;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/C.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+public class C {
+    /**
+     * case1 <ul> <li> end of sentence. <li> more </ul>
+     */
+    public void case1() {}
+
+    /**
+     * case2 <ul compact> <li> end of sentence. <li> more </ul>
+     */
+    public void case2() {}
+
+    /**
+     * case3 <ul type="square"> <li> end of sentence. <li> more </ul>
+     */
+    public void case3() {}
+
+    /**
+     * case4 <ul type="a<b"> <li> end of sentence. <li> more </ul>
+     */
+    public void case4() {}
+
+    /**
+     * case5 <ul type="a>b"> <li> end of sentence. <li> more </ul>
+     */
+    public void case5() {}
+
+    /**
+     * case6 <ul type='a>b'> <li> end of sentence. <li> more </ul>
+     */
+    public void case6() {}
+
+    /**
+     * case7 <ul type='"a>b"'> <li> end of sentence. <li> more </ul>
+     */
+    public void case7() {}
+
+    /**
+     * case8 <ul type="'a>b'"> <li> end of sentence. <li> more </ul>
+     */
+    public void case8() {}
+
+    /**
+     * case9 <ul type="'a'>b"> <li> end of sentence. <li> more </ul>
+     */
+    public void case9() {}
+
+    /**
+     * caseA <ul type='"a">b'> <li> end of sentence. <li> more </ul>
+     */
+    public void caseA() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/com/sun/javadoc/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, 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      8048628
+ * @summary  Verify html inline tags are removed correctly in the first sentence.
+ * @library  ../lib
+ * @modules jdk.javadoc
+ * @build    JavadocTester
+ * @run main TestNonInlineHtmlTagRemoval
+ */
+
+public class TestNonInlineHtmlTagRemoval extends JavadocTester {
+
+    public static void main(String... args) throws Exception {
+        TestNonInlineHtmlTagRemoval tester = new TestNonInlineHtmlTagRemoval();
+        tester.runTests();
+    }
+
+    @Test
+    void test() {
+        javadoc("-d", "out",
+                "-sourcepath", testSrc,
+                testSrc("C.java"));
+        checkExit(Exit.OK);
+
+        checkOutput("C.html", true,
+                "<div class=\"block\">case1 end of sentence.</div>",
+                "<div class=\"block\">case2 end of sentence.</div>",
+                "<div class=\"block\">case3 end of sentence.</div>",
+                "<div class=\"block\">case4 end of sentence.</div>",
+                "<div class=\"block\">case5 end of sentence.</div>",
+                "<div class=\"block\">case6 end of sentence.</div>",
+                "<div class=\"block\">case7 end of sentence.</div>",
+                "<div class=\"block\">case8 end of sentence.</div>",
+                "<div class=\"block\">case9 end of sentence.</div>",
+                "<div class=\"block\">caseA end of sentence.</div>");
+    }
+}
--- a/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8162353 8164747
+ * @bug 8162353 8164747 8173707
  * @summary javadoc should provide a way to disable use of frames
  * @library /tools/lib ../lib
  * @modules
@@ -323,10 +323,14 @@
         }
 
         private void checkIndex() {
-            // the index.html page only contains frames in frames mode
+            // the index.html page only contains frames and Javascript to default to no-frames view,
+            // in frames mode
             checkOutput("index.html", frames,
                     "<iframe ",
-                    "</iframe>");
+                    "</iframe>",
+                    "<body onload=\"loadFrames()\">\n"
+                    + "<script type=\"text/javascript\">\n"
+                    + "if (targetPage == \"\" || targetPage == \"undefined\")");
 
             // the index.html contains the overview if one
             // has been given, and not in frames mode
--- a/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testHtmlVersion/TestHtmlVersion.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8072945 8081854 8141492 8148985 8150188 4649116
+ * @bug 8072945 8081854 8141492 8148985 8150188 4649116 8173707
  * @summary Test the version of HTML generated by the javadoc tool.
  * @author bpatel
  * @library ../lib
@@ -607,6 +607,11 @@
                 "<!DOCTYPE HTML>",
                 "<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">",
                 "<body onload=\"loadFrames()\">\n"
+                + "<script type=\"text/javascript\">\n"
+                + "if (targetPage == \"\" || targetPage == \"undefined\")\n"
+                + "     window.location.replace('overview-summary.html');\n"
+                + "</script>\n"
+                + "<noscript>JavaScript is disabled on your browser.</noscript>\n"
                 + "<main role=\"main\">\n"
                 + "<div class=\"mainContainer\">\n"
                 + "<div class=\"leftContainer\">\n"
@@ -1012,6 +1017,11 @@
         checkOutput("index.html", false,
                 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">",
                 "<body>\n"
+                + "<script type=\"text/javascript\">\n"
+                + "if (targetPage == \"\" || targetPage == \"undefined\")\n"
+                + "     window.location.replace('overview-summary.html');\n"
+                + "</script>\n"
+                + "<noscript>JavaScript is disabled on your browser.</noscript>\n"
                 + "<div class=\"mainContainer\">\n");
     }
 
@@ -1424,6 +1434,11 @@
                 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">",
                 "<link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" title=\"Style\">",
                 "<body onload=\"loadFrames()\">\n"
+                + "<script type=\"text/javascript\">\n"
+                + "if (targetPage == \"\" || targetPage == \"undefined\")\n"
+                + "     window.location.replace('overview-summary.html');\n"
+                + "</script>\n"
+                + "<noscript>JavaScript is disabled on your browser.</noscript>\n"
                 + "<div class=\"mainContainer\">\n"
                 + "<div class=\"leftContainer\">\n"
                 + "<div class=\"leftTop\">\n"
@@ -1924,6 +1939,11 @@
         checkOutput("index.html", false,
                 "<!DOCTYPE HTML>",
                 "<body>\n"
+                + "<script type=\"text/javascript\">\n"
+                + "if (targetPage == \"\" || targetPage == \"undefined\")\n"
+                + "     window.location.replace('overview-summary.html');\n"
+                + "</script>\n"
+                + "<noscript>JavaScript is disabled on your browser.</noscript>\n"
                 + "<main role=\"main\">\n"
                 + "<div class=\"mainContainer\">\n");
     }
--- a/langtools/test/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7112427 8012295 8025633 8026567 8061305 8081854 8150130 8162363 8167967
+ * @bug 7112427 8012295 8025633 8026567 8061305 8081854 8150130 8162363 8167967 8172528
  * @summary Test of the JavaFX doclet features.
  * @author jvalenta
  * @library ../lib
@@ -50,93 +50,103 @@
 
         checkOutput("pkg1/C.html", true,
                 "<dt><span class=\"seeLabel\">See Also:</span></dt>\n"
-                    + "<dd><a href=\"../pkg1/C.html#getRate--\"><code>getRate()</code></a>, \n"
-                    + "<a href=\"../pkg1/C.html#setRate-double-\">"
-                    + "<code>setRate(double)</code></a></dd>",
+                + "<dd><a href=\"../pkg1/C.html#getRate--\"><code>getRate()</code></a>, \n"
+                + "<a href=\"../pkg1/C.html#setRate-double-\">"
+                + "<code>setRate(double)</code></a></dd>",
                 "<pre>public final&nbsp;void&nbsp;setRate(double&nbsp;value)</pre>\n"
-                    + "<div class=\"block\">Sets the value of the property rate.</div>\n"
-                    + "<dl>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>",
+                + "<div class=\"block\">Sets the value of the property rate.</div>\n"
+                + "<dl>\n"
+                + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>",
                 "<pre>public final&nbsp;double&nbsp;getRate()</pre>\n"
-                    + "<div class=\"block\">Gets the value of the property rate.</div>\n"
-                    + "<dl>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>",
+                + "<div class=\"block\">Gets the value of the property rate.</div>\n"
+                + "<dl>\n"
+                + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>",
                 "<td class=\"colFirst\"><code><a href=\"../pkg1/C.DoubleProperty.html\" "
-                    + "title=\"class in pkg1\">C.DoubleProperty</a></code></td>\n"
-                    + "<th class=\"colSecond\" scope=\"row\"><code><span class=\"memberNameLink\">"
-                    + "<a href=\"../pkg1/C.html#rateProperty\">rate</a></span></code></th>\n"
-                    + "<td class=\"colLast\">\n"
-                    + "<div class=\"block\">Defines the direction/speed at which the "
-                    + "<code>Timeline</code> is expected to\n"
-                    + " be played.</div>\n</td>",
+                + "title=\"class in pkg1\">C.DoubleProperty</a></code></td>\n"
+                + "<th class=\"colSecond\" scope=\"row\"><code><span class=\"memberNameLink\">"
+                + "<a href=\"../pkg1/C.html#rateProperty\">rate</a></span></code></th>\n"
+                + "<td class=\"colLast\">\n"
+                + "<div class=\"block\">Defines the direction/speed at which the "
+                + "<code>Timeline</code> is expected to\n"
+                + " be played.</div>\n</td>",
                 "<span class=\"simpleTagLabel\">Default value:</span>",
                 "<span class=\"simpleTagLabel\">Since:</span></dt>\n"
-                    + "<dd>JavaFX 8.0</dd>",
+                + "<dd>JavaFX 8.0</dd>",
                 "<p>Sets the value of the property <code>Property</code>",
                 "<p>Gets the value of the property <code>Property</code>",
                 "<span class=\"simpleTagLabel\">Property description:</span>",
                 "<th class=\"colSecond\" scope=\"row\"><code><span class=\"memberNameLink\">"
-                    + "<a href=\"../pkg1/C.html#setTestMethodProperty--\">"
-                    + "setTestMethodProperty</a></span>()</code></th>",
+                + "<a href=\"../pkg1/C.html#setTestMethodProperty--\">"
+                + "setTestMethodProperty</a></span>()</code></th>",
                 "<th class=\"colSecond\" scope=\"row\"><code><span class=\"memberNameLink\">"
-                    + "<a href=\"../pkg1/C.html#pausedProperty\">paused</a></span></code></th>\n"
-                    + "<td class=\"colLast\">\n"
-                    + "<div class=\"block\">Defines if paused.</div>",
+                + "<a href=\"../pkg1/C.html#pausedProperty\">paused</a></span></code></th>\n"
+                + "<td class=\"colLast\">\n"
+                + "<div class=\"block\">Defines if paused.</div>",
                 "<h4>paused</h4>\n"
-                    + "<pre>public final&nbsp;<a href=\"../pkg1/C.BooleanProperty.html\" "
-                    + "title=\"class in pkg1\">C.BooleanProperty</a> pausedProperty</pre>\n"
-                    + "<div class=\"block\">Defines if paused. The second line.</div>",
+                + "<pre>public final&nbsp;<a href=\"../pkg1/C.BooleanProperty.html\" "
+                + "title=\"class in pkg1\">C.BooleanProperty</a> pausedProperty</pre>\n"
+                + "<div class=\"block\">Defines if paused. The second line.</div>",
                 "<h4>isPaused</h4>\n"
-                    + "<pre>public final&nbsp;double&nbsp;isPaused()</pre>\n"
-                    + "<div class=\"block\">Gets the value of the property paused.</div>",
+                + "<pre>public final&nbsp;double&nbsp;isPaused()</pre>\n"
+                + "<div class=\"block\">Gets the value of the property paused.</div>",
                 "<h4>setPaused</h4>\n"
-                    + "<pre>public final&nbsp;void&nbsp;setPaused(boolean&nbsp;value)</pre>\n"
-                    + "<div class=\"block\">Sets the value of the property paused.</div>\n"
-                    + "<dl>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>\n"
-                    + "<dd>Defines if paused. The second line.</dd>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Default value:</span></dt>\n"
-                    + "<dd>false</dd>",
+                + "<pre>public final&nbsp;void&nbsp;setPaused(boolean&nbsp;value)</pre>\n"
+                + "<div class=\"block\">Sets the value of the property paused.</div>\n"
+                + "<dl>\n"
+                + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>\n"
+                + "<dd>Defines if paused. The second line.</dd>\n"
+                + "<dt><span class=\"simpleTagLabel\">Default value:</span></dt>\n"
+                + "<dd>false</dd>",
                 "<h4>isPaused</h4>\n"
-                    + "<pre>public final&nbsp;double&nbsp;isPaused()</pre>\n"
-                    + "<div class=\"block\">Gets the value of the property paused.</div>\n"
-                    + "<dl>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>\n"
-                    + "<dd>Defines if paused. The second line.</dd>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Default value:</span></dt>\n"
-                    + "<dd>false</dd>",
+                + "<pre>public final&nbsp;double&nbsp;isPaused()</pre>\n"
+                + "<div class=\"block\">Gets the value of the property paused.</div>\n"
+                + "<dl>\n"
+                + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>\n"
+                + "<dd>Defines if paused. The second line.</dd>\n"
+                + "<dt><span class=\"simpleTagLabel\">Default value:</span></dt>\n"
+                + "<dd>false</dd>",
                 "<h4>rate</h4>\n"
-                    + "<pre>public final&nbsp;<a href=\"../pkg1/C.DoubleProperty.html\" "
-                    + "title=\"class in pkg1\">C.DoubleProperty</a> rateProperty</pre>\n"
-                    + "<div class=\"block\">Defines the direction/speed at which the "
-                    + "<code>Timeline</code> is expected to\n"
-                    + " be played. This is the second line.</div>",
+                + "<pre>public final&nbsp;<a href=\"../pkg1/C.DoubleProperty.html\" "
+                + "title=\"class in pkg1\">C.DoubleProperty</a> rateProperty</pre>\n"
+                + "<div class=\"block\">Defines the direction/speed at which the "
+                + "<code>Timeline</code> is expected to\n"
+                + " be played. This is the second line.</div>",
                 "<h4>setRate</h4>\n"
-                    + "<pre>public final&nbsp;void&nbsp;setRate(double&nbsp;value)</pre>\n"
-                    + "<div class=\"block\">Sets the value of the property rate.</div>\n"
-                    + "<dl>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>\n"
-                    + "<dd>Defines the direction/speed at which the <code>Timeline</code> is expected to\n"
-                    + " be played. This is the second line.</dd>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Default value:</span></dt>\n"
-                    + "<dd>11</dd>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n"
-                    + "<dd>JavaFX 8.0</dd>",
+                + "<pre>public final&nbsp;void&nbsp;setRate(double&nbsp;value)</pre>\n"
+                + "<div class=\"block\">Sets the value of the property rate.</div>\n"
+                + "<dl>\n"
+                + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>\n"
+                + "<dd>Defines the direction/speed at which the <code>Timeline</code> is expected to\n"
+                + " be played. This is the second line.</dd>\n"
+                + "<dt><span class=\"simpleTagLabel\">Default value:</span></dt>\n"
+                + "<dd>11</dd>\n"
+                + "<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n"
+                + "<dd>JavaFX 8.0</dd>",
                 "<h4>getRate</h4>\n"
-                    + "<pre>public final&nbsp;double&nbsp;getRate()</pre>\n"
-                    + "<div class=\"block\">Gets the value of the property rate.</div>\n"
-                    + "<dl>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>\n"
-                    + "<dd>Defines the direction/speed at which the <code>Timeline</code> is expected to\n"
-                    + " be played. This is the second line.</dd>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Default value:</span></dt>\n"
-                    + "<dd>11</dd>\n"
-                    + "<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n"
-                    + "<dd>JavaFX 8.0</dd>",
+                + "<pre>public final&nbsp;double&nbsp;getRate()</pre>\n"
+                + "<div class=\"block\">Gets the value of the property rate.</div>\n"
+                + "<dl>\n"
+                + "<dt><span class=\"simpleTagLabel\">Property description:</span></dt>\n"
+                + "<dd>Defines the direction/speed at which the <code>Timeline</code> is expected to\n"
+                + " be played. This is the second line.</dd>\n"
+                + "<dt><span class=\"simpleTagLabel\">Default value:</span></dt>\n"
+                + "<dd>11</dd>\n"
+                + "<dt><span class=\"simpleTagLabel\">Since:</span></dt>\n"
+                + "<dd>JavaFX 8.0</dd>",
+                "<h3>Property Summary</h3>\n"
+                + "<table class=\"memberSummary\" summary=\"Property Summary table, listing properties, and an explanation\">\n"
+                + "<caption><span>Properties</span><span class=\"tabEnd\">&nbsp;</span></caption>",
                 "");
 
         checkOutput("pkg1/C.html", false,
-                "A()");
+                "A()",
+                "<h3>Property Summary</h3>\n"
+                + "<table class=\"memberSummary\" summary=\"Property Summary table, listing properties, and an explanation\">\n"
+                + "<caption><span id=\"t0\" class=\"activeTableTab\"><span>All Methods</span><span class=\"tabEnd\">&nbsp;</span>"
+                + "</span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">Instance Methods</a>"
+                + "</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span>"
+                + "<a href=\"javascript:show(8);\">Concrete Methods</a></span><span class=\"tabEnd\">&nbsp;</span></span>"
+                + "</caption>");
 
         checkOutput("index-all.html", true,
                 "<div class=\"block\">Gets the value of the property paused.</div>",
@@ -193,7 +203,19 @@
                 + "</li>\n"
                 + "</ul>\n"
                 + "</li>\n"
-                + "</ul>");
+                + "</ul>",
+                "<h3>Property Summary</h3>\n"
+                + "<table class=\"memberSummary\" summary=\"Property Summary table, listing properties, and an explanation\">\n"
+                + "<caption><span>Properties</span><span class=\"tabEnd\">&nbsp;</span></caption>");
+
+        checkOutput("pkg2/Test.html", false,
+                "<h3>Property Summary</h3>\n"
+                + "<table class=\"memberSummary\" summary=\"Property Summary table, listing properties, and an explanation\">\n"
+                + "<caption><span id=\"t0\" class=\"activeTableTab\"><span>All Methods</span><span class=\"tabEnd\">&nbsp;</span>"
+                + "</span><span id=\"t2\" class=\"tableTab\"><span><a href=\"javascript:show(2);\">Instance Methods</a>"
+                + "</span><span class=\"tabEnd\">&nbsp;</span></span><span id=\"t4\" class=\"tableTab\"><span>"
+                + "<a href=\"javascript:show(8);\">Concrete Methods</a></span><span class=\"tabEnd\">&nbsp;</span></span>"
+                + "</caption>");
     }
 
     /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/C.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+public class C {
+    /**
+     * case1 <ul> <li> end of sentence. <li> more </ul>
+     */
+    public void case1() {}
+
+    /**
+     * case2 <ul compact> <li> end of sentence. <li> more </ul>
+     */
+    public void case2() {}
+
+    /**
+     * case3 <ul type="square"> <li> end of sentence. <li> more </ul>
+     */
+    public void case3() {}
+
+    /**
+     * case4 <ul type="a<b"> <li> end of sentence. <li> more </ul>
+     */
+    public void case4() {}
+
+    /**
+     * case5 <ul type="a>b"> <li> end of sentence. <li> more </ul>
+     */
+    public void case5() {}
+
+    /**
+     * case6 <ul type='a>b'> <li> end of sentence. <li> more </ul>
+     */
+    public void case6() {}
+
+    /**
+     * case7 <ul type='"a>b"'> <li> end of sentence. <li> more </ul>
+     */
+    public void case7() {}
+
+    /**
+     * case8 <ul type="'a>b'"> <li> end of sentence. <li> more </ul>
+     */
+    public void case8() {}
+
+    /**
+     * case9 <ul type="'a'>b"> <li> end of sentence. <li> more </ul>
+     */
+    public void case9() {}
+
+    /**
+     * caseA <ul type='"a">b'> <li> end of sentence. <li> more </ul>
+     */
+    public void caseA() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, 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      8048628
+ * @summary  Verify html inline tags are removed correctly in the first sentence.
+ * @library  ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build    JavadocTester
+ * @run main TestNonInlineHtmlTagRemoval
+ */
+
+public class TestNonInlineHtmlTagRemoval extends JavadocTester {
+
+    public static void main(String... args) throws Exception {
+        TestNonInlineHtmlTagRemoval tester = new TestNonInlineHtmlTagRemoval();
+        tester.runTests();
+    }
+
+    @Test
+    void test() {
+        javadoc("-d", "out",
+                "-sourcepath", testSrc,
+                testSrc("C.java"));
+        checkExit(Exit.OK);
+
+        checkOutput("C.html", true,
+                "<div class=\"block\">case1   end of sentence.</div>",
+                "<div class=\"block\">case2   end of sentence.</div>",
+                "<div class=\"block\">case3   end of sentence.</div>",
+                "<div class=\"block\">case4   end of sentence.</div>",
+                "<div class=\"block\">case5   end of sentence.</div>",
+                "<div class=\"block\">case6   end of sentence.</div>",
+                "<div class=\"block\">case7   end of sentence.</div>",
+                "<div class=\"block\">case8   end of sentence.</div>",
+                "<div class=\"block\">case9   end of sentence.</div>",
+                "<div class=\"block\">caseA   end of sentence.</div>");
+    }
+}
--- a/langtools/test/jdk/javadoc/doclet/testOrdering/TestOrdering.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testOrdering/TestOrdering.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8039410 8042601 8042829 8049393 8050031 8155061 8155995 8167967
+ * @bug 8039410 8042601 8042829 8049393 8050031 8155061 8155995 8167967 8169813
  * @summary test to determine if members are ordered correctly
  * @library ../lib/
  * @modules jdk.javadoc/jdk.javadoc.internal.tool
@@ -494,23 +494,23 @@
         String[] composeTestVectors() {
             List<String> testList = new ArrayList<>();
 
-            testList.addAll(Arrays.asList(expectedPackageOrdering));
             for (String x : expectedEnumOrdering) {
                 testList.add(x.replace("REPLACE_ME", "&lt;Unnamed&gt;"));
-                for (int i = 0; i < MAX_PACKAGES; i++) {
-                    String wpkg = "add" + i;
-                    testList.add(wpkg + "/" + x.replace("REPLACE_ME",
-                            wpkg));
-                    String dpkg = wpkg;
-                    for (int j = 1; j < MAX_SUBPACKAGES_DEPTH; j++) {
-                        dpkg = dpkg + "/" + "add";
+            }
+            for (int i = 0; i < MAX_PACKAGES; i++) {
+                String wpkg = "add" + i;
+                for (String x : expectedEnumOrdering) {
+                    testList.add(wpkg + "/" + x.replace("REPLACE_ME", wpkg));
+                }
+                String dpkg = wpkg;
+                for (int j = 1; j < MAX_SUBPACKAGES_DEPTH; j++) {
+                    dpkg = dpkg + "/" + "add";
+                    for (String x : expectedEnumOrdering) {
                         testList.add(dpkg + "/" + x.replace("REPLACE_ME", pathToPackage(dpkg)));
                     }
                 }
             }
 
-            testList.addAll(Arrays.asList(expectedFieldOrdering));
-
             for (String x : expectedMethodOrdering) {
                 testList.add(x);
                 for (int i = 0; i < MAX_PACKAGES; i++) {
@@ -523,6 +523,8 @@
                     }
                 }
             }
+            testList.addAll(Arrays.asList(expectedPackageOrdering));
+            testList.addAll(Arrays.asList(expectedFieldOrdering));
 
             return testList.toArray(new String[testList.size()]);
         }
--- a/langtools/test/jdk/jshell/ExecutionControlTestBase.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/jshell/ExecutionControlTestBase.java	Fri Feb 10 08:57:42 2017 -0800
@@ -23,6 +23,7 @@
 
 import javax.tools.Diagnostic;
 
+import org.testng.annotations.Test;
 import jdk.jshell.VarSnippet;
 
 import static jdk.jshell.Snippet.Status.VALID;
@@ -30,6 +31,7 @@
 
 public class ExecutionControlTestBase extends KullaTesting {
 
+    @Test
     public void classesDeclaration() {
         assertEval("interface A { }");
         assertEval("class B implements A { }");
@@ -45,6 +47,7 @@
         assertActiveKeys();
     }
 
+    @Test
     public void interfaceTest() {
         String interfaceSource
                 = "interface A {\n"
@@ -72,6 +75,7 @@
         assertEval("new B.Inner2();");
     }
 
+    @Test
     public void variables() {
         VarSnippet snx = varKey(assertEval("int x = 10;"));
         VarSnippet sny = varKey(assertEval("String y = \"hi\";"));
@@ -83,6 +87,7 @@
         assertActiveKeys();
     }
 
+    @Test
     public void methodOverload() {
         assertEval("int m() { return 1; }");
         assertEval("int m(int x) { return 2; }");
@@ -107,6 +112,7 @@
         assertActiveKeys();
     }
 
+    @Test
     public void testExprSanity() {
         assertEval("int x = 3;", "3");
         assertEval("int y = 4;", "4");
@@ -114,6 +120,7 @@
         assertActiveKeys();
     }
 
+    @Test
     public void testImportOnDemand() {
         assertImportKeyMatch("import java.util.*;", "java.util.*", TYPE_IMPORT_ON_DEMAND_SUBKIND, added(VALID));
         assertEval("List<Integer> list = new ArrayList<>();");
--- a/langtools/test/jdk/jshell/FailOverDirectExecutionControlTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/jshell/FailOverDirectExecutionControlTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -61,7 +61,8 @@
 
     ClassLoader ccl;
     ExecutionControlProvider provider;
-    Map<Level, List<String>> logged = new HashMap<>();
+    LogTestHandler hndlr;
+    Map<Level, List<String>> logged;
 
     private class LogTestHandler extends Handler {
 
@@ -95,7 +96,9 @@
     public void setUp() {
         Logger logger = Logger.getLogger("jdk.jshell.execution");
         logger.setLevel(Level.ALL);
-        logger.addHandler(new LogTestHandler());
+        hndlr = new LogTestHandler();
+        logger.addHandler(hndlr);
+        logged = new HashMap<>();
         Compiler compiler = new Compiler();
         Path modDir = Paths.get("mod");
         compiler.compile(modDir,
@@ -133,6 +136,8 @@
     @Override
     public void tearDown() {
         super.tearDown();
+        Logger logger = Logger.getLogger("jdk.jshell.execution");
+        logger.removeHandler(hndlr);
         Thread.currentThread().setContextClassLoader(ccl);
     }
 
--- a/langtools/test/jdk/jshell/FailOverExecutionControlDyingLaunchTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/jshell/FailOverExecutionControlDyingLaunchTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -27,7 +27,7 @@
  * @summary Test that fail-over works for fail-over ExecutionControl generators.
  * @modules jdk.jshell/jdk.jshell.execution
  *          jdk.jshell/jdk.jshell.spi
- * @build KullaTesting ExecutionControlTestBase
+ * @build KullaTesting ExecutionControlTestBase DyingRemoteAgent
  * @run testng FailOverExecutionControlDyingLaunchTest
  */
 
--- a/langtools/test/jdk/jshell/SimpleRegressionTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/jshell/SimpleRegressionTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -22,7 +22,7 @@
  */
 
 /*
- * @test 8130450 8158906 8154374 8166400 8171892
+ * @test 8130450 8158906 8154374 8166400 8171892 8173807 8173848
  * @summary simple regression test
  * @build KullaTesting TestingInputStream
  * @run testng SimpleRegressionTest
@@ -76,6 +76,15 @@
         assertEval("c;", "600");
     }
 
+    public void testLessThanParsing() {
+        assertEval("int x = 3;", "3");
+        assertEval("int y = 4;", "4");
+        assertEval("int z = 5;", "5");
+        assertEval("x < y", "true");
+        assertEval("x < y;", "true");
+        assertEval("x < y && y < z", "true");
+    }
+
     public void testNotStmtCannotResolve() {
         assertDeclareFail("dfasder;", new ExpectedDiagnostic("compiler.err.cant.resolve.location", 0, 7, 0, -1, -1, Diagnostic.Kind.ERROR));
     }
@@ -182,4 +191,36 @@
         assertEval("new boolean[2][1][3]",
                 "boolean[2][][] { boolean[1][] { boolean[3] { false, false, false } }, boolean[1][] { boolean[3] { false, false, false } } }");
     }
+
+    public void testStringRepresentation() {
+        assertEval("\"A!\\rB!\"",
+                   "\"A!\\rB!\"");
+        assertEval("\"a\\bB\\tc\\nd\\fe\\rf\\\"g'\\\\h\"",
+                   "\"a\\bB\\tc\\nd\\fe\\rf\\\"g'\\\\h\"");
+        assertEval("\"\\141\\10B\\11c\\nd\\fe\\15f\\42g\\'\\134h\"",
+                   "\"a\\bB\\tc\\nd\\fe\\rf\\\"g'\\\\h\"");
+        assertEval("\"1234567890!@#$%^&*()-_=+qwertQWERT,./<>?;:[]{}\"",
+                   "\"1234567890!@#$%^&*()-_=+qwertQWERT,./<>?;:[]{}\"");
+        assertEval("\"AA\\1\\7\\35\\25\"",
+                   "\"AA\\001\\007\\035\\025\"");
+        assertEval("\"\"",
+                   "\"\"");
+        assertEval("(String)null",
+                   "null");
+    }
+
+    public void testCharRepresentation() {
+        for (String s : new String[]{"'A'", "'Z'", "'0'", "'9'",
+            "'a'", "'z'", "'*'", "'%'",
+            "'\\b'", "'\\t'", "'\\n'", "'\\f'", "'\\r'",
+            "'\"'", "'\\\''", "'\\\\'", "'\\007'", "'\\034'",}) {
+            assertEval(s, s);
+        }
+        assertEval("'\\3'",
+                "'\\003'");
+        assertEval("'\\u001D'",
+                "'\\035'");
+        assertEval("\"a\\bb\\tc\\nd\\fe\\rf\\\"g'\\\\h\".charAt(1)",
+                "'\\b'");
+    }
 }
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103  8165405 8173073
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103  8165405 8173073 8173848
  * @summary Simple jshell tool tests
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.main
@@ -74,6 +74,18 @@
     }
 
     @Test
+    public void testLessThan() {
+        test(
+                (a) -> assertCommand(a, "45", "$1 ==> 45"),
+                (a) -> assertCommand(a, "72", "$2 ==> 72"),
+                (a) -> assertCommand(a, "$1 < $2", "$3 ==> true"),
+                (a) -> assertCommand(a, "int a, b", "a ==> 0\n" +
+                        "b ==> 0"),
+                (a) -> assertCommand(a, "a < b", "$6 ==> false")
+        );
+    }
+
+    @Test
     public void oneLineOfError() {
         test(
                 (a) -> assertCommand(a, "12+", null),
--- a/langtools/test/tools/javac/diags/examples/DuplicateProvides/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/diags/examples/DuplicateProvides/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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,6 @@
 
 module DuplicateExports {
      exports exported;
-     provides exported.Service with impl.ServiceImplementation;
-     provides exported.Service with impl.ServiceImplementation;
+     provides exported.Service
+        with impl.ServiceImplementation, impl.ServiceImplementation;
 }
--- a/langtools/test/tools/javac/diags/examples/PackageEmptyOrNotFound/PackageEmptyOrNotFound.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-// key: compiler.err.package.empty.or.not.found
--- a/langtools/test/tools/javac/diags/examples/PackageEmptyOrNotFound/modulesourcepath/m1x/module-info.java	Fri Feb 10 13:32:11 2017 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * 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.
- */
-
-module m1x {
-    exports p1;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/PackageEmptyOrNotFoundError/PackageEmptyOrNotFound.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+// key: compiler.err.package.empty.or.not.found
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/PackageEmptyOrNotFoundError/modulesourcepath/m1x/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+module m1x {
+    exports p1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/PackageEmptyOrNotFoundWarning/PackageEmptyOrNotFound.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+// key: compiler.warn.package.empty.or.not.found
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/PackageEmptyOrNotFoundWarning/modulesourcepath/m1x/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, 2017, 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.
+ */
+
+module m1x {
+    opens p1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatedProvidesForService/RepeatedProvides.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+//key: compiler.err.repeated.provides.for.service
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatedProvidesForService/modulesourcepath/m/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,6 @@
+module m {
+    uses p.I;
+    provides p.I with p.A;
+    provides p.I with p.B;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatedProvidesForService/modulesourcepath/m/p/A.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,3 @@
+package p;
+public class A implements I { }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatedProvidesForService/modulesourcepath/m/p/B.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,3 @@
+package p;
+public class B implements I { }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatedProvidesForService/modulesourcepath/m/p/I.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,3 @@
+package p;
+public interface I { }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/UnexpectedTokenInModuleInfo/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+// key: compiler.err.expected.module.or.open
+
+weak module m {}
\ No newline at end of file
--- a/langtools/test/tools/javac/file/LimitedImage.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/file/LimitedImage.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -74,6 +74,7 @@
         );
 
         //check proper diagnostics when zip/jar FS not present:
+        System.err.println("Test " + testJar + " on classpath");
         actualOutput = new JavacTask(tb, Mode.CMDLINE)
                 .classpath(testJar)
                 .options("-XDrawDiagnostics")
@@ -84,9 +85,10 @@
                 .getOutputLines(OutputKind.DIRECT);
 
         if (!expectedOutput.equals(actualOutput)) {
-            throw new AssertionError("Unexpected output: " + actualOutput);
+            throw new AssertionError("Unexpected output");
         }
 
+        System.err.println("Test " + testJar + " on sourcepath");
         actualOutput = new JavacTask(tb, Mode.CMDLINE)
                 .sourcepath(testJar)
                 .options("-XDrawDiagnostics")
@@ -97,9 +99,10 @@
                 .getOutputLines(OutputKind.DIRECT);
 
         if (!expectedOutput.equals(actualOutput)) {
-            throw new AssertionError("Unexpected output: " + actualOutput);
+            throw new AssertionError("Unexpected output");
         }
 
+        System.err.println("Test " + testJar + " on modulepath");
         actualOutput = new JavacTask(tb, Mode.CMDLINE)
                 .options("-XDrawDiagnostics",
                          "--module-path", testJar.toString())
@@ -110,7 +113,7 @@
                 .getOutputLines(OutputKind.DIRECT);
 
         if (!expectedOutput.equals(actualOutput)) {
-            throw new AssertionError("Unexpected output: " + actualOutput);
+            throw new AssertionError("Unexpected output");
         }
 
         expectedOutput = Arrays.asList(
@@ -118,6 +121,7 @@
                 "1 error"
         );
 
+        System.err.println("Test directory containing " + testJar + " on modulepath");
         actualOutput = new JavacTask(tb, Mode.CMDLINE)
                 .classpath()
                 .options("-XDrawDiagnostics",
@@ -129,7 +133,7 @@
                 .getOutputLines(OutputKind.DIRECT);
 
         if (!expectedOutput.equals(actualOutput)) {
-            throw new AssertionError("Unexpected output: " + actualOutput);
+            throw new AssertionError("Unexpected output");
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReferenceNoThisTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8173456
+ * @summary com.sun.tools.javac.util.Assert.error during code compilation
+ * @compile/fail/ref=MethodReferenceNoThisTest.out -XDrawDiagnostics MethodReferenceNoThisTest.java
+ */
+
+import java.util.function.Function;
+
+abstract class MethodReferenceNoThisTest_Base {
+  protected MethodReferenceNoThisTest_Base(Function<MethodReferenceNoThisTest_Base, MethodReferenceNoThisTest_AV> x) {}
+}
+
+abstract class MethodReferenceNoThisTest_AV {
+    MethodReferenceNoThisTest_AV(MethodReferenceNoThisTest_Base b) {
+    }
+}
+
+public class MethodReferenceNoThisTest extends MethodReferenceNoThisTest_Base {
+
+    public MethodReferenceNoThisTest() {
+        super(V::new);
+    }
+
+    private class V extends MethodReferenceNoThisTest_AV {
+
+        V(MethodReferenceNoThisTest_Base b) {
+            super(b);
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReferenceNoThisTest.out	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,2 @@
+MethodReferenceNoThisTest.java:22:15: compiler.err.cant.ref.before.ctor.called: this
+1 error
\ No newline at end of file
--- a/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -26,7 +26,6 @@
  * @bug 8002099 8010822
  * @summary Add support for intersection types in cast expression
  * @modules jdk.compiler/com.sun.tools.javac.util
- * @run main/othervm IntersectionTargetTypeTest
  */
 
 import com.sun.source.util.JavacTask;
--- a/langtools/test/tools/javac/modules/AddLimitMods.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/modules/AddLimitMods.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -217,10 +217,10 @@
 
     private static final List<Entry<String[], String>> variants = Arrays.asList(
             new SimpleEntry<String[], String>(new String[] {},
-                                              "Test.java:2:7: compiler.err.package.not.visible: javax.annotation, (compiler.misc.not.def.access.does.not.read.from.unnamed: javax.annotation, java.annotations.common)\n"
+                                              "Test.java:2:7: compiler.err.package.not.visible: javax.annotation, (compiler.misc.not.def.access.does.not.read.from.unnamed: javax.annotation, java.xml.ws.annotation)\n"
                                             + "Test.java:5:14: compiler.err.package.not.visible: javax.xml.bind, (compiler.misc.not.def.access.does.not.read.from.unnamed: javax.xml.bind, java.xml.bind)\n"
                                             + "2 errors\n"),
-            new SimpleEntry<String[], String>(new String[] {"--add-modules", "java.annotations.common,java.xml.bind"},
+            new SimpleEntry<String[], String>(new String[] {"--add-modules", "java.xml.ws.annotation,java.xml.bind"},
                                               null),
             new SimpleEntry<String[], String>(new String[] {"--limit-modules", "java.xml.ws,jdk.compiler"},
                                               null),
--- a/langtools/test/tools/javac/modules/AnnotationProcessing.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/modules/AnnotationProcessing.java	Fri Feb 10 08:57:42 2017 -0800
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8133884 8162711 8133896 8172158 8172262
+ * @bug 8133884 8162711 8133896 8172158 8172262 8173636
  * @summary Verify that annotation processing works.
  * @library /tools/lib
  * @modules
@@ -173,7 +173,7 @@
                     String[] module2Packages = moduleDef.split("=>");
 
                     module2ExpectedEnclosedElements.put(module2Packages[0],
-                                                        Arrays.asList(module2Packages[1].split(":")));
+                                                        List.of(module2Packages[1].split(":")));
                 }
             }
 
@@ -359,7 +359,7 @@
             .writeAll()
             .getOutput(Task.OutputKind.DIRECT);
 
-        List<String> expected = Arrays.asList("Note: field: m1x");
+        List<String> expected = List.of("Note: field: m1x");
 
         for (Mode mode : new Mode[] {Mode.API, Mode.CMDLINE}) {
             List<String> log = new JavacTask(tb, mode)
@@ -424,7 +424,7 @@
                 .writeAll()
                 .getOutputLines(Task.OutputKind.STDERR);
 
-        assertEquals(Arrays.asList("module: m1x"), log);
+        assertEquals(List.of("module: m1x"), log);
     }
 
     @SupportedAnnotationTypes("*")
@@ -472,8 +472,8 @@
                 .writeAll()
                 .getOutputLines(Task.OutputKind.DIRECT);
 
-        List<String> expectedLog = Arrays.asList("Note: AP Invoked",
-                                                 "Note: AP Invoked");
+        List<String> expectedLog = List.of("Note: AP Invoked",
+                                           "Note: AP Invoked");
 
         assertEquals(expectedLog, log);
 
@@ -600,7 +600,7 @@
 
                 JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
                 try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) {
-                    List<String> options = Arrays.asList("-d", scratchClasses.toString());
+                    List<String> options = List.of("-d", scratchClasses.toString());
                     Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects(scratchSrc);
                     CompilationTask task = comp.getTask(null, fm, null, options, null, files);
 
@@ -939,7 +939,7 @@
             .writeAll()
             .getOutputLines(OutputKind.STDERR);
 
-        expected = Arrays.asList("");
+        expected = List.of("");
 
         if (!expected.equals(log)) {
             throw new AssertionError("Output does not match; output: " + log);
@@ -954,15 +954,17 @@
             .writeAll()
             .getOutputLines(OutputKind.STDERR);
 
-        expected = Arrays.asList("SelectAnnotationBTestAP",
-                                 "SelectAnnotationBTestAP");
+        expected = List.of("SelectAnnotationBTestAP",
+                           "SelectAnnotationBTestAP");
 
         if (!expected.equals(log)) {
             throw new AssertionError("Output does not match; output: " + log);
         }
 
         log = new JavacTask(tb)
-            .options("-processor", SelectAnnotationATestAP.class.getName() + "," + SelectAnnotationBTestAP.class.getName(),
+            .options("-processor", SelectAnnotationATestAP.class.getName() + "," +
+                                   SelectAnnotationBTestAP.class.getName() + "," +
+                                   SelectAnnotationAStrictTestAP.class.getName(),
                      "--module-source-path", src.toString(),
                      "-m", "m4x")
             .outdir(classes)
@@ -970,10 +972,43 @@
             .writeAll()
             .getOutputLines(OutputKind.STDERR);
 
-        expected = Arrays.asList("SelectAnnotationATestAP",
-                                 "SelectAnnotationBTestAP",
-                                 "SelectAnnotationATestAP",
-                                 "SelectAnnotationBTestAP");
+        expected = List.of("SelectAnnotationATestAP",
+                           "SelectAnnotationBTestAP",
+                           "SelectAnnotationAStrictTestAP",
+                           "SelectAnnotationATestAP",
+                           "SelectAnnotationBTestAP",
+                           "SelectAnnotationAStrictTestAP");
+
+        if (!expected.equals(log)) {
+            throw new AssertionError("Output does not match; output: " + log);
+        }
+    }
+
+    @Test
+    public void testDisambiguateAnnotationsUnnamedModule(Path base) throws Exception {
+        Path classes = base.resolve("classes");
+
+        Files.createDirectories(classes);
+
+        Path src = base.resolve("src");
+
+        tb.writeJavaFiles(src,
+                          "package api; public @interface A {}",
+                          "package api; public @interface B {}",
+                          "package impl; import api.*; @A @B public class T {}");
+
+        List<String> log = new JavacTask(tb)
+            .options("-processor", SelectAnnotationATestAP.class.getName() + "," +
+                                   SelectAnnotationBTestAP.class.getName() + "," +
+                                   SelectAnnotationAStrictTestAP.class.getName())
+            .outdir(classes)
+            .files(findJavaFiles(src))
+            .run()
+            .writeAll()
+            .getOutputLines(OutputKind.STDERR);
+
+        List<String> expected = List.of("SelectAnnotationBTestAP",
+                                        "SelectAnnotationBTestAP");
 
         if (!expected.equals(log)) {
             throw new AssertionError("Output does not match; output: " + log);
@@ -994,7 +1029,9 @@
                           "package impl; import api.*; @A @B public class T {}");
 
         List<String> log = new JavacTask(tb)
-            .options("-processor", SelectAnnotationATestAP.class.getName() + "," + SelectAnnotationBTestAP.class.getName(),
+            .options("-processor", SelectAnnotationATestAP.class.getName() + "," +
+                                   SelectAnnotationBTestAP.class.getName() + "," +
+                                   SelectAnnotationAStrictTestAP.class.getName(),
                      "-source", "8", "-target", "8")
             .outdir(classes)
             .files(findJavaFiles(src))
@@ -1002,10 +1039,10 @@
             .writeAll()
             .getOutputLines(OutputKind.STDERR);
 
-        List<String> expected = Arrays.asList("SelectAnnotationATestAP",
-                                              "SelectAnnotationBTestAP",
-                                              "SelectAnnotationATestAP",
-                                              "SelectAnnotationBTestAP");
+        List<String> expected = List.of("SelectAnnotationATestAP",
+                                        "SelectAnnotationBTestAP",
+                                        "SelectAnnotationATestAP",
+                                        "SelectAnnotationBTestAP");
 
         if (!expected.equals(log)) {
             throw new AssertionError("Output does not match; output: " + log);
@@ -1036,6 +1073,22 @@
 
     }
 
+    public static final class SelectAnnotationAStrictTestAP extends AbstractProcessor {
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            System.err.println("SelectAnnotationAStrictTestAP");
+
+            return false;
+        }
+
+        @Override
+        public Set<String> getSupportedAnnotationTypes() {
+            return Set.of("m2x/api.A");
+        }
+
+    }
+
     private static void writeFile(String content, Path base, String... pathElements) throws IOException {
         Path file = resolveFile(base, pathElements);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/MissingModuleTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2017, 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 8172240
+ * @summary javac should not need the transitive closure to compile a module
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.code
+ *      jdk.compiler/com.sun.tools.javac.main
+ *      jdk.compiler/com.sun.tools.javac.processing
+ * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
+ * @run main MissingModuleTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.Task.Expect;
+
+public class MissingModuleTest extends ModuleTestBase {
+
+    public static void main(String... args) throws Exception {
+        new MissingModuleTest().runTests();
+    }
+
+    @Test
+    public void testMissingNotNeeded(Path base) throws Exception {
+        doTest(base, "m1x", new String[0]);
+    }
+
+    @Test
+    public void testMissingNeededTransitive(Path base) throws Exception {
+        doTest(base, "m2x", "- compiler.err.module.not.found: m2x", "1 error");
+    }
+
+    @Test
+    public void testMissingNeededDirect(Path base) throws Exception {
+        doTest(base, "m3x", "module-info.java:1:24: compiler.err.module.not.found: m3x", "1 error");
+    }
+
+    @Test
+    public void testMultipleErrors(Path base) throws Exception {
+        doTest(base, "m4x", "module-info.java:1:38: compiler.err.module.not.found: m4x", "1 error");
+    }
+
+    private void doTest(Path base, String toDelete, String... errors) throws Exception {
+        //note: avoiding use of java.base, as that gets special handling on some places:
+        Path srcMP = base.resolve("src-mp");
+        Path m1x = srcMP.resolve("m1x");
+        tb.writeJavaFiles(m1x,
+                          "module m1x { exports api1; }",
+                          "package api1; public interface Api { }");
+        Path m2x = srcMP.resolve("m2x");
+        tb.writeJavaFiles(m2x,
+                          "module m2x { requires m1x; exports api2; }",
+                          "package api2; public interface Api { }");
+        Path m3x = srcMP.resolve("m3x");
+        tb.writeJavaFiles(m3x,
+                          "module m3x { requires transitive m2x; }");
+        Path m4x = srcMP.resolve("m4x");
+        tb.writeJavaFiles(m4x,
+                          "module m4x { requires transitive m2x; }");
+        Path m5x = srcMP.resolve("m5x");
+        tb.writeJavaFiles(m5x,
+                          "module m5x { requires transitive m4x; }");
+        Path classesMP = base.resolve("classes-mp");
+        tb.createDirectories(classesMP);
+
+        new JavacTask(tb)
+            .options("--module-source-path", srcMP.toString())
+            .outdir(classesMP)
+            .files(findJavaFiles(srcMP))
+            .run()
+            .writeAll();
+
+        tb.cleanDirectory(classesMP.resolve(toDelete));
+        Files.delete(classesMP.resolve(toDelete));
+
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                          "module test { requires m3x; requires m4x; requires m5x; } ");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        List<String> log = new JavacTask(tb)
+                .options("--module-path", classesMP.toString(),
+                         "-XDrawDiagnostics")
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(errors.length > 0 ? Expect.FAIL : Expect.SUCCESS)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        if (errors.length == 0) {
+            errors = new String[] {""};
+        }
+
+        if (!log.equals(Arrays.asList(errors)))
+            throw new Exception("expected output not found: " + log);
+    }
+
+}
--- a/langtools/test/tools/javac/modules/ModulesAndModuleSourcePathTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/modules/ModulesAndModuleSourcePathTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -22,7 +22,8 @@
  */
 
 /**
- * @test 8165102
+ * @test
+ * @bug 8165102
  * @summary incorrect message from javac
  * @library /tools/lib
  * @modules
--- a/langtools/test/tools/javac/modules/ProvidesTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/modules/ProvidesTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -24,7 +24,7 @@
 /**
  * @test
  * @summary simple tests of module provides
- * @bug 8168854
+ * @bug 8168854 8172807
  * @library /tools/lib
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
@@ -109,21 +109,56 @@
     }
 
     @Test
-    public void testDuplicateProvides(Path base) throws Exception {
+    public void testDuplicateImplementations1(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
-                "module m { provides p1.C1 with p2.C2; provides p1.C1 with p2.C2; }",
+                "module m { exports p1; exports p2; provides p1.C1 with p2.C2, p2.C2; }",
                 "package p1; public class C1 { }",
                 "package p2; public class C2 extends p1.C1 { }");
         Path classes = base.resolve("classes");
         Files.createDirectories(classes);
 
-        new JavacTask(tb)
-                .options("-XDrawDiagnostic")
+        List<String> output = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
                 .outdir(classes)
                 .files(findJavaFiles(src))
                 .run(Task.Expect.FAIL)
-                .writeAll();
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "module-info.java:1:65: compiler.err.duplicate.provides: p1.C1, p2.C2",
+                "1 error");
+        if (!output.containsAll(expected)) {
+            throw new Exception("Expected output not found");
+        }
+    }
+
+    @Test
+    public void testDuplicateImplementations2(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "module m { exports p1; provides p1.C1 with p2.C2; provides p1.C1 with p2.C2; }",
+                "package p1; public class C1 { }",
+                "package p2; public class C2 extends p1.C1 { }");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        List<String> output = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList(
+                "module-info.java:1:62: compiler.err.repeated.provides.for.service: p1.C1",
+                "module-info.java:1:73: compiler.err.duplicate.provides: p1.C1, p2.C2",
+                "2 errors");
+        if (!output.containsAll(expected)) {
+            throw new Exception("Expected output not found");
+        }
     }
 
     @Test
@@ -228,7 +263,7 @@
     public void testSeveralImplementations(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
-                "module m { provides p.C with p.Impl1; provides p.C with p.Impl2; }",
+                "module m { provides p.C with p.Impl1, p.Impl2; }",
                 "package p; public class C { }",
                 "package p; public class Impl1 extends p.C { }",
                 "package p; public class Impl2 extends p.C { }");
@@ -241,6 +276,30 @@
     }
 
     @Test
+    public void testRepeatedProvides(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "module m { exports p; provides p.C with p.Impl1; provides p.C with p.Impl2; }",
+                "package p; public class C { }",
+                "package p; public class Impl1 extends p.C { }",
+                "package p; public class Impl2 extends p.C { }");
+
+        List<String> output = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .outdir(Files.createDirectories(base.resolve("classes")))
+                .files(findJavaFiles(src))
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList("module-info.java:1:60: compiler.err.repeated.provides.for.service: p.C",
+                "1 error");
+        if (!output.containsAll(expected)) {
+            throw new Exception("Expected output not found");
+        }
+    }
+
+    @Test
     public void testOneImplementationsForServices(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
--- a/langtools/test/tools/javac/modules/ReportNonExistentPackageTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/modules/ReportNonExistentPackageTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -105,7 +105,7 @@
     }
 
     @Test
-    public void testExportPrivateEmptyPackage(Path base) throws Exception {
+    public void testOpensEmptyPackage(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { opens p; }");
@@ -116,15 +116,34 @@
                 .options("-XDrawDiagnostics")
                 .outdir(classes)
                 .files(findJavaFiles(src))
-                .run(Task.Expect.FAIL)
+                .run(Task.Expect.SUCCESS)
                 .writeAll()
                 .getOutput(Task.OutputKind.DIRECT);
-        if (!log.contains("module-info.java:1:18: compiler.err.package.empty.or.not.found: p"))
+        if (!log.contains("module-info.java:1:18: compiler.warn.package.empty.or.not.found: p"))
             throw new Exception("expected output not found, actual output: " + log);
     }
 
     @Test
-    public void testExportPrivateOnlyWithResources(Path base) throws Exception {
+    public void testOpensEmptyPackageSuppressed(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeJavaFiles(src,
+                "@SuppressWarnings(\"opens\") module m { opens p; }");
+        Path classes = base.resolve("classes");
+        Files.createDirectories(classes);
+
+        String log = new JavacTask(tb)
+                .options("-XDrawDiagnostics")
+                .outdir(classes)
+                .files(findJavaFiles(src))
+                .run(Task.Expect.SUCCESS)
+                .writeAll()
+                .getOutput(Task.OutputKind.DIRECT);
+        if (!log.equals(""))
+            throw new Exception("expected output not found, actual output: " + log);
+    }
+
+    @Test
+    public void testOpenOnlyWithResources(Path base) throws Exception {
         Path src = base.resolve("src");
         tb.writeJavaFiles(src,
                 "module m { opens p; }");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/UnexpectedTokenInModuleInfoTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, 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 8166420
+ * @summary Confusing error message when reading bad module declaration
+ * @library /tools/lib
+ * @modules
+ *      jdk.compiler/com.sun.tools.javac.api
+ *      jdk.compiler/com.sun.tools.javac.main
+ * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase
+ * @run main UnexpectedTokenInModuleInfoTest
+ */
+
+import java.nio.file.*;
+import java.util.List;
+import java.util.Arrays;
+
+import toolbox.JavacTask;
+import toolbox.Task;
+
+public class UnexpectedTokenInModuleInfoTest extends ModuleTestBase {
+    public static void main(String... args) throws Exception {
+        UnexpectedTokenInModuleInfoTest t = new UnexpectedTokenInModuleInfoTest();
+        t.runTests();
+    }
+
+    @Test
+    public void testSingleModule(Path base) throws Exception {
+        Path src = base.resolve("src");
+        tb.writeFile(src.resolve("module-info.java"), "weak module m { }");
+
+         List<String> output = new JavacTask(tb)
+            .options("-XDrawDiagnostics")
+            .files(src.resolve("module-info.java"))
+            .run(Task.Expect.FAIL)
+            .writeAll()
+            .getOutputLines(Task.OutputKind.DIRECT);
+
+         List<String> expected = Arrays.asList("module-info.java:1:1: compiler.err.expected.module.or.open",
+                "1 error");
+        if (!output.containsAll(expected)) {
+            throw new Exception("Expected output not found");
+        }
+    }
+}
\ No newline at end of file
--- a/langtools/test/tools/javac/parser/extend/TrialParserFactory.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/parser/extend/TrialParserFactory.java	Fri Feb 10 08:57:42 2017 -0800
@@ -52,4 +52,9 @@
         com.sun.tools.javac.parser.Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
         return new TrialParser(this, lexer, keepDocComments, keepLineMap, keepEndPos);
     }
+
+    @Override
+    public JavacParser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap, boolean parseModuleInfo) {
+        return newParser(input, keepDocComments, keepEndPos, keepLineMap);
+    }
 }
--- a/langtools/test/tools/javac/processing/messager/6362067/T6362067.out	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/processing/messager/6362067/T6362067.out	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 T6362067.java:19:8: compiler.note.proc.messager: note:elem
 T6362067.java:17:1: compiler.note.proc.messager: note:anno
 T6362067.java:18:1: compiler.note.proc.messager: note:anno
-T6362067.java:18:1: compiler.note.proc.messager: note:value
+T6362067.java:18:19: compiler.note.proc.messager: note:value
 - compiler.note.proc.messager: note:nopos
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/messager/6388543/T6388543.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,101 @@
+/*
+ * @test    /nodynamiccopyright/
+ * @bug     6388543
+ * @summary improve accuracy of source positions for AnnotationValue param of Messager.printMessage
+ * @library /tools/javac/lib
+ * @modules jdk.compiler
+ * @build   JavacTestingAbstractProcessor T6388543
+ * @compile/ref=T6388543.out -XDrawDiagnostics -processor T6388543 -proc:only T6388543.java
+ */
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+
+import static javax.tools.Diagnostic.Kind.NOTE;
+
+class Annotated {
+    @A(1)
+    int a1;
+
+    @A(value = 2)
+    int a2;
+
+    @A(value = {3})
+    int a3;
+
+    @A(value = {4, 5})
+    int a4;
+
+    @B(x = @C(x = E.ONE, y = E.TWO), y = @C(x = E.ONE, y = E.TWO))
+    int b;
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface A {
+    int[] value() default 0;
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface B {
+    C x() default @C;
+
+    C y() default @C;
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface C {
+    E x() default E.ONE;
+
+    E y() default E.ONE;
+}
+
+enum E {
+    ONE,
+    TWO
+}
+
+public class T6388543 extends JavacTestingAbstractProcessor {
+    public boolean process(Set<? extends TypeElement> annos, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+            return false;
+        }
+        for (Element e : elements.getTypeElement("Annotated").getEnclosedElements()) {
+            for (AnnotationMirror a : e.getAnnotationMirrors()) {
+                for (AnnotationValue v : a.getElementValues().values()) {
+                    printValue(e, a, v);
+                }
+            }
+        }
+        return false;
+    }
+
+    private void printValue(Element e, AnnotationMirror a, AnnotationValue v) {
+        messager.printMessage(NOTE, String.format("note:value %s + %s", a, v), e, a, v);
+        v.accept(
+                new SimpleAnnotationValueVisitor<Void, Void>() {
+                    @Override
+                    public Void visitArray(List<? extends AnnotationValue> values, Void unused) {
+                        for (AnnotationValue value : values) {
+                            printValue(e, a, value);
+                        }
+                        return null;
+                    }
+
+                    @Override
+                    public Void visitAnnotation(AnnotationMirror nestedAnnotation, Void unused) {
+                        for (AnnotationValue value : nestedAnnotation.getElementValues().values()) {
+                            printValue(e, a, value);
+                        }
+                        return null;
+                    }
+                },
+                null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/messager/6388543/T6388543.out	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,15 @@
+T6388543.java:24:8: compiler.note.proc.messager: note:value @A({1}) + {1}
+T6388543.java:24:8: compiler.note.proc.messager: note:value @A({1}) + 1
+T6388543.java:27:16: compiler.note.proc.messager: note:value @A({2}) + {2}
+T6388543.java:27:16: compiler.note.proc.messager: note:value @A({2}) + 2
+T6388543.java:30:16: compiler.note.proc.messager: note:value @A({3}) + {3}
+T6388543.java:30:17: compiler.note.proc.messager: note:value @A({3}) + 3
+T6388543.java:33:16: compiler.note.proc.messager: note:value @A({4, 5}) + {4, 5}
+T6388543.java:33:17: compiler.note.proc.messager: note:value @A({4, 5}) + 4
+T6388543.java:33:20: compiler.note.proc.messager: note:value @A({4, 5}) + 5
+T6388543.java:36:12: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + @C(x=E.ONE, y=E.TWO)
+T6388543.java:36:20: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + E.ONE
+T6388543.java:36:31: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + E.TWO
+T6388543.java:36:42: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + @C(x=E.ONE, y=E.TWO)
+T6388543.java:36:50: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + E.ONE
+T6388543.java:36:61: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + E.TWO
--- a/langtools/test/tools/javac/processing/model/element/TestPackageElement.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/processing/model/element/TestPackageElement.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -23,16 +23,18 @@
 
 /*
  * @test
- * @bug 6449798 6399404
+ * @bug 6449798 6399404 8173776
  * @summary Test basic workings of PackageElement
  * @author  Joseph D. Darcy
  * @library /tools/javac/lib
  * @modules java.compiler
  *          jdk.compiler
  * @build   JavacTestingAbstractProcessor TestPackageElement
- * @compile -processor TestPackageElement -proc:only TestPackageElement.java
+ * @compile -processor TestPackageElement -proc:only             TestPackageElement.java
+ * @compile -processor TestPackageElement -proc:only --release 8 TestPackageElement.java
  */
 
+import java.util.Objects;
 import java.util.Set;
 import javax.annotation.processing.*;
 import javax.lang.model.SourceVersion;
@@ -67,7 +69,22 @@
             PackageElement javaLang = eltUtils.getPackageElement("java.lang");
             if (javaLang.isUnnamed())
                 throw new RuntimeException("Package java.lang is unnamed!");
+
+            testEnclosingElement(javaLang);
         }
         return true;
     }
+
+    void testEnclosingElement(PackageElement javaLang) {
+        SourceVersion version = processingEnv.getSourceVersion();
+        Element enclosing = javaLang.getEnclosingElement();
+        Element expectedEnclosing =
+            (version.compareTo(RELEASE_9) < 0) ?  // No modules
+            null :
+            eltUtils.getModuleElement("java.base");
+
+        if (!Objects.equals(enclosing, expectedEnclosing))
+            throw new RuntimeException("Unexpected enclosing element under source version " +
+                                       version);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/printing/module-info.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,18 @@
+/*
+ * @test
+ * @bug 8173609
+ * @summary printing of modules
+ * @compile/ref=module-info.out -Xprint p/P.java module-info.java
+ */
+
+/**
+ * Printing of modules
+ */
+@Deprecated
+module printing {
+    requires static transitive java.base;
+    exports p to m.m1, m.m2;
+    opens p to m.m1, m.m2;
+    uses p.P;
+    provides p.P with p.P.P1, p.P.P2;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/printing/module-info.out	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,27 @@
+package p;
+
+public class P {
+
+  public static class P1 extends p.P {
+
+    public P1();
+  }
+
+  public static class P2 extends p.P {
+
+    public P2();
+  }
+
+  public P();
+}
+/**
+ * Printing of modules
+ */
+@java.lang.Deprecated
+module printing {
+  requires static transitive java.base;
+  exports p to m.m1, m.m2;
+  opens p to m.m1, m.m2;
+  uses p.P;
+  provides p.P with p.P.P1, p.P.P2;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/processing/model/util/printing/p/P.java	Fri Feb 10 08:57:42 2017 -0800
@@ -0,0 +1,6 @@
+package p;
+
+public class P {
+    public static class P1 extends P {}
+    public static class P2 extends P {}
+}
--- a/langtools/test/tools/javac/tree/JavacTreeScannerTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/tree/JavacTreeScannerTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -41,7 +41,7 @@
  *          jdk.compiler/com.sun.tools.javac.tree
  *          jdk.compiler/com.sun.tools.javac.util
  * @build AbstractTreeScannerTest JavacTreeScannerTest
- * @run main/othervm JavacTreeScannerTest -q -r .
+ * @run main JavacTreeScannerTest -q -r .
  */
 
 import java.io.*;
--- a/langtools/test/tools/javac/tree/SourceTreeScannerTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/tree/SourceTreeScannerTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -41,7 +41,7 @@
  *          jdk.compiler/com.sun.tools.javac.tree
  *          jdk.compiler/com.sun.tools.javac.util
  * @build AbstractTreeScannerTest SourceTreeScannerTest
- * @run main/othervm SourceTreeScannerTest -q -r .
+ * @run main SourceTreeScannerTest -q -r .
  */
 
 import java.io.*;
--- a/langtools/test/tools/javac/tree/TreePosTest.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/tree/TreePosTest.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -108,7 +108,7 @@
  *          jdk.compiler/com.sun.tools.javac.file
  *          jdk.compiler/com.sun.tools.javac.tree
  *          jdk.compiler/com.sun.tools.javac.util
- * @run main/othervm TreePosTest -q -r .
+ * @run main TreePosTest -q -r .
  */
 public class TreePosTest {
     /**
--- a/langtools/test/tools/javac/varargs/7043922/T7043922.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/javac/varargs/7043922/T7043922.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -28,7 +28,6 @@
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.file
  *          jdk.compiler/com.sun.tools.javac.util
- * @run main/othervm T7043922
  */
 
 import com.sun.source.util.JavacTask;
--- a/langtools/test/tools/jdeps/modules/SplitPackage.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/langtools/test/tools/jdeps/modules/SplitPackage.java	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 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
@@ -51,7 +51,7 @@
     private static final Path CLASSES_DIR = Paths.get("classes");
 
     private static final String SPLIT_PKG_NAME = "javax.annotation";
-    private static final String JAVA_ANNOTATIONS_COMMON = "java.annotations.common";
+    private static final String JAVA_XML_WS_ANNOTATION = "java.xml.ws.annotation";
     /**
      * Compiles classes used by the test
      */
@@ -64,7 +64,7 @@
     @Test
     public void runTest() throws Exception {
         // split package detected if java.annotation.common is in the root set
-        runTest(JAVA_ANNOTATIONS_COMMON, SPLIT_PKG_NAME);
+        runTest(JAVA_XML_WS_ANNOTATION, SPLIT_PKG_NAME);
         runTest("ALL-SYSTEM", SPLIT_PKG_NAME);
         // default
         runTest(null, SPLIT_PKG_NAME);
@@ -98,7 +98,7 @@
                 throw new RuntimeException(splitPackages.toString());
             }
 
-            // java.annotations.common is not observable
+            // java.xml.ws.annotation is not observable
             DepsAnalyzer analyzer = jdeps.getDepsAnalyzer();
 
             assertTrue(analyzer.run());
--- a/make/CompileJavaModules.gmk	Fri Feb 10 13:32:11 2017 +0530
+++ b/make/CompileJavaModules.gmk	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2017, 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
@@ -247,6 +247,10 @@
 
 ################################################################################
 
+java.management.rmi_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference '-Xdoclint/package:javax.*'
+
+################################################################################
+
 java.prefs_ADD_JAVAC_FLAGS := -Xdoclint:all/protected '-Xdoclint/package:java.*,javax.*'
 
 ################################################################################
@@ -450,7 +454,7 @@
 
 ################################################################################
 
-jdk.jvmstat_COPY := aliasmap
+jdk.internal.jvmstat_COPY := aliasmap
 
 ################################################################################
 
--- a/make/Images.gmk	Fri Feb 10 13:32:11 2017 +0530
+++ b/make/Images.gmk	Fri Feb 10 08:57:42 2017 -0800
@@ -72,6 +72,7 @@
     java.compiler \
     java.instrument \
     java.management \
+    java.management.rmi \
     java.naming \
     java.prefs \
     java.security.jgss \
--- a/make/common/Modules.gmk	Fri Feb 10 13:32:11 2017 +0530
+++ b/make/common/Modules.gmk	Fri Feb 10 08:57:42 2017 -0800
@@ -51,6 +51,7 @@
     java.instrument \
     java.logging \
     java.management \
+    java.management.rmi \
     java.naming \
     java.prefs \
     java.rmi \
@@ -58,6 +59,7 @@
     java.xml \
     jdk.httpserver \
     jdk.management \
+    jdk.management.agent \
     jdk.net \
     jdk.sctp \
     jdk.unsupported \
@@ -71,11 +73,11 @@
 
 UPGRADEABLE_MODULES += \
     java.activation \
-    java.annotations.common \
     java.corba \
     java.transaction \
     java.xml.bind \
     java.xml.ws \
+    java.xml.ws.annotation \
     #
 
 # Modules explicitly declared as not being upgradeable even though they require
--- a/make/common/NativeCompilation.gmk	Fri Feb 10 13:32:11 2017 +0530
+++ b/make/common/NativeCompilation.gmk	Fri Feb 10 08:57:42 2017 -0800
@@ -685,7 +685,7 @@
       $$($1_OBJECT_DIR)/$$($1_NOSUFFIX).comp.vardeps)
 
   ifneq ($$($1_PRECOMPILED_HEADER), )
-    ifeq ($(USE_PRECOMPILED_HEADER), 1)
+    ifeq ($(USE_PRECOMPILED_HEADER), true)
       ifeq ($(TOOLCHAIN_TYPE), microsoft)
         $1_PCH_FILE := $$($1_OBJECT_DIR)/$1.pch
         $1_GENERATED_PCH_SRC := $$($1_OBJECT_DIR)/$1_pch.cpp
--- a/nashorn/.hgtags	Fri Feb 10 13:32:11 2017 +0530
+++ b/nashorn/.hgtags	Fri Feb 10 08:57:42 2017 -0800
@@ -388,3 +388,4 @@
 ddc52e72757086a75a54371e8e7f56a3f89f1e55 jdk-9+152
 19aaaf2d02b7d6986538cd9a8c46901ecb50eebf jdk-9+153
 a84b49cfee63716975535abae2865ffef4dd6474 jdk-9+154
+f9bb37a817b3cd3b758a60f3c68258a6554eb382 jdk-9+155
--- a/nashorn/make/BuildNashorn.gmk	Fri Feb 10 13:32:11 2017 +0530
+++ b/nashorn/make/BuildNashorn.gmk	Fri Feb 10 08:57:42 2017 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2017, 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
@@ -36,12 +36,10 @@
 JDK_CLASSES := $(call PathList, $(strip $(addprefix $(JDK_OUTPUTDIR)/modules/, \
       java.base java.logging java.scripting jdk.dynalink)))
 
-NASHORN_JAR := $(IMAGES_OUTPUTDIR)/nashorn.jar
-
 MODULESOURCEPATH := $(NASHORN_TOPDIR)/src/*/share/classes
 
 # Need to use source and target 8 for nasgen to work.
-$(eval $(call SetupJavaCompiler,GENERATE_NEWBYTECODE_DEBUG, \
+$(eval $(call SetupJavaCompiler, GENERATE_NEWBYTECODE_DEBUG, \
     JVM := $(JAVA_JAVAC), \
     JAVAC := $(NEW_JAVAC), \
     FLAGS := -g -source 9 -target 9 --upgrade-module-path "$(JDK_OUTPUTDIR)/modules/" \
@@ -53,11 +51,10 @@
 # Name the compilation setup the same as the module, as is done in the global
 # CompileJavaModules.gmk, to make dependency checking with other modules work
 # seamlessly.
-$(eval $(call SetupJavaCompilation,jdk.scripting.nashorn, \
+$(eval $(call SetupJavaCompilation, jdk.scripting.nashorn, \
     SETUP := GENERATE_NEWBYTECODE_DEBUG, \
     MODULE := jdk.scripting.nashorn, \
     SRC := $(NASHORN_TOPDIR)/src/jdk.scripting.nashorn/share/classes, \
-    EXCLUDE_FILES := META-INF/MANIFEST.MF, \
     COPY := .properties .js, \
     BIN := $(SUPPORT_OUTPUTDIR)/special_classes))
 
@@ -65,7 +62,7 @@
 ASM_SRC := $(JDK_TOPDIR)/src/java.base/share/classes/jdk/internal/org/objectweb/asm
 
 # Build nasgen
-$(eval $(call SetupJavaCompilation,BUILD_NASGEN, \
+$(eval $(call SetupJavaCompilation, BUILD_NASGEN, \
     SETUP := GENERATE_OLDBYTECODE, \
     SRC := $(NASGEN_SRC) $(ASM_SRC), \
     BIN := $(BUILDTOOLS_OUTPUTDIR)/nasgen_classes))
@@ -107,21 +104,7 @@
 # Version processing needs to happen after nasgen run since nasgen run deletes it
 $(BUILD_VERSION_FILE): $(NASGEN_RUN_FILE)
 
-
-MANIFEST_ATTRIBUTES := Name: jdk/nashorn/\nImplementation-Title: Oracle Nashorn\nImplementation-Version: $(VERSION_SHORT)
-
-# Create nashorn.jar from the final classes dir
-$(eval $(call SetupJarArchive,BUILD_NASHORN_JAR, \
-    DEPENDENCIES := $(NASGEN_RUN_FILE) $(BUILD_VERSION_FILE), \
-    SRCS := $(NASHORN_CLASSES_DIR), \
-    SUFFIXES := .class .js .properties Factory, \
-    MANIFEST := $(NASHORN_TOPDIR)/src/jdk.scripting.nashorn/share/classes/META-INF/MANIFEST.MF, \
-    EXTRA_MANIFEST_ATTR := $(MANIFEST_ATTRIBUTES), \
-    SKIP_METAINF := true, \
-    JAR := $(NASHORN_JAR), \
-))
-
-compile: $(NASHORN_RUN_FILE) $(BUILD_VERSION_FILE)
-all: $(NASHORN_JAR)
+compile: $(NASGEN_RUN_FILE) $(BUILD_VERSION_FILE)
+all: compile
 
 .PHONY: compile all
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/WeighNodes.java	Fri Feb 10 08:57:42 2017 -0800
@@ -77,6 +77,7 @@
     static final long CALL_WEIGHT      = 10;
     static final long CATCH_WEIGHT     = 10;
     static final long COMPARE_WEIGHT   =  6;
+    static final long CONST_WEIGHT     =  2;
     static final long CONTINUE_WEIGHT  =  1;
     static final long IF_WEIGHT        =  2;
     static final long LITERAL_WEIGHT   = 10;
@@ -185,7 +186,7 @@
 
     @Override
     public Node leaveIdentNode(final IdentNode identNode) {
-        weight += ACCESS_WEIGHT + identNode.getName().length() * 2;
+        weight += ACCESS_WEIGHT;
         return identNode;
     }
 
@@ -210,6 +211,11 @@
     @SuppressWarnings("rawtypes")
     @Override
     public boolean enterLiteralNode(final LiteralNode literalNode) {
+        if (literalNode instanceof LiteralNode.PrimitiveLiteralNode) {
+            weight += CONST_WEIGHT;
+            return false;
+        }
+
         weight += LITERAL_WEIGHT;
 
         if (literalNode instanceof ArrayLiteralNode) {
--- a/nashorn/test/script/basic/JDK-8030182_2.js	Fri Feb 10 13:32:11 2017 +0530
+++ b/nashorn/test/script/basic/JDK-8030182_2.js	Fri Feb 10 08:57:42 2017 -0800
@@ -31,7 +31,7 @@
 var str = "";
 
 // large code to force splitting
-for (i = 0; i < 1000; ++i)
+for (i = 0; i < 2000; ++i)
     str +="o = new Object()\n";
 
 str +="g()";
--- a/test/Makefile	Fri Feb 10 13:32:11 2017 +0530
+++ b/test/Makefile	Fri Feb 10 08:57:42 2017 -0800
@@ -60,7 +60,12 @@
 -include $(TOPDIR)/closed/test/Makefile
 
 ifeq ($(TEST_JOBS), 0)
-  JDK_TEST_JOBS=$(JOBS)
+  ifeq ($(shell $(EXPR) $(JOBS) \> 50), 1)
+    # JTReg cannot handle more than 50 in concurrency
+    JDK_TEST_JOBS=50
+  else
+    JDK_TEST_JOBS=$(JOBS)
+  endif
 else
   JDK_TEST_JOBS=$(TEST_JOBS)
 endif
--- a/test/jtreg-ext/requires/VMProps.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/test/jtreg-ext/requires/VMProps.java	Fri Feb 10 08:57:42 2017 -0800
@@ -33,6 +33,8 @@
 import java.util.concurrent.Callable;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+
+import sun.hotspot.cpuinfo.CPUInfo;
 import sun.hotspot.gc.GC;
 import sun.hotspot.WhiteBox;
 
@@ -62,6 +64,8 @@
         map.put("vm.simpleArch", vmArch());
         map.put("vm.debug", vmDebug());
         map.put("vm.jvmci", vmJvmci());
+        map.put("vm.emulatedClient", vmEmulatedClient());
+        map.put("vm.cpu.features", cpuFeatures());
         vmGC(map); // vm.gc.X = true/false
 
         VMProps.dump(map);
@@ -166,6 +170,24 @@
     }
 
     /**
+     * @return true if VM runs in emulated-client mode and false otherwise.
+     */
+    protected String vmEmulatedClient() {
+        String vmInfo = System.getProperty("java.vm.info");
+        if (vmInfo == null) {
+            return "false";
+        }
+        return "" + vmInfo.contains(" emulated-client");
+    }
+
+    /**
+     * @return supported CPU features
+     */
+    protected String cpuFeatures() {
+        return CPUInfo.getFeatures().toString();
+    }
+
+    /**
      * For all existing GC sets vm.gc.X property.
      * Example vm.gc.G1=true means:
      *    VM supports G1
--- a/test/lib/jdk/test/lib/Platform.java	Fri Feb 10 13:32:11 2017 +0530
+++ b/test/lib/jdk/test/lib/Platform.java	Fri Feb 10 08:57:42 2017 -0800
@@ -63,6 +63,10 @@
         return vmName.contains("Embedded");
     }
 
+    public static boolean isEmulatedClient() {
+        return vmInfo.contains(" emulated-client");
+    }
+
     public static boolean isTieredSupported() {
         return compiler.contains("Tiered Compilers");
     }