Merge
authorprr
Thu, 12 Jan 2017 12:14:13 -0800
changeset 43092 28706e25308f
parent 43091 a03e216c92ea (current diff)
parent 43071 acc32a3bcb73 (diff)
child 43094 c39e882a5149
Merge
jdk/test/java/rmi/testlibrary/REGISTRY.java
--- a/jdk/src/java.base/share/classes/java/lang/Class.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2477,7 +2477,7 @@
      * <ul>
      *
      * <li> If the {@code name} begins with a {@code '/'}
-     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
+     * (<code>'&#92;u002f'</code>), then the absolute name of the resource is the
      * portion of the {@code name} following the {@code '/'}.
      *
      * <li> Otherwise, the absolute name is of the following form:
@@ -2488,7 +2488,7 @@
      *
      * <p> Where the {@code modified_package_name} is the package name of this
      * object with {@code '/'} substituted for {@code '.'}
-     * (<tt>'&#92;u002e'</tt>).
+     * (<code>'&#92;u002e'</code>).
      *
      * </ul>
      *
@@ -2570,7 +2570,7 @@
      * <ul>
      *
      * <li> If the {@code name} begins with a {@code '/'}
-     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
+     * (<code>'&#92;u002f'</code>), then the absolute name of the resource is the
      * portion of the {@code name} following the {@code '/'}.
      *
      * <li> Otherwise, the absolute name is of the following form:
@@ -2581,7 +2581,7 @@
      *
      * <p> Where the {@code modified_package_name} is the package name of this
      * object with {@code '/'} substituted for {@code '.'}
-     * (<tt>'&#92;u002e'</tt>).
+     * (<code>'&#92;u002e'</code>).
      *
      * </ul>
      *
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Thu Jan 12 12:14:13 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
@@ -70,34 +70,34 @@
 
 /**
  * A class loader is an object that is responsible for loading classes. The
- * class <tt>ClassLoader</tt> is an abstract class.  Given the <a
+ * class {@code ClassLoader} is an abstract class.  Given the <a
  * href="#name">binary name</a> of a class, a class loader should attempt to
  * locate or generate data that constitutes a definition for the class.  A
  * typical strategy is to transform the name into a file name and then read a
  * "class file" of that name from a file system.
  *
- * <p> Every {@link Class <tt>Class</tt>} object contains a {@link
- * Class#getClassLoader() reference} to the <tt>ClassLoader</tt> that defined
+ * <p> Every {@link java.lang.Class Class} object contains a {@link
+ * Class#getClassLoader() reference} to the {@code ClassLoader} that defined
  * it.
  *
- * <p> <tt>Class</tt> objects for array classes are not created by class
+ * <p> {@code Class} objects for array classes are not created by class
  * loaders, but are created automatically as required by the Java runtime.
  * The class loader for an array class, as returned by {@link
  * Class#getClassLoader()} is the same as the class loader for its element
  * type; if the element type is a primitive type, then the array class has no
  * class loader.
  *
- * <p> Applications implement subclasses of <tt>ClassLoader</tt> in order to
+ * <p> Applications implement subclasses of {@code ClassLoader} in order to
  * extend the manner in which the Java virtual machine dynamically loads
  * classes.
  *
  * <p> Class loaders may typically be used by security managers to indicate
  * security domains.
  *
- * <p> The <tt>ClassLoader</tt> class uses a delegation model to search for
- * classes and resources.  Each instance of <tt>ClassLoader</tt> has an
+ * <p> The {@code ClassLoader} class uses a delegation model to search for
+ * classes and resources.  Each instance of {@code ClassLoader} has an
  * associated parent class loader.  When requested to find a class or
- * resource, a <tt>ClassLoader</tt> instance will delegate the search for the
+ * resource, a {@code ClassLoader} instance will delegate the search for the
  * class or resource to its parent class loader before attempting to find the
  * class or resource itself.
  *
@@ -105,15 +105,15 @@
  * <em>{@linkplain #isRegisteredAsParallelCapable() parallel capable}</em> class
  * loaders and are required to register themselves at their class initialization
  * time by invoking the {@link
- * #registerAsParallelCapable <tt>ClassLoader.registerAsParallelCapable</tt>}
- * method. Note that the <tt>ClassLoader</tt> class is registered as parallel
+ * #registerAsParallelCapable ClassLoader.registerAsParallelCapable}
+ * method. Note that the {@code ClassLoader} class is registered as parallel
  * capable by default. However, its subclasses still need to register themselves
  * if they are parallel capable.
  * In environments in which the delegation model is not strictly
  * hierarchical, class loaders need to be parallel capable, otherwise class
  * loading can lead to deadlocks because the loader lock is held for the
  * duration of the class loading process (see {@link #loadClass
- * <tt>loadClass</tt>} methods).
+ * loadClass} methods).
  *
  * <h3> <a name="builtinLoaders">Run-time Built-in Class Loaders</a></h3>
  *
@@ -143,13 +143,13 @@
  * However, some classes may not originate from a file; they may originate
  * from other sources, such as the network, or they could be constructed by an
  * application.  The method {@link #defineClass(String, byte[], int, int)
- * <tt>defineClass</tt>} converts an array of bytes into an instance of class
- * <tt>Class</tt>. Instances of this newly defined class can be created using
- * {@link Class#newInstance <tt>Class.newInstance</tt>}.
+ * defineClass} converts an array of bytes into an instance of class
+ * {@code Class}. Instances of this newly defined class can be created using
+ * {@link Class#newInstance Class.newInstance}.
  *
  * <p> The methods and constructors of objects created by a class loader may
  * reference other classes.  To determine the class(es) referred to, the Java
- * virtual machine invokes the {@link #loadClass <tt>loadClass</tt>} method of
+ * virtual machine invokes the {@link #loadClass loadClass} method of
  * the class loader that originally created the class.
  *
  * <p> For example, an application could create a network class loader to
@@ -162,9 +162,9 @@
  * </pre></blockquote>
  *
  * <p> The network class loader subclass must define the methods {@link
- * #findClass <tt>findClass</tt>} and <tt>loadClassData</tt> to load a class
+ * #findClass findClass} and {@code loadClassData} to load a class
  * from the network.  Once it has downloaded the bytes that make up the class,
- * it should use the method {@link #defineClass <tt>defineClass</tt>} to
+ * it should use the method {@link #defineClass defineClass} to
  * create a class instance.  A sample implementation is:
  *
  * <blockquote><pre>
@@ -392,7 +392,7 @@
      *
      * <p> If there is a security manager, its {@link
      * SecurityManager#checkCreateClassLoader()
-     * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
+     * checkCreateClassLoader} method is invoked.  This may result in
      * a security exception.  </p>
      *
      * @param  parent
@@ -400,7 +400,7 @@
      *
      * @throws  SecurityException
      *          If a security manager exists and its
-     *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
+     *          {@code checkCreateClassLoader} method doesn't allow creation
      *          of a new class loader.
      *
      * @since  1.2
@@ -410,18 +410,18 @@
     }
 
     /**
-     * Creates a new class loader using the <tt>ClassLoader</tt> returned by
+     * Creates a new class loader using the {@code ClassLoader} returned by
      * the method {@link #getSystemClassLoader()
-     * <tt>getSystemClassLoader()</tt>} as the parent class loader.
+     * getSystemClassLoader()} as the parent class loader.
      *
      * <p> If there is a security manager, its {@link
      * SecurityManager#checkCreateClassLoader()
-     * <tt>checkCreateClassLoader</tt>} method is invoked.  This may result in
+     * checkCreateClassLoader} method is invoked.  This may result in
      * a security exception.  </p>
      *
      * @throws  SecurityException
      *          If a security manager exists and its
-     *          <tt>checkCreateClassLoader</tt> method doesn't allow creation
+     *          {@code checkCreateClassLoader} method doesn't allow creation
      *          of a new class loader.
      */
     protected ClassLoader() {
@@ -458,13 +458,13 @@
      * This method searches for classes in the same manner as the {@link
      * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
      * machine to resolve class references.  Invoking this method is equivalent
-     * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
-     * false)</tt>}.
+     * to invoking {@link #loadClass(String, boolean) loadClass(name,
+     * false)}.
      *
      * @param  name
      *         The <a href="#name">binary name</a> of the class
      *
-     * @return  The resulting <tt>Class</tt> object
+     * @return  The resulting {@code Class} object
      *
      * @throws  ClassNotFoundException
      *          If the class was not found
@@ -483,8 +483,8 @@
      *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
      *   has already been loaded.  </p></li>
      *
-     *   <li><p> Invoke the {@link #loadClass(String) <tt>loadClass</tt>} method
-     *   on the parent class loader.  If the parent is <tt>null</tt> the class
+     *   <li><p> Invoke the {@link #loadClass(String) loadClass} method
+     *   on the parent class loader.  If the parent is {@code null} the class
      *   loader built-in to the virtual machine is used, instead.  </p></li>
      *
      *   <li><p> Invoke the {@link #findClass(String)} method to find the
@@ -493,23 +493,23 @@
      * </ol>
      *
      * <p> If the class was found using the above steps, and the
-     * <tt>resolve</tt> flag is true, this method will then invoke the {@link
-     * #resolveClass(Class)} method on the resulting <tt>Class</tt> object.
+     * {@code resolve} flag is true, this method will then invoke the {@link
+     * #resolveClass(Class)} method on the resulting {@code Class} object.
      *
-     * <p> Subclasses of <tt>ClassLoader</tt> are encouraged to override {@link
+     * <p> Subclasses of {@code ClassLoader} are encouraged to override {@link
      * #findClass(String)}, rather than this method.  </p>
      *
      * <p> Unless overridden, this method synchronizes on the result of
-     * {@link #getClassLoadingLock <tt>getClassLoadingLock</tt>} method
+     * {@link #getClassLoadingLock getClassLoadingLock} method
      * during the entire class loading process.
      *
      * @param  name
      *         The <a href="#name">binary name</a> of the class
      *
      * @param  resolve
-     *         If <tt>true</tt> then resolve the class
+     *         If {@code true} then resolve the class
      *
-     * @return  The resulting <tt>Class</tt> object
+     * @return  The resulting {@code Class} object
      *
      * @throws  ClassNotFoundException
      *          If the class could not be found
@@ -606,7 +606,7 @@
      * @return the lock for class loading operations
      *
      * @throws NullPointerException
-     *         If registered as parallel capable and <tt>className</tt> is null
+     *         If registered as parallel capable and {@code className} is null
      *
      * @see #loadClass(String, boolean)
      *
@@ -667,14 +667,14 @@
      * Finds the class with the specified <a href="#name">binary name</a>.
      * This method should be overridden by class loader implementations that
      * follow the delegation model for loading classes, and will be invoked by
-     * the {@link #loadClass <tt>loadClass</tt>} method after checking the
+     * the {@link #loadClass loadClass} method after checking the
      * parent class loader for the requested class.  The default implementation
-     * throws a <tt>ClassNotFoundException</tt>.
+     * throws a {@code ClassNotFoundException}.
      *
      * @param  name
      *         The <a href="#name">binary name</a> of the class
      *
-     * @return  The resulting <tt>Class</tt> object
+     * @return  The resulting {@code Class} object
      *
      * @throws  ClassNotFoundException
      *          If the class could not be found
@@ -722,32 +722,32 @@
 
 
     /**
-     * Converts an array of bytes into an instance of class <tt>Class</tt>.
-     * Before the <tt>Class</tt> can be used it must be resolved.  This method
+     * Converts an array of bytes into an instance of class {@code Class}.
+     * Before the {@code Class} can be used it must be resolved.  This method
      * is deprecated in favor of the version that takes a <a
      * href="#name">binary name</a> as its first argument, and is more secure.
      *
      * @param  b
      *         The bytes that make up the class data.  The bytes in positions
-     *         <tt>off</tt> through <tt>off+len-1</tt> should have the format
+     *         {@code off} through {@code off+len-1} should have the format
      *         of a valid class file as defined by
      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
      *
      * @param  off
-     *         The start offset in <tt>b</tt> of the class data
+     *         The start offset in {@code b} of the class data
      *
      * @param  len
      *         The length of the class data
      *
-     * @return  The <tt>Class</tt> object that was created from the specified
+     * @return  The {@code Class} object that was created from the specified
      *          class data
      *
      * @throws  ClassFormatError
      *          If the data did not contain a valid class
      *
      * @throws  IndexOutOfBoundsException
-     *          If either <tt>off</tt> or <tt>len</tt> is negative, or if
-     *          <tt>off+len</tt> is greater than <tt>b.length</tt>.
+     *          If either {@code off} or {@code len} is negative, or if
+     *          {@code off+len} is greater than {@code b.length}.
      *
      * @throws  SecurityException
      *          If an attempt is made to add this class to a package that
@@ -994,11 +994,11 @@
      * #defineClass(String, byte[], int, int, ProtectionDomain)}.
      *
      * <p> An invocation of this method of the form
-     * <i>cl</i><tt>.defineClass(</tt><i>name</i><tt>,</tt>
-     * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
+     * <i>cl</i>{@code .defineClass(}<i>name</i>{@code ,}
+     * <i>bBuffer</i>{@code ,} <i>pd</i>{@code )} yields exactly the same
      * result as the statements
      *
-     *<p> <tt>
+     *<p> <code>
      * ...<br>
      * byte[] temp = new byte[bBuffer.{@link
      * java.nio.ByteBuffer#remaining remaining}()];<br>
@@ -1007,16 +1007,16 @@
      *     return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
      * cl.defineClass}(name, temp, 0,
      * temp.length, pd);<br>
-     * </tt></p>
+     * </code></p>
      *
      * @param  name
      *         The expected <a href="#name">binary name</a>. of the class, or
-     *         <tt>null</tt> if not known
+     *         {@code null} if not known
      *
      * @param  b
      *         The bytes that make up the class data. The bytes from positions
-     *         <tt>b.position()</tt> through <tt>b.position() + b.limit() -1
-     *         </tt> should have the format of a valid class file as defined by
+     *         {@code b.position()} through {@code b.position() + b.limit() -1
+     *         } should have the format of a valid class file as defined by
      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
      *
      * @param  protectionDomain
@@ -1158,7 +1158,7 @@
 
     /**
      * Links the specified class.  This (misleadingly named) method may be
-     * used by a class loader to link a class.  If the class <tt>c</tt> has
+     * used by a class loader to link a class.  If the class {@code c} has
      * already been linked, then this method simply returns. Otherwise, the
      * class is linked as described in the "Execution" chapter of
      * <cite>The Java&trade; Language Specification</cite>.
@@ -1167,7 +1167,7 @@
      *         The class to link
      *
      * @throws  NullPointerException
-     *          If <tt>c</tt> is <tt>null</tt>.
+     *          If {@code c} is {@code null}.
      *
      * @see  #defineClass(String, byte[], int, int)
      */
@@ -1182,16 +1182,16 @@
      * loading it if necessary.
      *
      * <p> This method loads the class through the system class loader (see
-     * {@link #getSystemClassLoader()}).  The <tt>Class</tt> object returned
-     * might have more than one <tt>ClassLoader</tt> associated with it.
-     * Subclasses of <tt>ClassLoader</tt> need not usually invoke this method,
+     * {@link #getSystemClassLoader()}).  The {@code Class} object returned
+     * might have more than one {@code ClassLoader} associated with it.
+     * Subclasses of {@code ClassLoader} need not usually invoke this method,
      * because most class loaders need to override just {@link
      * #findClass(String)}.  </p>
      *
      * @param  name
      *         The <a href="#name">binary name</a> of the class
      *
-     * @return  The <tt>Class</tt> object for the specified <tt>name</tt>
+     * @return  The {@code Class} object for the specified {@code name}
      *
      * @throws  ClassNotFoundException
      *          If the class could not be found
@@ -1222,12 +1222,12 @@
      * Returns the class with the given <a href="#name">binary name</a> if this
      * loader has been recorded by the Java virtual machine as an initiating
      * loader of a class with that <a href="#name">binary name</a>.  Otherwise
-     * <tt>null</tt> is returned.
+     * {@code null} is returned.
      *
      * @param  name
      *         The <a href="#name">binary name</a> of the class
      *
-     * @return  The <tt>Class</tt> object, or <tt>null</tt> if the class has
+     * @return  The {@code Class} object, or {@code null} if the class has
      *          not been loaded
      *
      * @since  1.1
@@ -1245,7 +1245,7 @@
      * class.
      *
      * @param  c
-     *         The <tt>Class</tt> object
+     *         The {@code Class} object
      *
      * @param  signers
      *         The signers for the class
@@ -1306,11 +1306,11 @@
      * (images, audio, text, etc) that can be accessed by class code in a way
      * that is independent of the location of the code.
      *
-     * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
+     * <p> The name of a resource is a '{@code /}'-separated path name that
      * identifies the resource.
      *
      * <p> This method will first search the parent class loader for the
-     * resource; if the parent is <tt>null</tt> the path of the class loader
+     * resource; if the parent is {@code null} the path of the class loader
      * built-in to the virtual machine is searched.  That failing, this method
      * will invoke {@link #findResource(String)} to find the resource.  </p>
      *
@@ -1362,7 +1362,7 @@
      * (images, audio, text, etc) that can be accessed by class code in a way
      * that is independent of the location of the code.
      *
-     * <p> The name of a resource is a <tt>/</tt>-separated path name that
+     * <p> The name of a resource is a {@code /}-separated path name that
      * identifies the resource.
      *
      * <p> The delegation order for searching is described in the documentation
@@ -1389,7 +1389,7 @@
      * @param  name
      *         The resource name
      *
-     * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+     * @return  An enumeration of {@link java.net.URL URL} objects for
      *          the resource. If no resources could  be found, the enumeration
      *          will be empty. Resources for which a {@code URL} cannot be
      *          constructed, are in package that is not opened unconditionally,
@@ -1505,7 +1505,7 @@
     }
 
     /**
-     * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
+     * Returns an enumeration of {@link java.net.URL URL} objects
      * representing all the resources with the given name. Class loader
      * implementations should override this method to specify where to load
      * resources from.
@@ -1520,7 +1520,7 @@
      * @param  name
      *         The resource name
      *
-     * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+     * @return  An enumeration of {@link java.net.URL URL} objects for
      *          the resource. If no resources could  be found, the enumeration
      *          will be empty. Resources for which a {@code URL} cannot be
      *          constructed, are in a package that is not opened unconditionally,
@@ -1594,7 +1594,7 @@
      * @param  name
      *         The resource name
      *
-     * @return  A {@link java.net.URL <tt>URL</tt>} to the resource; {@code
+     * @return  A {@link java.net.URL URL} to the resource; {@code
      *          null} if the resource could not be found, a URL could not be
      *          constructed to locate the resource, the resource is in a package
      *          that is not opened unconditionally or access to the resource is
@@ -1609,8 +1609,8 @@
     /**
      * Finds all resources of the specified name from the search path used to
      * load classes.  The resources thus found are returned as an
-     * {@link java.util.Enumeration <tt>Enumeration</tt>} of {@link
-     * java.net.URL <tt>URL</tt>} objects.
+     * {@link java.util.Enumeration Enumeration} of {@link
+     * java.net.URL URL} objects.
      *
      * <p> The search order is described in the documentation for {@link
      * #getSystemResource(String)}.  </p>
@@ -1625,7 +1625,7 @@
      * @param  name
      *         The resource name
      *
-     * @return  An enumeration of {@link java.net.URL <tt>URL</tt>} objects for
+     * @return  An enumeration of {@link java.net.URL URL} objects for
      *          the resource. If no resources could  be found, the enumeration
      *          will be empty. Resources for which a {@code URL} cannot be
      *          constructed, are in a package that is not opened unconditionally,
@@ -1714,11 +1714,11 @@
 
     /**
      * Returns the parent class loader for delegation. Some implementations may
-     * use <tt>null</tt> to represent the bootstrap class loader. This method
-     * will return <tt>null</tt> in such implementations if this class loader's
+     * use {@code null} to represent the bootstrap class loader. This method
+     * will return {@code null} in such implementations if this class loader's
      * parent is the bootstrap class loader.
      *
-     * @return  The parent <tt>ClassLoader</tt>
+     * @return  The parent {@code ClassLoader}
      *
      * @throws  SecurityException
      *          If a security manager is present, and the caller's class loader
@@ -1785,7 +1785,7 @@
 
     /**
      * Returns the system class loader for delegation.  This is the default
-     * delegation parent for new <tt>ClassLoader</tt> instances, and is
+     * delegation parent for new {@code ClassLoader} instances, and is
      * typically the class loader used to start the application.
      *
      * <p> This method is first invoked early in the runtime's startup
@@ -1797,12 +1797,12 @@
      * <p> The default system class loader is an implementation-dependent
      * instance of this class.
      *
-     * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
+     * <p> If the system property "{@code java.system.class.loader}" is defined
      * when this method is first invoked then the value of that property is
      * taken to be the name of a class that will be returned as the system
      * class loader.  The class is loaded using the default system class loader
      * and must define a public constructor that takes a single parameter of
-     * type <tt>ClassLoader</tt> which is used as the delegation parent.  An
+     * type {@code ClassLoader} which is used as the delegation parent.  An
      * instance is then created using this constructor with the default system
      * class loader as the parameter.  The resulting class loader is defined
      * to be the system class loader. During construction, the class loader
@@ -1825,7 +1825,7 @@
      * the application module path then the class path defaults to
      * the current working directory.
      *
-     * @return  The system <tt>ClassLoader</tt> for delegation
+     * @return  The system {@code ClassLoader} for delegation
      *
      * @throws  SecurityException
      *          If a security manager is present, and the caller's class loader
@@ -1835,11 +1835,11 @@
      *
      * @throws  IllegalStateException
      *          If invoked recursively during the construction of the class
-     *          loader specified by the "<tt>java.system.class.loader</tt>"
+     *          loader specified by the "{@code java.system.class.loader}"
      *          property.
      *
      * @throws  Error
-     *          If the system property "<tt>java.system.class.loader</tt>"
+     *          If the system property "{@code java.system.class.loader}"
      *          is defined but the named class could not be loaded, the
      *          provider class does not define the required constructor, or an
      *          exception is thrown by that constructor when it is invoked. The
@@ -2249,9 +2249,9 @@
     /**
      * Returns the absolute path name of a native library.  The VM invokes this
      * method to locate the native libraries that belong to classes loaded with
-     * this class loader. If this method returns <tt>null</tt>, the VM
+     * this class loader. If this method returns {@code null}, the VM
      * searches the library along the path specified as the
-     * "<tt>java.library.path</tt>" property.
+     * "{@code java.library.path}" property.
      *
      * @param  libname
      *         The library name
@@ -2270,12 +2270,12 @@
     /**
      * The inner class NativeLibrary denotes a loaded native library instance.
      * Every classloader contains a vector of loaded native libraries in the
-     * private field <tt>nativeLibraries</tt>.  The native libraries loaded
-     * into the system are entered into the <tt>systemNativeLibraries</tt>
+     * private field {@code nativeLibraries}.  The native libraries loaded
+     * into the system are entered into the {@code systemNativeLibraries}
      * vector.
      *
      * <p> Every native library requires a particular version of JNI. This is
-     * denoted by the private <tt>jniVersion</tt> field.  This field is set by
+     * denoted by the private {@code jniVersion} field.  This field is set by
      * the VM when it loads the library, and used by the VM to pass the correct
      * version of JNI to the native methods.  </p>
      *
@@ -2592,8 +2592,8 @@
      * #setClassAssertionStatus(String, boolean)}.
      *
      * @param  enabled
-     *         <tt>true</tt> if classes loaded by this class loader will
-     *         henceforth have assertions enabled by default, <tt>false</tt>
+     *         {@code true} if classes loaded by this class loader will
+     *         henceforth have assertions enabled by default, {@code false}
      *         if they will have assertions disabled by default.
      *
      * @since  1.4
@@ -2614,16 +2614,16 @@
      * any of its "subpackages".
      *
      * <p> A subpackage of a package named p is any package whose name begins
-     * with "<tt>p.</tt>".  For example, <tt>javax.swing.text</tt> is a
-     * subpackage of <tt>javax.swing</tt>, and both <tt>java.util</tt> and
-     * <tt>java.lang.reflect</tt> are subpackages of <tt>java</tt>.
+     * with "{@code p.}".  For example, {@code javax.swing.text} is a
+     * subpackage of {@code javax.swing}, and both {@code java.util} and
+     * {@code java.lang.reflect} are subpackages of {@code java}.
      *
      * <p> In the event that multiple package defaults apply to a given class,
      * the package default pertaining to the most specific package takes
-     * precedence over the others.  For example, if <tt>javax.lang</tt> and
-     * <tt>javax.lang.reflect</tt> both have package defaults associated with
+     * precedence over the others.  For example, if {@code javax.lang} and
+     * {@code javax.lang.reflect} both have package defaults associated with
      * them, the latter package default applies to classes in
-     * <tt>javax.lang.reflect</tt>.
+     * {@code javax.lang.reflect}.
      *
      * <p> Package defaults take precedence over the class loader's default
      * assertion status, and may be overridden on a per-class basis by invoking
@@ -2631,15 +2631,15 @@
      *
      * @param  packageName
      *         The name of the package whose package default assertion status
-     *         is to be set. A <tt>null</tt> value indicates the unnamed
+     *         is to be set. A {@code null} value indicates the unnamed
      *         package that is "current"
      *         (see section 7.4.2 of
      *         <cite>The Java&trade; Language Specification</cite>.)
      *
      * @param  enabled
-     *         <tt>true</tt> if classes loaded by this classloader and
+     *         {@code true} if classes loaded by this classloader and
      *         belonging to the named package or any of its subpackages will
-     *         have assertions enabled by default, <tt>false</tt> if they will
+     *         have assertions enabled by default, {@code false} if they will
      *         have assertions disabled by default.
      *
      * @since  1.4
@@ -2670,8 +2670,8 @@
      *         assertion status is to be set.
      *
      * @param  enabled
-     *         <tt>true</tt> if the named class is to have assertions
-     *         enabled when (and if) it is initialized, <tt>false</tt> if the
+     *         {@code true} if the named class is to have assertions
+     *         enabled when (and if) it is initialized, {@code false} if the
      *         class is to have assertions disabled.
      *
      * @since  1.4
@@ -2687,7 +2687,7 @@
 
     /**
      * Sets the default assertion status for this class loader to
-     * <tt>false</tt> and discards any package defaults or class assertion
+     * {@code false} and discards any package defaults or class assertion
      * status settings associated with the class loader.  This method is
      * provided so that class loaders can be made to ignore any command line or
      * persistent assertion status settings and "start with a clean slate."
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java	Thu Jan 12 12:14:13 2017 -0800
@@ -30,8 +30,10 @@
 import java.io.OutputStream;
 import java.security.PrivilegedAction;
 import java.util.Hashtable;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.Date;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.Objects;
 import java.util.ServiceConfigurationError;
 import java.util.ServiceLoader;
@@ -231,7 +233,7 @@
      */
     protected boolean allowUserInteraction = defaultAllowUserInteraction;
 
-    private static boolean defaultUseCaches = true;
+    private static volatile boolean defaultUseCaches = true;
 
    /**
      * If {@code true}, the protocol is allowed to use caching
@@ -243,12 +245,18 @@
      * <p>
      * Its default value is the value given in the last invocation of the
      * {@code setDefaultUseCaches} method.
+     * <p>
+     * The default setting may be overridden per protocol with
+     * {@link #setDefaultUseCaches(String,boolean)}.
      *
      * @see     java.net.URLConnection#setUseCaches(boolean)
      * @see     java.net.URLConnection#getUseCaches()
      * @see     java.net.URLConnection#setDefaultUseCaches(boolean)
      */
-    protected boolean useCaches = defaultUseCaches;
+    protected boolean useCaches;
+
+    private static final ConcurrentHashMap<String,Boolean> defaultCaching =
+        new ConcurrentHashMap<>();
 
    /**
      * Some protocols support skipping the fetching of the object unless
@@ -460,6 +468,11 @@
      */
     protected URLConnection(URL url) {
         this.url = url;
+        if (url == null) {
+            this.useCaches = defaultUseCaches;
+        } else {
+            this.useCaches = getDefaultUseCaches(url.getProtocol());
+        }
     }
 
     /**
@@ -981,7 +994,8 @@
      * is true, the connection is allowed to use whatever caches it can.
      *  If false, caches are to be ignored.
      *  The default value comes from DefaultUseCaches, which defaults to
-     * true.
+     * true. A default value can also be set per-protocol using
+     * {@link #setDefaultUseCaches(String,boolean)}.
      *
      * @param usecaches a {@code boolean} indicating whether
      * or not to allow caching
@@ -1032,9 +1046,10 @@
      * Returns the default value of a {@code URLConnection}'s
      * {@code useCaches} flag.
      * <p>
-     * Ths default is "sticky", being a part of the static state of all
+     * This default is "sticky", being a part of the static state of all
      * URLConnections.  This flag applies to the next, and all following
-     * URLConnections that are created.
+     * URLConnections that are created. This default value can be over-ridden
+     * per protocol using {@link #setDefaultUseCaches(String,boolean)}
      *
      * @return  the default value of a {@code URLConnection}'s
      *          {@code useCaches} flag.
@@ -1046,7 +1061,8 @@
 
    /**
      * Sets the default value of the {@code useCaches} field to the
-     * specified value.
+     * specified value. This default value can be over-ridden
+     * per protocol using {@link #setDefaultUseCaches(String,boolean)}
      *
      * @param   defaultusecaches   the new value.
      * @see     #getDefaultUseCaches()
@@ -1055,6 +1071,43 @@
         defaultUseCaches = defaultusecaches;
     }
 
+   /**
+     * Sets the default value of the {@code useCaches} field for the named
+     * protocol to the given value. This value overrides any default setting
+     * set by {@link #setDefaultUseCaches(boolean)} for the given protocol.
+     * Successive calls to this method change the setting and affect the
+     * default value for all future connections of that protocol. The protocol
+     * name is case insensitive.
+     *
+     * @param   protocol the protocol to set the default for
+     * @param   defaultVal whether caching is enabled by default for the given protocol
+     * @since 9
+     */
+    public static void setDefaultUseCaches(String protocol, boolean defaultVal) {
+        protocol = protocol.toLowerCase(Locale.US);
+        defaultCaching.put(protocol, defaultVal);
+    }
+
+   /**
+     * Returns the default value of the {@code useCaches} flag for the given protocol. If
+     * {@link #setDefaultUseCaches(String,boolean)} was called for the given protocol,
+     * then that value is returned. Otherwise, if {@link #setDefaultUseCaches(boolean)}
+     * was called, then that value is returned. If neither method was called,
+     * the return value is {@code true}. The protocol name is case insensitive.
+     *
+     * @param protocol the protocol whose defaultUseCaches setting is required
+     * @return  the default value of the {@code useCaches} flag for the given protocol.
+     * @since 9
+     */
+    public static boolean getDefaultUseCaches(String protocol) {
+        Boolean protoDefault = defaultCaching.get(protocol.toLowerCase(Locale.US));
+        if (protoDefault != null) {
+            return protoDefault.booleanValue();
+        } else {
+            return defaultUseCaches;
+        }
+    }
+
     /**
      * Sets the general request property. If a property with the key already
      * exists, overwrite its value with the new value.
--- a/jdk/src/java.base/share/classes/java/util/Collections.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Collections.java	Thu Jan 12 12:14:13 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
@@ -4354,6 +4354,11 @@
         private Object readResolve() {
             return EMPTY_SET;
         }
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
     }
 
     /**
@@ -4786,6 +4791,10 @@
         public boolean removeIf(Predicate<? super E> filter) {
             throw new UnsupportedOperationException();
         }
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(element);
+        }
     }
 
     /**
@@ -4848,6 +4857,10 @@
         public Spliterator<E> spliterator() {
             return singletonSpliterator(element);
         }
+        @Override
+        public int hashCode() {
+            return 31 + Objects.hashCode(element);
+        }
     }
 
     /**
@@ -4970,6 +4983,11 @@
                 BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
             throw new UnsupportedOperationException();
         }
+
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(k) ^ Objects.hashCode(v);
+        }
     }
 
     // Miscellaneous
--- a/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/ImmutableCollections.java	Thu Jan 12 12:14:13 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
@@ -35,6 +35,7 @@
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
+import jdk.internal.vm.annotation.Stable;
 
 /**
  * Container class for immutable collections. Not part of the public API.
@@ -105,6 +106,11 @@
             return null;                  // but the compiler doesn't know this
         }
 
+        @Override
+        public Iterator<E> iterator() {
+            return Collections.emptyIterator();
+        }
+
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
             throw new InvalidObjectException("not serial proxy");
         }
@@ -112,9 +118,26 @@
         private Object writeReplace() {
             return new CollSer(CollSer.IMM_LIST);
         }
+
+        @Override
+        public boolean contains(Object o) {
+            Objects.requireNonNull(o);
+            return false;
+        }
+
+        @Override
+        public boolean containsAll(Collection<?> o) {
+            return o.isEmpty(); // implicit nullcheck of o
+        }
+
+        @Override
+        public int hashCode() {
+            return 1;
+        }
     }
 
     static final class List1<E> extends AbstractImmutableList<E> {
+        @Stable
         private final E e0;
 
         List1(E e0) {
@@ -129,7 +152,6 @@
         @Override
         public E get(int index) {
             Objects.checkIndex(index, 1);
-            // assert index == 0
             return e0;
         }
 
@@ -140,10 +162,22 @@
         private Object writeReplace() {
             return new CollSer(CollSer.IMM_LIST, e0);
         }
+
+        @Override
+        public boolean contains(Object o) {
+            return o.equals(e0); // implicit nullcheck of o
+        }
+
+        @Override
+        public int hashCode() {
+            return 31 + e0.hashCode();
+        }
     }
 
     static final class List2<E> extends AbstractImmutableList<E> {
+        @Stable
         private final E e0;
+        @Stable
         private final E e1;
 
         List2(E e0, E e1) {
@@ -166,6 +200,17 @@
             }
         }
 
+        @Override
+        public boolean contains(Object o) {
+            return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 31 + e0.hashCode();
+            return 31 * hash + e1.hashCode();
+        }
+
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
             throw new InvalidObjectException("not serial proxy");
         }
@@ -176,6 +221,7 @@
     }
 
     static final class ListN<E> extends AbstractImmutableList<E> {
+        @Stable
         private final E[] elements;
 
         @SafeVarargs
@@ -200,6 +246,25 @@
             return elements[index];
         }
 
+        @Override
+        public boolean contains(Object o) {
+            for (E e : elements) {
+                if (o.equals(e)) { // implicit nullcheck of o
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 1;
+            for (E e : elements) {
+                hash = 31 * hash + e.hashCode();
+            }
+            return hash;
+        }
+
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
             throw new InvalidObjectException("not serial proxy");
         }
@@ -238,7 +303,13 @@
 
         @Override
         public boolean contains(Object o) {
-            return super.contains(Objects.requireNonNull(o));
+            Objects.requireNonNull(o);
+            return false;
+        }
+
+        @Override
+        public boolean containsAll(Collection<?> o) {
+            return o.isEmpty(); // implicit nullcheck of o
         }
 
         @Override
@@ -253,9 +324,15 @@
         private Object writeReplace() {
             return new CollSer(CollSer.IMM_SET);
         }
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
     }
 
     static final class Set1<E> extends AbstractImmutableSet<E> {
+        @Stable
         private final E e0;
 
         Set1(E e0) {
@@ -269,7 +346,7 @@
 
         @Override
         public boolean contains(Object o) {
-            return super.contains(Objects.requireNonNull(o));
+            return o.equals(e0); // implicit nullcheck of o
         }
 
         @Override
@@ -284,17 +361,21 @@
         private Object writeReplace() {
             return new CollSer(CollSer.IMM_SET, e0);
         }
+
+        @Override
+        public int hashCode() {
+            return e0.hashCode();
+        }
     }
 
     static final class Set2<E> extends AbstractImmutableSet<E> {
-        private final E e0;
-        private final E e1;
+        @Stable
+        final E e0;
+        @Stable
+        final E e1;
 
         Set2(E e0, E e1) {
-            Objects.requireNonNull(e0);
-            Objects.requireNonNull(e1);
-
-            if (e0.equals(e1)) {
+            if (e0.equals(Objects.requireNonNull(e1))) { // implicit nullcheck of e0
                 throw new IllegalArgumentException("duplicate element: " + e0);
             }
 
@@ -314,7 +395,12 @@
 
         @Override
         public boolean contains(Object o) {
-            return super.contains(Objects.requireNonNull(o));
+            return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
+        }
+
+        @Override
+        public int hashCode() {
+            return e0.hashCode() + e1.hashCode();
         }
 
         @Override
@@ -358,8 +444,10 @@
      * @param <E> the element type
      */
     static final class SetN<E> extends AbstractImmutableSet<E> {
-        private final E[] elements;
-        private final int size;
+        @Stable
+        final E[] elements;
+        @Stable
+        final int size;
 
         @SafeVarargs
         @SuppressWarnings("unchecked")
@@ -368,8 +456,8 @@
 
             elements = (E[])new Object[EXPAND_FACTOR * input.length];
             for (int i = 0; i < input.length; i++) {
-                E e = Objects.requireNonNull(input[i]);
-                int idx = probe(e);
+                E e = input[i];
+                int idx = probe(e); // implicit nullcheck of e
                 if (idx >= 0) {
                     throw new IllegalArgumentException("duplicate element: " + e);
                 } else {
@@ -385,8 +473,7 @@
 
         @Override
         public boolean contains(Object o) {
-            Objects.requireNonNull(o);
-            return probe(o) >= 0;
+            return probe(o) >= 0; // implicit nullcheck of o
         }
 
         @Override
@@ -414,8 +501,21 @@
             };
         }
 
+        @Override
+        public int hashCode() {
+            int h = 0;
+            for (E e : elements) {
+                if (e != null) {
+                    h += e.hashCode();
+                }
+            }
+            return h;
+        }
+
         // returns index at which element is present; or if absent,
-        // (-i - 1) where i is location where element should be inserted
+        // (-i - 1) where i is location where element should be inserted.
+        // Callers are relying on this method to perform an implicit nullcheck
+        // of pe
         private int probe(Object pe) {
             int idx = Math.floorMod(pe.hashCode() ^ SALT, elements.length);
             while (true) {
@@ -481,12 +581,14 @@
 
         @Override
         public boolean containsKey(Object o) {
-            return super.containsKey(Objects.requireNonNull(o));
+            Objects.requireNonNull(o);
+            return false;
         }
 
         @Override
         public boolean containsValue(Object o) {
-            return super.containsValue(Objects.requireNonNull(o));
+            Objects.requireNonNull(o);
+            return false;
         }
 
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -496,10 +598,17 @@
         private Object writeReplace() {
             return new CollSer(CollSer.IMM_MAP);
         }
+
+        @Override
+        public int hashCode() {
+            return 0;
+        }
     }
 
     static final class Map1<K,V> extends AbstractImmutableMap<K,V> {
+        @Stable
         private final K k0;
+        @Stable
         private final V v0;
 
         Map1(K k0, V v0) {
@@ -514,12 +623,12 @@
 
         @Override
         public boolean containsKey(Object o) {
-            return super.containsKey(Objects.requireNonNull(o));
+            return o.equals(k0); // implicit nullcheck of o
         }
 
         @Override
         public boolean containsValue(Object o) {
-            return super.containsValue(Objects.requireNonNull(o));
+            return o.equals(v0); // implicit nullcheck of o
         }
 
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -529,6 +638,11 @@
         private Object writeReplace() {
             return new CollSer(CollSer.IMM_MAP, k0, v0);
         }
+
+        @Override
+        public int hashCode() {
+            return k0.hashCode() ^ v0.hashCode();
+        }
     }
 
     /**
@@ -541,12 +655,13 @@
      * @param <V> the value type
      */
     static final class MapN<K,V> extends AbstractImmutableMap<K,V> {
-        private final Object[] table; // pairs of key, value
-        private final int size; // number of pairs
+        @Stable
+        final Object[] table; // pairs of key, value
+        @Stable
+        final int size; // number of pairs
 
         MapN(Object... input) {
-            Objects.requireNonNull(input);
-            if ((input.length & 1) != 0) {
+            if ((input.length & 1) != 0) { // implicit nullcheck of input
                 throw new InternalError("length is odd");
             }
             size = input.length >> 1;
@@ -573,12 +688,30 @@
 
         @Override
         public boolean containsKey(Object o) {
-            return probe(Objects.requireNonNull(o)) >= 0;
+            return probe(o) >= 0; // implicit nullcheck of o
         }
 
         @Override
         public boolean containsValue(Object o) {
-            return super.containsValue(Objects.requireNonNull(o));
+            for (int i = 1; i < table.length; i += 2) {
+                Object v = table[i];
+                if (v != null && o.equals(v)) { // implicit nullcheck of o
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 0;
+            for (int i = 0; i < table.length; i += 2) {
+                Object k = table[i];
+                if (k != null) {
+                    hash += k.hashCode() ^ table[i + 1].hashCode();
+                }
+            }
+            return hash;
         }
 
         @Override
@@ -638,7 +771,9 @@
         }
 
         // returns index at which the probe key is present; or if absent,
-        // (-i - 1) where i is location where element should be inserted
+        // (-i - 1) where i is location where element should be inserted.
+        // Callers are relying on this method to perform an implicit nullcheck
+        // of pk.
         private int probe(Object pk) {
             int idx = Math.floorMod(pk.hashCode() ^ SALT, table.length >> 1) << 1;
             while (true) {
--- a/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java	Thu Jan 12 12:14:13 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
@@ -25,6 +25,8 @@
 
 package java.util;
 
+import jdk.internal.vm.annotation.Stable;
+
 /**
  * An immutable container for a key and a value, suitable for use
  * in creating and populating {@code Map} instances.
@@ -48,7 +50,9 @@
  * @since 9
  */
 final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
+    @Stable
     final K key;
+    @Stable
     final V value;
 
     KeyValueHolder(K k, V v) {
--- a/jdk/src/java.base/share/classes/java/util/List.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/List.java	Thu Jan 12 12:14:13 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
@@ -1027,8 +1027,7 @@
     @SafeVarargs
     @SuppressWarnings("varargs")
     static <E> List<E> of(E... elements) {
-        Objects.requireNonNull(elements);
-        switch (elements.length) {
+        switch (elements.length) { // implicit null check of elements
             case 0:
                 return ImmutableCollections.List0.instance();
             case 1:
--- a/jdk/src/java.base/share/classes/java/util/Map.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Map.java	Thu Jan 12 12:14:13 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
@@ -1602,8 +1602,7 @@
     @SafeVarargs
     @SuppressWarnings("varargs")
     static <K, V> Map<K, V> ofEntries(Entry<? extends K, ? extends V>... entries) {
-        Objects.requireNonNull(entries);
-        if (entries.length == 0) {
+        if (entries.length == 0) { // implicit null check of entries
             return ImmutableCollections.Map0.instance();
         } else if (entries.length == 1) {
             return new ImmutableCollections.Map1<>(entries[0].getKey(),
--- a/jdk/src/java.base/share/classes/java/util/Set.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Set.java	Thu Jan 12 12:14:13 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
@@ -689,8 +689,7 @@
     @SafeVarargs
     @SuppressWarnings("varargs")
     static <E> Set<E> of(E... elements) {
-        Objects.requireNonNull(elements);
-        switch (elements.length) {
+        switch (elements.length) { // implicit null check of elements
             case 0:
                 return ImmutableCollections.Set0.instance();
             case 1:
--- a/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, 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
@@ -362,59 +362,81 @@
     }
 
     /**
-     * Main program to start a registry. <br>
-     * The port number can be specified on the command line.
+     * Return a new RegistryImpl on the requested port and export it to serve
+     * registry requests. A classloader is initialized from the system property
+     * "env.class.path" and a security manager is set unless one is already set.
+     * <p>
+     * The returned Registry is fully functional within the current process and
+     * is usable for internal and testing purposes.
+     *
+     * @param regPort port on which the rmiregistry accepts requests;
+     *                if 0, an implementation specific port is assigned
+     * @return a RegistryImpl instance
+     * @exception RemoteException If remote operation failed.
+     * @since 9
      */
-    public static void main(String args[])
-    {
+    public static RegistryImpl createRegistry(int regPort) throws RemoteException {
         // Create and install the security manager if one is not installed
         // already.
         if (System.getSecurityManager() == null) {
             System.setSecurityManager(new SecurityManager());
         }
 
+        /*
+         * Fix bugid 4147561: When JDK tools are executed, the value of
+         * the CLASSPATH environment variable for the shell in which they
+         * were invoked is no longer incorporated into the application
+         * class path; CLASSPATH's only effect is to be the value of the
+         * system property "env.class.path".  To preserve the previous
+         * (JDK1.1 and JDK1.2beta3) behavior of this tool, however, its
+         * CLASSPATH should still be considered when resolving classes
+         * being unmarshalled.  To effect this old behavior, a class
+         * loader that loads from the file path specified in the
+         * "env.class.path" property is created and set to be the context
+         * class loader before the remote object is exported.
+         */
+        String envcp = System.getProperty("env.class.path");
+        if (envcp == null) {
+            envcp = ".";            // preserve old default behavior
+        }
+        URL[] urls = pathToURLs(envcp);
+        ClassLoader cl = new URLClassLoader(urls);
+
+        /*
+         * Fix bugid 4242317: Classes defined by this class loader should
+         * be annotated with the value of the "java.rmi.server.codebase"
+         * property, not the "file:" URLs for the CLASSPATH elements.
+         */
+        sun.rmi.server.LoaderHandler.registerCodebaseLoader(cl);
+
+        Thread.currentThread().setContextClassLoader(cl);
+
+        RegistryImpl registryImpl = null;
         try {
-            /*
-             * Fix bugid 4147561: When JDK tools are executed, the value of
-             * the CLASSPATH environment variable for the shell in which they
-             * were invoked is no longer incorporated into the application
-             * class path; CLASSPATH's only effect is to be the value of the
-             * system property "env.class.path".  To preserve the previous
-             * (JDK1.1 and JDK1.2beta3) behavior of this tool, however, its
-             * CLASSPATH should still be considered when resolving classes
-             * being unmarshalled.  To effect this old behavior, a class
-             * loader that loads from the file path specified in the
-             * "env.class.path" property is created and set to be the context
-             * class loader before the remote object is exported.
-             */
-            String envcp = System.getProperty("env.class.path");
-            if (envcp == null) {
-                envcp = ".";            // preserve old default behavior
-            }
-            URL[] urls = pathToURLs(envcp);
-            ClassLoader cl = new URLClassLoader(urls);
+            registryImpl = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<RegistryImpl>() {
+                    public RegistryImpl run() throws RemoteException {
+                        return new RegistryImpl(regPort);
+                    }
+                }, getAccessControlContext(regPort));
+        } catch (PrivilegedActionException ex) {
+            throw (RemoteException) ex.getException();
+        }
 
-            /*
-             * Fix bugid 4242317: Classes defined by this class loader should
-             * be annotated with the value of the "java.rmi.server.codebase"
-             * property, not the "file:" URLs for the CLASSPATH elements.
-             */
-            sun.rmi.server.LoaderHandler.registerCodebaseLoader(cl);
+        return registryImpl;
+    }
 
-            Thread.currentThread().setContextClassLoader(cl);
-
+    /**
+     * Main program to start a registry. <br>
+     * The port number can be specified on the command line.
+     */
+    public static void main(String args[])
+    {
+        try {
             final int regPort = (args.length >= 1) ? Integer.parseInt(args[0])
                                                    : Registry.REGISTRY_PORT;
-            try {
-                registry = AccessController.doPrivileged(
-                    new PrivilegedExceptionAction<RegistryImpl>() {
-                        public RegistryImpl run() throws RemoteException {
-                            return new RegistryImpl(regPort);
-                        }
-                    }, getAccessControlContext(regPort));
-            } catch (PrivilegedActionException ex) {
-                throw (RemoteException) ex.getException();
-            }
+
+            registry = createRegistry(regPort);
 
             // prevent registry from exiting
             while (true) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1088,34 +1088,58 @@
         }
     }
 
-    static class ClassPathConverter implements ValueConverter<Path> {
-        static final ValueConverter<Path> INSTANCE = new ClassPathConverter();
+    /**
+     * An abstract converter that given a string representing a list of paths,
+     * separated by the File.pathSeparator, returns a List of java.nio.Path's.
+     * Specific subclasses should do whatever validation is required on the
+     * individual path elements, if any.
+     */
+    static abstract class AbstractPathConverter implements ValueConverter<List<Path>> {
+        @Override
+        public List<Path> convert(String value) {
+            List<Path> paths = new ArrayList<>();
+            String[] pathElements = value.split(File.pathSeparator);
+            for (String pathElement : pathElements) {
+                paths.add(toPath(pathElement));
+            }
+            return paths;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public Class<List<Path>> valueType() {
+            return (Class<List<Path>>)(Object)List.class;
+        }
+
+        @Override public String valuePattern() { return "path"; }
+
+        abstract Path toPath(String path);
+    }
+
+    static class ClassPathConverter extends AbstractPathConverter {
+        static final ValueConverter<List<Path>> INSTANCE = new ClassPathConverter();
 
         @Override
-        public Path convert(String value) {
+        public Path toPath(String value) {
             try {
                 Path path = CWD.resolve(value);
                 if (Files.notExists(path))
                     throw new CommandException("err.path.not.found", path);
-                if (! (Files.isDirectory(path) ||
-                       (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
+                if (!(Files.isDirectory(path) ||
+                        (Files.isRegularFile(path) && path.toString().endsWith(".jar"))))
                     throw new CommandException("err.invalid.class.path.entry", path);
                 return path;
             } catch (InvalidPathException x) {
                 throw new CommandException("err.path.not.valid", value);
             }
         }
-
-        @Override  public Class<Path> valueType() { return Path.class; }
-
-        @Override  public String valuePattern() { return "path"; }
     }
 
-    static class DirPathConverter implements ValueConverter<Path> {
-        static final ValueConverter<Path> INSTANCE = new DirPathConverter();
+    static class DirPathConverter extends AbstractPathConverter {
+        static final ValueConverter<List<Path>> INSTANCE = new DirPathConverter();
 
         @Override
-        public Path convert(String value) {
+        public Path toPath(String value) {
             try {
                 Path path = CWD.resolve(value);
                 if (Files.notExists(path))
@@ -1127,10 +1151,6 @@
                 throw new CommandException("err.path.not.valid", value);
             }
         }
-
-        @Override  public Class<Path> valueType() { return Path.class; }
-
-        @Override  public String valuePattern() { return "path"; }
     }
 
     static class ExtractDirPathConverter implements ValueConverter<Path> {
@@ -1142,12 +1162,6 @@
                 if (Files.exists(path)) {
                     if (!Files.isDirectory(path))
                         throw new CommandException("err.cannot.create.dir", path);
-                } else {
-                    try {
-                        Files.createDirectories(path);
-                    } catch (IOException ioe) {
-                        throw new CommandException("err.cannot.create.dir", path);
-                    }
                 }
                 return path;
             } catch (InvalidPathException x) {
@@ -1316,22 +1330,19 @@
         options = new Options();
         parser.formatHelpWith(new JmodHelpFormatter(options));
 
-        OptionSpec<Path> classPath
+        OptionSpec<List<Path>> classPath
                 = parser.accepts("class-path", getMessage("main.opt.class-path"))
                         .withRequiredArg()
-                        .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(ClassPathConverter.INSTANCE);
 
-        OptionSpec<Path> cmds
+        OptionSpec<List<Path>> cmds
                 = parser.accepts("cmds", getMessage("main.opt.cmds"))
                         .withRequiredArg()
-                        .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
-        OptionSpec<Path> config
+        OptionSpec<List<Path>> config
                 = parser.accepts("config", getMessage("main.opt.config"))
                         .withRequiredArg()
-                        .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
         OptionSpec<Path> dir
@@ -1359,22 +1370,19 @@
         OptionSpec<Void> helpExtra
                 = parser.accepts("help-extra", getMessage("main.opt.help-extra"));
 
-        OptionSpec<Path> headerFiles
+        OptionSpec<List<Path>> headerFiles
                 = parser.accepts("header-files", getMessage("main.opt.header-files"))
                         .withRequiredArg()
-                        .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
-        OptionSpec<Path> libs
+        OptionSpec<List<Path>> libs
                 = parser.accepts("libs", getMessage("main.opt.libs"))
                         .withRequiredArg()
-                        .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
-        OptionSpec<Path> legalNotices
+        OptionSpec<List<Path>> legalNotices
                 = parser.accepts("legal-notices", getMessage("main.opt.legal-notices"))
                         .withRequiredArg()
-                        .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
 
@@ -1383,17 +1391,15 @@
                         .withRequiredArg()
                         .describedAs(getMessage("main.opt.main-class.arg"));
 
-        OptionSpec<Path> manPages
+        OptionSpec<List<Path>> manPages
                 = parser.accepts("man-pages", getMessage("main.opt.man-pages"))
                         .withRequiredArg()
-                        .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
-        OptionSpec<Path> modulePath
+        OptionSpec<List<Path>> modulePath
                 = parser.acceptsAll(Set.of("p", "module-path"),
                                     getMessage("main.opt.module-path"))
                         .withRequiredArg()
-                        .withValuesSeparatedBy(File.pathSeparatorChar)
                         .withValuesConvertedBy(DirPathConverter.INSTANCE);
 
         OptionSpec<Version> moduleVersion
@@ -1452,48 +1458,48 @@
             }
 
             if (opts.has(classPath))
-                options.classpath = opts.valuesOf(classPath);
+                options.classpath = getLastElement(opts.valuesOf(classPath));
             if (opts.has(cmds))
-                options.cmds = opts.valuesOf(cmds);
+                options.cmds = getLastElement(opts.valuesOf(cmds));
             if (opts.has(config))
-                options.configs = opts.valuesOf(config);
+                options.configs = getLastElement(opts.valuesOf(config));
             if (opts.has(dir))
-                options.extractDir = opts.valueOf(dir);
+                options.extractDir = getLastElement(opts.valuesOf(dir));
             if (opts.has(dryrun))
                 options.dryrun = true;
             if (opts.has(excludes))
-                options.excludes = opts.valuesOf(excludes);
+                options.excludes = opts.valuesOf(excludes);  // excludes is repeatable
             if (opts.has(libs))
-                options.libs = opts.valuesOf(libs);
+                options.libs = getLastElement(opts.valuesOf(libs));
             if (opts.has(headerFiles))
-                options.headerFiles = opts.valuesOf(headerFiles);
+                options.headerFiles = getLastElement(opts.valuesOf(headerFiles));
             if (opts.has(manPages))
-                options.manPages = opts.valuesOf(manPages);
+                options.manPages = getLastElement(opts.valuesOf(manPages));
             if (opts.has(legalNotices))
-                options.legalNotices = opts.valuesOf(legalNotices);
+                options.legalNotices = getLastElement(opts.valuesOf(legalNotices));
             if (opts.has(modulePath)) {
-                Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
+                Path[] dirs = getLastElement(opts.valuesOf(modulePath)).toArray(new Path[0]);
                 options.moduleFinder = new ModulePath(Runtime.version(), true, dirs);
             }
             if (opts.has(moduleVersion))
-                options.moduleVersion = opts.valueOf(moduleVersion);
+                options.moduleVersion = getLastElement(opts.valuesOf(moduleVersion));
             if (opts.has(mainClass))
-                options.mainClass = opts.valueOf(mainClass);
+                options.mainClass = getLastElement(opts.valuesOf(mainClass));
             if (opts.has(osName))
-                options.osName = opts.valueOf(osName);
+                options.osName = getLastElement(opts.valuesOf(osName));
             if (opts.has(osArch))
-                options.osArch = opts.valueOf(osArch);
+                options.osArch = getLastElement(opts.valuesOf(osArch));
             if (opts.has(osVersion))
-                options.osVersion = opts.valueOf(osVersion);
+                options.osVersion = getLastElement(opts.valuesOf(osVersion));
             if (opts.has(warnIfResolved))
-                options.moduleResolution = opts.valueOf(warnIfResolved);
+                options.moduleResolution = getLastElement(opts.valuesOf(warnIfResolved));
             if (opts.has(doNotResolveByDefault)) {
                 if (options.moduleResolution == null)
                     options.moduleResolution = ModuleResolution.empty();
                 options.moduleResolution = options.moduleResolution.withDoNotResolveByDefault();
             }
             if (opts.has(hashModules)) {
-                options.modulesToHash = opts.valueOf(hashModules);
+                options.modulesToHash = getLastElement(opts.valuesOf(hashModules));
                 // if storing hashes then the module path is required
                 if (options.moduleFinder == null)
                     throw new CommandException("err.modulepath.must.be.specified")
@@ -1531,6 +1537,13 @@
                 throw new CommandException("err.classpath.must.be.specified").showUsage(true);
             if (options.mainClass != null && !isValidJavaIdentifier(options.mainClass))
                 throw new CommandException("err.invalid.main-class", options.mainClass);
+            if (options.mode.equals(Mode.EXTRACT) && options.extractDir != null) {
+                try {
+                    Files.createDirectories(options.extractDir);
+                } catch (IOException ioe) {
+                    throw new CommandException("err.cannot.create.dir", options.extractDir);
+                }
+            }
         } catch (OptionException e) {
              throw new CommandException(e.getMessage());
         }
@@ -1558,6 +1571,12 @@
         return true;
     }
 
+    static <E> E getLastElement(List<E> list) {
+        if (list.size() == 0)
+            throw new InternalError("Unexpected 0 list size");
+        return list.get(list.size() - 1);
+    }
+
     private void reportError(String message) {
         out.println(getMessage("error.prefix") + " " + message);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/URLConnection/SetDefaultUseCaches.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8163449
+ * @summary Allow per protocol setting for URLConnection defaultUseCaches
+ * @run main/othervm SetDefaultUseCaches
+ */
+
+import java.net.*;
+import java.io.*;
+
+public class SetDefaultUseCaches {
+    static void testAssert(boolean value, boolean comparator) {
+        if (value != comparator) {
+            System.err.println("Expected " + comparator + " Got " + value);
+            throw new RuntimeException("Test failed:");
+        } else
+            System.err.println("OK");
+    }
+
+    public static void main(String s[]) throws Exception {
+        URL url = new URL("http://www.foo.com/");
+        URL url1 = new URL("file:///a/b.txt");
+
+        // check default default is true
+        URLConnection urlc = url.openConnection();
+        testAssert(urlc.getDefaultUseCaches(), true);
+
+        // set default for http to false and check
+        URLConnection.setDefaultUseCaches("HTTP", false);
+
+        urlc = url.openConnection();
+        testAssert(urlc.getDefaultUseCaches(), true);
+        testAssert(urlc.getUseCaches(), false);
+        testAssert(URLConnection.getDefaultUseCaches("http"), false);
+
+        URLConnection urlc1 = url1.openConnection();
+        testAssert(urlc1.getDefaultUseCaches(), true);
+
+        // set default default to false and check other values the same
+        urlc.setDefaultUseCaches(false);
+        urlc1.setDefaultUseCaches("fiLe", true);
+        testAssert(urlc1.getDefaultUseCaches(), false);
+        testAssert(URLConnection.getDefaultUseCaches("fiLE"), true);
+    }
+}
--- a/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java	Thu Jan 12 12:14:13 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
@@ -31,7 +31,9 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary JavaVM RMID TestSecurityManager
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider RegistryVM RMIRegistryRunner
+ *        TestSecurityManager
  * @run main/othervm AltSecurityManager
  */
 
@@ -44,7 +46,6 @@
  * if registry and rmid take too long to exit.
  */
 public class AltSecurityManager implements Runnable {
-    private final int regPort;
     // variable to hold registry and rmid children
     static JavaVM vm = null;
 
@@ -57,31 +58,34 @@
     private static final long TIME_OUT =
             (long)(15000 * TestLibrary.getTimeoutFactor());
 
-    public AltSecurityManager(int port) {
-        if (port <= 0) {
-            TestLibrary.bomb("Port must be greater than 0.");
-        }
-
-        this.regPort = port;
-    }
-
     public void run() {
         try {
             if (utilityToStart.equals(REGISTRY_IMPL)) {
-                vm = new JavaVM(utilityToStart,
-                        " -Djava.security.manager=TestSecurityManager",
-                        Integer.toString(regPort));
+                vm = RegistryVM.createRegistryVMWithRunner(
+                        "RMIRegistryRunner",
+                        "-Djava.security.manager=TestSecurityManager");
             } else if (utilityToStart.contains(ACTIVATION)) {
-                vm = new JavaVM(utilityToStart,
-                        " -Djava.security.manager=TestSecurityManager",
-                        "-port " + Integer.toString(regPort));
+                vm = RMID.createRMIDOnEphemeralPortWithOptions(
+                        "-Djava.security.manager=TestSecurityManager");
             } else {
                 TestLibrary.bomb("Utility to start must be " + REGISTRY_IMPL +
                         " or " + ACTIVATION);
             }
 
             System.err.println("starting " + utilityToStart);
-            vm.execute();
+            try {
+                vm.start();
+                throw new RuntimeException("Expected exception did not occur!");
+            } catch (Exception expected) {
+                int exit = vm.waitFor();
+                if (exit != TestSecurityManager.EXIT_VALUE) {
+                    throw new RuntimeException(utilityToStart
+                            + " exit with an unexpected value "
+                            + exit + ".");
+                }
+                System.err.format("Success: starting %s exited with status %d%n",
+                                  utilityToStart, TestSecurityManager.EXIT_VALUE);
+            }
 
         } catch (Exception e) {
             TestLibrary.bomb(e);
@@ -96,8 +100,7 @@
         utilityToStart = utility;
 
         try {
-            int port = TestLibrary.getUnusedRandomPort();
-            Thread thread = new Thread(new AltSecurityManager(port));
+            Thread thread = new Thread(new AltSecurityManager());
             System.err.println("expecting RuntimeException for " +
                                "checkListen in child process");
             long start = System.currentTimeMillis();
@@ -116,7 +119,7 @@
                                    " terminated on time");
             }
         } finally {
-            vm.destroy();
+            vm.cleanup();
             vm = null;
         }
     }
--- a/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/altSecurityManager/TestSecurityManager.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, 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
@@ -24,6 +24,8 @@
 /**/
 
 public class TestSecurityManager extends SecurityManager {
+    public static final int EXIT_VALUE = 123;
+
     public TestSecurityManager() {
     }
 
@@ -36,7 +38,7 @@
         // by the main test process to detect that the proper security
         // manager has been installed in the relevant VMs.
         //
-        System.exit(1);
+        System.exit(EXIT_VALUE);
     }
 
     public void checkExit(int status) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/altSecurityManager/registry.security.policy	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,8 @@
+grant {
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+  permission java.util.PropertyPermission "env.class.path", "read";
+  permission java.io.FilePermission ".", "read";
+  permission java.util.PropertyPermission "user.dir", "read";
+  permission java.lang.RuntimePermission "createClassLoader";
+  permission java.lang.RuntimePermission "setContextClassLoader";
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/altSecurityManager/rmid.security.policy	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,7 @@
+grant {
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
+  permission java.util.PropertyPermission "test.java.rmi.testlibrary.RMIDSelectorProvider.port", "read";
+  permission java.util.PropertyPermission "test.java.rmi.testlibrary.RMIDSelectorProvider.timeout", "read";
+  permission java.net.SocketPermission "*:1024-", "listen,resolve,connect,accept";
+};
--- a/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, 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
@@ -34,7 +34,7 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary Dummy
+ * @build TestLibrary Dummy RegistryVM RMIRegistryRunner
  * @run main/othervm/policy=security.policy
  *     -Djava.rmi.server.useCodebaseOnly=false ClassPathCodebase
  */
@@ -48,8 +48,9 @@
 
 public class ClassPathCodebase {
 
-    /** wait 10 seconds for the registry process to be ready to call */
-    private final static long REGISTRY_WAIT = 15000;
+    /** wait dozens of seconds for the registry process to be ready to call */
+    private static final long REGISTRY_WAIT =
+            (long)(10000 * TestLibrary.getTimeoutFactor());
 
     private final static String dummyClassName = "Dummy";
 
@@ -64,7 +65,7 @@
 
         TestLibrary.suggestSecurityManager("java.lang.SecurityManager");
 
-        Process rmiregistry = null;
+        RegistryVM rmiregistry = null;
 
         try {
             /*
@@ -82,27 +83,13 @@
              * Spawn an rmiregistry in the "import" codebase directory.
              */
             File rmiregistryDir =
-                new File(System.getProperty("user.dir", "."), importCodebase);
-
-            String rmiregistryCommand =
-                System.getProperty("java.home") + File.separator +
-                "bin" + File.separator + "rmiregistry";
-
-            int port = TestLibrary.getUnusedRandomPort();
-            String cmdarray[] = new String[] {
-                rmiregistryCommand,
-                "-J-Denv.class.path=.",
-                "-J-Djava.rmi.server.codebase=" + exportCodebaseURL,
-                Integer.toString(port) };
-
-            System.err.println("\nCommand used to spawn rmiregistry process:");
-            System.err.println("\t" + Arrays.asList(cmdarray).toString());
-
-            rmiregistry = Runtime.getRuntime().exec(cmdarray, null, rmiregistryDir);
-
-            // pipe rmiregistry output to our output, for debugging failures
-            StreamPipe.plugTogether(rmiregistry.getInputStream(), System.err);
-            StreamPipe.plugTogether(rmiregistry.getErrorStream(), System.err);
+                  new File(System.getProperty("user.dir", "."), importCodebase);
+            rmiregistry = RegistryVM.createRegistryVMWithRunner("RMIRegistryRunner",
+                            " -Denv.class.path=."
+                            + " -Djava.rmi.server.codebase=" + exportCodebaseURL
+                            + " -Duser.dir=" + rmiregistryDir.getAbsolutePath());
+            rmiregistry.start();
+            int port = rmiregistry.getPort();
 
             /*
              * Wait for the registry to initialize and be ready to call.
@@ -174,7 +161,7 @@
             throw new RuntimeException("TEST FAILED: " + e.toString());
         } finally {
             if (rmiregistry != null) {
-                rmiregistry.destroy();
+                rmiregistry.cleanup();
             }
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/registry/classPathCodebase/registry.security.policy	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,18 @@
+/*
+ * security policy used by the registry process started by RegistryVM.
+ */
+
+grant {
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+  permission java.util.PropertyPermission "env.class.path", "read";
+  permission java.io.FilePermission ".", "read";
+  permission java.util.PropertyPermission "user.dir", "read";
+  permission java.lang.RuntimePermission "createClassLoader";
+  permission java.lang.RuntimePermission "setContextClassLoader";
+  permission java.io.FilePermission ".-Djava.rmi.server.codebase=file", "read";
+  permission java.io.FilePermission ".${/}-", "read";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
+  permission java.net.SocketPermission "*:1024-", "listen,resolve,connect,accept";
+};
--- a/jdk/test/java/rmi/registry/classPathCodebase/security.policy	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/classPathCodebase/security.policy	Thu Jan 12 12:14:13 2017 -0800
@@ -18,6 +18,12 @@
   // test needs to use java to exec an rmiregistry
   permission java.io.FilePermission "${java.home}${/}bin${/}-", "execute";
 
-  // test needs to communicate with this its registry
+  // test needs to communicate with its registry
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.util.PropertyPermission "java.security.policy", "read";
+  permission java.util.PropertyPermission "java.security.manager", "read";
+
+  // used by TestLibrary to determine extra commandline properties
+  permission java.io.FilePermission "..${/}..${/}test.props", "read";
 };
--- a/jdk/test/java/rmi/registry/reexport/Reexport.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/registry/reexport/Reexport.java	Thu Jan 12 12:14:13 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
@@ -29,7 +29,7 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary REGISTRY RegistryRunner
+ * @build TestLibrary RegistryVM RegistryRunner
  * @run main/othervm Reexport
  */
 
@@ -114,7 +114,7 @@
 
     public static void makeRegistry() {
         try {
-            subreg = REGISTRY.createREGISTRY();
+            subreg = RegistryVM.createRegistryVM();
             subreg.start();
             port = subreg.getPort();
             System.out.println("Starting registry on port " + port);
@@ -125,12 +125,12 @@
         }
     }
 
-    private static REGISTRY subreg = null;
+    private static RegistryVM subreg = null;
     private static int port = -1;
 
     public static void killRegistry() {
         if (subreg != null) {
-            subreg.shutdown();
+            subreg.cleanup();
             subreg = null;
         }
     }
--- a/jdk/test/java/rmi/testlibrary/JavaVM.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/testlibrary/JavaVM.java	Thu Jan 12 12:14:13 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
@@ -230,6 +230,22 @@
     }
 
     /**
+     * Return exit value for vm process.
+     * @return exit value for vm process
+     * @throws IllegalThreadStateException if the vm process has not yet terminated
+     */
+    public int exitValue() {
+        return vm.exitValue();
+    }
+
+    /**
+     * Destroy the vm process, and do necessary cleanup.
+     */
+    public void cleanup() {
+        destroy();
+    }
+
+    /**
      * Destroys the VM, waits for it to terminate, and returns
      * its exit status.
      *
--- a/jdk/test/java/rmi/testlibrary/REGISTRY.java	Thu Jan 12 11:58:01 2017 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +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.
- */
-
-import java.io.OutputStream;
-import java.io.IOException;
-
-/**
- * Class to run and control rmiregistry in a sub-process.
- *
- * We can't kill a registry if we have too-close control
- * over it.  We must make it in a subprocess, and then kill the
- * subprocess when it has served our needs.
- */
-public class REGISTRY extends JavaVM {
-
-    private static final double START_TIMEOUT =
-            20_000 * TestLibrary.getTimeoutFactor();
-    private static final String DEFAULT_RUNNER = "RegistryRunner";
-
-    private int port = -1;
-
-    private REGISTRY(String runner, OutputStream out, OutputStream err,
-                    String options, int port) {
-        super(runner, options, Integer.toString(port), out, err);
-        try {
-            Class runnerClass = Class.forName(runner);
-            if (!RegistryRunner.class.isAssignableFrom(runnerClass)) {
-                throw new RuntimeException("runner class must be RegistryRunner"
-                        + " or its sub class");
-            }
-        } catch (ClassNotFoundException ex) {
-            throw new RuntimeException(ex);
-        }
-        this.port = port;
-    }
-
-    public static REGISTRY createREGISTRY() {
-        return createREGISTRYWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
-    }
-
-    public static REGISTRY createREGISTRY(OutputStream out, OutputStream err,
-                                    String options, int port) {
-        return createREGISTRYWithRunner(DEFAULT_RUNNER, out, err, options, port);
-    }
-
-    public static REGISTRY createREGISTRYWithRunner(String runner, String options) {
-        return createREGISTRYWithRunner(runner, System.out, System.err, options, 0);
-    }
-
-    public static REGISTRY createREGISTRYWithRunner(String runner, OutputStream out,
-                                        OutputStream err, String options, int port) {
-        options += " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
-                + " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
-                + " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
-                + " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
-       REGISTRY reg = new REGISTRY(runner, out, err, options, port);
-       return reg;
-    }
-
-    /**
-     * Starts the registry in a sub-process and waits up to
-     * the given timeout period to confirm that it's running,
-     * and get the port where it's running.
-     */
-    public void start() throws IOException {
-        super.start();
-        long startTime = System.currentTimeMillis();
-        long deadline = TestLibrary.computeDeadline(startTime, (long)START_TIMEOUT);
-        while (true) {
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException ignore) { }
-
-            String output = outputStream.ba.toString();
-            port = RegistryRunner.getRegistryPort(output);
-            if (port != -1) {
-                break;
-            }
-            if (System.currentTimeMillis() > deadline) {
-                TestLibrary.bomb("Failed to start registry, giving up after " +
-                    (System.currentTimeMillis() - startTime) + "ms.", null);
-            }
-        }
-    }
-
-    /**
-     * Shuts down the registry.
-     */
-    public void shutdown() {
-        RegistryRunner.requestExit(port);
-    }
-
-    /**
-     * Gets the port where the registry is serving.
-     */
-    public int getPort() {
-        return port;
-    }
-}
--- a/jdk/test/java/rmi/testlibrary/RMID.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/testlibrary/RMID.java	Thu Jan 12 12:14:13 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
@@ -140,18 +140,6 @@
     }
 
     private static String makeArgs(boolean includePortArg, int port) {
-        String propagateManager = null;
-
-        // rmid will run with a security manager set, but no policy
-        // file - it should not need one.
-        if (System.getSecurityManager() == null) {
-            propagateManager = MANAGER_OPTION +
-                TestParams.defaultSecurityManager;
-        } else {
-            propagateManager = MANAGER_OPTION +
-                System.getSecurityManager().getClass().getName();
-        }
-
         // getAbsolutePath requires permission to read user.dir
         String args =
             " -log " + (new File(LOGDIR, log)).getAbsolutePath();
@@ -210,7 +198,30 @@
                                   boolean debugExec, boolean includePortArg,
                                   int port)
     {
+        return createRMIDWithOptions(out, err, debugExec, includePortArg, port, "");
+    }
+
+    /**
+     * Create a RMID on a specified port capturing stdout and stderr
+     * with additional command line options and whether to print out
+     * debugging information that is used for spawning activation groups.
+     *
+     * @param out the OutputStream where the normal output of the
+     *            rmid subprocess goes
+     * @param err the OutputStream where the error output of the
+     *            rmid subprocess goes
+     * @param debugExec whether to print out debugging information
+     * @param includePortArg whether to include port argument
+     * @param port the port on which rmid accepts requests
+     * @param additionalOptions additional command line options
+     * @return a RMID instance
+     */
+    public static RMID createRMIDWithOptions(OutputStream out, OutputStream err,
+                                  boolean debugExec, boolean includePortArg,
+                                  int port, String additionalOptions)
+    {
         String options = makeOptions(port, debugExec, false);
+        options += " " + additionalOptions;
         String args = makeArgs(includePortArg, port);
         RMID rmid = new RMID("sun.rmi.server.Activation", options, args,
                              out, err, port);
@@ -223,6 +234,19 @@
         return createRMID(System.out, System.err, true, false, 0);
     }
 
+    /**
+     * Create a RMID on an ephemeral port capturing stdout and stderr
+     * with additional command line options.
+     *
+     * @param additionalOptions additional command line options
+     * @return a RMID instance
+     */
+    public static RMID createRMIDOnEphemeralPortWithOptions(
+                                            String additionalOptions) {
+        return createRMIDWithOptions(System.out, System.err,
+                                     true, false, 0, additionalOptions);
+    }
+
     public static RMID createRMIDOnEphemeralPort(OutputStream out,
                                                  OutputStream err,
                                                  boolean debugExec)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/testlibrary/RMIRegistryRunner.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,79 @@
+/*
+ * 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.rmi.*;
+import java.rmi.registry.*;
+import java.rmi.server.*;
+
+/**
+ * Class to run a rmiregistry whose VM can be told to exit remotely;
+ * Difference between this class and RegistryRunner is that this class
+ * simulate rmiregistry closer than RegistryRunner.
+ */
+public class RMIRegistryRunner extends RegistryRunner
+{
+    public RMIRegistryRunner() throws RemoteException {
+    }
+
+    /**
+     * port 0 means to use ephemeral port to start registry.
+     *
+     * @param args command line arguments passed in from main
+     * @return the port number on which registry accepts requests
+     */
+    protected static int init(String[] args) {
+        try {
+            if (args.length == 0) {
+                System.err.println("Usage: <port>");
+                System.exit(0);
+            }
+            int port = -1;
+            port = Integer.parseInt(args[0]);
+
+            // call RegistryImpl.createRegistry to simulate rmiregistry.
+            registry = sun.rmi.registry.RegistryImpl.createRegistry(port);
+            if (port == 0) {
+                port = TestLibrary.getRegistryPort(registry);
+            }
+
+            // create a remote object to tell this VM to exit
+            exiter = new RMIRegistryRunner();
+            Naming.rebind("rmi://localhost:" + port +
+                          "/RemoteExiter", exiter);
+
+            return port;
+        } catch (Exception e) {
+            System.err.println(e.getMessage());
+            e.printStackTrace();
+            System.exit(1);
+        }
+        return -1;
+    }
+
+    public static void main(String[] args) {
+        int port = init(args);
+        notify(port);
+    }
+}
--- a/jdk/test/java/rmi/testlibrary/RegistryRunner.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/testlibrary/RegistryRunner.java	Thu Jan 12 12:14:13 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
@@ -29,7 +29,7 @@
 
 /**
  * Class to run a registry whose VM can be told to exit remotely; using
- * the rmiregistry in this fashion makes tests more robust under
+ * a registry (in a sub-process) in this fashion makes tests more robust under
  * windows where Process.destroy() seems not to be 100% reliable.
  */
 public class RegistryRunner extends UnicastRemoteObject
@@ -38,8 +38,8 @@
     private static final String PORT_LABEL_START = "RegistryRunner.port.start:";
     private static final String PORT_LABEL_END = ":RegistryRunner.port.end";
 
-    private static Registry registry = null;
-    private static RemoteExiter exiter = null;
+    protected static Registry registry = null;
+    protected static RemoteExiter exiter = null;
 
     public RegistryRunner() throws RemoteException {
     }
@@ -72,6 +72,7 @@
             } catch (RemoteException re) {
             }
             e = null;
+
         } catch (java.net.MalformedURLException mfue) {
             // will not happen
         } catch (NotBoundException nbe) {
@@ -97,6 +98,9 @@
 
     /**
      * port 0 means to use ephemeral port to start registry.
+     *
+     * @param args command line arguments passed in from main
+     * @return the port number on which registry accepts requests
      */
     protected static int init(String[] args) {
         try {
@@ -128,13 +132,15 @@
     }
 
     /**
-     * REGISTRY.start() will filter the output of registry subprocess,
-     * when valid port is detected, REGISTRY.start() returns.
+     * RegistryVM.start() will filter the output of registry subprocess,
+     * when valid port is detected, RegistryVM.start() returns.
      * So, for subclass, it's important to call this method after registry
      * is initialized and necessary remote objects have been bound.
+     *
+     * @param port the port on which registry accepts requests
      */
     protected static void notify(int port) {
-        // this output is important for REGISTRY to get the port
+        // this output is important for RegistryVM to get the port
         // where rmiregistry is serving
         System.out.println(PORT_LABEL_START + port + PORT_LABEL_END);
         System.out.flush();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/testlibrary/RegistryVM.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,184 @@
+/*
+ * 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.OutputStream;
+import java.io.IOException;
+
+/**
+ * Class to run and control registry/rmiregistry in a sub-process.
+ * The behaviour changes when use different runner, currently
+ * there are 2 built-in runners, RegistryRunner and RMIRegistryRunner.
+ *
+ * We can't kill a registry if we have too-close control
+ * over it.  We must make it in a subprocess, and then kill the
+ * subprocess when it has served our needs.
+ */
+public class RegistryVM extends JavaVM {
+
+    private static final double START_TIMEOUT =
+            20_000 * TestLibrary.getTimeoutFactor();
+    private static final String DEFAULT_RUNNER = "RegistryRunner";
+
+    private int port = -1;
+
+    private RegistryVM(String runner, OutputStream out, OutputStream err,
+                    String options, int port) {
+        super(runner, options, Integer.toString(port), out, err);
+        try {
+            Class runnerClass = Class.forName(runner);
+            if (!RegistryRunner.class.isAssignableFrom(runnerClass)) {
+                throw new RuntimeException("runner class must be RegistryRunner"
+                        + " or its sub class");
+            }
+        } catch (ClassNotFoundException ex) {
+            throw new RuntimeException(ex);
+        }
+        this.port = port;
+    }
+
+    /**
+     * Create a RegistryVM instance on an ephemeral port.
+     *
+     * @return a RegistryVM instance
+     */
+    public static RegistryVM createRegistryVM() {
+        return createRegistryVMWithRunner(DEFAULT_RUNNER, System.out, System.err, "", 0);
+    }
+
+    /**
+     * Create a RegistryVM instance on an ephemeral port with additional
+     * command line options.
+     *
+     * @param options command line options
+     * @return a RegistryVM instance
+     */
+    public static RegistryVM createRegistryVM(String options) {
+        return createRegistryVMWithRunner(
+                DEFAULT_RUNNER, System.out, System.err, options, 0);
+    }
+
+    /**
+     * Create a RegistryVM instance on a specified port capturing stdout and
+     * stderr with additional command line options.
+     *
+     * @param out the OutputStream where the normal output of the
+     *            registry subprocess goes
+     * @param err the OutputStream where the error output of the
+     *            registry subprocess goes
+     * @param options the command line options
+     * @param port the port on which Registry accepts requests
+     * @return a RegistryVM instance
+     */
+    public static RegistryVM createRegistryVM(OutputStream out, OutputStream err,
+                                              String options, int port) {
+        return createRegistryVMWithRunner(DEFAULT_RUNNER, out, err, options, port);
+    }
+
+    /**
+     * Create a RegistryVM instance on an ephemeral port with additional
+     * command line options and a specified runner.
+     *
+     * @param runner the runner class name
+     * @param options command line options
+     * @return a RegistryVM instance
+     */
+    public static RegistryVM createRegistryVMWithRunner(String runner, String options) {
+        return createRegistryVMWithRunner(runner, System.out, System.err, options, 0);
+    }
+
+    /**
+     * Create a RegistryVM instance on a specified port capturing stdout and
+     * stderr with additional command line options and a specified runner.
+     *
+     * @param runner the runner class name
+     * @param out the OutputStream where the normal output of the
+     *            registry subprocess goes
+     * @param err the OutputStream where the error output of the
+     *            registry subprocess goes
+     * @param options the command line options
+     * @param port the port on which Registry accepts requests
+     * @return a RegistryVM instance
+     */
+    public static RegistryVM createRegistryVMWithRunner(String runner, OutputStream out,
+                                        OutputStream err, String options, int port) {
+        options += " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED"
+                + " --add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED"
+                + " --add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED"
+                + " --add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED";
+        RegistryVM reg = new RegistryVM(runner, out, err, options, port);
+        reg.setPolicyFile(TestParams.defaultRegistryPolicy);
+        return reg;
+    }
+
+    /**
+     * Starts the registry in a sub-process and waits up to
+     * the given timeout period to confirm that it's running,
+     * and get the port where it's running.
+     *
+     * @throws IOException if fails to start subprocess
+     */
+    public void start() throws IOException {
+        super.start();
+        long startTime = System.currentTimeMillis();
+        long deadline = TestLibrary.computeDeadline(startTime, (long)START_TIMEOUT);
+        while (true) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ignore) { }
+
+            String output = outputStream.ba.toString();
+            port = RegistryRunner.getRegistryPort(output);
+            if (port != -1) {
+                break;
+            }
+            try {
+                int exit = vm.exitValue();
+                TestLibrary.bomb("[RegistryVM] registry sub-process exited with status "
+                        + exit + ".");
+            } catch (IllegalThreadStateException ignore) { }
+
+            if (System.currentTimeMillis() > deadline) {
+                TestLibrary.bomb("Failed to start registry, giving up after " +
+                    (System.currentTimeMillis() - startTime) + "ms.", null);
+            }
+        }
+    }
+
+    /**
+     * Shuts down the registry.
+     */
+    @Override
+    public void cleanup() {
+        RegistryRunner.requestExit(port);
+        super.destroy();
+    }
+
+    /**
+     * Gets the port where the registry is serving.
+     *
+     * @return the port where the registry is serving
+     */
+    public int getPort() {
+        return port;
+    }
+}
--- a/jdk/test/java/rmi/testlibrary/TestParams.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/testlibrary/TestParams.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, 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
@@ -42,6 +42,9 @@
     /** name of default security policy for RMID */
     public static final String defaultRmidPolicy;
 
+    /** name of default security policy for RegistryVM */
+    public static final String defaultRegistryPolicy;
+
     /** name of default security policy for activation groups */
     public static final String defaultGroupPolicy;
 
@@ -69,6 +72,9 @@
         defaultRmidPolicy =
             testSrc + File.separatorChar + "rmid.security.policy";
 
+        defaultRegistryPolicy =
+            testSrc + File.separatorChar + "registry.security.policy";
+
         defaultGroupPolicy =
             testSrc + File.separatorChar + "group.security.policy";
 
--- a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java	Thu Jan 12 12:14:13 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
@@ -33,7 +33,7 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary Test TestImpl REGISTRY RegistryRunner
+ * @build TestLibrary Test TestImpl RegistryVM RegistryRunner
  * @run main/othervm/policy=security.policy/timeout=360 DGCDeadLock
  */
 
@@ -68,21 +68,18 @@
 
     static public void main(String[] args) {
 
-        REGISTRY testImplVM = null;
+        RegistryVM testImplVM = null;
 
         System.err.println("\nregression test for 4118056\n");
         TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
 
         try {
-            String options = " -Djava.security.policy=" +
-                TestParams.defaultPolicy +
-                " --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED" +
+            String options = " --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED" +
                 " -Djava.rmi.dgc.leaseValue=500000" +
                 " -Dsun.rmi.dgc.checkInterval=" +
-                (HOLD_TARGET_TIME - 5000) +
-                "" ;
+                (HOLD_TARGET_TIME - 5000);
 
-            testImplVM = REGISTRY.createREGISTRYWithRunner("TestImpl", options);
+            testImplVM = RegistryVM.createRegistryVMWithRunner("TestImpl", options);
             testImplVM.start();
             registryPort = testImplVM.getPort();
 
@@ -107,7 +104,7 @@
             TestLibrary.bomb("test failed in main()", e);
         } finally {
             if (testImplVM != null) {
-                testImplVM.shutdown();
+                testImplVM.cleanup();
                 testImplVM = null;
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/registry.security.policy	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,27 @@
+/*
+ * security policy used by the registry sub-process
+ */
+
+grant {
+  // used by TestLibrary to determine extra commandline properties
+  permission java.io.FilePermission "..${/}..${/}test.props", "read";
+
+  // property specifically accessed by this test.
+  permission java.util.PropertyPermission "sun.rmi.transport.cleanInterval", "write";
+  permission java.util.PropertyPermission "package.restrict.access.sun", "read";
+  permission java.util.PropertyPermission "package.restrict.access.sun.rmi", "read";
+
+  // test needs to use java to exec an EchoImpl object
+  permission java.io.FilePermission "${java.home}${/}bin${/}java", "execute";
+
+  // used by TestLibrary to determine test environment 
+  permission java.util.PropertyPermission "test.*", "read";
+  permission java.util.PropertyPermission "user.dir", "read";
+  permission java.util.PropertyPermission "java.home", "read";
+
+  permission java.util.PropertyPermission "java.security.policy", "read";
+  permission java.util.PropertyPermission "java.security.manager", "read";
+
+  // test needs to export rmid and communicate with objects on arbitrary ports
+  permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+};
--- a/jdk/test/java/time/TEST.properties	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/TEST.properties	Thu Jan 12 12:14:13 2017 -0800
@@ -1,7 +1,6 @@
 # Threeten test uses TestNG
 TestNG.dirs = .
 othervm.dirs = tck/java/time/chrono test/java/time/chrono test/java/time/format
-modules = jdk.localedata
 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/test/java/time/format/TestDateTimeFormatterBuilder.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java	Thu Jan 12 12:14:13 2017 -0800
@@ -880,25 +880,6 @@
     }
 
     //-----------------------------------------------------------------------
-    @DataProvider(name="patternPrint")
-    Object[][] data_patternPrint() {
-        return new Object[][] {
-            {"Q", date(2012, 2, 10), "1"},
-            {"QQ", date(2012, 2, 10), "01"},
-            {"QQQ", date(2012, 2, 10), "Q1"},
-            {"QQQQ", date(2012, 2, 10), "1st quarter"},
-            {"QQQQQ", date(2012, 2, 10), "1"},
-        };
-    }
-
-    @Test(dataProvider="patternPrint")
-    public void test_appendPattern_patternPrint(String input, Temporal temporal, String expected) throws Exception {
-        DateTimeFormatter f = builder.appendPattern(input).toFormatter(Locale.UK);
-        String test = f.format(temporal);
-        assertEquals(test, expected);
-    }
-
-    //-----------------------------------------------------------------------
     @DataProvider(name="localePatterns")
     Object[][] localizedDateTimePatterns() {
         return new Object[][] {
@@ -914,48 +895,6 @@
             {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a z"},
             {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.US, "h:mm:ss a"},
             {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.US, "h:mm a"},
-
-            // French Locale and ISO Chronology
-            {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y '\u00e0' HH:mm:ss zzzz"},
-            {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y '\u00e0' HH:mm:ss z"},
-            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y '\u00e0' HH:mm:ss"},
-            {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y HH:mm"},
-            {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y"},
-            {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y"},
-            {FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y"},
-            {FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y"},
-            {null, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss zzzz"},
-            {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss z"},
-            {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss"},
-            {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm"},
-
-            // Japanese Locale and JapaneseChronology
-            {FormatStyle.FULL, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE H\u6642mm\u5206ss\u79d2 zzzz"},
-            {FormatStyle.LONG, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss z"},
-            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss"},
-            {FormatStyle.SHORT, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d H:mm"},
-            {FormatStyle.FULL, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
-            {FormatStyle.LONG, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
-            {FormatStyle.MEDIUM, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
-            {FormatStyle.SHORT, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d"},
-            {null, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H\u6642mm\u5206ss\u79d2 zzzz"},
-            {null, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss z"},
-            {null, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss"},
-            {null, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm"},
-
-            // Chinese Local and Chronology
-            {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
-            {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
-            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
-            {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
-            {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
-            {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
-            {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
-            {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
-            {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
-            {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
-            {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
-            {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
         };
     }
 
@@ -1004,5 +943,4 @@
     private static Temporal date(int y, int m, int d) {
         return LocalDate.of(y, m, d);
     }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeFormatterBuilderWithLocale.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,195 @@
+/*
+ * 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
+ * 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:
+ *
+ * Copyright (c) 2009-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+package test.java.time.format;
+
+import java.time.chrono.Chronology;
+import java.time.chrono.IsoChronology;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.MinguoChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
+import java.time.LocalDate;
+import java.time.temporal.Temporal;
+
+import java.util.Locale;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test DateTimeFormatterBuilder.
+ */
+@Test
+public class TestDateTimeFormatterBuilderWithLocale {
+
+    private DateTimeFormatterBuilder builder;
+
+    @BeforeMethod
+    public void setUp() {
+        builder = new DateTimeFormatterBuilder();
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="patternPrint")
+    Object[][] data_patternPrint() {
+        return new Object[][] {
+            {"Q", date(2012, 2, 10), "1"},
+            {"QQ", date(2012, 2, 10), "01"},
+            {"QQQ", date(2012, 2, 10), "Q1"},
+            {"QQQQ", date(2012, 2, 10), "1st quarter"},
+            {"QQQQQ", date(2012, 2, 10), "1"},
+        };
+    }
+
+    @Test(dataProvider="patternPrint")
+    public void test_appendPattern_patternPrint(String input, Temporal temporal, String expected) throws Exception {
+        DateTimeFormatter f = builder.appendPattern(input).toFormatter(Locale.UK);
+        String test = f.format(temporal);
+        assertEquals(test, expected);
+    }
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="localePatterns")
+    Object[][] localizedDateTimePatterns() {
+        return new Object[][] {
+            // French Locale and ISO Chronology
+            {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y '\u00e0' HH:mm:ss zzzz"},
+            {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y '\u00e0' HH:mm:ss z"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y '\u00e0' HH:mm:ss"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y HH:mm"},
+            {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y"},
+            {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y"},
+            {FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y"},
+            {FormatStyle.SHORT, null, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y"},
+            {null, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss zzzz"},
+            {null, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss z"},
+            {null, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm:ss"},
+            {null, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "HH:mm"},
+
+            // Japanese Locale and JapaneseChronology
+            {FormatStyle.FULL, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE H\u6642mm\u5206ss\u79d2 zzzz"},
+            {FormatStyle.LONG, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss z"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5 H:mm:ss"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d H:mm"},
+            {FormatStyle.FULL, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
+            {FormatStyle.LONG, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
+            {FormatStyle.MEDIUM, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "Gy\u5e74M\u6708d\u65e5"},
+            {FormatStyle.SHORT, null, JapaneseChronology.INSTANCE, Locale.JAPANESE, "GGGGGy/M/d"},
+            {null, FormatStyle.FULL, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H\u6642mm\u5206ss\u79d2 zzzz"},
+            {null, FormatStyle.LONG, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss z"},
+            {null, FormatStyle.MEDIUM, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm:ss"},
+            {null, FormatStyle.SHORT, JapaneseChronology.INSTANCE, Locale.JAPANESE, "H:mm"},
+
+            // Chinese Local and Chronology
+            {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
+            {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
+            {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
+            {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
+            {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
+            {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
+            {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
+            {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
+            {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
+            {null, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm"},
+        };
+    }
+
+    @Test(dataProvider="localePatterns")
+    public void test_getLocalizedDateTimePattern(FormatStyle dateStyle, FormatStyle timeStyle,
+            Chronology chrono, Locale locale, String expected) {
+        String actual = DateTimeFormatterBuilder.getLocalizedDateTimePattern(dateStyle, timeStyle, chrono, locale);
+        assertEquals(actual, expected, "Pattern " + convertNonAscii(actual));
+    }
+
+    /**
+     * Returns a string that includes non-ascii characters after expanding
+     * the non-ascii characters to their Java language \\uxxxx form.
+     * @param input an input string
+     * @return the encoded string.
+     */
+    private String convertNonAscii(String input) {
+        StringBuilder sb = new StringBuilder(input.length() * 6);
+        for (int i = 0; i < input.length(); i++) {
+            char ch = input.charAt(i);
+            if (ch < 255) {
+                sb.append(ch);
+            } else {
+                sb.append("\\u");
+                sb.append(Integer.toHexString(ch));
+            }
+        }
+        return sb.toString();
+    }
+
+    private static Temporal date(int y, int m, int d) {
+        return LocalDate.of(y, m, d);
+    }
+}
--- a/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProvider.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, 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
@@ -80,7 +80,6 @@
 public class TestDateTimeTextProvider extends AbstractTestPrinterParser {
 
     Locale enUS = new Locale("en", "US");
-    Locale ptBR = new Locale("pt", "BR");
 
     //-----------------------------------------------------------------------
     @DataProvider(name = "Text")
@@ -94,14 +93,6 @@
             {DAY_OF_WEEK, 6, TextStyle.SHORT, enUS, "Sat"},
             {DAY_OF_WEEK, 7, TextStyle.SHORT, enUS, "Sun"},
 
-            {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg"},
-            {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter"},
-            {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua"},
-            {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui"},
-            {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex"},
-            {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b"},
-            {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom"},
-
             {DAY_OF_WEEK, 1, TextStyle.FULL, enUS, "Monday"},
             {DAY_OF_WEEK, 2, TextStyle.FULL, enUS, "Tuesday"},
             {DAY_OF_WEEK, 3, TextStyle.FULL, enUS, "Wednesday"},
@@ -110,14 +101,6 @@
             {DAY_OF_WEEK, 6, TextStyle.FULL, enUS, "Saturday"},
             {DAY_OF_WEEK, 7, TextStyle.FULL, enUS, "Sunday"},
 
-            {DAY_OF_WEEK, 1, TextStyle.FULL, ptBR, "segunda-feira"},
-            {DAY_OF_WEEK, 2, TextStyle.FULL, ptBR, "ter\u00E7a-feira"},
-            {DAY_OF_WEEK, 3, TextStyle.FULL, ptBR, "quarta-feira"},
-            {DAY_OF_WEEK, 4, TextStyle.FULL, ptBR, "quinta-feira"},
-            {DAY_OF_WEEK, 5, TextStyle.FULL, ptBR, "sexta-feira"},
-            {DAY_OF_WEEK, 6, TextStyle.FULL, ptBR, "s\u00E1bado"},
-            {DAY_OF_WEEK, 7, TextStyle.FULL, ptBR, "domingo"},
-
             {MONTH_OF_YEAR, 1, TextStyle.SHORT, enUS, "Jan"},
             {MONTH_OF_YEAR, 2, TextStyle.SHORT, enUS, "Feb"},
             {MONTH_OF_YEAR, 3, TextStyle.SHORT, enUS, "Mar"},
@@ -131,19 +114,6 @@
             {MONTH_OF_YEAR, 11, TextStyle.SHORT, enUS, "Nov"},
             {MONTH_OF_YEAR, 12, TextStyle.SHORT, enUS, "Dec"},
 
-            {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"},
-            {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"},
-            {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"},
-            {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"},
-            {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"},
-            {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"},
-            {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"},
-            {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"},
-            {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"},
-            {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"},
-            {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"},
-            {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"},
-
             {MONTH_OF_YEAR, 1, TextStyle.FULL, enUS, "January"},
             {MONTH_OF_YEAR, 2, TextStyle.FULL, enUS, "February"},
             {MONTH_OF_YEAR, 3, TextStyle.FULL, enUS, "March"},
@@ -157,19 +127,6 @@
             {MONTH_OF_YEAR, 11, TextStyle.FULL, enUS, "November"},
             {MONTH_OF_YEAR, 12, TextStyle.FULL, enUS, "December"},
 
-            {MONTH_OF_YEAR, 1, TextStyle.FULL, ptBR, "janeiro"},
-            {MONTH_OF_YEAR, 2, TextStyle.FULL, ptBR, "fevereiro"},
-            {MONTH_OF_YEAR, 3, TextStyle.FULL, ptBR, "mar\u00E7o"},
-            {MONTH_OF_YEAR, 4, TextStyle.FULL, ptBR, "abril"},
-            {MONTH_OF_YEAR, 5, TextStyle.FULL, ptBR, "maio"},
-            {MONTH_OF_YEAR, 6, TextStyle.FULL, ptBR, "junho"},
-            {MONTH_OF_YEAR, 7, TextStyle.FULL, ptBR, "julho"},
-            {MONTH_OF_YEAR, 8, TextStyle.FULL, ptBR, "agosto"},
-            {MONTH_OF_YEAR, 9, TextStyle.FULL, ptBR, "setembro"},
-            {MONTH_OF_YEAR, 10, TextStyle.FULL, ptBR, "outubro"},
-            {MONTH_OF_YEAR, 11, TextStyle.FULL, ptBR, "novembro"},
-            {MONTH_OF_YEAR, 12, TextStyle.FULL, ptBR, "dezembro"},
-
             {AMPM_OF_DAY, 0, TextStyle.SHORT, enUS, "AM"},
             {AMPM_OF_DAY, 1, TextStyle.SHORT, enUS, "PM"},
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestDateTimeTextProviderWithLocale.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,146 @@
+/*
+ * 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
+ * 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:
+ *
+ * Copyright (c) 2011-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import static java.time.temporal.ChronoField.AMPM_OF_DAY;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * Test SimpleDateTimeTextProviderWithLocale.
+ */
+@Test
+public class TestDateTimeTextProviderWithLocale extends AbstractTestPrinterParser {
+
+    Locale enUS = new Locale("en", "US");
+    Locale ptBR = new Locale("pt", "BR");
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name = "Text")
+    Object[][] data_text() {
+        return new Object[][] {
+            {DAY_OF_WEEK, 1, TextStyle.SHORT, ptBR, "seg"},
+            {DAY_OF_WEEK, 2, TextStyle.SHORT, ptBR, "ter"},
+            {DAY_OF_WEEK, 3, TextStyle.SHORT, ptBR, "qua"},
+            {DAY_OF_WEEK, 4, TextStyle.SHORT, ptBR, "qui"},
+            {DAY_OF_WEEK, 5, TextStyle.SHORT, ptBR, "sex"},
+            {DAY_OF_WEEK, 6, TextStyle.SHORT, ptBR, "s\u00E1b"},
+            {DAY_OF_WEEK, 7, TextStyle.SHORT, ptBR, "dom"},
+
+            {DAY_OF_WEEK, 1, TextStyle.FULL, ptBR, "segunda-feira"},
+            {DAY_OF_WEEK, 2, TextStyle.FULL, ptBR, "ter\u00E7a-feira"},
+            {DAY_OF_WEEK, 3, TextStyle.FULL, ptBR, "quarta-feira"},
+            {DAY_OF_WEEK, 4, TextStyle.FULL, ptBR, "quinta-feira"},
+            {DAY_OF_WEEK, 5, TextStyle.FULL, ptBR, "sexta-feira"},
+            {DAY_OF_WEEK, 6, TextStyle.FULL, ptBR, "s\u00E1bado"},
+            {DAY_OF_WEEK, 7, TextStyle.FULL, ptBR, "domingo"},
+
+            {MONTH_OF_YEAR, 1, TextStyle.SHORT, ptBR, "jan"},
+            {MONTH_OF_YEAR, 2, TextStyle.SHORT, ptBR, "fev"},
+            {MONTH_OF_YEAR, 3, TextStyle.SHORT, ptBR, "mar"},
+            {MONTH_OF_YEAR, 4, TextStyle.SHORT, ptBR, "abr"},
+            {MONTH_OF_YEAR, 5, TextStyle.SHORT, ptBR, "mai"},
+            {MONTH_OF_YEAR, 6, TextStyle.SHORT, ptBR, "jun"},
+            {MONTH_OF_YEAR, 7, TextStyle.SHORT, ptBR, "jul"},
+            {MONTH_OF_YEAR, 8, TextStyle.SHORT, ptBR, "ago"},
+            {MONTH_OF_YEAR, 9, TextStyle.SHORT, ptBR, "set"},
+            {MONTH_OF_YEAR, 10, TextStyle.SHORT, ptBR, "out"},
+            {MONTH_OF_YEAR, 11, TextStyle.SHORT, ptBR, "nov"},
+            {MONTH_OF_YEAR, 12, TextStyle.SHORT, ptBR, "dez"},
+
+            {MONTH_OF_YEAR, 1, TextStyle.FULL, ptBR, "janeiro"},
+            {MONTH_OF_YEAR, 2, TextStyle.FULL, ptBR, "fevereiro"},
+            {MONTH_OF_YEAR, 3, TextStyle.FULL, ptBR, "mar\u00E7o"},
+            {MONTH_OF_YEAR, 4, TextStyle.FULL, ptBR, "abril"},
+            {MONTH_OF_YEAR, 5, TextStyle.FULL, ptBR, "maio"},
+            {MONTH_OF_YEAR, 6, TextStyle.FULL, ptBR, "junho"},
+            {MONTH_OF_YEAR, 7, TextStyle.FULL, ptBR, "julho"},
+            {MONTH_OF_YEAR, 8, TextStyle.FULL, ptBR, "agosto"},
+            {MONTH_OF_YEAR, 9, TextStyle.FULL, ptBR, "setembro"},
+            {MONTH_OF_YEAR, 10, TextStyle.FULL, ptBR, "outubro"},
+            {MONTH_OF_YEAR, 11, TextStyle.FULL, ptBR, "novembro"},
+            {MONTH_OF_YEAR, 12, TextStyle.FULL, ptBR, "dezembro"},
+
+        };
+    }
+
+    @Test(dataProvider = "Text")
+    public void test_getText(TemporalField field, Number value, TextStyle style, Locale locale, String expected) {
+          DateTimeFormatter fmt = getFormatter(field, style).withLocale(locale);
+          assertEquals(fmt.format(ZonedDateTime.now().with(field, value.longValue())), expected);
+    }
+
+}
--- a/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java	Thu Jan 12 12:14:13 2017 -0800
@@ -20,13 +20,14 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package test.java.time.format;
-
 /*
  * @test
+ * @modules jdk.localedata
  * @bug 8146750
  * @summary Test Narrow and NarrowStandalone month names are retrieved correctly.
  */
+package test.java.time.format;
+
 import static org.testng.Assert.assertEquals;
 
 import java.time.DayOfWeek;
--- a/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestNonIsoFormatter.java	Thu Jan 12 12:14:13 2017 -0800
@@ -20,6 +20,13 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
+/*
+ *
+ * @test
+ * @modules jdk.localedata
+ */
+
 package test.java.time.format;
 
 import static org.testng.Assert.assertEquals;
--- a/jdk/test/java/time/test/java/time/format/TestTextParser.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestTextParser.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, 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
@@ -68,16 +68,9 @@
 
 import java.text.ParsePosition;
 import java.time.DayOfWeek;
-import java.time.chrono.ChronoLocalDate;
-import java.time.chrono.JapaneseChronology;
-import java.time.chrono.HijrahDate;
-import java.time.chrono.JapaneseDate;
-import java.time.chrono.MinguoDate;
-import java.time.chrono.ThaiBuddhistDate;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.TextStyle;
-import java.time.format.SignStyle;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQueries;
@@ -92,8 +85,6 @@
  */
 @Test
 public class TestTextParser extends AbstractTestPrinterParser {
-    static final Locale RUSSIAN = new Locale("ru");
-    static final Locale FINNISH = new Locale("fi");
 
     //-----------------------------------------------------------------------
     @DataProvider(name="error")
@@ -213,20 +204,6 @@
        };
     }
 
-    // Test data is dependent on localized resources.
-    @DataProvider(name="parseStandaloneText")
-    Object[][] providerStandaloneText() {
-        // Locale, TemporalField, TextStyle, expected value, input text
-        return new Object[][] {
-            {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE,   1, "\u044f\u043d\u0432\u0430\u0440\u044c"},
-            {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE,  12, "\u0434\u0435\u043a\u0430\u0431\u0440\u044c"},
-            {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE,  1, "\u044f\u043d\u0432."},
-            {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 12, "\u0434\u0435\u043a."},
-            {FINNISH, DAY_OF_WEEK,   TextStyle.FULL_STANDALONE,   2, "tiistai"},
-            {FINNISH, DAY_OF_WEEK,   TextStyle.SHORT_STANDALONE,  2, "ti"},
-        };
-    }
-
     @DataProvider(name="parseDayOfWeekText")
     Object[][] providerDayOfWeekData() {
         return new Object[][] {
@@ -234,26 +211,9 @@
             {Locale.US, "e",  "1",  DayOfWeek.SUNDAY},
             {Locale.US, "ee", "01", DayOfWeek.SUNDAY},
             {Locale.US, "c",  "1",  DayOfWeek.SUNDAY},
-
-            {Locale.UK, "e",  "1",  DayOfWeek.MONDAY},
-            {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
-            {Locale.UK, "c",  "1",  DayOfWeek.MONDAY},
         };
     }
 
-    // Test data is dependent on localized resources.
-    @DataProvider(name="parseLenientText")
-    Object[][] providerLenientText() {
-        // Locale, TemporalField, expected value, input text
-        return new Object[][] {
-            {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044f"}, // full format
-            {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"}, // full standalone
-            {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short format
-            {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short standalone
-        };
-    }
-
-
 
     @Test(dataProvider="parseText")
     public void test_parseText(TemporalField field, TextStyle style, int value, String input) throws Exception {
@@ -269,14 +229,6 @@
         assertEquals(pos.getIndex(), input.length());
     }
 
-    @Test(dataProvider="parseStandaloneText")
-    public void test_parseStandaloneText(Locale locale, TemporalField field, TextStyle style, int expectedValue, String input) {
-        DateTimeFormatter formatter = getFormatter(field, style).withLocale(locale);
-        ParsePosition pos = new ParsePosition(0);
-        assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
-        assertEquals(pos.getIndex(), input.length());
-    }
-
     @Test(dataProvider="parseDayOfWeekText")
     public void test_parseDayOfWeekText(Locale locale, String pattern, String input, DayOfWeek expected) {
         DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
@@ -374,25 +326,6 @@
     }
 
     //-----------------------------------------------------------------------
-    public void test_parse_french_short_strict_full_noMatch() throws Exception {
-        setStrict(true);
-        ParsePosition pos = new ParsePosition(0);
-        getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
-                                                    .parseUnresolved("janvier", pos);
-        assertEquals(pos.getErrorIndex(), 0);
-    }
-
-    public void test_parse_french_short_strict_short_match() throws Exception {
-        setStrict(true);
-        ParsePosition pos = new ParsePosition(0);
-        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
-                                                                 .parseUnresolved("janv.", pos)
-                                                                 .getLong(MONTH_OF_YEAR),
-                     1L);
-        assertEquals(pos.getIndex(), 5);
-    }
-
-    //-----------------------------------------------------------------------
     public void test_parse_full_lenient_full_match() throws Exception {
         setStrict(false);
         ParsePosition pos = new ParsePosition(0);
@@ -436,51 +369,4 @@
         assertEquals(pos.getIndex(), 1);
     }
 
-    @Test(dataProvider="parseLenientText")
-    public void test_parseLenientText(Locale locale, TemporalField field, int expectedValue, String input) {
-        setStrict(false);
-        ParsePosition pos = new ParsePosition(0);
-        DateTimeFormatter formatter = getFormatter(field).withLocale(locale);
-        assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
-        assertEquals(pos.getIndex(), input.length());
-    }
-
-    //-----------------------------------------------------------------------
-    @DataProvider(name="parseChronoLocalDate")
-    Object[][] provider_chronoLocalDate() {
-        return new Object[][] {
-            { HijrahDate.now() },
-            { JapaneseDate.now() },
-            { MinguoDate.now() },
-            { ThaiBuddhistDate.now() }};
-    }
-
-    private static final DateTimeFormatter fmt_chrono =
-        new DateTimeFormatterBuilder()
-            .optionalStart()
-            .appendChronologyId()
-            .appendLiteral(' ')
-            .optionalEnd()
-            .optionalStart()
-            .appendText(ChronoField.ERA, TextStyle.SHORT)
-            .appendLiteral(' ')
-            .optionalEnd()
-            .appendValue(ChronoField.YEAR_OF_ERA, 1, 9, SignStyle.NORMAL)
-            .appendLiteral('-')
-            .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
-            .appendLiteral('-')
-            .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
-            .toFormatter();
-
-    @Test(dataProvider="parseChronoLocalDate")
-    public void test_chronoLocalDate(ChronoLocalDate date) throws Exception {
-        System.out.printf(" %s, [fmt=%s]%n", date, fmt_chrono.format(date));
-        assertEquals(date, fmt_chrono.parse(fmt_chrono.format(date), ChronoLocalDate::from));
-
-        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[GGG ]yyy-MM-dd")
-                                                 .withChronology(date.getChronology());
-        System.out.printf(" %s, [fmt=%s]%n", date.toString(), fmt.format(date));
-        assertEquals(date, fmt.parse(fmt.format(date), ChronoLocalDate::from));
-    }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestTextParserWithLocale.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,226 @@
+/*
+ * 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
+ * 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:
+ *
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import java.text.ParsePosition;
+import java.time.chrono.ChronoLocalDate;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.HijrahDate;
+import java.time.chrono.JapaneseDate;
+import java.time.chrono.MinguoDate;
+import java.time.chrono.ThaiBuddhistDate;
+import java.time.DayOfWeek;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.TextStyle;
+import java.time.format.SignStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Test TextPrinterParser.
+ */
+@Test
+public class TestTextParserWithLocale extends AbstractTestPrinterParser {
+    static final Locale RUSSIAN = new Locale("ru");
+    static final Locale FINNISH = new Locale("fi");
+
+    @DataProvider(name="parseDayOfWeekText")
+    Object[][] providerDayOfWeekData() {
+        return new Object[][] {
+            // Locale, pattern, input text, expected DayOfWeek
+            {Locale.US, "e",  "1",  DayOfWeek.SUNDAY},
+            {Locale.US, "ee", "01", DayOfWeek.SUNDAY},
+            {Locale.US, "c",  "1",  DayOfWeek.SUNDAY},
+
+            {Locale.UK, "e",  "1",  DayOfWeek.MONDAY},
+            {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
+            {Locale.UK, "c",  "1",  DayOfWeek.MONDAY},
+        };
+    }
+
+    @Test(dataProvider="parseDayOfWeekText")
+    public void test_parseDayOfWeekText(Locale locale, String pattern, String input, DayOfWeek expected) {
+        DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
+        ParsePosition pos = new ParsePosition(0);
+        assertEquals(DayOfWeek.from(formatter.parse(input, pos)), expected);
+        assertEquals(pos.getIndex(), input.length());
+    }
+
+    //--------------------------------------------------------------------
+    // Test data is dependent on localized resources.
+    @DataProvider(name="parseStandaloneText")
+    Object[][] providerStandaloneText() {
+        // Locale, TemporalField, TextStyle, expected value, input text
+        return new Object[][] {
+            {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE,   1, "\u044f\u043d\u0432\u0430\u0440\u044c"},
+            {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE,  12, "\u0434\u0435\u043a\u0430\u0431\u0440\u044c"},
+            {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE,  1, "\u044f\u043d\u0432."},
+            {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, 12, "\u0434\u0435\u043a."},
+            {FINNISH, DAY_OF_WEEK,   TextStyle.FULL_STANDALONE,   2, "tiistai"},
+            {FINNISH, DAY_OF_WEEK,   TextStyle.SHORT_STANDALONE,  2, "ti"},
+        };
+    }
+
+    // Test data is dependent on localized resources.
+    @DataProvider(name="parseLenientText")
+    Object[][] providerLenientText() {
+        // Locale, TemporalField, expected value, input text
+        return new Object[][] {
+            {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044f"}, // full format
+            {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432\u0430\u0440\u044c"}, // full standalone
+            {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short format
+            {RUSSIAN, MONTH_OF_YEAR, 1, "\u044f\u043d\u0432."}, // short standalone
+        };
+    }
+
+    @Test(dataProvider="parseStandaloneText")
+    public void test_parseStandaloneText(Locale locale, TemporalField field, TextStyle style, int expectedValue, String input) {
+        DateTimeFormatter formatter = getFormatter(field, style).withLocale(locale);
+        ParsePosition pos = new ParsePosition(0);
+        assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
+        assertEquals(pos.getIndex(), input.length());
+    }
+
+    //-----------------------------------------------------------------------
+    public void test_parse_french_short_strict_full_noMatch() throws Exception {
+        setStrict(true);
+        ParsePosition pos = new ParsePosition(0);
+        getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
+                                                    .parseUnresolved("janvier", pos);
+        assertEquals(pos.getErrorIndex(), 0);
+    }
+
+    public void test_parse_french_short_strict_short_match() throws Exception {
+        setStrict(true);
+        ParsePosition pos = new ParsePosition(0);
+        assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH)
+                                                                 .parseUnresolved("janv.", pos)
+                                                                 .getLong(MONTH_OF_YEAR),
+                     1L);
+        assertEquals(pos.getIndex(), 5);
+    }
+
+    //-----------------------------------------------------------------------
+
+    @Test(dataProvider="parseLenientText")
+    public void test_parseLenientText(Locale locale, TemporalField field, int expectedValue, String input) {
+        setStrict(false);
+        ParsePosition pos = new ParsePosition(0);
+        DateTimeFormatter formatter = getFormatter(field).withLocale(locale);
+        assertEquals(formatter.parseUnresolved(input, pos).getLong(field), (long) expectedValue);
+        assertEquals(pos.getIndex(), input.length());
+    }
+
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="parseChronoLocalDate")
+    Object[][] provider_chronoLocalDate() {
+        return new Object[][] {
+            { HijrahDate.now() },
+            { JapaneseDate.now() },
+            { MinguoDate.now() },
+            { ThaiBuddhistDate.now() }};
+    }
+
+    private static final DateTimeFormatter fmt_chrono =
+        new DateTimeFormatterBuilder()
+            .optionalStart()
+            .appendChronologyId()
+            .appendLiteral(' ')
+            .optionalEnd()
+            .optionalStart()
+            .appendText(ChronoField.ERA, TextStyle.SHORT)
+            .appendLiteral(' ')
+            .optionalEnd()
+            .appendValue(ChronoField.YEAR_OF_ERA, 1, 9, SignStyle.NORMAL)
+            .appendLiteral('-')
+            .appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NEVER)
+            .appendLiteral('-')
+            .appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NEVER)
+            .toFormatter();
+
+    @Test(dataProvider="parseChronoLocalDate")
+    public void test_chronoLocalDate(ChronoLocalDate date) throws Exception {
+        System.out.printf(" %s, [fmt=%s]%n", date, fmt_chrono.format(date));
+        assertEquals(date, fmt_chrono.parse(fmt_chrono.format(date), ChronoLocalDate::from));
+
+        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("[GGG ]yyy-MM-dd")
+                                                 .withChronology(date.getChronology());
+        System.out.printf(" %s, [fmt=%s]%n", date.toString(), fmt.format(date));
+        assertEquals(date, fmt.parse(fmt.format(date), ChronoLocalDate::from));
+    }
+}
--- a/jdk/test/java/time/test/java/time/format/TestTextPrinter.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/time/test/java/time/format/TestTextPrinter.java	Thu Jan 12 12:14:13 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, 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
@@ -84,8 +84,6 @@
  */
 @Test
 public class TestTextPrinter extends AbstractTestPrinterParser {
-    static final Locale RUSSIAN = new Locale("ru");
-    static final Locale FINNISH = new Locale("fi");
 
     //-----------------------------------------------------------------------
     @Test(expectedExceptions=DateTimeException.class)
@@ -213,32 +211,6 @@
             {Locale.US, "e",  "1",  DayOfWeek.SUNDAY},
             {Locale.US, "ee", "01", DayOfWeek.SUNDAY},
             {Locale.US, "c",  "1",  DayOfWeek.SUNDAY},
-
-            {Locale.UK, "e",  "1",  DayOfWeek.MONDAY},
-            {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
-            {Locale.UK, "c",  "1",  DayOfWeek.MONDAY},
-        };
-    }
-
-    @DataProvider(name="print_JapaneseChronology")
-    Object[][] provider_japaneseEra() {
-       return new Object[][] {
-            {ERA,           TextStyle.FULL, 2, "Heisei"}, // Note: CLDR doesn't define "wide" Japanese era names.
-            {ERA,           TextStyle.SHORT, 2, "Heisei"},
-            {ERA,           TextStyle.NARROW, 2, "H"},
-       };
-    };
-
-    // Test data is dependent on localized resources.
-    @DataProvider(name="print_standalone")
-    Object[][] provider_StandaloneNames() {
-        return new Object[][] {
-            // standalone names for 2013-01-01 (Tue)
-            // Locale, TemporalField, TextStyle, expected text
-            {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE,  "\u044f\u043d\u0432\u0430\u0440\u044c"},
-            {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, "\u044f\u043d\u0432."},
-            {FINNISH, DAY_OF_WEEK,   TextStyle.FULL_STANDALONE,  "tiistai"},
-            {FINNISH, DAY_OF_WEEK,   TextStyle.SHORT_STANDALONE, "ti"},
         };
     }
 
@@ -255,30 +227,6 @@
         assertEquals(text, expected);
     }
 
-    @Test(dataProvider="print_JapaneseChronology")
-    public void test_formatJapaneseEra(TemporalField field, TextStyle style, int value, String expected) throws Exception {
-        LocalDate ld = LocalDate.of(2013, 1, 31);
-        getFormatter(field, style).withChronology(JapaneseChronology.INSTANCE).formatTo(ld, buf);
-        assertEquals(buf.toString(), expected);
-    }
-
-    @Test(dataProvider="print_standalone")
-    public void test_standaloneNames(Locale locale, TemporalField field, TextStyle style, String expected) {
-        getFormatter(field, style).withLocale(locale).formatTo(LocalDate.of(2013, 1, 1), buf);
-        assertEquals(buf.toString(), expected);
-    }
-
-    //-----------------------------------------------------------------------
-    public void test_print_french_long() throws Exception {
-        getFormatter(MONTH_OF_YEAR, TextStyle.FULL).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
-        assertEquals(buf.toString(), "janvier");
-    }
-
-    public void test_print_french_short() throws Exception {
-        getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
-        assertEquals(buf.toString(), "janv.");
-    }
-
     //-----------------------------------------------------------------------
     public void test_toString1() throws Exception {
         assertEquals(getFormatter(MONTH_OF_YEAR, TextStyle.FULL).toString(), "Text(MonthOfYear)");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestTextPrinterWithLocale.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,163 @@
+/*
+ * 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
+ * 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:
+ *
+ * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of JSR-310 nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @test
+ * @modules jdk.localedata
+ */
+
+package test.java.time.format;
+
+import static java.time.temporal.ChronoField.DAY_OF_MONTH;
+import static java.time.temporal.ChronoField.DAY_OF_WEEK;
+import static java.time.temporal.ChronoField.ERA;
+import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
+import static java.time.temporal.IsoFields.QUARTER_OF_YEAR;
+import static org.testng.Assert.assertEquals;
+
+import java.time.DateTimeException;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.chrono.JapaneseChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.time.temporal.TemporalField;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import test.java.time.temporal.MockFieldValue;
+
+/**
+ * Test TextPrinterParserWithLocale.
+ */
+@Test
+public class TestTextPrinterWithLocale extends AbstractTestPrinterParser {
+    static final Locale RUSSIAN = new Locale("ru");
+    static final Locale FINNISH = new Locale("fi");
+
+    //-----------------------------------------------------------------------
+    @DataProvider(name="print_DayOfWeekData")
+    Object[][] providerDayOfWeekData() {
+        return new Object[][] {
+            // Locale, pattern, expected text, input DayOfWeek
+            {Locale.US, "e",  "1",  DayOfWeek.SUNDAY},
+            {Locale.US, "ee", "01", DayOfWeek.SUNDAY},
+            {Locale.US, "c",  "1",  DayOfWeek.SUNDAY},
+
+            {Locale.UK, "e",  "1",  DayOfWeek.MONDAY},
+            {Locale.UK, "ee", "01", DayOfWeek.MONDAY},
+            {Locale.UK, "c",  "1",  DayOfWeek.MONDAY},
+        };
+    }
+
+    // Test data is dependent on localized resources.
+    @DataProvider(name="print_standalone")
+    Object[][] provider_StandaloneNames() {
+        return new Object[][] {
+            // standalone names for 2013-01-01 (Tue)
+            // Locale, TemporalField, TextStyle, expected text
+            {RUSSIAN, MONTH_OF_YEAR, TextStyle.FULL_STANDALONE,  "\u044f\u043d\u0432\u0430\u0440\u044c"},
+            {RUSSIAN, MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE, "\u044f\u043d\u0432."},
+            {FINNISH, DAY_OF_WEEK,   TextStyle.FULL_STANDALONE,  "tiistai"},
+            {FINNISH, DAY_OF_WEEK,   TextStyle.SHORT_STANDALONE, "ti"},
+        };
+    }
+
+    @Test(dataProvider="print_DayOfWeekData")
+    public void test_formatDayOfWeek(Locale locale, String pattern, String expected, DayOfWeek dayOfWeek) {
+        DateTimeFormatter formatter = getPatternFormatter(pattern).withLocale(locale);
+        String text = formatter.format(dayOfWeek);
+        assertEquals(text, expected);
+    }
+
+    @Test(dataProvider="print_standalone")
+    public void test_standaloneNames(Locale locale, TemporalField field, TextStyle style, String expected) {
+        getFormatter(field, style).withLocale(locale).formatTo(LocalDate.of(2013, 1, 1), buf);
+        assertEquals(buf.toString(), expected);
+    }
+
+    //-----------------------------------------------------------------------
+    public void test_print_french_long() throws Exception {
+        getFormatter(MONTH_OF_YEAR, TextStyle.FULL).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
+        assertEquals(buf.toString(), "janvier");
+    }
+
+    public void test_print_french_short() throws Exception {
+        getFormatter(MONTH_OF_YEAR, TextStyle.SHORT).withLocale(Locale.FRENCH).formatTo(LocalDate.of(2012, 1, 1), buf);
+        assertEquals(buf.toString(), "janv.");
+    }
+
+    @DataProvider(name="print_JapaneseChronology")
+    Object[][] provider_japaneseEra() {
+       return new Object[][] {
+            {ERA,           TextStyle.FULL, 2, "Heisei"}, // Note: CLDR doesn't define "wide" Japanese era names.
+            {ERA,           TextStyle.SHORT, 2, "Heisei"},
+            {ERA,           TextStyle.NARROW, 2, "H"},
+       };
+    };
+
+    @Test(dataProvider="print_JapaneseChronology")
+    public void test_formatJapaneseEra(TemporalField field, TextStyle style, int value, String expected) throws Exception {
+        LocalDate ld = LocalDate.of(2013, 1, 31);
+        getFormatter(field, style).withChronology(JapaneseChronology.INSTANCE).formatTo(ld, buf);
+        assertEquals(buf.toString(), expected);
+    }
+}
--- a/jdk/test/java/util/Collection/SetFactories.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/util/Collection/SetFactories.java	Thu Jan 12 12:14:13 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
@@ -103,6 +103,8 @@
               hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i")),
             a(   Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
               hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+                 Set.of("j", "i", "h", "g", "f", "e", "d", "c", "b", "a")),
             a(   Set.of(stringArray),
               hashSetOf(stringArray))
         ).iterator();
@@ -183,6 +185,17 @@
         Set<String> set = Set.of(array);
     }
 
+    @Test(dataProvider="all")
+    public void hashCodeEqual(Set<String> act, Set<String> exp) {
+        assertEquals(act.hashCode(), exp.hashCode());
+    }
+
+    @Test(dataProvider="all")
+    public void containsAll(Set<String> act, Set<String> exp) {
+        assertTrue(act.containsAll(exp));
+        assertTrue(exp.containsAll(act));
+    }
+
     @Test(expectedExceptions=NullPointerException.class)
     public void nullDisallowed1() {
         Set.of((String)null); // force one-arg overload
--- a/jdk/test/java/util/Map/MapFactories.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/java/util/Map/MapFactories.java	Thu Jan 12 12:14:13 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
@@ -103,6 +103,8 @@
             a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h"), genMap(8)),
             a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i"), genMap(9)),
             a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j"), genMap(10)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j"),
+              Map.of(4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j", 0, "a", 1, "b", 2, "c", 3, "d")),
             a(Map.ofEntries(genEntries(MAX_ENTRIES)), genMap(MAX_ENTRIES))
         ).iterator();
     }
@@ -135,6 +137,18 @@
         assertEquals(act, exp);
     }
 
+    @Test(dataProvider="all")
+    public void containsAllKeys(Map<Integer,String> act, Map<Integer,String> exp) {
+        assertTrue(act.keySet().containsAll(exp.keySet()));
+        assertTrue(exp.keySet().containsAll(act.keySet()));
+    }
+
+    @Test(dataProvider="all")
+    public void containsAllValues(Map<Integer,String> act, Map<Integer,String> exp) {
+        assertTrue(act.values().containsAll(exp.values()));
+        assertTrue(exp.values().containsAll(act.values()));
+    }
+
     @Test(expectedExceptions=IllegalArgumentException.class)
     public void dupKeysDisallowed2() {
         Map<Integer, String> map = Map.of(0, "a", 0, "b");
@@ -192,6 +206,11 @@
         Map<Integer, String> map = Map.ofEntries(entries);
     }
 
+    @Test(dataProvider="all")
+    public void hashCodeEquals(Map<Integer,String> act, Map<Integer,String> exp) {
+        assertEquals(act.hashCode(), exp.hashCode());
+    }
+
     @Test(expectedExceptions=NullPointerException.class)
     public void nullKeyDisallowed1() {
         Map<Integer, String> map = Map.of(null, "a");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,284 @@
+/*
+ * 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 8159058
+ * @summary Test that empty default namespace declaration clears the
+ *          default namespace value
+ * @modules java.xml.ws/com.sun.xml.internal.ws.api
+ *          java.xml.ws/com.sun.xml.internal.ws.api.message.saaj
+ *          java.xml.ws/com.sun.xml.internal.ws.message.stream
+ * @run testng/othervm SaajEmptyNamespaceTest
+ */
+
+import com.sun.xml.internal.ws.api.SOAPVersion;
+import com.sun.xml.internal.ws.api.message.saaj.SAAJFactory;
+import com.sun.xml.internal.ws.message.stream.StreamMessage;
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import javax.xml.namespace.QName;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPBody;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.w3c.dom.Node;
+
+public class SaajEmptyNamespaceTest {
+
+    /*
+     * Test that SOAP message with default namespace declaration that contains empty
+     * string is properly processed by SAAJ reader.
+     */
+    @Test
+    public void testResetDefaultNamespaceSAAJ() throws Exception {
+        // Create SOAP message from XML string and process it with SAAJ reader
+        XMLStreamReader envelope = XMLInputFactory.newFactory().createXMLStreamReader(
+                new StringReader(INPUT_SOAP_MESSAGE));
+        StreamMessage streamMessage = new StreamMessage(SOAPVersion.SOAP_11,
+                envelope, null);
+        SAAJFactory saajFact = new SAAJFactory();
+        SOAPMessage soapMessage = saajFact.readAsSOAPMessage(SOAPVersion.SOAP_11, streamMessage);
+
+        // Check if constructed object model meets local names and namespace expectations
+        SOAPElement request = (SOAPElement) soapMessage.getSOAPBody().getFirstChild();
+        // Check top body element name
+        Assert.assertEquals(request.getLocalName(), "SampleServiceRequest");
+        // Check top body element namespace
+        Assert.assertEquals(request.getNamespaceURI(), TEST_NS);
+        SOAPElement params = (SOAPElement) request.getFirstChild();
+        // Check first child name
+        Assert.assertEquals(params.getLocalName(), "RequestParams");
+        // Check if first child namespace is null
+        Assert.assertNull(params.getNamespaceURI());
+
+        // Check inner elements of the first child
+        SOAPElement param1 = (SOAPElement) params.getFirstChild();
+        Assert.assertEquals(param1.getLocalName(), "Param1");
+        Assert.assertNull(param1.getNamespaceURI());
+        SOAPElement param2 = (SOAPElement) params.getChildNodes().item(1);
+        Assert.assertEquals(param2.getLocalName(), "Param2");
+        Assert.assertNull(param2.getNamespaceURI());
+        // Check full content of SOAP body
+        Assert.assertEquals(nodeToText(request), EXPECTED_RESULT);
+    }
+
+    /*
+     * Test that adding element with explicitly null namespace URI shall put the
+     * element into global namespace. Namespace declarations are not added explicitly.
+     */
+    @Test
+    public void testAddElementToNullNsNoDeclarations() throws Exception {
+        // Create empty SOAP message
+        SOAPMessage msg = createSoapMessage();
+        SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+        // Add elements
+        SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+        SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", null);
+        SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+        // Check namespace URIs
+        Assert.assertNull(childGlobalNS.getNamespaceURI());
+        Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+    }
+
+    /*
+     * Test that adding element with explicitly empty namespace URI shall put
+     * the element into global namespace. Namespace declarations are not added
+     * explicitly.
+     */
+    @Test
+    public void testAddElementToGlobalNsNoDeclarations() throws Exception {
+        // Create empty SOAP message
+        SOAPMessage msg = createSoapMessage();
+        SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+        // Add elements
+        SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+        SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", "");
+        SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+        // Check namespace URIs
+        Assert.assertNull(childGlobalNS.getNamespaceURI());
+        Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+    }
+
+    /*
+     * Test that adding element with explicitly empty namespace URI set via QName
+     * shall put the element into global namespace.
+     */
+    @Test
+    public void testAddElementToNullNsQName() throws Exception {
+        // Create empty SOAP message
+        SOAPMessage msg = createSoapMessage();
+        SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+        // Add elements
+        SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+        parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+        SOAPElement childGlobalNS = parentExplicitNS.addChildElement(new QName(null, "global-child"));
+        childGlobalNS.addNamespaceDeclaration("", "");
+        SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+        SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+        // Check namespace URIs
+        Assert.assertNull(childGlobalNS.getNamespaceURI());
+        Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+        Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+    }
+
+    /*
+     * Test that adding element with explicitly empty namespace URI shall put
+     * the element into global namespace.
+     */
+    @Test
+    public void testAddElementToGlobalNs() throws Exception {
+        // Create empty SOAP message
+        SOAPMessage msg = createSoapMessage();
+        SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+        // Add elements
+        SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+        parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+        SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", "");
+        childGlobalNS.addNamespaceDeclaration("", "");
+        SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+        SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+        // Check namespace URIs
+        Assert.assertNull(childGlobalNS.getNamespaceURI());
+        Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+        Assert.assertEquals(childDefaultNS.getNamespaceURI(), TEST_NS);
+    }
+
+    /*
+     * Test that adding element with explicitly null namespace URI shall put
+     * the element into global namespace.
+     */
+    @Test
+    public void testAddElementToNullNs() throws Exception {
+        // Create empty SOAP message
+        SOAPMessage msg = createSoapMessage();
+        SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+        // Add elements
+        SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+        parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+        SOAPElement childGlobalNS = parentExplicitNS.addChildElement("global-child", "", null);
+        childGlobalNS.addNamespaceDeclaration("", null);
+        SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+        SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+        // Check namespace URIs
+        Assert.assertNull(childGlobalNS.getNamespaceURI());
+        Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+        Assert.assertEquals(TEST_NS, childDefaultNS.getNamespaceURI());
+    }
+
+    /*
+     * Test that adding element with explicitly empty namespace URI via QName
+     * shall put the element in global namespace.
+     */
+    @Test
+    public void testAddElementToGlobalNsQName() throws Exception {
+        // Create empty SOAP message
+        SOAPMessage msg = createSoapMessage();
+        SOAPBody body = msg.getSOAPPart().getEnvelope().getBody();
+
+        // Add elements
+        SOAPElement parentExplicitNS = body.addChildElement("content", "", TEST_NS);
+        parentExplicitNS.addNamespaceDeclaration("", TEST_NS);
+        SOAPElement childGlobalNS = parentExplicitNS.addChildElement(new QName("", "global-child"));
+        childGlobalNS.addNamespaceDeclaration("", "");
+        SOAPElement grandChildGlobalNS = childGlobalNS.addChildElement("global-grand-child");
+        SOAPElement childDefaultNS = parentExplicitNS.addChildElement("default-child");
+
+        // Check namespace URIs
+        Assert.assertNull(childGlobalNS.getNamespaceURI());
+        Assert.assertNull(grandChildGlobalNS.getNamespaceURI());
+        Assert.assertEquals(childDefaultNS.getNamespaceURI(),TEST_NS);
+    }
+
+    // Convert DOM node to text representation
+    private String nodeToText(Node node) throws TransformerException {
+        Transformer trans = TransformerFactory.newInstance().newTransformer();
+        trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+        StringWriter writer = new StringWriter();
+        StreamResult result = new StreamResult(writer);
+        trans.transform(new DOMSource(node), result);
+        String bodyContent = writer.toString();
+        System.out.println("SOAP body content read by SAAJ:"+bodyContent);
+        return bodyContent;
+    }
+
+    // Create SOAP message with empty body
+    private static SOAPMessage createSoapMessage() throws SOAPException, UnsupportedEncodingException {
+        String xml = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+                    +"<SOAP-ENV:Body/></SOAP-ENV:Envelope>";
+        MessageFactory mFactory = MessageFactory.newInstance();
+        SOAPMessage msg = mFactory.createMessage();
+        msg.getSOAPPart().setContent(new StreamSource(new ByteArrayInputStream(xml.getBytes("utf-8"))));
+        return msg;
+    }
+
+    // Namespace value used in tests
+    private static String TEST_NS = "http://example.org/test";
+
+    // Content of SOAP message passed to SAAJ factory
+    private static String INPUT_SOAP_MESSAGE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+            + "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+            + "<s:Body>"
+            + "<SampleServiceRequest xmlns=\"http://example.org/test\""
+            + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+            + "<RequestParams xmlns=\"\">"
+            + "<Param1>hogehoge</Param1>"
+            + "<Param2>fugafuga</Param2>"
+            + "</RequestParams>"
+            + "</SampleServiceRequest>"
+            + "</s:Body>"
+            + "</s:Envelope>";
+
+    // Expected body content after SAAJ processing
+    private static String EXPECTED_RESULT = "<SampleServiceRequest"
+            +" xmlns=\"http://example.org/test\">"
+            + "<RequestParams xmlns=\"\">"
+            + "<Param1>hogehoge</Param1>"
+            + "<Param2>fugafuga</Param2>"
+            + "</RequestParams>"
+            + "</SampleServiceRequest>";
+}
--- a/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java	Thu Jan 12 12:14:13 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
@@ -29,7 +29,7 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary REGISTRY RegistryRunner
+ * @build TestLibrary RegistryVM RegistryRunner
  * @run main/othervm DeadCachedConnection
  */
 
@@ -100,7 +100,7 @@
 
     public static int makeRegistry(int port) {
         try {
-            subreg = REGISTRY.createREGISTRY(System.out, System.err, "", port);
+            subreg = RegistryVM.createRegistryVM(System.out, System.err, "", port);
             subreg.start();
             int regPort = subreg.getPort();
             System.out.println("Starting registry on port " + regPort);
@@ -113,11 +113,11 @@
         return -1;
     }
 
-    private static REGISTRY subreg = null;
+    private static RegistryVM subreg = null;
 
     public static void killRegistry() throws InterruptedException {
         if (subreg != null) {
-            subreg.shutdown();
+            subreg.cleanup();
             subreg = null;
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/RuntimeTest.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test Multi-Release jar usage in runtime
+ * @library /test/lib
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * @build jdk.test.lib.JDKToolFinder jdk.test.lib.JDKToolLauncher
+ *        jdk.test.lib.process.OutputAnalyzer
+ *        jdk.test.lib.process.ProcessTools
+ *        CompilerUtils RuntimeTest
+ * @run testng RuntimeTest
+ */
+
+import static org.testng.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class RuntimeTest {
+    public static final int SUCCESS = 0;
+    private final String src = System.getProperty("test.src", ".");
+    private final String usr = System.getProperty("user.dir", ".");
+
+    @DataProvider(name = "jarFiles")
+    Object[][] jarFiles() {
+        return new Object[][] { { "MV_BOTH.jar", 9, 9, 9 },
+                { "MV_ONLY_9.jar", 9, 9, 9 },
+                { "NON_MV.jar", 8, 8, 8 } };
+    }
+
+    @BeforeClass
+    protected void setUpTest() throws Throwable {
+        compile();
+        Path classes = Paths.get("classes");
+        jar("cfm", "MV_BOTH.jar", "manifest.txt",
+                "-C", classes.resolve("base").toString(), ".",
+                "--release", "9", "-C", classes.resolve("v9").toString(), ".",
+                "--release", "10", "-C", classes.resolve("v10").toString(), ".")
+                .shouldHaveExitValue(0);
+
+        jar("cfm", "MV_ONLY_9.jar", "manifest.txt",
+                "-C", classes.resolve("base").toString(), ".",
+                "--release", "9", "-C", classes.resolve("v9").toString(), ".")
+                .shouldHaveExitValue(0);
+        jar("cfm", "NON_MV.jar", "manifest.txt",
+                "-C", classes.resolve("base").toString(), ".")
+                .shouldHaveExitValue(0);
+    }
+
+    @Test(dataProvider = "jarFiles")
+    public void testClasspath(String jar, int mainVer, int helperVer,
+            int resVer) throws Throwable {
+        String[] command = { "-cp", jar, "testpackage.Main" };
+        System.out.println("Command arguments:" + Arrays.asList(command));
+        System.out.println();
+        java(command).shouldHaveExitValue(SUCCESS)
+                .shouldContain("Main version: " + mainVer)
+                .shouldContain("Helpers version: " + helperVer)
+                .shouldContain("Resource version: " + resVer);
+    }
+
+    @Test(dataProvider = "jarFiles")
+    void testMVJarAsLib(String jar, int mainVer, int helperVer, int resVer)
+            throws Throwable {
+        String[] apps = { "UseByImport", "UseByReflection" };
+        for (String app : apps) {
+            String[] command = {"-cp",
+                    jar + File.pathSeparatorChar + "classes/test/", app };
+            System.out.println("Command arguments:" + Arrays.asList(command));
+            System.out.println();
+            java(command).shouldHaveExitValue(SUCCESS)
+                    .shouldContain("Main version: " + mainVer)
+                    .shouldContain("Helpers version: " + helperVer)
+                    .shouldContain("Resource version: " + resVer);
+        }
+    }
+
+    @Test(dataProvider = "jarFiles")
+    void testJavaJar(String jar, int mainVer, int helperVer, int resVer)
+            throws Throwable {
+        String[] command = { "-jar", jar };
+        System.out.println("Command arguments:" + Arrays.asList(command));
+        System.out.println();
+        java(command).shouldHaveExitValue(SUCCESS)
+                .shouldContain("Main version: " + mainVer)
+                .shouldContain("Helpers version: " + helperVer)
+                .shouldContain("Resource version: " + resVer);
+    }
+
+    @Test(dataProvider = "jarFiles")
+    void testURLClassLoader(String jarName, int mainVer, int helperVer,
+            int resVer) throws ClassNotFoundException, NoSuchMethodException,
+            IllegalAccessException, IllegalArgumentException,
+            InvocationTargetException, IOException {
+        Path pathToJAR = Paths.get(jarName).toAbsolutePath();
+        URL jarURL1 = new URL("jar:file:" + pathToJAR + "!/");
+        URL jarURL2 = new URL("file:///" + pathToJAR);
+        testURLClassLoaderURL(jarURL1, mainVer, helperVer, resVer);
+        testURLClassLoaderURL(jarURL2, mainVer, helperVer, resVer);
+    }
+
+    private static void testURLClassLoaderURL(URL jarURL,
+            int mainVersionExpected, int helperVersionExpected,
+            int resourceVersionExpected) throws ClassNotFoundException,
+            NoSuchMethodException, IllegalAccessException,
+            IllegalArgumentException, InvocationTargetException, IOException {
+        System.out.println(
+                "Testing URLClassLoader MV JAR support for URL: " + jarURL);
+        URL[] urls = { jarURL };
+        int mainVersionActual;
+        int helperVersionActual;
+        int resourceVersionActual;
+        try (URLClassLoader cl = URLClassLoader.newInstance(urls)) {
+            Class c = cl.loadClass("testpackage.Main");
+            Method getMainVersion = c.getMethod("getMainVersion");
+            mainVersionActual = (int) getMainVersion.invoke(null);
+            Method getHelperVersion = c.getMethod("getHelperVersion");
+            helperVersionActual = (int) getHelperVersion.invoke(null);
+            try (InputStream ris = cl.getResourceAsStream("versionResource");
+                    BufferedReader br = new BufferedReader(
+                            new InputStreamReader(ris))) {
+                resourceVersionActual = Integer.parseInt(br.readLine());
+            }
+        }
+
+        assertEquals(mainVersionActual, mainVersionExpected,
+                         "Test failed: Expected Main class version: "
+                         + mainVersionExpected + " Actual version: "
+                         + mainVersionActual);
+        assertEquals(helperVersionActual, helperVersionExpected,
+                         "Test failed: Expected Helper class version: "
+                         + helperVersionExpected + " Actual version: "
+                         + helperVersionActual);
+        assertEquals(resourceVersionActual, resourceVersionExpected,
+                         "Test failed: Expected resource version: "
+                         + resourceVersionExpected + " Actual version: "
+                         + resourceVersionActual);
+    }
+
+    @Test(dataProvider = "jarFiles")
+    void testJjs(String jar, int mainVer, int helperVer, int resVer)
+            throws Throwable {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jjs");
+        launcher.addToolArg("-cp").addToolArg(jar)
+                .addToolArg(src + "/data/runtimetest/MVJarJJSTestScript.js");
+        ProcessTools.executeCommand(launcher.getCommand())
+                .shouldHaveExitValue(SUCCESS)
+                .shouldContain("Main version: " + mainVer)
+                .shouldContain("Helpers version: " + helperVer)
+                .shouldContain("Resource version: " + resVer);
+    }
+
+    private static OutputAnalyzer jar(String... args) throws Throwable {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jar");
+        Stream.of(args).forEach(launcher::addToolArg);
+        return ProcessTools.executeCommand(launcher.getCommand());
+    }
+
+    private void compile() throws Throwable {
+        String[] vers = { "base", "v9", "v10" };
+        for (String ver : vers) {
+            Path classes = Paths.get(usr, "classes", ver);
+            Files.createDirectories(classes);
+            Path source = Paths.get(src, "data", "runtimetest", ver);
+            assertTrue(CompilerUtils.compile(source, classes));
+            Files.copy(source.resolve("versionResource"),
+                    classes.resolve("versionResource"),
+                    StandardCopyOption.REPLACE_EXISTING);
+        }
+
+        Path classes = Paths.get(usr, "classes", "test");
+        Files.createDirectory(classes);
+        Path source = Paths.get(src, "data", "runtimetest", "test");
+        assertTrue(
+                CompilerUtils.compile(source, classes, "-cp", "classes/base/"));
+        Files.copy(Paths.get(src, "data", "runtimetest", "manifest.txt"),
+                Paths.get(usr, "manifest.txt"),
+                StandardCopyOption.REPLACE_EXISTING);
+    }
+
+    OutputAnalyzer java(String... args) throws Throwable {
+        String java = JDKToolFinder.getJDKTool("java");
+
+        List<String> commands = new ArrayList<>();
+        commands.add(java);
+        Stream.of(args).forEach(x -> commands.add(x));
+        return ProcessTools.executeCommand(new ProcessBuilder(commands));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/MVJarJJSTestScript.js	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+var Main = Java.type("testpackage.Main");
+var mainVersion = Main.getMainVersion();
+var helperVersion = Main.getHelperVersion();
+var resourceVersion = Main.getResourceVersion();
+print("Main version: " + mainVersion);
+print("Helpers version: " + helperVersion);
+print("Resource version: " + resourceVersion);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/testpackage/Helper.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,33 @@
+/*
+ * 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 testpackage;
+
+public class Helper {
+
+    private static final int HELPER_VERSION = 8;
+
+    public static int getHelperVersion() {
+        return HELPER_VERSION;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/testpackage/Main.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,62 @@
+/*
+ * 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 testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+    private static final int MAIN_VERSION = 8;
+
+    public static void main(String[] args) {
+        System.out.println("Main version: " + getMainVersion());
+        System.out.println("Helpers version: " + getHelperVersion());
+        System.out.println("Resource version: " + getResourceVersion());
+    }
+
+    public static int getMainVersion() {
+        return MAIN_VERSION;
+    }
+
+    public static int getHelperVersion() {
+        return testpackage.Helper.getHelperVersion();
+    }
+
+    public static int getResourceVersion() {
+        ClassLoader cl = Main.class.getClassLoader();
+        InputStream ris = cl.getResourceAsStream("versionResource");
+        if (ris == null) {
+            throw new Error("Test issue: resource versionResource"
+                    + " cannot be loaded!");
+        }
+        try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+            return Integer.parseInt(br.readLine());
+        } catch (IOException ioe) {
+            throw new Error("Unexpected issue", ioe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/base/versionResource	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,1 @@
+8
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/manifest.txt	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,1 @@
+Main-Class: testpackage.Main
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/test/UseByImport.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+import testpackage.Main;
+
+/**
+ * This class is used in MVJarAsLibraryTest.java test.
+ * It is a part of the test.
+ */
+public class UseByImport {
+
+    /**
+     * Method for the test execution.
+     * @param args - no args needed
+     */
+    public static void main(String[] args) {
+        System.out.println("Main version: " + Main.getMainVersion());
+        System.out.println("Helpers version: " + Main.getHelperVersion());
+        System.out.println("Resource version: " + Main.getResourceVersion());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/test/UseByReflection.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * This class is used in RuntimeTest.java.
+ */
+public class UseByReflection {
+
+    /**
+     * Method for the test execution.
+     *
+     * @param args - no args needed
+     * @throws java.lang.ClassNotFoundException
+     * @throws java.lang.NoSuchMethodException
+     * @throws java.lang.IllegalAccessException
+     * @throws java.lang.reflect.InvocationTargetException
+     * @throws java.io.IOException
+     */
+    public static void main(String[] args) throws ClassNotFoundException,
+            NoSuchMethodException, IllegalAccessException,
+            IllegalArgumentException, InvocationTargetException, IOException {
+        Class mainClass = Class.forName("testpackage.Main");
+        Method getMainVersion = mainClass.getMethod("getMainVersion");
+        int mainVersionActual = (int) getMainVersion.invoke(null);
+        Method getHelperVersion = mainClass.getMethod("getHelperVersion");
+        int helperVersionActual = (int) getHelperVersion.invoke(null);
+        ClassLoader cl = UseByReflection.class.getClassLoader();
+        int resourceVersionActual;
+        try (InputStream ris = cl.getResourceAsStream("versionResource");
+                BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+            resourceVersionActual = Integer.parseInt(br.readLine());
+        }
+        System.out.println("Main version: " + mainVersionActual);
+        System.out.println("Helpers version: " + helperVersionActual);
+        System.out.println("Resource version: " + resourceVersionActual);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/testpackage/Helper.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,33 @@
+/*
+ * 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 testpackage;
+
+public class Helper {
+
+    private static final int HELPER_VERSION = 10;
+
+    public static int getHelperVersion() {
+        return HELPER_VERSION;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/testpackage/Main.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,62 @@
+/*
+ * 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 testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+    private static final int MAIN_VERSION = 10;
+
+    public static void main(String[] args) {
+        System.out.println("Main version: " + getMainVersion());
+        System.out.println("Helpers version: " + getHelperVersion());
+        System.out.println("Resource version: " + getResourceVersion());
+    }
+
+    public static int getMainVersion() {
+        return MAIN_VERSION;
+    }
+
+    public static int getHelperVersion() {
+        return testpackage.Helper.getHelperVersion();
+    }
+
+    public static int getResourceVersion() {
+        ClassLoader cl = Main.class.getClassLoader();
+        InputStream ris = cl.getResourceAsStream("versionResource");
+        if (ris == null) {
+            throw new Error("Test issue: resource versionResource"
+                    + " cannot be loaded!");
+        }
+        try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+            return Integer.parseInt(br.readLine());
+        } catch (IOException ioe) {
+            throw new Error("Unexpected issue", ioe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v10/versionResource	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,1 @@
+10
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/testpackage/Helper.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,33 @@
+/*
+ * 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 testpackage;
+
+public class Helper {
+
+    private static final int HELPER_VERSION = 9;
+
+    public static int getHelperVersion() {
+        return HELPER_VERSION;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/testpackage/Main.java	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,62 @@
+/*
+ * 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 testpackage;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Main {
+
+    private static final int MAIN_VERSION = 9;
+
+    public static void main(String[] args) {
+        System.out.println("Main version: " + getMainVersion());
+        System.out.println("Helpers version: " + getHelperVersion());
+        System.out.println("Resource version: " + getResourceVersion());
+    }
+
+    public static int getMainVersion() {
+        return MAIN_VERSION;
+    }
+
+    public static int getHelperVersion() {
+        return testpackage.Helper.getHelperVersion();
+    }
+
+    public static int getResourceVersion() {
+        ClassLoader cl = Main.class.getClassLoader();
+        InputStream ris = cl.getResourceAsStream("versionResource");
+        if (ris == null) {
+            throw new Error("Test issue: resource versionResource"
+                    + " cannot be loaded!");
+        }
+        try (BufferedReader br = new BufferedReader(new InputStreamReader(ris))) {
+            return Integer.parseInt(br.readLine());
+        } catch (IOException ioe) {
+            throw new Error("Unexpected issue", ioe);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/multiRelease/data/runtimetest/v9/versionResource	Thu Jan 12 12:14:13 2017 -0800
@@ -0,0 +1,1 @@
+9
--- a/jdk/test/tools/jmod/JmodTest.java	Thu Jan 12 11:58:01 2017 -0800
+++ b/jdk/test/tools/jmod/JmodTest.java	Thu Jan 12 12:14:13 2017 -0800
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8142968 8166568 8166286 8170618
+ * @bug 8142968 8166568 8166286 8170618 8168149
  * @summary Basic test for jmod
  * @library /lib/testlibrary
  * @modules jdk.compiler
@@ -459,6 +459,76 @@
     }
 
     @Test
+    public void testLastOneWins() throws IOException {
+        Path workDir = Paths.get("lastOneWins");
+        if (Files.exists(workDir))
+            FileUtils.deleteFileTreeWithRetry(workDir);
+        Files.createDirectory(workDir);
+        Path jmod = MODS_DIR.resolve("lastOneWins.jmod");
+        FileUtils.deleteFileIfExistsWithRetry(jmod);
+        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
+        Path bp = EXPLODED_DIR.resolve("foo").resolve("bin");
+        Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");
+        Path cf = EXPLODED_DIR.resolve("foo").resolve("conf");
+
+        Path shouldNotBeAdded = workDir.resolve("shouldNotBeAdded");
+        Files.createDirectory(shouldNotBeAdded);
+        Files.write(shouldNotBeAdded.resolve("aFile"), "hello".getBytes(UTF_8));
+
+        // Pairs of options. For options with required arguments the last one
+        // should win ( first should be effectively ignored, but may still be
+        // validated ).
+        jmod("create",
+             "--conf", shouldNotBeAdded.toString(),
+             "--conf", cf.toString(),
+             "--cmds", shouldNotBeAdded.toString(),
+             "--cmds", bp.toString(),
+             "--libs", shouldNotBeAdded.toString(),
+             "--libs", lp.toString(),
+             "--class-path", shouldNotBeAdded.toString(),
+             "--class-path", cp.toString(),
+             "--main-class", "does.NotExist",
+             "--main-class", "jdk.test.foo.Foo",
+             "--module-version", "00001",
+             "--module-version", "5.4.3",
+             "--do-not-resolve-by-default",
+             "--do-not-resolve-by-default",
+             "--warn-if-resolved=incubating",
+             "--warn-if-resolved=deprecated",
+             MODS_DIR.resolve("lastOneWins.jmod").toString())
+            .assertSuccess()
+            .resultChecker(r -> {
+                ModuleDescriptor md = getModuleDescriptor(jmod);
+                Optional<String> omc = md.mainClass();
+                assertTrue(omc.isPresent());
+                assertEquals(omc.get(), "jdk.test.foo.Foo");
+                Optional<Version> ov = md.version();
+                assertTrue(ov.isPresent());
+                assertEquals(ov.get().toString(), "5.4.3");
+
+                try (Stream<String> s1 = findFiles(lp).map(p -> LIBS_PREFIX + p);
+                     Stream<String> s2 = findFiles(cp).map(p -> CLASSES_PREFIX + p);
+                     Stream<String> s3 = findFiles(bp).map(p -> CMDS_PREFIX + p);
+                     Stream<String> s4 = findFiles(cf).map(p -> CONFIGS_PREFIX + p)) {
+                    Set<String> expectedFilenames = Stream.concat(Stream.concat(s1,s2),
+                                                                  Stream.concat(s3, s4))
+                                                          .collect(toSet());
+                    assertJmodContent(jmod, expectedFilenames);
+                }
+            });
+
+        jmod("extract",
+             "--dir", "blah",
+             "--dir", "lastOneWinsExtractDir",
+             jmod.toString())
+            .assertSuccess()
+            .resultChecker(r -> {
+                assertTrue(Files.exists(Paths.get("lastOneWinsExtractDir")));
+                assertTrue(Files.notExists(Paths.get("blah")));
+            });
+    }
+
+    @Test
     public void testPackagesAttribute() throws IOException {
         Path jmod = MODS_DIR.resolve("foo.jmod");
         FileUtils.deleteFileIfExistsWithRetry(jmod);