Merge
authorlana
Thu, 27 Oct 2016 21:22:57 +0000
changeset 41815 b3da085a9846
parent 41748 17a1e89a3f34 (current diff)
parent 41814 a0333150713e (diff)
child 41816 07e906f1a20b
Merge
jdk/src/java.base/share/classes/sun/util/locale/provider/BreakDictionary.java
jdk/src/java.base/share/classes/sun/util/locale/provider/DictionaryBasedBreakIterator.java
jdk/src/java.base/share/classes/sun/util/locale/provider/RuleBasedBreakIterator.java
jdk/src/java.base/windows/native/libnet/icmp.h
jdk/src/java.desktop/share/classes/com/sun/media/sound/SunCodec.java
jdk/test/java/awt/Modal/InvisibleParentTest/InvisibleParentTest.html
--- a/jdk/make/gendata/GendataBreakIterator.gmk	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/make/gendata/GendataBreakIterator.gmk	Thu Oct 27 21:22:57 2016 +0000
@@ -55,7 +55,6 @@
 $(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR_LD, \
     SETUP := GENERATE_OLDBYTECODE, \
     SRC := $(JDK_TOPDIR)/src/jdk.localedata/share/classes, \
-    INCLUDES := $(TEXT_PKG_LD), \
     INCLUDE_FILES := \
         $(TEXT_PKG_LD)/BreakIteratorRules_th.java \
         $(TEXT_PKG_LD)/BreakIteratorInfo_th.java, \
--- a/jdk/make/mapfiles/libsplashscreen/mapfile-vers	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/make/mapfiles/libsplashscreen/mapfile-vers	Thu Oct 27 21:22:57 2016 +0000
@@ -44,6 +44,7 @@
         SplashSetFileJarName;
         SplashSetScaleFactor;
         SplashGetScaledImageName;
+        SplashGetScaledImgNameMaxPstfixLen;
     local:
         *;
 };
--- a/jdk/src/java.base/share/classes/java/io/FileInputStream.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/FileInputStream.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -26,7 +26,6 @@
 package java.io;
 
 import java.nio.channels.FileChannel;
-import java.util.concurrent.atomic.AtomicBoolean;
 import sun.nio.ch.FileChannelImpl;
 
 
@@ -60,7 +59,9 @@
 
     private volatile FileChannel channel;
 
-    private final AtomicBoolean closed = new AtomicBoolean(false);
+    private final Object closeLock = new Object();
+
+    private volatile boolean closed;
 
     /**
      * Creates a <code>FileInputStream</code> by
@@ -313,14 +314,21 @@
      * @spec JSR-51
      */
     public void close() throws IOException {
-        if (!closed.compareAndSet(false, true)) {
-            // if compareAndSet() returns false closed was already true
+        if (closed) {
             return;
         }
+        synchronized (closeLock) {
+            if (closed) {
+                return;
+            }
+            closed = true;
+        }
 
         FileChannel fc = channel;
         if (fc != null) {
-           fc.close();
+            // possible race with getChannel(), benign since
+            // FileChannel.close is final and idempotent
+            fc.close();
         }
 
         fd.closeAll(new Closeable() {
@@ -370,8 +378,10 @@
                 fc = this.channel;
                 if (fc == null) {
                     this.channel = fc = FileChannelImpl.open(fd, path, true, false, this);
-                    if (closed.get()) {
+                    if (closed) {
                         try {
+                            // possible race with close(), benign since
+                            // FileChannel.close is final and idempotent
                             fc.close();
                         } catch (IOException ioe) {
                             throw new InternalError(ioe); // should not happen
--- a/jdk/src/java.base/share/classes/java/io/FileOutputStream.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/FileOutputStream.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -26,7 +26,6 @@
 package java.io;
 
 import java.nio.channels.FileChannel;
-import java.util.concurrent.atomic.AtomicBoolean;
 import jdk.internal.misc.SharedSecrets;
 import jdk.internal.misc.JavaIOFileDescriptorAccess;
 import sun.nio.ch.FileChannelImpl;
@@ -77,7 +76,9 @@
      */
     private final String path;
 
-    private final AtomicBoolean closed = new AtomicBoolean(false);
+    private final Object closeLock = new Object();
+
+    private volatile boolean closed;
 
     /**
      * Creates a file output stream to write to the file with the
@@ -341,14 +342,21 @@
      * @spec JSR-51
      */
     public void close() throws IOException {
-        if (!closed.compareAndSet(false, true)) {
-            // if compareAndSet() returns false closed was already true
+        if (closed) {
             return;
         }
+        synchronized (closeLock) {
+            if (closed) {
+                return;
+            }
+            closed = true;
+        }
 
         FileChannel fc = channel;
         if (fc != null) {
-           fc.close();
+            // possible race with getChannel(), benign since
+            // FileChannel.close is final and idempotent
+            fc.close();
         }
 
         fd.closeAll(new Closeable() {
@@ -399,8 +407,10 @@
                 fc = this.channel;
                 if (fc == null) {
                     this.channel = fc = FileChannelImpl.open(fd, path, false, true, this);
-                    if (closed.get()) {
+                    if (closed) {
                         try {
+                            // possible race with close(), benign since
+                            // FileChannel.close is final and idempotent
                             fc.close();
                         } catch (IOException ioe) {
                             throw new InternalError(ioe); // should not happen
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java	Thu Oct 27 21:22:57 2016 +0000
@@ -104,9 +104,9 @@
  * class or resource itself.
  *
  * <p> Class loaders that support concurrent loading of classes are known as
- * <em>parallel capable</em> class loaders and are required to register
- * themselves at their class initialization time by invoking the
- * {@link
+ * <em>{@linkplain #isParallelCapable() 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
  * capable by default. However, its subclasses still need to register themselves
@@ -1437,7 +1437,7 @@
     }
 
     /**
-     * Registers the caller as parallel capable.
+     * Registers the caller as {@linkplain #isParallelCapable() parallel capable}.
      * The registration succeeds if and only if all of the following
      * conditions are met:
      * <ol>
@@ -1448,8 +1448,10 @@
      * <p>Note that once a class loader is registered as parallel capable, there
      * is no way to change it back.</p>
      *
-     * @return  true if the caller is successfully registered as
-     *          parallel capable and false if otherwise.
+     * @return  {@code true} if the caller is successfully registered as
+     *          parallel capable and {@code false} if otherwise.
+     *
+     * @see #isParallelCapable()
      *
      * @since   1.7
      */
@@ -1461,6 +1463,22 @@
     }
 
     /**
+     * Returns {@code true} if this class loader is
+     * {@linkplain #registerAsParallelCapable parallel capable}, otherwise
+     * {@code false}.
+     *
+     * @return  {@code true} if this class loader is parallel capable,
+     *          otherwise {@code false}.
+     *
+     * @see #registerAsParallelCapable()
+     *
+     * @since   9
+     */
+    public final boolean isParallelCapable() {
+        return ParallelLoaders.isRegistered(this.getClass());
+    }
+
+    /**
      * Find a resource of the specified name from the search path used to load
      * classes.  This method locates the resource through the system class
      * loader (see {@link #getSystemClassLoader()}).
@@ -1663,6 +1681,15 @@
      * this method during startup should take care not to cache the return
      * value until the system is fully initialized.
      *
+     * <p> The class path used by the built-in system class loader is determined
+     * by the system property "{@code java.class.path}" during early
+     * initialization of the VM. If the system property is not defined,
+     * or its value is an empty string, then there is no class path
+     * when the initial module is a module on the application module path,
+     * i.e. <em>a named module</em>. If the initial module is not on
+     * the application module path then the class path defaults to
+     * the current working directory.
+     *
      * @return  The system <tt>ClassLoader</tt> for delegation
      *
      * @throws  SecurityException
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java	Thu Oct 27 21:22:57 2016 +0000
@@ -201,13 +201,13 @@
      * Specify the address family: Internet Protocol, Version 4
      * @since 1.4
      */
-    static final int IPv4 = 1;
+    @Native static final int IPv4 = 1;
 
     /**
      * Specify the address family: Internet Protocol, Version 6
      * @since 1.4
      */
-    static final int IPv6 = 2;
+    @Native static final int IPv6 = 2;
 
     /* Specify address family preference */
     static transient final int preferIPv6Address;
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java	Thu Oct 27 21:22:57 2016 +0000
@@ -69,16 +69,17 @@
             bcp = toURLClassPath(s);
 
         // we have a class path if -cp is specified or -m is not specified.
-        // If neither is specified then default to -cp <working directory>.
+        // If neither is specified then default to -cp <working directory>
+        // If -cp is not specified and -m is specified, the value of
+        // java.class.path is an empty string, then no class path.
         URLClassPath ucp = null;
         String mainMid = System.getProperty("jdk.module.main");
         String cp = System.getProperty("java.class.path");
-        if (mainMid == null && cp == null)
+        if (cp == null)
             cp = "";
-        if (cp != null)
+        if (mainMid == null || cp.length() > 0)
             ucp = toURLClassPath(cp);
 
-
         // create the class loaders
         BOOT_LOADER = new BootClassLoader(bcp);
         PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 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
@@ -31,7 +31,7 @@
 \           (to execute the main class in a module)\n\
 where options include:\n
 
-java.launcher.opt.datamodel  =\    -d{0}\t  use a {0}-bit data model if available\n
+java.launcher.opt.datamodel  =\    -d{0}\t  Deprecated, will be removed in a future release\n
 java.launcher.opt.vmselect   =\    {0}\t  to select the "{1}" VM\n
 java.launcher.opt.hotspot    =\    {0}\t  is a synonym for the "{1}" VM  [deprecated]\n
 
@@ -95,6 +95,12 @@
 \                  load Java programming language agent, see java.lang.instrument\n\
 \    -splash:<imagepath>\n\
 \                  show splash screen with specified image\n\
+\                  HiDPI scaled images are automatically supported and used\n\
+\                  if available. The unscaled image filename, e.g. image.ext,\n\
+\                  should always be passed as the argument to the -splash option.\n\
+\                  The most appropriate scaled image provided will be picked up\n\
+\                  automatically.\n\
+\                  See the SplashScreen API documentation for more information.\n\
 \    @<filepath>   read options from the specified file\n\
 \To specify an argument for a long option, you can use --<name>=<value> or\n\
 \--<name> <value>.\n\
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/text/BreakDictionary.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ */
+package sun.text;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.util.MissingResourceException;
+import sun.text.CompactByteArray;
+import sun.text.SupplementaryCharacterData;
+
+/**
+ * This is the class that represents the list of known words used by
+ * DictionaryBasedBreakIterator.  The conceptual data structure used
+ * here is a trie: there is a node hanging off the root node for every
+ * letter that can start a word.  Each of these nodes has a node hanging
+ * off of it for every letter that can be the second letter of a word
+ * if this node is the first letter, and so on.  The trie is represented
+ * as a two-dimensional array that can be treated as a table of state
+ * transitions.  Indexes are used to compress this array, taking
+ * advantage of the fact that this array will always be very sparse.
+ */
+class BreakDictionary {
+
+    //=========================================================================
+    // data members
+    //=========================================================================
+
+    /**
+      * The version of the dictionary that was read in.
+      */
+    private static int supportedVersion = 1;
+
+    /**
+     * Maps from characters to column numbers.  The main use of this is to
+     * avoid making room in the array for empty columns.
+     */
+    private CompactByteArray columnMap = null;
+    private SupplementaryCharacterData supplementaryCharColumnMap = null;
+
+    /**
+     * The number of actual columns in the table
+     */
+    private int numCols;
+
+    /**
+     * Columns are organized into groups of 32.  This says how many
+     * column groups.  (We could calculate this, but we store the
+     * value to avoid having to repeatedly calculate it.)
+     */
+    private int numColGroups;
+
+    /**
+     * The actual compressed state table.  Each conceptual row represents
+     * a state, and the cells in it contain the row numbers of the states
+     * to transition to for each possible letter.  0 is used to indicate
+     * an illegal combination of letters (i.e., the error state).  The
+     * table is compressed by eliminating all the unpopulated (i.e., zero)
+     * cells.  Multiple conceptual rows can then be doubled up in a single
+     * physical row by sliding them up and possibly shifting them to one
+     * side or the other so the populated cells don't collide.  Indexes
+     * are used to identify unpopulated cells and to locate populated cells.
+     */
+    private short[] table = null;
+
+    /**
+     * This index maps logical row numbers to physical row numbers
+     */
+    private short[] rowIndex = null;
+
+    /**
+     * A bitmap is used to tell which cells in the comceptual table are
+     * populated.  This array contains all the unique bit combinations
+     * in that bitmap.  If the table is more than 32 columns wide,
+     * successive entries in this array are used for a single row.
+     */
+    private int[] rowIndexFlags = null;
+
+    /**
+     * This index maps from a logical row number into the bitmap table above.
+     * (This keeps us from storing duplicate bitmap combinations.)  Since there
+     * are a lot of rows with only one populated cell, instead of wasting space
+     * in the bitmap table, we just store a negative number in this index for
+     * rows with one populated cell.  The absolute value of that number is
+     * the column number of the populated cell.
+     */
+    private short[] rowIndexFlagsIndex = null;
+
+    /**
+     * For each logical row, this index contains a constant that is added to
+     * the logical column number to get the physical column number
+     */
+    private byte[] rowIndexShifts = null;
+
+    //=========================================================================
+    // deserialization
+    //=========================================================================
+
+    BreakDictionary(String dictionaryName, byte[] dictionaryData) {
+        try {
+            setupDictionary(dictionaryName, dictionaryData);
+        } catch (BufferUnderflowException bue) {
+            MissingResourceException e;
+            e = new MissingResourceException("Corrupted dictionary data",
+                                             dictionaryName, "");
+            e.initCause(bue);
+            throw e;
+        }
+    }
+
+    private void setupDictionary(String dictionaryName, byte[] dictionaryData) {
+        ByteBuffer bb = ByteBuffer.wrap(dictionaryData);
+
+        // check version
+        int version = bb.getInt();
+        if (version != supportedVersion) {
+            throw new MissingResourceException("Dictionary version(" + version + ") is unsupported",
+                                               dictionaryName, "");
+        }
+
+        // Check data size
+        int len = bb.getInt();
+        if (bb.position() + len != bb.limit()) {
+            throw new MissingResourceException("Dictionary size is wrong: " + bb.limit(),
+                                               dictionaryName, "");
+        }
+
+        // read in the column map for BMP characteres (this is serialized in
+        // its internal form: an index array followed by a data array)
+        len = bb.getInt();
+        short[] temp = new short[len];
+        for (int i = 0; i < len; i++) {
+            temp[i] = bb.getShort();
+        }
+        len = bb.getInt();
+        byte[] temp2 = new byte[len];
+        bb.get(temp2);
+        columnMap = new CompactByteArray(temp, temp2);
+
+        // read in numCols and numColGroups
+        numCols = bb.getInt();
+        numColGroups = bb.getInt();
+
+        // read in the row-number index
+        len = bb.getInt();
+        rowIndex = new short[len];
+        for (int i = 0; i < len; i++) {
+            rowIndex[i] = bb.getShort();
+        }
+
+        // load in the populated-cells bitmap: index first, then bitmap list
+        len = bb.getInt();
+        rowIndexFlagsIndex = new short[len];
+        for (int i = 0; i < len; i++) {
+            rowIndexFlagsIndex[i] = bb.getShort();
+        }
+        len = bb.getInt();
+        rowIndexFlags = new int[len];
+        for (int i = 0; i < len; i++) {
+            rowIndexFlags[i] = bb.getInt();
+        }
+
+        // load in the row-shift index
+        len = bb.getInt();
+        rowIndexShifts = new byte[len];
+        bb.get(rowIndexShifts);
+
+        // load in the actual state table
+        len = bb.getInt();
+        table = new short[len];
+        for (int i = 0; i < len; i++) {
+            table[i] = bb.getShort();
+        }
+
+        // finally, prepare the column map for supplementary characters
+        len = bb.getInt();
+        int[] temp3 = new int[len];
+        for (int i = 0; i < len; i++) {
+            temp3[i] = bb.getInt();
+        }
+        assert bb.position() == bb.limit();
+
+        supplementaryCharColumnMap = new SupplementaryCharacterData(temp3);
+    }
+
+    //=========================================================================
+    // access to the words
+    //=========================================================================
+
+    /**
+     * Uses the column map to map the character to a column number, then
+     * passes the row and column number to getNextState()
+     * @param row The current state
+     * @param ch The character whose column we're interested in
+     * @return The new state to transition to
+     */
+    public final short getNextStateFromCharacter(int row, int ch) {
+        int col;
+        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            col = columnMap.elementAt((char)ch);
+        } else {
+            col = supplementaryCharColumnMap.getValue(ch);
+        }
+        return getNextState(row, col);
+    }
+
+    /**
+     * Returns the value in the cell with the specified (logical) row and
+     * column numbers.  In DictionaryBasedBreakIterator, the row number is
+     * a state number, the column number is an input, and the return value
+     * is the row number of the new state to transition to.  (0 is the
+     * "error" state, and -1 is the "end of word" state in a dictionary)
+     * @param row The row number of the current state
+     * @param col The column number of the input character (0 means "not a
+     * dictionary character")
+     * @return The row number of the new state to transition to
+     */
+    public final short getNextState(int row, int col) {
+        if (cellIsPopulated(row, col)) {
+            // we map from logical to physical row number by looking up the
+            // mapping in rowIndex; we map from logical column number to
+            // physical column number by looking up a shift value for this
+            // logical row and offsetting the logical column number by
+            // the shift amount.  Then we can use internalAt() to actually
+            // get the value out of the table.
+            return internalAt(rowIndex[row], col + rowIndexShifts[row]);
+        }
+        else {
+            return 0;
+        }
+    }
+
+    /**
+     * Given (logical) row and column numbers, returns true if the
+     * cell in that position is populated
+     */
+    private boolean cellIsPopulated(int row, int col) {
+        // look up the entry in the bitmap index for the specified row.
+        // If it's a negative number, it's the column number of the only
+        // populated cell in the row
+        if (rowIndexFlagsIndex[row] < 0) {
+            return col == -rowIndexFlagsIndex[row];
+        }
+
+        // if it's a positive number, it's the offset of an entry in the bitmap
+        // list.  If the table is more than 32 columns wide, the bitmap is stored
+        // successive entries in the bitmap list, so we have to divide the column
+        // number by 32 and offset the number we got out of the index by the result.
+        // Once we have the appropriate piece of the bitmap, test the appropriate
+        // bit and return the result.
+        else {
+            int flags = rowIndexFlags[rowIndexFlagsIndex[row] + (col >> 5)];
+            return (flags & (1 << (col & 0x1f))) != 0;
+        }
+    }
+
+    /**
+     * Implementation of getNextState() when we know the specified cell is
+     * populated.
+     * @param row The PHYSICAL row number of the cell
+     * @param col The PHYSICAL column number of the cell
+     * @return The value stored in the cell
+     */
+    private short internalAt(int row, int col) {
+        // the table is a one-dimensional array, so this just does the math necessary
+        // to treat it as a two-dimensional array (we don't just use a two-dimensional
+        // array because two-dimensional arrays are inefficient in Java)
+        return table[row * numCols + col];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/text/DictionaryBasedBreakIterator.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ */
+
+package sun.text;
+
+import java.text.CharacterIterator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/**
+ * A subclass of RuleBasedBreakIterator that adds the ability to use a dictionary
+ * to further subdivide ranges of text beyond what is possible using just the
+ * state-table-based algorithm.  This is necessary, for example, to handle
+ * word and line breaking in Thai, which doesn't use spaces between words.  The
+ * state-table-based algorithm used by RuleBasedBreakIterator is used to divide
+ * up text as far as possible, and then contiguous ranges of letters are
+ * repeatedly compared against a list of known words (i.e., the dictionary)
+ * to divide them up into words.
+ *
+ * DictionaryBasedBreakIterator uses the same rule language as RuleBasedBreakIterator,
+ * but adds one more special substitution name: &lt;dictionary&gt;.  This substitution
+ * name is used to identify characters in words in the dictionary.  The idea is that
+ * if the iterator passes over a chunk of text that includes two or more characters
+ * in a row that are included in &lt;dictionary&gt;, it goes back through that range and
+ * derives additional break positions (if possible) using the dictionary.
+ *
+ * DictionaryBasedBreakIterator is also constructed with the filename of a dictionary
+ * file.  It follows a prescribed search path to locate the dictionary (right now,
+ * it looks for it in /com/ibm/text/resources in each directory in the classpath,
+ * and won't find it in JAR files, but this location is likely to change).  The
+ * dictionary file is in a serialized binary format.  We have a very primitive (and
+ * slow) BuildDictionaryFile utility for creating dictionary files, but aren't
+ * currently making it public.  Contact us for help.
+ */
+public class DictionaryBasedBreakIterator extends RuleBasedBreakIterator {
+
+    /**
+     * a list of known words that is used to divide up contiguous ranges of letters,
+     * stored in a compressed, indexed, format that offers fast access
+     */
+    private BreakDictionary dictionary;
+
+    /**
+     * a list of flags indicating which character categories are contained in
+     * the dictionary file (this is used to determine which ranges of characters
+     * to apply the dictionary to)
+     */
+    private boolean[] categoryFlags;
+
+    /**
+     * a temporary hiding place for the number of dictionary characters in the
+     * last range passed over by next()
+     */
+    private int dictionaryCharCount;
+
+    /**
+     * when a range of characters is divided up using the dictionary, the break
+     * positions that are discovered are stored here, preventing us from having
+     * to use either the dictionary or the state table again until the iterator
+     * leaves this range of text
+     */
+    private int[] cachedBreakPositions;
+
+    /**
+     * if cachedBreakPositions is not null, this indicates which item in the
+     * cache the current iteration position refers to
+     */
+    private int positionInCache;
+
+    /**
+     * Constructs a DictionaryBasedBreakIterator.
+     *
+     * @param ruleFile       the name of the rule data file
+     * @param ruleData       the rule data loaded from the rule data file
+     * @param dictionaryFile the name of the dictionary file
+     * @param dictionartData the dictionary data loaded from the dictionary file
+     * @throws MissingResourceException if rule data or dictionary initialization failed
+     */
+    public DictionaryBasedBreakIterator(String ruleFile, byte[] ruleData,
+                                        String dictionaryFile, byte[] dictionaryData) {
+        super(ruleFile, ruleData);
+        byte[] tmp = super.getAdditionalData();
+        if (tmp != null) {
+            prepareCategoryFlags(tmp);
+            super.setAdditionalData(null);
+        }
+        dictionary = new BreakDictionary(dictionaryFile, dictionaryData);
+    }
+
+    private void prepareCategoryFlags(byte[] data) {
+        categoryFlags = new boolean[data.length];
+        for (int i = 0; i < data.length; i++) {
+            categoryFlags[i] = (data[i] == (byte)1) ? true : false;
+        }
+    }
+
+    @Override
+    public void setText(CharacterIterator newText) {
+        super.setText(newText);
+        cachedBreakPositions = null;
+        dictionaryCharCount = 0;
+        positionInCache = 0;
+    }
+
+    /**
+     * Sets the current iteration position to the beginning of the text.
+     * (i.e., the CharacterIterator's starting offset).
+     * @return The offset of the beginning of the text.
+     */
+    @Override
+    public int first() {
+        cachedBreakPositions = null;
+        dictionaryCharCount = 0;
+        positionInCache = 0;
+        return super.first();
+    }
+
+    /**
+     * Sets the current iteration position to the end of the text.
+     * (i.e., the CharacterIterator's ending offset).
+     * @return The text's past-the-end offset.
+     */
+    @Override
+    public int last() {
+        cachedBreakPositions = null;
+        dictionaryCharCount = 0;
+        positionInCache = 0;
+        return super.last();
+    }
+
+    /**
+     * Advances the iterator one step backwards.
+     * @return The position of the last boundary position before the
+     * current iteration position
+     */
+    @Override
+    public int previous() {
+        CharacterIterator text = getText();
+
+        // if we have cached break positions and we're still in the range
+        // covered by them, just move one step backward in the cache
+        if (cachedBreakPositions != null && positionInCache > 0) {
+            --positionInCache;
+            text.setIndex(cachedBreakPositions[positionInCache]);
+            return cachedBreakPositions[positionInCache];
+        }
+
+        // otherwise, dump the cache and use the inherited previous() method to move
+        // backward.  This may fill up the cache with new break positions, in which
+        // case we have to mark our position in the cache
+        else {
+            cachedBreakPositions = null;
+            int result = super.previous();
+            if (cachedBreakPositions != null) {
+                positionInCache = cachedBreakPositions.length - 2;
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Sets the current iteration position to the last boundary position
+     * before the specified position.
+     * @param offset The position to begin searching from
+     * @return The position of the last boundary before "offset"
+     */
+    @Override
+    public int preceding(int offset) {
+        CharacterIterator text = getText();
+        checkOffset(offset, text);
+
+        // if we have no cached break positions, or "offset" is outside the
+        // range covered by the cache, we can just call the inherited routine
+        // (which will eventually call other routines in this class that may
+        // refresh the cache)
+        if (cachedBreakPositions == null || offset <= cachedBreakPositions[0] ||
+                offset > cachedBreakPositions[cachedBreakPositions.length - 1]) {
+            cachedBreakPositions = null;
+            return super.preceding(offset);
+        }
+
+        // on the other hand, if "offset" is within the range covered by the cache,
+        // then all we have to do is search the cache for the last break position
+        // before "offset"
+        else {
+            positionInCache = 0;
+            while (positionInCache < cachedBreakPositions.length
+                   && offset > cachedBreakPositions[positionInCache]) {
+                ++positionInCache;
+            }
+            --positionInCache;
+            text.setIndex(cachedBreakPositions[positionInCache]);
+            return text.getIndex();
+        }
+    }
+
+    /**
+     * Sets the current iteration position to the first boundary position after
+     * the specified position.
+     * @param offset The position to begin searching forward from
+     * @return The position of the first boundary after "offset"
+     */
+    @Override
+    public int following(int offset) {
+        CharacterIterator text = getText();
+        checkOffset(offset, text);
+
+        // if we have no cached break positions, or if "offset" is outside the
+        // range covered by the cache, then dump the cache and call our
+        // inherited following() method.  This will call other methods in this
+        // class that may refresh the cache.
+        if (cachedBreakPositions == null || offset < cachedBreakPositions[0] ||
+                offset >= cachedBreakPositions[cachedBreakPositions.length - 1]) {
+            cachedBreakPositions = null;
+            return super.following(offset);
+        }
+
+        // on the other hand, if "offset" is within the range covered by the
+        // cache, then just search the cache for the first break position
+        // after "offset"
+        else {
+            positionInCache = 0;
+            while (positionInCache < cachedBreakPositions.length
+                   && offset >= cachedBreakPositions[positionInCache]) {
+                ++positionInCache;
+            }
+            text.setIndex(cachedBreakPositions[positionInCache]);
+            return text.getIndex();
+        }
+    }
+
+    /**
+     * This is the implementation function for next().
+     */
+    @Override
+    protected int handleNext() {
+        CharacterIterator text = getText();
+
+        // if there are no cached break positions, or if we've just moved
+        // off the end of the range covered by the cache, we have to dump
+        // and possibly regenerate the cache
+        if (cachedBreakPositions == null ||
+            positionInCache == cachedBreakPositions.length - 1) {
+
+            // start by using the inherited handleNext() to find a tentative return
+            // value.   dictionaryCharCount tells us how many dictionary characters
+            // we passed over on our way to the tentative return value
+            int startPos = text.getIndex();
+            dictionaryCharCount = 0;
+            int result = super.handleNext();
+
+            // if we passed over more than one dictionary character, then we use
+            // divideUpDictionaryRange() to regenerate the cached break positions
+            // for the new range
+            if (dictionaryCharCount > 1 && result - startPos > 1) {
+                divideUpDictionaryRange(startPos, result);
+            }
+
+            // otherwise, the value we got back from the inherited fuction
+            // is our return value, and we can dump the cache
+            else {
+                cachedBreakPositions = null;
+                return result;
+            }
+        }
+
+        // if the cache of break positions has been regenerated (or existed all
+        // along), then just advance to the next break position in the cache
+        // and return it
+        if (cachedBreakPositions != null) {
+            ++positionInCache;
+            text.setIndex(cachedBreakPositions[positionInCache]);
+            return cachedBreakPositions[positionInCache];
+        }
+        return -9999;   // SHOULD NEVER GET HERE!
+    }
+
+    /**
+     * Looks up a character category for a character.
+     */
+    @Override
+    protected int lookupCategory(int c) {
+        // this override of lookupCategory() exists only to keep track of whether we've
+        // passed over any dictionary characters.  It calls the inherited lookupCategory()
+        // to do the real work, and then checks whether its return value is one of the
+        // categories represented in the dictionary.  If it is, bump the dictionary-
+        // character count.
+        int result = super.lookupCategory(c);
+        if (result != RuleBasedBreakIterator.IGNORE && categoryFlags[result]) {
+            ++dictionaryCharCount;
+        }
+        return result;
+    }
+
+    /**
+     * This is the function that actually implements the dictionary-based
+     * algorithm.  Given the endpoints of a range of text, it uses the
+     * dictionary to determine the positions of any boundaries in this
+     * range.  It stores all the boundary positions it discovers in
+     * cachedBreakPositions so that we only have to do this work once
+     * for each time we enter the range.
+     */
+    @SuppressWarnings("unchecked")
+    private void divideUpDictionaryRange(int startPos, int endPos) {
+        CharacterIterator text = getText();
+
+        // the range we're dividing may begin or end with non-dictionary characters
+        // (i.e., for line breaking, we may have leading or trailing punctuation
+        // that needs to be kept with the word).  Seek from the beginning of the
+        // range to the first dictionary character
+        text.setIndex(startPos);
+        int c = getCurrent();
+        int category = lookupCategory(c);
+        while (category == IGNORE || !categoryFlags[category]) {
+            c = getNext();
+            category = lookupCategory(c);
+        }
+
+        // initialize.  We maintain two stacks: currentBreakPositions contains
+        // the list of break positions that will be returned if we successfully
+        // finish traversing the whole range now.  possibleBreakPositions lists
+        // all other possible word ends we've passed along the way.  (Whenever
+        // we reach an error [a sequence of characters that can't begin any word
+        // in the dictionary], we back up, possibly delete some breaks from
+        // currentBreakPositions, move a break from possibleBreakPositions
+        // to currentBreakPositions, and start over from there.  This process
+        // continues in this way until we either successfully make it all the way
+        // across the range, or exhaust all of our combinations of break
+        // positions.)
+        Stack<Integer> currentBreakPositions = new Stack<>();
+        Stack<Integer> possibleBreakPositions = new Stack<>();
+        List<Integer> wrongBreakPositions = new ArrayList<>();
+
+        // the dictionary is implemented as a trie, which is treated as a state
+        // machine.  -1 represents the end of a legal word.  Every word in the
+        // dictionary is represented by a path from the root node to -1.  A path
+        // that ends in state 0 is an illegal combination of characters.
+        int state = 0;
+
+        // these two variables are used for error handling.  We keep track of the
+        // farthest we've gotten through the range being divided, and the combination
+        // of breaks that got us that far.  If we use up all possible break
+        // combinations, the text contains an error or a word that's not in the
+        // dictionary.  In this case, we "bless" the break positions that got us the
+        // farthest as real break positions, and then start over from scratch with
+        // the character where the error occurred.
+        int farthestEndPoint = text.getIndex();
+        Stack<Integer> bestBreakPositions = null;
+
+        // initialize (we always exit the loop with a break statement)
+        c = getCurrent();
+        while (true) {
+
+            // if we can transition to state "-1" from our current state, we're
+            // on the last character of a legal word.  Push that position onto
+            // the possible-break-positions stack
+            if (dictionary.getNextState(state, 0) == -1) {
+                possibleBreakPositions.push(text.getIndex());
+            }
+
+            // look up the new state to transition to in the dictionary
+            state = dictionary.getNextStateFromCharacter(state, c);
+
+            // if the character we're sitting on causes us to transition to
+            // the "end of word" state, then it was a non-dictionary character
+            // and we've successfully traversed the whole range.  Drop out
+            // of the loop.
+            if (state == -1) {
+                currentBreakPositions.push(text.getIndex());
+                break;
+            }
+
+            // if the character we're sitting on causes us to transition to
+            // the error state, or if we've gone off the end of the range
+            // without transitioning to the "end of word" state, we've hit
+            // an error...
+            else if (state == 0 || text.getIndex() >= endPos) {
+
+                // if this is the farthest we've gotten, take note of it in
+                // case there's an error in the text
+                if (text.getIndex() > farthestEndPoint) {
+                    farthestEndPoint = text.getIndex();
+
+                    @SuppressWarnings("unchecked")
+                    Stack<Integer> currentBreakPositionsCopy = (Stack<Integer>) currentBreakPositions.clone();
+
+                    bestBreakPositions = currentBreakPositionsCopy;
+                }
+
+                // wrongBreakPositions is a list of all break positions
+                // we've tried starting that didn't allow us to traverse
+                // all the way through the text.  Every time we pop a
+                // break position off of currentBreakPositions, we put it
+                // into wrongBreakPositions to avoid trying it again later.
+                // If we make it to this spot, we're either going to back
+                // up to a break in possibleBreakPositions and try starting
+                // over from there, or we've exhausted all possible break
+                // positions and are going to do the fallback procedure.
+                // This loop prevents us from messing with anything in
+                // possibleBreakPositions that didn't work as a starting
+                // point the last time we tried it (this is to prevent a bunch of
+                // repetitive checks from slowing down some extreme cases)
+                while (!possibleBreakPositions.isEmpty()
+                        && wrongBreakPositions.contains(possibleBreakPositions.peek())) {
+                    possibleBreakPositions.pop();
+                }
+
+                // if we've used up all possible break-position combinations, there's
+                // an error or an unknown word in the text.  In this case, we start
+                // over, treating the farthest character we've reached as the beginning
+                // of the range, and "blessing" the break positions that got us that
+                // far as real break positions
+                if (possibleBreakPositions.isEmpty()) {
+                    if (bestBreakPositions != null) {
+                        currentBreakPositions = bestBreakPositions;
+                        if (farthestEndPoint < endPos) {
+                            text.setIndex(farthestEndPoint + 1);
+                        }
+                        else {
+                            break;
+                        }
+                    }
+                    else {
+                        if ((currentBreakPositions.size() == 0 ||
+                             currentBreakPositions.peek().intValue() != text.getIndex())
+                            && text.getIndex() != startPos) {
+                            currentBreakPositions.push(text.getIndex());
+                        }
+                        getNext();
+                        currentBreakPositions.push(text.getIndex());
+                    }
+                }
+
+                // if we still have more break positions we can try, then promote the
+                // last break in possibleBreakPositions into currentBreakPositions,
+                // and get rid of all entries in currentBreakPositions that come after
+                // it.  Then back up to that position and start over from there (i.e.,
+                // treat that position as the beginning of a new word)
+                else {
+                    Integer temp = possibleBreakPositions.pop();
+                    Integer temp2 = null;
+                    while (!currentBreakPositions.isEmpty() && temp.intValue() <
+                           currentBreakPositions.peek().intValue()) {
+                        temp2 = currentBreakPositions.pop();
+                        wrongBreakPositions.add(temp2);
+                    }
+                    currentBreakPositions.push(temp);
+                    text.setIndex(currentBreakPositions.peek().intValue());
+                }
+
+                // re-sync "c" for the next go-round, and drop out of the loop if
+                // we've made it off the end of the range
+                c = getCurrent();
+                if (text.getIndex() >= endPos) {
+                    break;
+                }
+            }
+
+            // if we didn't hit any exceptional conditions on this last iteration,
+            // just advance to the next character and loop
+            else {
+                c = getNext();
+            }
+        }
+
+        // dump the last break position in the list, and replace it with the actual
+        // end of the range (which may be the same character, or may be further on
+        // because the range actually ended with non-dictionary characters we want to
+        // keep with the word)
+        if (!currentBreakPositions.isEmpty()) {
+            currentBreakPositions.pop();
+        }
+        currentBreakPositions.push(endPos);
+
+        // create a regular array to hold the break positions and copy
+        // the break positions from the stack to the array (in addition,
+        // our starting position goes into this array as a break position).
+        // This array becomes the cache of break positions used by next()
+        // and previous(), so this is where we actually refresh the cache.
+        cachedBreakPositions = new int[currentBreakPositions.size() + 1];
+        cachedBreakPositions[0] = startPos;
+
+        for (int i = 0; i < currentBreakPositions.size(); i++) {
+            cachedBreakPositions[i + 1] = currentBreakPositions.elementAt(i).intValue();
+        }
+        positionInCache = 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/text/RuleBasedBreakIterator.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,1144 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ */
+
+package sun.text;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.text.BreakIterator;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.MissingResourceException;
+import sun.text.CompactByteArray;
+import sun.text.SupplementaryCharacterData;
+
+/**
+ * <p>A subclass of BreakIterator whose behavior is specified using a list of rules.</p>
+ *
+ * <p>There are two kinds of rules, which are separated by semicolons: <i>substitutions</i>
+ * and <i>regular expressions.</i></p>
+ *
+ * <p>A substitution rule defines a name that can be used in place of an expression. It
+ * consists of a name, which is a string of characters contained in angle brackets, an equals
+ * sign, and an expression. (There can be no whitespace on either side of the equals sign.)
+ * To keep its syntactic meaning intact, the expression must be enclosed in parentheses or
+ * square brackets. A substitution is visible after its definition, and is filled in using
+ * simple textual substitution. Substitution definitions can contain other substitutions, as
+ * long as those substitutions have been defined first. Substitutions are generally used to
+ * make the regular expressions (which can get quite complex) shorted and easier to read.
+ * They typically define either character categories or commonly-used subexpressions.</p>
+ *
+ * <p>There is one special substitution.&nbsp; If the description defines a substitution
+ * called &quot;&lt;ignore&gt;&quot;, the expression must be a [] expression, and the
+ * expression defines a set of characters (the &quot;<em>ignore characters</em>&quot;) that
+ * will be transparent to the BreakIterator.&nbsp; A sequence of characters will break the
+ * same way it would if any ignore characters it contains are taken out.&nbsp; Break
+ * positions never occur befoer ignore characters.</p>
+ *
+ * <p>A regular expression uses a subset of the normal Unix regular-expression syntax, and
+ * defines a sequence of characters to be kept together. With one significant exception, the
+ * iterator uses a longest-possible-match algorithm when matching text to regular
+ * expressions. The iterator also treats descriptions containing multiple regular expressions
+ * as if they were ORed together (i.e., as if they were separated by |).</p>
+ *
+ * <p>The special characters recognized by the regular-expression parser are as follows:</p>
+ *
+ * <blockquote>
+ *   <table border="1" width="100%">
+ *     <tr>
+ *       <td width="6%">*</td>
+ *       <td width="94%">Specifies that the expression preceding the asterisk may occur any number
+ *       of times (including not at all).</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">{}</td>
+ *       <td width="94%">Encloses a sequence of characters that is optional.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">()</td>
+ *       <td width="94%">Encloses a sequence of characters.&nbsp; If followed by *, the sequence
+ *       repeats.&nbsp; Otherwise, the parentheses are just a grouping device and a way to delimit
+ *       the ends of expressions containing |.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">|</td>
+ *       <td width="94%">Separates two alternative sequences of characters.&nbsp; Either one
+ *       sequence or the other, but not both, matches this expression.&nbsp; The | character can
+ *       only occur inside ().</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">.</td>
+ *       <td width="94%">Matches any character.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">*?</td>
+ *       <td width="94%">Specifies a non-greedy asterisk.&nbsp; *? works the same way as *, except
+ *       when there is overlap between the last group of characters in the expression preceding the
+ *       * and the first group of characters following the *.&nbsp; When there is this kind of
+ *       overlap, * will match the longest sequence of characters that match the expression before
+ *       the *, and *? will match the shortest sequence of characters matching the expression
+ *       before the *?.&nbsp; For example, if you have &quot;xxyxyyyxyxyxxyxyxyy&quot; in the text,
+ *       &quot;x[xy]*x&quot; will match through to the last x (i.e., &quot;<strong>xxyxyyyxyxyxxyxyx</strong>yy&quot;,
+ *       but &quot;x[xy]*?x&quot; will only match the first two xes (&quot;<strong>xx</strong>yxyyyxyxyxxyxyxyy&quot;).</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">[]</td>
+ *       <td width="94%">Specifies a group of alternative characters.&nbsp; A [] expression will
+ *       match any single character that is specified in the [] expression.&nbsp; For more on the
+ *       syntax of [] expressions, see below.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">/</td>
+ *       <td width="94%">Specifies where the break position should go if text matches this
+ *       expression.&nbsp; (e.g., &quot;[a-z]&#42;/[:Zs:]*[1-0]&quot; will match if the iterator sees a run
+ *       of letters, followed by a run of whitespace, followed by a digit, but the break position
+ *       will actually go before the whitespace).&nbsp; Expressions that don't contain / put the
+ *       break position at the end of the matching text.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">\</td>
+ *       <td width="94%">Escape character.&nbsp; The \ itself is ignored, but causes the next
+ *       character to be treated as literal character.&nbsp; This has no effect for many
+ *       characters, but for the characters listed above, this deprives them of their special
+ *       meaning.&nbsp; (There are no special escape sequences for Unicode characters, or tabs and
+ *       newlines; these are all handled by a higher-level protocol.&nbsp; In a Java string,
+ *       &quot;\n&quot; will be converted to a literal newline character by the time the
+ *       regular-expression parser sees it.&nbsp; Of course, this means that \ sequences that are
+ *       visible to the regexp parser must be written as \\ when inside a Java string.)&nbsp; All
+ *       characters in the ASCII range except for letters, digits, and control characters are
+ *       reserved characters to the parser and must be preceded by \ even if they currently don't
+ *       mean anything.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">!</td>
+ *       <td width="94%">If ! appears at the beginning of a regular expression, it tells the regexp
+ *       parser that this expression specifies the backwards-iteration behavior of the iterator,
+ *       and not its normal iteration behavior.&nbsp; This is generally only used in situations
+ *       where the automatically-generated backwards-iteration brhavior doesn't produce
+ *       satisfactory results and must be supplemented with extra client-specified rules.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%"><em>(all others)</em></td>
+ *       <td width="94%">All other characters are treated as literal characters, which must match
+ *       the corresponding character(s) in the text exactly.</td>
+ *     </tr>
+ *   </table>
+ * </blockquote>
+ *
+ * <p>Within a [] expression, a number of other special characters can be used to specify
+ * groups of characters:</p>
+ *
+ * <blockquote>
+ *   <table border="1" width="100%">
+ *     <tr>
+ *       <td width="6%">-</td>
+ *       <td width="94%">Specifies a range of matching characters.&nbsp; For example
+ *       &quot;[a-p]&quot; matches all lowercase Latin letters from a to p (inclusive).&nbsp; The -
+ *       sign specifies ranges of continuous Unicode numeric values, not ranges of characters in a
+ *       language's alphabetical order: &quot;[a-z]&quot; doesn't include capital letters, nor does
+ *       it include accented letters such as a-umlaut.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">::</td>
+ *       <td width="94%">A pair of colons containing a one- or two-letter code matches all
+ *       characters in the corresponding Unicode category.&nbsp; The two-letter codes are the same
+ *       as the two-letter codes in the Unicode database (for example, &quot;[:Sc::Sm:]&quot;
+ *       matches all currency symbols and all math symbols).&nbsp; Specifying a one-letter code is
+ *       the same as specifying all two-letter codes that begin with that letter (for example,
+ *       &quot;[:L:]&quot; matches all letters, and is equivalent to
+ *       &quot;[:Lu::Ll::Lo::Lm::Lt:]&quot;).&nbsp; Anything other than a valid two-letter Unicode
+ *       category code or a single letter that begins a Unicode category code is illegal within
+ *       colons.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">[]</td>
+ *       <td width="94%">[] expressions can nest.&nbsp; This has no effect, except when used in
+ *       conjunction with the ^ token.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%">^</td>
+ *       <td width="94%">Excludes the character (or the characters in the [] expression) following
+ *       it from the group of characters.&nbsp; For example, &quot;[a-z^p]&quot; matches all Latin
+ *       lowercase letters except p.&nbsp; &quot;[:L:^[&#92;u4e00-&#92;u9fff]]&quot; matches all letters
+ *       except the Han ideographs.</td>
+ *     </tr>
+ *     <tr>
+ *       <td width="6%"><em>(all others)</em></td>
+ *       <td width="94%">All other characters are treated as literal characters.&nbsp; (For
+ *       example, &quot;[aeiou]&quot; specifies just the letters a, e, i, o, and u.)</td>
+ *     </tr>
+ *   </table>
+ * </blockquote>
+ *
+ * <p>For a more complete explanation, see <a
+ * href="http://www.ibm.com/java/education/boundaries/boundaries.html">http://www.ibm.com/java/education/boundaries/boundaries.html</a>.
+ * &nbsp; For examples, see the resource data (which is annotated).</p>
+ *
+ * @author Richard Gillam
+ */
+public class RuleBasedBreakIterator extends BreakIterator {
+
+    /**
+     * A token used as a character-category value to identify ignore characters
+     */
+    protected static final byte IGNORE = -1;
+
+    /**
+     * The state number of the starting state
+     */
+    private static final short START_STATE = 1;
+
+    /**
+     * The state-transition value indicating "stop"
+     */
+    private static final short STOP_STATE = 0;
+
+    /**
+     * Magic number for the BreakIterator data file format.
+     */
+    static final byte[] LABEL = {
+        (byte)'B', (byte)'I', (byte)'d', (byte)'a', (byte)'t', (byte)'a',
+        (byte)'\0'
+    };
+    static final int    LABEL_LENGTH = LABEL.length;
+
+    /**
+     * Version number of the dictionary that was read in.
+     */
+    static final byte supportedVersion = 1;
+
+    /**
+     * An array length of indices for BMP characters
+     */
+    private static final int BMP_INDICES_LENGTH = 512;
+
+    /**
+     * Tables that indexes from character values to character category numbers
+     */
+    private CompactByteArray charCategoryTable = null;
+    private SupplementaryCharacterData supplementaryCharCategoryTable = null;
+
+    /**
+     * The table of state transitions used for forward iteration
+     */
+    private short[] stateTable = null;
+
+    /**
+     * The table of state transitions used to sync up the iterator with the
+     * text in backwards and random-access iteration
+     */
+    private short[] backwardsStateTable = null;
+
+    /**
+     * A list of flags indicating which states in the state table are accepting
+     * ("end") states
+     */
+    private boolean[] endStates = null;
+
+    /**
+     * A list of flags indicating which states in the state table are
+     * lookahead states (states which turn lookahead on and off)
+     */
+    private boolean[] lookaheadStates = null;
+
+    /**
+     * A table for additional data. May be used by a subclass of
+     * RuleBasedBreakIterator.
+     */
+    private byte[] additionalData = null;
+
+    /**
+     * The number of character categories (and, thus, the number of columns in
+     * the state tables)
+     */
+    private int numCategories;
+
+    /**
+     * The character iterator through which this BreakIterator accesses the text
+     */
+    private CharacterIterator text = null;
+
+    /**
+     * A CRC32 value of all data in datafile
+     */
+    private long checksum;
+
+    //=======================================================================
+    // constructors
+    //=======================================================================
+
+    /**
+     * Constructs a RuleBasedBreakIterator using the given rule data.
+     *
+     * @throws MissingResourceException if the rule data is invalid or corrupted
+     */
+    public RuleBasedBreakIterator(String ruleFile, byte[] ruleData) {
+        ByteBuffer bb = ByteBuffer.wrap(ruleData);
+        try {
+            validateRuleData(ruleFile, bb);
+            setupTables(ruleFile, bb);
+        } catch (BufferUnderflowException bue) {
+            MissingResourceException e;
+            e = new MissingResourceException("Corrupted rule data file", ruleFile, "");
+            e.initCause(bue);
+            throw e;
+        }
+    }
+
+    /**
+     * Initializes the fields with the given rule data.
+     * The data format is as follows:
+     * <pre>
+     *   BreakIteratorData {
+     *       u1           magic[7];
+     *       u1           version;
+     *       u4           totalDataSize;
+     *       header_info  header;
+     *       body         value;
+     *   }
+     * </pre>
+     * <code>totalDataSize</code> is the summation of the size of
+     * <code>header_info</code> and <code>body</code> in byte count.
+     * <p>
+     * In <code>header</code>, each field except for checksum implies the
+     * length of each field. Since <code>BMPdataLength</code> is a fixed-length
+     *  data(512 entries), its length isn't included in <code>header</code>.
+     * <code>checksum</code> is a CRC32 value of all in <code>body</code>.
+     * <pre>
+     *   header_info {
+     *       u4           stateTableLength;
+     *       u4           backwardsStateTableLength;
+     *       u4           endStatesLength;
+     *       u4           lookaheadStatesLength;
+     *       u4           BMPdataLength;
+     *       u4           nonBMPdataLength;
+     *       u4           additionalDataLength;
+     *       u8           checksum;
+     *   }
+     * </pre>
+     * <p>
+     *
+     * Finally, <code>BMPindices</code> and <code>BMPdata</code> are set to
+     * <code>charCategoryTable</code>. <code>nonBMPdata</code> is set to
+     * <code>supplementaryCharCategoryTable</code>.
+     * <pre>
+     *   body {
+     *       u2           stateTable[stateTableLength];
+     *       u2           backwardsStateTable[backwardsStateTableLength];
+     *       u1           endStates[endStatesLength];
+     *       u1           lookaheadStates[lookaheadStatesLength];
+     *       u2           BMPindices[512];
+     *       u1           BMPdata[BMPdataLength];
+     *       u4           nonBMPdata[numNonBMPdataLength];
+     *       u1           additionalData[additionalDataLength];
+     *   }
+     * </pre>
+     *
+     * @throws BufferUnderflowException if the end-of-data is reached before
+     *                                  setting up all the tables
+     */
+    private void setupTables(String ruleFile, ByteBuffer bb) {
+        /* Read header_info. */
+        int stateTableLength = bb.getInt();
+        int backwardsStateTableLength = bb.getInt();
+        int endStatesLength = bb.getInt();
+        int lookaheadStatesLength = bb.getInt();
+        int BMPdataLength = bb.getInt();
+        int nonBMPdataLength = bb.getInt();
+        int additionalDataLength = bb.getInt();
+        checksum = bb.getLong();
+
+        /* Read stateTable[numCategories * numRows] */
+        stateTable = new short[stateTableLength];
+        for (int i = 0; i < stateTableLength; i++) {
+            stateTable[i] = bb.getShort();
+        }
+
+        /* Read backwardsStateTable[numCategories * numRows] */
+        backwardsStateTable = new short[backwardsStateTableLength];
+        for (int i = 0; i < backwardsStateTableLength; i++) {
+            backwardsStateTable[i] = bb.getShort();
+        }
+
+        /* Read endStates[numRows] */
+        endStates = new boolean[endStatesLength];
+        for (int i = 0; i < endStatesLength; i++) {
+            endStates[i] = bb.get() == 1;
+        }
+
+        /* Read lookaheadStates[numRows] */
+        lookaheadStates = new boolean[lookaheadStatesLength];
+        for (int i = 0; i < lookaheadStatesLength; i++) {
+            lookaheadStates[i] = bb.get() == 1;
+        }
+
+        /* Read a category table and indices for BMP characters. */
+        short[] temp1 = new short[BMP_INDICES_LENGTH];  // BMPindices
+        for (int i = 0; i < BMP_INDICES_LENGTH; i++) {
+            temp1[i] = bb.getShort();
+        }
+        byte[] temp2 = new byte[BMPdataLength];  // BMPdata
+        bb.get(temp2);
+        charCategoryTable = new CompactByteArray(temp1, temp2);
+
+        /* Read a category table for non-BMP characters. */
+        int[] temp3 = new int[nonBMPdataLength];
+        for (int i = 0; i < nonBMPdataLength; i++) {
+            temp3[i] = bb.getInt();
+        }
+        supplementaryCharCategoryTable = new SupplementaryCharacterData(temp3);
+
+        /* Read additional data */
+        if (additionalDataLength > 0) {
+            additionalData = new byte[additionalDataLength];
+            bb.get(additionalData);
+        }
+        assert bb.position() == bb.limit();
+
+        /* Set numCategories */
+        numCategories = stateTable.length / endStates.length;
+    }
+
+    /**
+     * Validates the magic number, version, and the length of the given data.
+     *
+     * @throws BufferUnderflowException if the end-of-data is reached while
+     *                                  validating data
+     * @throws MissingResourceException if valification failed
+     */
+    void validateRuleData(String ruleFile, ByteBuffer bb) {
+        /* Verify the magic number. */
+        for (int i = 0; i < LABEL_LENGTH; i++) {
+            if (bb.get() != LABEL[i]) {
+                throw new MissingResourceException("Wrong magic number",
+                                                   ruleFile, "");
+            }
+        }
+
+        /* Verify the version number. */
+        byte version = bb.get();
+        if (version != supportedVersion) {
+            throw new MissingResourceException("Unsupported version(" + version + ")",
+                                               ruleFile, "");
+        }
+
+        // Check the length of the rest of data
+        int len = bb.getInt();
+        if (bb.position() + len != bb.limit()) {
+            throw new MissingResourceException("Wrong data length",
+                                               ruleFile, "");
+        }
+    }
+
+    byte[] getAdditionalData() {
+        return additionalData;
+    }
+
+    void setAdditionalData(byte[] b) {
+        additionalData = b;
+    }
+
+    //=======================================================================
+    // boilerplate
+    //=======================================================================
+    /**
+     * Clones this iterator.
+     * @return A newly-constructed RuleBasedBreakIterator with the same
+     * behavior as this one.
+     */
+    @Override
+    public Object clone() {
+        RuleBasedBreakIterator result = (RuleBasedBreakIterator) super.clone();
+        if (text != null) {
+            result.text = (CharacterIterator) text.clone();
+        }
+        return result;
+    }
+
+    /**
+     * Returns true if both BreakIterators are of the same class, have the same
+     * rules, and iterate over the same text.
+     */
+    @Override
+    public boolean equals(Object that) {
+        try {
+            if (that == null) {
+                return false;
+            }
+
+            RuleBasedBreakIterator other = (RuleBasedBreakIterator) that;
+            if (checksum != other.checksum) {
+                return false;
+            }
+            if (text == null) {
+                return other.text == null;
+            } else {
+                return text.equals(other.text);
+            }
+        }
+        catch(ClassCastException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Returns text
+     */
+    @Override
+    public String toString() {
+        return "[checksum=0x" + Long.toHexString(checksum) + ']';
+    }
+
+    /**
+     * Compute a hashcode for this BreakIterator
+     * @return A hash code
+     */
+    @Override
+    public int hashCode() {
+        return (int)checksum;
+    }
+
+    //=======================================================================
+    // BreakIterator overrides
+    //=======================================================================
+
+    /**
+     * Sets the current iteration position to the beginning of the text.
+     * (i.e., the CharacterIterator's starting offset).
+     * @return The offset of the beginning of the text.
+     */
+    @Override
+    public int first() {
+        CharacterIterator t = getText();
+
+        t.first();
+        return t.getIndex();
+    }
+
+    /**
+     * Sets the current iteration position to the end of the text.
+     * (i.e., the CharacterIterator's ending offset).
+     * @return The text's past-the-end offset.
+     */
+    @Override
+    public int last() {
+        CharacterIterator t = getText();
+
+        // I'm not sure why, but t.last() returns the offset of the last character,
+        // rather than the past-the-end offset
+        t.setIndex(t.getEndIndex());
+        return t.getIndex();
+    }
+
+    /**
+     * Advances the iterator either forward or backward the specified number of steps.
+     * Negative values move backward, and positive values move forward.  This is
+     * equivalent to repeatedly calling next() or previous().
+     * @param n The number of steps to move.  The sign indicates the direction
+     * (negative is backwards, and positive is forwards).
+     * @return The character offset of the boundary position n boundaries away from
+     * the current one.
+     */
+    @Override
+    public int next(int n) {
+        int result = current();
+        while (n > 0) {
+            result = handleNext();
+            --n;
+        }
+        while (n < 0) {
+            result = previous();
+            ++n;
+        }
+        return result;
+    }
+
+    /**
+     * Advances the iterator to the next boundary position.
+     * @return The position of the first boundary after this one.
+     */
+    @Override
+    public int next() {
+        return handleNext();
+    }
+
+    private int cachedLastKnownBreak = BreakIterator.DONE;
+
+    /**
+     * Advances the iterator backwards, to the last boundary preceding this one.
+     * @return The position of the last boundary position preceding this one.
+     */
+    @Override
+    public int previous() {
+        // if we're already sitting at the beginning of the text, return DONE
+        CharacterIterator text = getText();
+        if (current() == text.getBeginIndex()) {
+            return BreakIterator.DONE;
+        }
+
+        // set things up.  handlePrevious() will back us up to some valid
+        // break position before the current position (we back our internal
+        // iterator up one step to prevent handlePrevious() from returning
+        // the current position), but not necessarily the last one before
+        // where we started
+        int start = current();
+        int lastResult = cachedLastKnownBreak;
+        if (lastResult >= start || lastResult <= BreakIterator.DONE) {
+            getPrevious();
+            lastResult = handlePrevious();
+        } else {
+            //it might be better to check if handlePrevious() give us closer
+            //safe value but handlePrevious() is slow too
+            //So, this has to be done carefully
+            text.setIndex(lastResult);
+        }
+        int result = lastResult;
+
+        // iterate forward from the known break position until we pass our
+        // starting point.  The last break position before the starting
+        // point is our return value
+        while (result != BreakIterator.DONE && result < start) {
+            lastResult = result;
+            result = handleNext();
+        }
+
+        // set the current iteration position to be the last break position
+        // before where we started, and then return that value
+        text.setIndex(lastResult);
+        cachedLastKnownBreak = lastResult;
+        return lastResult;
+    }
+
+    /**
+     * Returns previous character
+     */
+    private int getPrevious() {
+        char c2 = text.previous();
+        if (Character.isLowSurrogate(c2) &&
+            text.getIndex() > text.getBeginIndex()) {
+            char c1 = text.previous();
+            if (Character.isHighSurrogate(c1)) {
+                return Character.toCodePoint(c1, c2);
+            } else {
+                text.next();
+            }
+        }
+        return (int)c2;
+    }
+
+    /**
+     * Returns current character
+     */
+    int getCurrent() {
+        char c1 = text.current();
+        if (Character.isHighSurrogate(c1) &&
+            text.getIndex() < text.getEndIndex()) {
+            char c2 = text.next();
+            text.previous();
+            if (Character.isLowSurrogate(c2)) {
+                return Character.toCodePoint(c1, c2);
+            }
+        }
+        return (int)c1;
+    }
+
+    /**
+     * Returns the count of next character.
+     */
+    private int getCurrentCodePointCount() {
+        char c1 = text.current();
+        if (Character.isHighSurrogate(c1) &&
+            text.getIndex() < text.getEndIndex()) {
+            char c2 = text.next();
+            text.previous();
+            if (Character.isLowSurrogate(c2)) {
+                return 2;
+            }
+        }
+        return 1;
+    }
+
+    /**
+     * Returns next character
+     */
+    int getNext() {
+        int index = text.getIndex();
+        int endIndex = text.getEndIndex();
+        if (index == endIndex ||
+            (index += getCurrentCodePointCount()) >= endIndex) {
+            return CharacterIterator.DONE;
+        }
+        text.setIndex(index);
+        return getCurrent();
+    }
+
+    /**
+     * Returns the position of next character.
+     */
+    private int getNextIndex() {
+        int index = text.getIndex() + getCurrentCodePointCount();
+        int endIndex = text.getEndIndex();
+        if (index > endIndex) {
+            return endIndex;
+        } else {
+            return index;
+        }
+    }
+
+    /**
+     * Throw IllegalArgumentException unless begin <= offset < end.
+     */
+    protected static final void checkOffset(int offset, CharacterIterator text) {
+        if (offset < text.getBeginIndex() || offset > text.getEndIndex()) {
+            throw new IllegalArgumentException("offset out of bounds");
+        }
+    }
+
+    /**
+     * Sets the iterator to refer to the first boundary position following
+     * the specified position.
+     * @offset The position from which to begin searching for a break position.
+     * @return The position of the first break after the current position.
+     */
+    @Override
+    public int following(int offset) {
+
+        CharacterIterator text = getText();
+        checkOffset(offset, text);
+
+        // Set our internal iteration position (temporarily)
+        // to the position passed in.  If this is the _beginning_ position,
+        // then we can just use next() to get our return value
+        text.setIndex(offset);
+        if (offset == text.getBeginIndex()) {
+            cachedLastKnownBreak = handleNext();
+            return cachedLastKnownBreak;
+        }
+
+        // otherwise, we have to sync up first.  Use handlePrevious() to back
+        // us up to a known break position before the specified position (if
+        // we can determine that the specified position is a break position,
+        // we don't back up at all).  This may or may not be the last break
+        // position at or before our starting position.  Advance forward
+        // from here until we've passed the starting position.  The position
+        // we stop on will be the first break position after the specified one.
+        int result = cachedLastKnownBreak;
+        if (result >= offset || result <= BreakIterator.DONE) {
+            result = handlePrevious();
+        } else {
+            //it might be better to check if handlePrevious() give us closer
+            //safe value but handlePrevious() is slow too
+            //So, this has to be done carefully
+            text.setIndex(result);
+        }
+        while (result != BreakIterator.DONE && result <= offset) {
+            result = handleNext();
+        }
+        cachedLastKnownBreak = result;
+        return result;
+    }
+
+    /**
+     * Sets the iterator to refer to the last boundary position before the
+     * specified position.
+     * @offset The position to begin searching for a break from.
+     * @return The position of the last boundary before the starting position.
+     */
+    @Override
+    public int preceding(int offset) {
+        // if we start by updating the current iteration position to the
+        // position specified by the caller, we can just use previous()
+        // to carry out this operation
+        CharacterIterator text = getText();
+        checkOffset(offset, text);
+        text.setIndex(offset);
+        return previous();
+    }
+
+    /**
+     * Returns true if the specified position is a boundary position.  As a side
+     * effect, leaves the iterator pointing to the first boundary position at
+     * or after "offset".
+     * @param offset the offset to check.
+     * @return True if "offset" is a boundary position.
+     */
+    @Override
+    public boolean isBoundary(int offset) {
+        CharacterIterator text = getText();
+        checkOffset(offset, text);
+        if (offset == text.getBeginIndex()) {
+            return true;
+        }
+
+        // to check whether this is a boundary, we can use following() on the
+        // position before the specified one and return true if the position we
+        // get back is the one the user specified
+        else {
+            return following(offset - 1) == offset;
+        }
+    }
+
+    /**
+     * Returns the current iteration position.
+     * @return The current iteration position.
+     */
+    @Override
+    public int current() {
+        return getText().getIndex();
+    }
+
+    /**
+     * Return a CharacterIterator over the text being analyzed.  This version
+     * of this method returns the actual CharacterIterator we're using internally.
+     * Changing the state of this iterator can have undefined consequences.  If
+     * you need to change it, clone it first.
+     * @return An iterator over the text being analyzed.
+     */
+    @Override
+    public CharacterIterator getText() {
+        // The iterator is initialized pointing to no text at all, so if this
+        // function is called while we're in that state, we have to fudge an
+        // iterator to return.
+        if (text == null) {
+            text = new StringCharacterIterator("");
+        }
+        return text;
+    }
+
+    /**
+     * Set the iterator to analyze a new piece of text.  This function resets
+     * the current iteration position to the beginning of the text.
+     * @param newText An iterator over the text to analyze.
+     */
+    @Override
+    public void setText(CharacterIterator newText) {
+        // Test iterator to see if we need to wrap it in a SafeCharIterator.
+        // The correct behavior for CharacterIterators is to allow the
+        // position to be set to the endpoint of the iterator.  Many
+        // CharacterIterators do not uphold this, so this is a workaround
+        // to permit them to use this class.
+        int end = newText.getEndIndex();
+        boolean goodIterator;
+        try {
+            newText.setIndex(end);  // some buggy iterators throw an exception here
+            goodIterator = newText.getIndex() == end;
+        }
+        catch(IllegalArgumentException e) {
+            goodIterator = false;
+        }
+
+        if (goodIterator) {
+            text = newText;
+        }
+        else {
+            text = new SafeCharIterator(newText);
+        }
+        text.first();
+
+        cachedLastKnownBreak = BreakIterator.DONE;
+    }
+
+
+    //=======================================================================
+    // implementation
+    //=======================================================================
+
+    /**
+     * This method is the actual implementation of the next() method.  All iteration
+     * vectors through here.  This method initializes the state machine to state 1
+     * and advances through the text character by character until we reach the end
+     * of the text or the state machine transitions to state 0.  We update our return
+     * value every time the state machine passes through a possible end state.
+     */
+    protected int handleNext() {
+        // if we're already at the end of the text, return DONE.
+        CharacterIterator text = getText();
+        if (text.getIndex() == text.getEndIndex()) {
+            return BreakIterator.DONE;
+        }
+
+        // no matter what, we always advance at least one character forward
+        int result = getNextIndex();
+        int lookaheadResult = 0;
+
+        // begin in state 1
+        int state = START_STATE;
+        int category;
+        int c = getCurrent();
+
+        // loop until we reach the end of the text or transition to state 0
+        while (c != CharacterIterator.DONE && state != STOP_STATE) {
+
+            // look up the current character's character category (which tells us
+            // which column in the state table to look at)
+            category = lookupCategory(c);
+
+            // if the character isn't an ignore character, look up a state
+            // transition in the state table
+            if (category != IGNORE) {
+                state = lookupState(state, category);
+            }
+
+            // if the state we've just transitioned to is a lookahead state,
+            // (but not also an end state), save its position.  If it's
+            // both a lookahead state and an end state, update the break position
+            // to the last saved lookup-state position
+            if (lookaheadStates[state]) {
+                if (endStates[state]) {
+                    result = lookaheadResult;
+                }
+                else {
+                    lookaheadResult = getNextIndex();
+                }
+            }
+
+            // otherwise, if the state we've just transitioned to is an accepting
+            // state, update the break position to be the current iteration position
+            else {
+                if (endStates[state]) {
+                    result = getNextIndex();
+                }
+            }
+
+            c = getNext();
+        }
+
+        // if we've run off the end of the text, and the very last character took us into
+        // a lookahead state, advance the break position to the lookahead position
+        // (the theory here is that if there are no characters at all after the lookahead
+        // position, that always matches the lookahead criteria)
+        if (c == CharacterIterator.DONE && lookaheadResult == text.getEndIndex()) {
+            result = lookaheadResult;
+        }
+
+        text.setIndex(result);
+        return result;
+    }
+
+    /**
+     * This method backs the iterator back up to a "safe position" in the text.
+     * This is a position that we know, without any context, must be a break position.
+     * The various calling methods then iterate forward from this safe position to
+     * the appropriate position to return.  (For more information, see the description
+     * of buildBackwardsStateTable() in RuleBasedBreakIterator.Builder.)
+     */
+    protected int handlePrevious() {
+        CharacterIterator text = getText();
+        int state = START_STATE;
+        int category = 0;
+        int lastCategory = 0;
+        int c = getCurrent();
+
+        // loop until we reach the beginning of the text or transition to state 0
+        while (c != CharacterIterator.DONE && state != STOP_STATE) {
+
+            // save the last character's category and look up the current
+            // character's category
+            lastCategory = category;
+            category = lookupCategory(c);
+
+            // if the current character isn't an ignore character, look up a
+            // state transition in the backwards state table
+            if (category != IGNORE) {
+                state = lookupBackwardState(state, category);
+            }
+
+            // then advance one character backwards
+            c = getPrevious();
+        }
+
+        // if we didn't march off the beginning of the text, we're either one or two
+        // positions away from the real break position.  (One because of the call to
+        // previous() at the end of the loop above, and another because the character
+        // that takes us into the stop state will always be the character BEFORE
+        // the break position.)
+        if (c != CharacterIterator.DONE) {
+            if (lastCategory != IGNORE) {
+                getNext();
+                getNext();
+            }
+            else {
+                getNext();
+            }
+        }
+        return text.getIndex();
+    }
+
+    /**
+     * Looks up a character's category (i.e., its category for breaking purposes,
+     * not its Unicode category)
+     */
+    protected int lookupCategory(int c) {
+        if (c < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            return charCategoryTable.elementAt((char)c);
+        } else {
+            return supplementaryCharCategoryTable.getValue(c);
+        }
+    }
+
+    /**
+     * Given a current state and a character category, looks up the
+     * next state to transition to in the state table.
+     */
+    protected int lookupState(int state, int category) {
+        return stateTable[state * numCategories + category];
+    }
+
+    /**
+     * Given a current state and a character category, looks up the
+     * next state to transition to in the backwards state table.
+     */
+    protected int lookupBackwardState(int state, int category) {
+        return backwardsStateTable[state * numCategories + category];
+    }
+
+    /*
+     * This class exists to work around a bug in incorrect implementations
+     * of CharacterIterator, which incorrectly handle setIndex(endIndex).
+     * This iterator relies only on base.setIndex(n) where n is less than
+     * endIndex.
+     *
+     * One caveat:  if the base iterator's begin and end indices change
+     * the change will not be reflected by this wrapper.  Does that matter?
+     */
+    // TODO: Review this class to see if it's still required.
+    private static final class SafeCharIterator implements CharacterIterator,
+                                                           Cloneable {
+
+        private CharacterIterator base;
+        private int rangeStart;
+        private int rangeLimit;
+        private int currentIndex;
+
+        SafeCharIterator(CharacterIterator base) {
+            this.base = base;
+            this.rangeStart = base.getBeginIndex();
+            this.rangeLimit = base.getEndIndex();
+            this.currentIndex = base.getIndex();
+        }
+
+        @Override
+        public char first() {
+            return setIndex(rangeStart);
+        }
+
+        @Override
+        public char last() {
+            return setIndex(rangeLimit - 1);
+        }
+
+        @Override
+        public char current() {
+            if (currentIndex < rangeStart || currentIndex >= rangeLimit) {
+                return DONE;
+            }
+            else {
+                return base.setIndex(currentIndex);
+            }
+        }
+
+        @Override
+        public char next() {
+
+            currentIndex++;
+            if (currentIndex >= rangeLimit) {
+                currentIndex = rangeLimit;
+                return DONE;
+            }
+            else {
+                return base.setIndex(currentIndex);
+            }
+        }
+
+        @Override
+        public char previous() {
+
+            currentIndex--;
+            if (currentIndex < rangeStart) {
+                currentIndex = rangeStart;
+                return DONE;
+            }
+            else {
+                return base.setIndex(currentIndex);
+            }
+        }
+
+        @Override
+        public char setIndex(int i) {
+
+            if (i < rangeStart || i > rangeLimit) {
+                throw new IllegalArgumentException("Invalid position");
+            }
+            currentIndex = i;
+            return current();
+        }
+
+        @Override
+        public int getBeginIndex() {
+            return rangeStart;
+        }
+
+        @Override
+        public int getEndIndex() {
+            return rangeLimit;
+        }
+
+        @Override
+        public int getIndex() {
+            return currentIndex;
+        }
+
+        @Override
+        public Object clone() {
+
+            SafeCharIterator copy = null;
+            try {
+                copy = (SafeCharIterator) super.clone();
+            }
+            catch(CloneNotSupportedException e) {
+                throw new Error("Clone not supported: " + e);
+            }
+
+            CharacterIterator copyOfBase = (CharacterIterator) base.clone();
+            copy.base = copyOfBase;
+            return copy;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/text/resources/BreakIteratorResources.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.text.resources;
+
+import java.util.ResourceBundle;
+import sun.util.resources.BreakIteratorResourceBundle;
+
+public class BreakIteratorResources extends BreakIteratorResourceBundle {
+    @Override
+    protected ResourceBundle getBreakIteratorInfo() {
+        return new BreakIteratorInfo();
+    }
+}
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/BreakDictionary.java	Thu Oct 27 16:29:00 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- *
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
- *
- * The original version of this source code and documentation
- * is copyrighted and owned by Taligent, Inc., a wholly-owned
- * subsidiary of IBM. These materials are provided under terms
- * of a License Agreement between Taligent and Sun. This technology
- * is protected by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- */
-package sun.util.locale.provider;
-
-import java.io.BufferedInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.lang.reflect.Module;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.MissingResourceException;
-import sun.text.CompactByteArray;
-import sun.text.SupplementaryCharacterData;
-
-/**
- * This is the class that represents the list of known words used by
- * DictionaryBasedBreakIterator.  The conceptual data structure used
- * here is a trie: there is a node hanging off the root node for every
- * letter that can start a word.  Each of these nodes has a node hanging
- * off of it for every letter that can be the second letter of a word
- * if this node is the first letter, and so on.  The trie is represented
- * as a two-dimensional array that can be treated as a table of state
- * transitions.  Indexes are used to compress this array, taking
- * advantage of the fact that this array will always be very sparse.
- */
-class BreakDictionary {
-
-    //=========================================================================
-    // data members
-    //=========================================================================
-
-    /**
-      * The version of the dictionary that was read in.
-      */
-    private static int supportedVersion = 1;
-
-    /**
-     * Maps from characters to column numbers.  The main use of this is to
-     * avoid making room in the array for empty columns.
-     */
-    private CompactByteArray columnMap = null;
-    private SupplementaryCharacterData supplementaryCharColumnMap = null;
-
-    /**
-     * The number of actual columns in the table
-     */
-    private int numCols;
-
-    /**
-     * Columns are organized into groups of 32.  This says how many
-     * column groups.  (We could calculate this, but we store the
-     * value to avoid having to repeatedly calculate it.)
-     */
-    private int numColGroups;
-
-    /**
-     * The actual compressed state table.  Each conceptual row represents
-     * a state, and the cells in it contain the row numbers of the states
-     * to transition to for each possible letter.  0 is used to indicate
-     * an illegal combination of letters (i.e., the error state).  The
-     * table is compressed by eliminating all the unpopulated (i.e., zero)
-     * cells.  Multiple conceptual rows can then be doubled up in a single
-     * physical row by sliding them up and possibly shifting them to one
-     * side or the other so the populated cells don't collide.  Indexes
-     * are used to identify unpopulated cells and to locate populated cells.
-     */
-    private short[] table = null;
-
-    /**
-     * This index maps logical row numbers to physical row numbers
-     */
-    private short[] rowIndex = null;
-
-    /**
-     * A bitmap is used to tell which cells in the comceptual table are
-     * populated.  This array contains all the unique bit combinations
-     * in that bitmap.  If the table is more than 32 columns wide,
-     * successive entries in this array are used for a single row.
-     */
-    private int[] rowIndexFlags = null;
-
-    /**
-     * This index maps from a logical row number into the bitmap table above.
-     * (This keeps us from storing duplicate bitmap combinations.)  Since there
-     * are a lot of rows with only one populated cell, instead of wasting space
-     * in the bitmap table, we just store a negative number in this index for
-     * rows with one populated cell.  The absolute value of that number is
-     * the column number of the populated cell.
-     */
-    private short[] rowIndexFlagsIndex = null;
-
-    /**
-     * For each logical row, this index contains a constant that is added to
-     * the logical column number to get the physical column number
-     */
-    private byte[] rowIndexShifts = null;
-
-    //=========================================================================
-    // deserialization
-    //=========================================================================
-
-    BreakDictionary(Module module, String dictionaryName)
-        throws IOException, MissingResourceException {
-
-        readDictionaryFile(module, dictionaryName);
-    }
-
-    private void readDictionaryFile(final Module module, final String dictionaryName)
-        throws IOException, MissingResourceException {
-
-        BufferedInputStream in;
-        try {
-            PrivilegedExceptionAction<BufferedInputStream> pa = () -> {
-                String pathName = "jdk.localedata".equals(module.getName()) ?
-                     "sun/text/resources/ext/" :
-                     "sun/text/resources/";
-                InputStream is = module.getResourceAsStream(pathName + dictionaryName);
-                if (is == null) {
-                    // Try to load the file with "java.base" module instance. Assumption
-                    // here is that the fall back data files to be read should reside in
-                    // java.base.
-                    is = BreakDictionary.class.getModule().getResourceAsStream("sun/text/resources/" + dictionaryName);
-                }
-
-                return new BufferedInputStream(is);
-            };
-            in = AccessController.doPrivileged(pa);
-        }
-        catch (PrivilegedActionException e) {
-            throw new InternalError(e.toString(), e);
-        }
-
-        byte[] buf = new byte[8];
-        if (in.read(buf) != 8) {
-            throw new MissingResourceException("Wrong data length",
-                                               dictionaryName, "");
-        }
-
-        // check version
-        int version = RuleBasedBreakIterator.getInt(buf, 0);
-        if (version != supportedVersion) {
-            throw new MissingResourceException("Dictionary version(" + version + ") is unsupported",
-                                                           dictionaryName, "");
-        }
-
-        // get data size
-        int len = RuleBasedBreakIterator.getInt(buf, 4);
-        buf = new byte[len];
-        if (in.read(buf) != len) {
-            throw new MissingResourceException("Wrong data length",
-                                               dictionaryName, "");
-        }
-
-        // close the stream
-        in.close();
-
-        int l;
-        int offset = 0;
-
-        // read in the column map for BMP characteres (this is serialized in
-        // its internal form: an index array followed by a data array)
-        l = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        short[] temp = new short[l];
-        for (int i = 0; i < l; i++, offset+=2) {
-            temp[i] = RuleBasedBreakIterator.getShort(buf, offset);
-        }
-        l = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        byte[] temp2 = new byte[l];
-        for (int i = 0; i < l; i++, offset++) {
-            temp2[i] = buf[offset];
-        }
-        columnMap = new CompactByteArray(temp, temp2);
-
-        // read in numCols and numColGroups
-        numCols = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        numColGroups = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-
-        // read in the row-number index
-        l = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        rowIndex = new short[l];
-        for (int i = 0; i < l; i++, offset+=2) {
-            rowIndex[i] = RuleBasedBreakIterator.getShort(buf, offset);
-        }
-
-        // load in the populated-cells bitmap: index first, then bitmap list
-        l = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        rowIndexFlagsIndex = new short[l];
-        for (int i = 0; i < l; i++, offset+=2) {
-            rowIndexFlagsIndex[i] = RuleBasedBreakIterator.getShort(buf, offset);
-        }
-        l = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        rowIndexFlags = new int[l];
-        for (int i = 0; i < l; i++, offset+=4) {
-            rowIndexFlags[i] = RuleBasedBreakIterator.getInt(buf, offset);
-        }
-
-        // load in the row-shift index
-        l = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        rowIndexShifts = new byte[l];
-        for (int i = 0; i < l; i++, offset++) {
-            rowIndexShifts[i] = buf[offset];
-        }
-
-        // load in the actual state table
-        l = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        table = new short[l];
-        for (int i = 0; i < l; i++, offset+=2) {
-            table[i] = RuleBasedBreakIterator.getShort(buf, offset);
-        }
-
-        // finally, prepare the column map for supplementary characters
-        l = RuleBasedBreakIterator.getInt(buf, offset);
-        offset += 4;
-        int[] temp3 = new int[l];
-        for (int i = 0; i < l; i++, offset+=4) {
-            temp3[i] = RuleBasedBreakIterator.getInt(buf, offset);
-        }
-        supplementaryCharColumnMap = new SupplementaryCharacterData(temp3);
-    }
-
-    //=========================================================================
-    // access to the words
-    //=========================================================================
-
-    /**
-     * Uses the column map to map the character to a column number, then
-     * passes the row and column number to getNextState()
-     * @param row The current state
-     * @param ch The character whose column we're interested in
-     * @return The new state to transition to
-     */
-    public final short getNextStateFromCharacter(int row, int ch) {
-        int col;
-        if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
-            col = columnMap.elementAt((char)ch);
-        } else {
-            col = supplementaryCharColumnMap.getValue(ch);
-        }
-        return getNextState(row, col);
-    }
-
-    /**
-     * Returns the value in the cell with the specified (logical) row and
-     * column numbers.  In DictionaryBasedBreakIterator, the row number is
-     * a state number, the column number is an input, and the return value
-     * is the row number of the new state to transition to.  (0 is the
-     * "error" state, and -1 is the "end of word" state in a dictionary)
-     * @param row The row number of the current state
-     * @param col The column number of the input character (0 means "not a
-     * dictionary character")
-     * @return The row number of the new state to transition to
-     */
-    public final short getNextState(int row, int col) {
-        if (cellIsPopulated(row, col)) {
-            // we map from logical to physical row number by looking up the
-            // mapping in rowIndex; we map from logical column number to
-            // physical column number by looking up a shift value for this
-            // logical row and offsetting the logical column number by
-            // the shift amount.  Then we can use internalAt() to actually
-            // get the value out of the table.
-            return internalAt(rowIndex[row], col + rowIndexShifts[row]);
-        }
-        else {
-            return 0;
-        }
-    }
-
-    /**
-     * Given (logical) row and column numbers, returns true if the
-     * cell in that position is populated
-     */
-    private boolean cellIsPopulated(int row, int col) {
-        // look up the entry in the bitmap index for the specified row.
-        // If it's a negative number, it's the column number of the only
-        // populated cell in the row
-        if (rowIndexFlagsIndex[row] < 0) {
-            return col == -rowIndexFlagsIndex[row];
-        }
-
-        // if it's a positive number, it's the offset of an entry in the bitmap
-        // list.  If the table is more than 32 columns wide, the bitmap is stored
-        // successive entries in the bitmap list, so we have to divide the column
-        // number by 32 and offset the number we got out of the index by the result.
-        // Once we have the appropriate piece of the bitmap, test the appropriate
-        // bit and return the result.
-        else {
-            int flags = rowIndexFlags[rowIndexFlagsIndex[row] + (col >> 5)];
-            return (flags & (1 << (col & 0x1f))) != 0;
-        }
-    }
-
-    /**
-     * Implementation of getNextState() when we know the specified cell is
-     * populated.
-     * @param row The PHYSICAL row number of the cell
-     * @param col The PHYSICAL column number of the cell
-     * @return The value stored in the cell
-     */
-    private short internalAt(int row, int col) {
-        // the table is a one-dimensional array, so this just does the math necessary
-        // to treat it as a two-dimensional array (we don't just use a two-dimensional
-        // array because two-dimensional arrays are inefficient in Java)
-        return table[row * numCols + col];
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/BreakIteratorProviderImpl.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/BreakIteratorProviderImpl.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -32,6 +32,8 @@
 import java.util.MissingResourceException;
 import java.util.Objects;
 import java.util.Set;
+import sun.text.DictionaryBasedBreakIterator;
+import sun.text.RuleBasedBreakIterator;
 
 /**
  * Concrete implementation of the  {@link java.text.spi.BreakIteratorProvider
@@ -153,29 +155,31 @@
     }
 
     private BreakIterator getBreakInstance(Locale locale,
-                                                  int type,
-                                                  String dataName,
-                                                  String dictionaryName) {
+                                           int type,
+                                           String ruleName,
+                                           String dictionaryName) {
         Objects.requireNonNull(locale);
 
         LocaleResources lr = LocaleProviderAdapter.forJRE().getLocaleResources(locale);
         String[] classNames = (String[]) lr.getBreakIteratorInfo("BreakIteratorClasses");
-        String dataFile = (String) lr.getBreakIteratorInfo(dataName);
+        String ruleFile = (String) lr.getBreakIteratorInfo(ruleName);
+        byte[] ruleData = lr.getBreakIteratorResources(ruleName);
 
         try {
             switch (classNames[type]) {
             case "RuleBasedBreakIterator":
-                return new RuleBasedBreakIterator(
-                    lr.getBreakIteratorDataModule(), dataFile);
+                return new RuleBasedBreakIterator(ruleFile, ruleData);
+
             case "DictionaryBasedBreakIterator":
                 String dictionaryFile = (String) lr.getBreakIteratorInfo(dictionaryName);
-                return new DictionaryBasedBreakIterator(
-                    lr.getBreakIteratorDataModule(), dataFile, dictionaryFile);
+                byte[] dictionaryData = lr.getBreakIteratorResources(dictionaryName);
+                return new DictionaryBasedBreakIterator(ruleFile, ruleData,
+                                                        dictionaryFile, dictionaryData);
             default:
                 throw new IllegalArgumentException("Invalid break iterator class \"" +
                                 classNames[type] + "\"");
             }
-        } catch (IOException | MissingResourceException | IllegalArgumentException e) {
+        } catch (MissingResourceException | IllegalArgumentException e) {
             throw new InternalError(e.toString(), e);
         }
     }
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/DictionaryBasedBreakIterator.java	Thu Oct 27 16:29:00 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,524 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- *
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
- *
- * The original version of this source code and documentation
- * is copyrighted and owned by Taligent, Inc., a wholly-owned
- * subsidiary of IBM. These materials are provided under terms
- * of a License Agreement between Taligent and Sun. This technology
- * is protected by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- */
-
-package sun.util.locale.provider;
-
-import java.io.IOException;
-import java.lang.reflect.Module;
-import java.text.CharacterIterator;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Stack;
-
-/**
- * A subclass of RuleBasedBreakIterator that adds the ability to use a dictionary
- * to further subdivide ranges of text beyond what is possible using just the
- * state-table-based algorithm.  This is necessary, for example, to handle
- * word and line breaking in Thai, which doesn't use spaces between words.  The
- * state-table-based algorithm used by RuleBasedBreakIterator is used to divide
- * up text as far as possible, and then contiguous ranges of letters are
- * repeatedly compared against a list of known words (i.e., the dictionary)
- * to divide them up into words.
- *
- * DictionaryBasedBreakIterator uses the same rule language as RuleBasedBreakIterator,
- * but adds one more special substitution name: &lt;dictionary&gt;.  This substitution
- * name is used to identify characters in words in the dictionary.  The idea is that
- * if the iterator passes over a chunk of text that includes two or more characters
- * in a row that are included in &lt;dictionary&gt;, it goes back through that range and
- * derives additional break positions (if possible) using the dictionary.
- *
- * DictionaryBasedBreakIterator is also constructed with the filename of a dictionary
- * file.  It follows a prescribed search path to locate the dictionary (right now,
- * it looks for it in /com/ibm/text/resources in each directory in the classpath,
- * and won't find it in JAR files, but this location is likely to change).  The
- * dictionary file is in a serialized binary format.  We have a very primitive (and
- * slow) BuildDictionaryFile utility for creating dictionary files, but aren't
- * currently making it public.  Contact us for help.
- */
-class DictionaryBasedBreakIterator extends RuleBasedBreakIterator {
-
-    /**
-     * a list of known words that is used to divide up contiguous ranges of letters,
-     * stored in a compressed, indexed, format that offers fast access
-     */
-    private BreakDictionary dictionary;
-
-    /**
-     * a list of flags indicating which character categories are contained in
-     * the dictionary file (this is used to determine which ranges of characters
-     * to apply the dictionary to)
-     */
-    private boolean[] categoryFlags;
-
-    /**
-     * a temporary hiding place for the number of dictionary characters in the
-     * last range passed over by next()
-     */
-    private int dictionaryCharCount;
-
-    /**
-     * when a range of characters is divided up using the dictionary, the break
-     * positions that are discovered are stored here, preventing us from having
-     * to use either the dictionary or the state table again until the iterator
-     * leaves this range of text
-     */
-    private int[] cachedBreakPositions;
-
-    /**
-     * if cachedBreakPositions is not null, this indicates which item in the
-     * cache the current iteration position refers to
-     */
-    private int positionInCache;
-
-    /**
-     * Constructs a DictionaryBasedBreakIterator.
-     * @param module The module where the dictionary file resides
-     * @param dictionaryFilename The filename of the dictionary file to use
-     */
-    DictionaryBasedBreakIterator(Module module, String dataFile, String dictionaryFile)
-                                        throws IOException {
-        super(module, dataFile);
-        byte[] tmp = super.getAdditionalData();
-        if (tmp != null) {
-            prepareCategoryFlags(tmp);
-            super.setAdditionalData(null);
-        }
-        dictionary = new BreakDictionary(module, dictionaryFile);
-    }
-
-    private void prepareCategoryFlags(byte[] data) {
-        categoryFlags = new boolean[data.length];
-        for (int i = 0; i < data.length; i++) {
-            categoryFlags[i] = (data[i] == (byte)1) ? true : false;
-        }
-    }
-
-    @Override
-    public void setText(CharacterIterator newText) {
-        super.setText(newText);
-        cachedBreakPositions = null;
-        dictionaryCharCount = 0;
-        positionInCache = 0;
-    }
-
-    /**
-     * Sets the current iteration position to the beginning of the text.
-     * (i.e., the CharacterIterator's starting offset).
-     * @return The offset of the beginning of the text.
-     */
-    @Override
-    public int first() {
-        cachedBreakPositions = null;
-        dictionaryCharCount = 0;
-        positionInCache = 0;
-        return super.first();
-    }
-
-    /**
-     * Sets the current iteration position to the end of the text.
-     * (i.e., the CharacterIterator's ending offset).
-     * @return The text's past-the-end offset.
-     */
-    @Override
-    public int last() {
-        cachedBreakPositions = null;
-        dictionaryCharCount = 0;
-        positionInCache = 0;
-        return super.last();
-    }
-
-    /**
-     * Advances the iterator one step backwards.
-     * @return The position of the last boundary position before the
-     * current iteration position
-     */
-    @Override
-    public int previous() {
-        CharacterIterator text = getText();
-
-        // if we have cached break positions and we're still in the range
-        // covered by them, just move one step backward in the cache
-        if (cachedBreakPositions != null && positionInCache > 0) {
-            --positionInCache;
-            text.setIndex(cachedBreakPositions[positionInCache]);
-            return cachedBreakPositions[positionInCache];
-        }
-
-        // otherwise, dump the cache and use the inherited previous() method to move
-        // backward.  This may fill up the cache with new break positions, in which
-        // case we have to mark our position in the cache
-        else {
-            cachedBreakPositions = null;
-            int result = super.previous();
-            if (cachedBreakPositions != null) {
-                positionInCache = cachedBreakPositions.length - 2;
-            }
-            return result;
-        }
-    }
-
-    /**
-     * Sets the current iteration position to the last boundary position
-     * before the specified position.
-     * @param offset The position to begin searching from
-     * @return The position of the last boundary before "offset"
-     */
-    @Override
-    public int preceding(int offset) {
-        CharacterIterator text = getText();
-        checkOffset(offset, text);
-
-        // if we have no cached break positions, or "offset" is outside the
-        // range covered by the cache, we can just call the inherited routine
-        // (which will eventually call other routines in this class that may
-        // refresh the cache)
-        if (cachedBreakPositions == null || offset <= cachedBreakPositions[0] ||
-                offset > cachedBreakPositions[cachedBreakPositions.length - 1]) {
-            cachedBreakPositions = null;
-            return super.preceding(offset);
-        }
-
-        // on the other hand, if "offset" is within the range covered by the cache,
-        // then all we have to do is search the cache for the last break position
-        // before "offset"
-        else {
-            positionInCache = 0;
-            while (positionInCache < cachedBreakPositions.length
-                   && offset > cachedBreakPositions[positionInCache]) {
-                ++positionInCache;
-            }
-            --positionInCache;
-            text.setIndex(cachedBreakPositions[positionInCache]);
-            return text.getIndex();
-        }
-    }
-
-    /**
-     * Sets the current iteration position to the first boundary position after
-     * the specified position.
-     * @param offset The position to begin searching forward from
-     * @return The position of the first boundary after "offset"
-     */
-    @Override
-    public int following(int offset) {
-        CharacterIterator text = getText();
-        checkOffset(offset, text);
-
-        // if we have no cached break positions, or if "offset" is outside the
-        // range covered by the cache, then dump the cache and call our
-        // inherited following() method.  This will call other methods in this
-        // class that may refresh the cache.
-        if (cachedBreakPositions == null || offset < cachedBreakPositions[0] ||
-                offset >= cachedBreakPositions[cachedBreakPositions.length - 1]) {
-            cachedBreakPositions = null;
-            return super.following(offset);
-        }
-
-        // on the other hand, if "offset" is within the range covered by the
-        // cache, then just search the cache for the first break position
-        // after "offset"
-        else {
-            positionInCache = 0;
-            while (positionInCache < cachedBreakPositions.length
-                   && offset >= cachedBreakPositions[positionInCache]) {
-                ++positionInCache;
-            }
-            text.setIndex(cachedBreakPositions[positionInCache]);
-            return text.getIndex();
-        }
-    }
-
-    /**
-     * This is the implementation function for next().
-     */
-    @Override
-    protected int handleNext() {
-        CharacterIterator text = getText();
-
-        // if there are no cached break positions, or if we've just moved
-        // off the end of the range covered by the cache, we have to dump
-        // and possibly regenerate the cache
-        if (cachedBreakPositions == null ||
-            positionInCache == cachedBreakPositions.length - 1) {
-
-            // start by using the inherited handleNext() to find a tentative return
-            // value.   dictionaryCharCount tells us how many dictionary characters
-            // we passed over on our way to the tentative return value
-            int startPos = text.getIndex();
-            dictionaryCharCount = 0;
-            int result = super.handleNext();
-
-            // if we passed over more than one dictionary character, then we use
-            // divideUpDictionaryRange() to regenerate the cached break positions
-            // for the new range
-            if (dictionaryCharCount > 1 && result - startPos > 1) {
-                divideUpDictionaryRange(startPos, result);
-            }
-
-            // otherwise, the value we got back from the inherited fuction
-            // is our return value, and we can dump the cache
-            else {
-                cachedBreakPositions = null;
-                return result;
-            }
-        }
-
-        // if the cache of break positions has been regenerated (or existed all
-        // along), then just advance to the next break position in the cache
-        // and return it
-        if (cachedBreakPositions != null) {
-            ++positionInCache;
-            text.setIndex(cachedBreakPositions[positionInCache]);
-            return cachedBreakPositions[positionInCache];
-        }
-        return -9999;   // SHOULD NEVER GET HERE!
-    }
-
-    /**
-     * Looks up a character category for a character.
-     */
-    @Override
-    protected int lookupCategory(int c) {
-        // this override of lookupCategory() exists only to keep track of whether we've
-        // passed over any dictionary characters.  It calls the inherited lookupCategory()
-        // to do the real work, and then checks whether its return value is one of the
-        // categories represented in the dictionary.  If it is, bump the dictionary-
-        // character count.
-        int result = super.lookupCategory(c);
-        if (result != RuleBasedBreakIterator.IGNORE && categoryFlags[result]) {
-            ++dictionaryCharCount;
-        }
-        return result;
-    }
-
-    /**
-     * This is the function that actually implements the dictionary-based
-     * algorithm.  Given the endpoints of a range of text, it uses the
-     * dictionary to determine the positions of any boundaries in this
-     * range.  It stores all the boundary positions it discovers in
-     * cachedBreakPositions so that we only have to do this work once
-     * for each time we enter the range.
-     */
-    @SuppressWarnings("unchecked")
-    private void divideUpDictionaryRange(int startPos, int endPos) {
-        CharacterIterator text = getText();
-
-        // the range we're dividing may begin or end with non-dictionary characters
-        // (i.e., for line breaking, we may have leading or trailing punctuation
-        // that needs to be kept with the word).  Seek from the beginning of the
-        // range to the first dictionary character
-        text.setIndex(startPos);
-        int c = getCurrent();
-        int category = lookupCategory(c);
-        while (category == IGNORE || !categoryFlags[category]) {
-            c = getNext();
-            category = lookupCategory(c);
-        }
-
-        // initialize.  We maintain two stacks: currentBreakPositions contains
-        // the list of break positions that will be returned if we successfully
-        // finish traversing the whole range now.  possibleBreakPositions lists
-        // all other possible word ends we've passed along the way.  (Whenever
-        // we reach an error [a sequence of characters that can't begin any word
-        // in the dictionary], we back up, possibly delete some breaks from
-        // currentBreakPositions, move a break from possibleBreakPositions
-        // to currentBreakPositions, and start over from there.  This process
-        // continues in this way until we either successfully make it all the way
-        // across the range, or exhaust all of our combinations of break
-        // positions.)
-        Stack<Integer> currentBreakPositions = new Stack<>();
-        Stack<Integer> possibleBreakPositions = new Stack<>();
-        List<Integer> wrongBreakPositions = new ArrayList<>();
-
-        // the dictionary is implemented as a trie, which is treated as a state
-        // machine.  -1 represents the end of a legal word.  Every word in the
-        // dictionary is represented by a path from the root node to -1.  A path
-        // that ends in state 0 is an illegal combination of characters.
-        int state = 0;
-
-        // these two variables are used for error handling.  We keep track of the
-        // farthest we've gotten through the range being divided, and the combination
-        // of breaks that got us that far.  If we use up all possible break
-        // combinations, the text contains an error or a word that's not in the
-        // dictionary.  In this case, we "bless" the break positions that got us the
-        // farthest as real break positions, and then start over from scratch with
-        // the character where the error occurred.
-        int farthestEndPoint = text.getIndex();
-        Stack<Integer> bestBreakPositions = null;
-
-        // initialize (we always exit the loop with a break statement)
-        c = getCurrent();
-        while (true) {
-
-            // if we can transition to state "-1" from our current state, we're
-            // on the last character of a legal word.  Push that position onto
-            // the possible-break-positions stack
-            if (dictionary.getNextState(state, 0) == -1) {
-                possibleBreakPositions.push(text.getIndex());
-            }
-
-            // look up the new state to transition to in the dictionary
-            state = dictionary.getNextStateFromCharacter(state, c);
-
-            // if the character we're sitting on causes us to transition to
-            // the "end of word" state, then it was a non-dictionary character
-            // and we've successfully traversed the whole range.  Drop out
-            // of the loop.
-            if (state == -1) {
-                currentBreakPositions.push(text.getIndex());
-                break;
-            }
-
-            // if the character we're sitting on causes us to transition to
-            // the error state, or if we've gone off the end of the range
-            // without transitioning to the "end of word" state, we've hit
-            // an error...
-            else if (state == 0 || text.getIndex() >= endPos) {
-
-                // if this is the farthest we've gotten, take note of it in
-                // case there's an error in the text
-                if (text.getIndex() > farthestEndPoint) {
-                    farthestEndPoint = text.getIndex();
-
-                    @SuppressWarnings("unchecked")
-                    Stack<Integer> currentBreakPositionsCopy = (Stack<Integer>) currentBreakPositions.clone();
-
-                    bestBreakPositions = currentBreakPositionsCopy;
-                }
-
-                // wrongBreakPositions is a list of all break positions
-                // we've tried starting that didn't allow us to traverse
-                // all the way through the text.  Every time we pop a
-                // break position off of currentBreakPositions, we put it
-                // into wrongBreakPositions to avoid trying it again later.
-                // If we make it to this spot, we're either going to back
-                // up to a break in possibleBreakPositions and try starting
-                // over from there, or we've exhausted all possible break
-                // positions and are going to do the fallback procedure.
-                // This loop prevents us from messing with anything in
-                // possibleBreakPositions that didn't work as a starting
-                // point the last time we tried it (this is to prevent a bunch of
-                // repetitive checks from slowing down some extreme cases)
-                while (!possibleBreakPositions.isEmpty()
-                        && wrongBreakPositions.contains(possibleBreakPositions.peek())) {
-                    possibleBreakPositions.pop();
-                }
-
-                // if we've used up all possible break-position combinations, there's
-                // an error or an unknown word in the text.  In this case, we start
-                // over, treating the farthest character we've reached as the beginning
-                // of the range, and "blessing" the break positions that got us that
-                // far as real break positions
-                if (possibleBreakPositions.isEmpty()) {
-                    if (bestBreakPositions != null) {
-                        currentBreakPositions = bestBreakPositions;
-                        if (farthestEndPoint < endPos) {
-                            text.setIndex(farthestEndPoint + 1);
-                        }
-                        else {
-                            break;
-                        }
-                    }
-                    else {
-                        if ((currentBreakPositions.size() == 0 ||
-                             currentBreakPositions.peek().intValue() != text.getIndex())
-                            && text.getIndex() != startPos) {
-                            currentBreakPositions.push(text.getIndex());
-                        }
-                        getNext();
-                        currentBreakPositions.push(text.getIndex());
-                    }
-                }
-
-                // if we still have more break positions we can try, then promote the
-                // last break in possibleBreakPositions into currentBreakPositions,
-                // and get rid of all entries in currentBreakPositions that come after
-                // it.  Then back up to that position and start over from there (i.e.,
-                // treat that position as the beginning of a new word)
-                else {
-                    Integer temp = possibleBreakPositions.pop();
-                    Integer temp2 = null;
-                    while (!currentBreakPositions.isEmpty() && temp.intValue() <
-                           currentBreakPositions.peek().intValue()) {
-                        temp2 = currentBreakPositions.pop();
-                        wrongBreakPositions.add(temp2);
-                    }
-                    currentBreakPositions.push(temp);
-                    text.setIndex(currentBreakPositions.peek().intValue());
-                }
-
-                // re-sync "c" for the next go-round, and drop out of the loop if
-                // we've made it off the end of the range
-                c = getCurrent();
-                if (text.getIndex() >= endPos) {
-                    break;
-                }
-            }
-
-            // if we didn't hit any exceptional conditions on this last iteration,
-            // just advance to the next character and loop
-            else {
-                c = getNext();
-            }
-        }
-
-        // dump the last break position in the list, and replace it with the actual
-        // end of the range (which may be the same character, or may be further on
-        // because the range actually ended with non-dictionary characters we want to
-        // keep with the word)
-        if (!currentBreakPositions.isEmpty()) {
-            currentBreakPositions.pop();
-        }
-        currentBreakPositions.push(endPos);
-
-        // create a regular array to hold the break positions and copy
-        // the break positions from the stack to the array (in addition,
-        // our starting position goes into this array as a break position).
-        // This array becomes the cache of break positions used by next()
-        // and previous(), so this is where we actually refresh the cache.
-        cachedBreakPositions = new int[currentBreakPositions.size() + 1];
-        cachedBreakPositions[0] = startPos;
-
-        for (int i = 0; i < currentBreakPositions.size(); i++) {
-            cachedBreakPositions[i + 1] = currentBreakPositions.elementAt(i).intValue();
-        }
-        positionInCache = 0;
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, 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
@@ -42,7 +42,6 @@
 
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
-import java.lang.reflect.Module;
 import java.text.MessageFormat;
 import java.util.Calendar;
 import java.util.LinkedHashSet;
@@ -113,13 +112,14 @@
         if (data == null || ((biInfo = data.get()) == null)) {
            biInfo = localeData.getBreakIteratorInfo(locale).getObject(key);
            cache.put(cacheKey, new ResourceReference(cacheKey, biInfo, referenceQueue));
-       }
+        }
 
        return biInfo;
     }
 
-    Module getBreakIteratorDataModule() {
-       return localeData.getBreakIteratorInfo(locale).getClass().getModule();
+    @SuppressWarnings("unchecked")
+    byte[] getBreakIteratorResources(String key) {
+        return (byte[]) localeData.getBreakIteratorResources(locale).getObject(key);
     }
 
     int getCalendarData(String key) {
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/RuleBasedBreakIterator.java	Thu Oct 27 16:29:00 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1198 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- *
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 2002 - All Rights Reserved
- *
- * The original version of this source code and documentation
- * is copyrighted and owned by Taligent, Inc., a wholly-owned
- * subsidiary of IBM. These materials are provided under terms
- * of a License Agreement between Taligent and Sun. This technology
- * is protected by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- */
-
-package sun.util.locale.provider;
-
-import java.io.BufferedInputStream;
-import java.io.InputStream;
-import java.io.IOException;
-import java.lang.reflect.Module;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.text.BreakIterator;
-import java.text.CharacterIterator;
-import java.text.StringCharacterIterator;
-import java.util.MissingResourceException;
-import sun.text.CompactByteArray;
-import sun.text.SupplementaryCharacterData;
-
-/**
- * <p>A subclass of BreakIterator whose behavior is specified using a list of rules.</p>
- *
- * <p>There are two kinds of rules, which are separated by semicolons: <i>substitutions</i>
- * and <i>regular expressions.</i></p>
- *
- * <p>A substitution rule defines a name that can be used in place of an expression. It
- * consists of a name, which is a string of characters contained in angle brackets, an equals
- * sign, and an expression. (There can be no whitespace on either side of the equals sign.)
- * To keep its syntactic meaning intact, the expression must be enclosed in parentheses or
- * square brackets. A substitution is visible after its definition, and is filled in using
- * simple textual substitution. Substitution definitions can contain other substitutions, as
- * long as those substitutions have been defined first. Substitutions are generally used to
- * make the regular expressions (which can get quite complex) shorted and easier to read.
- * They typically define either character categories or commonly-used subexpressions.</p>
- *
- * <p>There is one special substitution.&nbsp; If the description defines a substitution
- * called &quot;&lt;ignore&gt;&quot;, the expression must be a [] expression, and the
- * expression defines a set of characters (the &quot;<em>ignore characters</em>&quot;) that
- * will be transparent to the BreakIterator.&nbsp; A sequence of characters will break the
- * same way it would if any ignore characters it contains are taken out.&nbsp; Break
- * positions never occur befoer ignore characters.</p>
- *
- * <p>A regular expression uses a subset of the normal Unix regular-expression syntax, and
- * defines a sequence of characters to be kept together. With one significant exception, the
- * iterator uses a longest-possible-match algorithm when matching text to regular
- * expressions. The iterator also treats descriptions containing multiple regular expressions
- * as if they were ORed together (i.e., as if they were separated by |).</p>
- *
- * <p>The special characters recognized by the regular-expression parser are as follows:</p>
- *
- * <blockquote>
- *   <table border="1" width="100%">
- *     <tr>
- *       <td width="6%">*</td>
- *       <td width="94%">Specifies that the expression preceding the asterisk may occur any number
- *       of times (including not at all).</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">{}</td>
- *       <td width="94%">Encloses a sequence of characters that is optional.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">()</td>
- *       <td width="94%">Encloses a sequence of characters.&nbsp; If followed by *, the sequence
- *       repeats.&nbsp; Otherwise, the parentheses are just a grouping device and a way to delimit
- *       the ends of expressions containing |.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">|</td>
- *       <td width="94%">Separates two alternative sequences of characters.&nbsp; Either one
- *       sequence or the other, but not both, matches this expression.&nbsp; The | character can
- *       only occur inside ().</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">.</td>
- *       <td width="94%">Matches any character.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">*?</td>
- *       <td width="94%">Specifies a non-greedy asterisk.&nbsp; *? works the same way as *, except
- *       when there is overlap between the last group of characters in the expression preceding the
- *       * and the first group of characters following the *.&nbsp; When there is this kind of
- *       overlap, * will match the longest sequence of characters that match the expression before
- *       the *, and *? will match the shortest sequence of characters matching the expression
- *       before the *?.&nbsp; For example, if you have &quot;xxyxyyyxyxyxxyxyxyy&quot; in the text,
- *       &quot;x[xy]*x&quot; will match through to the last x (i.e., &quot;<strong>xxyxyyyxyxyxxyxyx</strong>yy&quot;,
- *       but &quot;x[xy]*?x&quot; will only match the first two xes (&quot;<strong>xx</strong>yxyyyxyxyxxyxyxyy&quot;).</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">[]</td>
- *       <td width="94%">Specifies a group of alternative characters.&nbsp; A [] expression will
- *       match any single character that is specified in the [] expression.&nbsp; For more on the
- *       syntax of [] expressions, see below.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">/</td>
- *       <td width="94%">Specifies where the break position should go if text matches this
- *       expression.&nbsp; (e.g., &quot;[a-z]&#42;/[:Zs:]*[1-0]&quot; will match if the iterator sees a run
- *       of letters, followed by a run of whitespace, followed by a digit, but the break position
- *       will actually go before the whitespace).&nbsp; Expressions that don't contain / put the
- *       break position at the end of the matching text.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">\</td>
- *       <td width="94%">Escape character.&nbsp; The \ itself is ignored, but causes the next
- *       character to be treated as literal character.&nbsp; This has no effect for many
- *       characters, but for the characters listed above, this deprives them of their special
- *       meaning.&nbsp; (There are no special escape sequences for Unicode characters, or tabs and
- *       newlines; these are all handled by a higher-level protocol.&nbsp; In a Java string,
- *       &quot;\n&quot; will be converted to a literal newline character by the time the
- *       regular-expression parser sees it.&nbsp; Of course, this means that \ sequences that are
- *       visible to the regexp parser must be written as \\ when inside a Java string.)&nbsp; All
- *       characters in the ASCII range except for letters, digits, and control characters are
- *       reserved characters to the parser and must be preceded by \ even if they currently don't
- *       mean anything.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">!</td>
- *       <td width="94%">If ! appears at the beginning of a regular expression, it tells the regexp
- *       parser that this expression specifies the backwards-iteration behavior of the iterator,
- *       and not its normal iteration behavior.&nbsp; This is generally only used in situations
- *       where the automatically-generated backwards-iteration brhavior doesn't produce
- *       satisfactory results and must be supplemented with extra client-specified rules.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%"><em>(all others)</em></td>
- *       <td width="94%">All other characters are treated as literal characters, which must match
- *       the corresponding character(s) in the text exactly.</td>
- *     </tr>
- *   </table>
- * </blockquote>
- *
- * <p>Within a [] expression, a number of other special characters can be used to specify
- * groups of characters:</p>
- *
- * <blockquote>
- *   <table border="1" width="100%">
- *     <tr>
- *       <td width="6%">-</td>
- *       <td width="94%">Specifies a range of matching characters.&nbsp; For example
- *       &quot;[a-p]&quot; matches all lowercase Latin letters from a to p (inclusive).&nbsp; The -
- *       sign specifies ranges of continuous Unicode numeric values, not ranges of characters in a
- *       language's alphabetical order: &quot;[a-z]&quot; doesn't include capital letters, nor does
- *       it include accented letters such as a-umlaut.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">::</td>
- *       <td width="94%">A pair of colons containing a one- or two-letter code matches all
- *       characters in the corresponding Unicode category.&nbsp; The two-letter codes are the same
- *       as the two-letter codes in the Unicode database (for example, &quot;[:Sc::Sm:]&quot;
- *       matches all currency symbols and all math symbols).&nbsp; Specifying a one-letter code is
- *       the same as specifying all two-letter codes that begin with that letter (for example,
- *       &quot;[:L:]&quot; matches all letters, and is equivalent to
- *       &quot;[:Lu::Ll::Lo::Lm::Lt:]&quot;).&nbsp; Anything other than a valid two-letter Unicode
- *       category code or a single letter that begins a Unicode category code is illegal within
- *       colons.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">[]</td>
- *       <td width="94%">[] expressions can nest.&nbsp; This has no effect, except when used in
- *       conjunction with the ^ token.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%">^</td>
- *       <td width="94%">Excludes the character (or the characters in the [] expression) following
- *       it from the group of characters.&nbsp; For example, &quot;[a-z^p]&quot; matches all Latin
- *       lowercase letters except p.&nbsp; &quot;[:L:^[&#92;u4e00-&#92;u9fff]]&quot; matches all letters
- *       except the Han ideographs.</td>
- *     </tr>
- *     <tr>
- *       <td width="6%"><em>(all others)</em></td>
- *       <td width="94%">All other characters are treated as literal characters.&nbsp; (For
- *       example, &quot;[aeiou]&quot; specifies just the letters a, e, i, o, and u.)</td>
- *     </tr>
- *   </table>
- * </blockquote>
- *
- * <p>For a more complete explanation, see <a
- * href="http://www.ibm.com/java/education/boundaries/boundaries.html">http://www.ibm.com/java/education/boundaries/boundaries.html</a>.
- * &nbsp; For examples, see the resource data (which is annotated).</p>
- *
- * @author Richard Gillam
- */
-class RuleBasedBreakIterator extends BreakIterator {
-
-    /**
-     * A token used as a character-category value to identify ignore characters
-     */
-    protected static final byte IGNORE = -1;
-
-    /**
-     * The state number of the starting state
-     */
-    private static final short START_STATE = 1;
-
-    /**
-     * The state-transition value indicating "stop"
-     */
-    private static final short STOP_STATE = 0;
-
-    /**
-     * Magic number for the BreakIterator data file format.
-     */
-    static final byte[] LABEL = {
-        (byte)'B', (byte)'I', (byte)'d', (byte)'a', (byte)'t', (byte)'a',
-        (byte)'\0'
-    };
-    static final int    LABEL_LENGTH = LABEL.length;
-
-    /**
-     * Version number of the dictionary that was read in.
-     */
-    static final byte supportedVersion = 1;
-
-    /**
-     * Header size in byte count
-     */
-    private static final int HEADER_LENGTH = 36;
-
-    /**
-     * An array length of indices for BMP characters
-     */
-    private static final int BMP_INDICES_LENGTH = 512;
-
-    /**
-     * Tables that indexes from character values to character category numbers
-     */
-    private CompactByteArray charCategoryTable = null;
-    private SupplementaryCharacterData supplementaryCharCategoryTable = null;
-
-    /**
-     * The table of state transitions used for forward iteration
-     */
-    private short[] stateTable = null;
-
-    /**
-     * The table of state transitions used to sync up the iterator with the
-     * text in backwards and random-access iteration
-     */
-    private short[] backwardsStateTable = null;
-
-    /**
-     * A list of flags indicating which states in the state table are accepting
-     * ("end") states
-     */
-    private boolean[] endStates = null;
-
-    /**
-     * A list of flags indicating which states in the state table are
-     * lookahead states (states which turn lookahead on and off)
-     */
-    private boolean[] lookaheadStates = null;
-
-    /**
-     * A table for additional data. May be used by a subclass of
-     * RuleBasedBreakIterator.
-     */
-    private byte[] additionalData = null;
-
-    /**
-     * The number of character categories (and, thus, the number of columns in
-     * the state tables)
-     */
-    private int numCategories;
-
-    /**
-     * The character iterator through which this BreakIterator accesses the text
-     */
-    private CharacterIterator text = null;
-
-    /**
-     * A CRC32 value of all data in datafile
-     */
-    private long checksum;
-
-    //=======================================================================
-    // constructors
-    //=======================================================================
-
-    /**
-     * Constructs a RuleBasedBreakIterator according to the module and the datafile
-     * provided.
-     */
-    RuleBasedBreakIterator(Module module, String datafile)
-        throws IOException, MissingResourceException {
-        readTables(module, datafile);
-    }
-
-    /**
-     * Read datafile. The datafile's format is as follows:
-     * <pre>
-     *   BreakIteratorData {
-     *       u1           magic[7];
-     *       u1           version;
-     *       u4           totalDataSize;
-     *       header_info  header;
-     *       body         value;
-     *   }
-     * </pre>
-     * <code>totalDataSize</code> is the summation of the size of
-     * <code>header_info</code> and <code>body</code> in byte count.
-     * <p>
-     * In <code>header</code>, each field except for checksum implies the
-     * length of each field. Since <code>BMPdataLength</code> is a fixed-length
-     *  data(512 entries), its length isn't included in <code>header</code>.
-     * <code>checksum</code> is a CRC32 value of all in <code>body</code>.
-     * <pre>
-     *   header_info {
-     *       u4           stateTableLength;
-     *       u4           backwardsStateTableLength;
-     *       u4           endStatesLength;
-     *       u4           lookaheadStatesLength;
-     *       u4           BMPdataLength;
-     *       u4           nonBMPdataLength;
-     *       u4           additionalDataLength;
-     *       u8           checksum;
-     *   }
-     * </pre>
-     * <p>
-     *
-     * Finally, <code>BMPindices</code> and <code>BMPdata</code> are set to
-     * <code>charCategoryTable</code>. <code>nonBMPdata</code> is set to
-     * <code>supplementaryCharCategoryTable</code>.
-     * <pre>
-     *   body {
-     *       u2           stateTable[stateTableLength];
-     *       u2           backwardsStateTable[backwardsStateTableLength];
-     *       u1           endStates[endStatesLength];
-     *       u1           lookaheadStates[lookaheadStatesLength];
-     *       u2           BMPindices[512];
-     *       u1           BMPdata[BMPdataLength];
-     *       u4           nonBMPdata[numNonBMPdataLength];
-     *       u1           additionalData[additionalDataLength];
-     *   }
-     * </pre>
-     */
-    protected final void readTables(Module module, String datafile)
-        throws IOException, MissingResourceException {
-
-        byte[] buffer = readFile(module, datafile);
-
-        /* Read header_info. */
-        int stateTableLength = getInt(buffer, 0);
-        int backwardsStateTableLength = getInt(buffer, 4);
-        int endStatesLength = getInt(buffer, 8);
-        int lookaheadStatesLength = getInt(buffer, 12);
-        int BMPdataLength = getInt(buffer, 16);
-        int nonBMPdataLength = getInt(buffer, 20);
-        int additionalDataLength = getInt(buffer, 24);
-        checksum = getLong(buffer, 28);
-
-        /* Read stateTable[numCategories * numRows] */
-        stateTable = new short[stateTableLength];
-        int offset = HEADER_LENGTH;
-        for (int i = 0; i < stateTableLength; i++, offset+=2) {
-           stateTable[i] = getShort(buffer, offset);
-        }
-
-        /* Read backwardsStateTable[numCategories * numRows] */
-        backwardsStateTable = new short[backwardsStateTableLength];
-        for (int i = 0; i < backwardsStateTableLength; i++, offset+=2) {
-           backwardsStateTable[i] = getShort(buffer, offset);
-        }
-
-        /* Read endStates[numRows] */
-        endStates = new boolean[endStatesLength];
-        for (int i = 0; i < endStatesLength; i++, offset++) {
-           endStates[i] = buffer[offset] == 1;
-        }
-
-        /* Read lookaheadStates[numRows] */
-        lookaheadStates = new boolean[lookaheadStatesLength];
-        for (int i = 0; i < lookaheadStatesLength; i++, offset++) {
-           lookaheadStates[i] = buffer[offset] == 1;
-        }
-
-        /* Read a category table and indices for BMP characters. */
-        short[] temp1 = new short[BMP_INDICES_LENGTH];  // BMPindices
-        for (int i = 0; i < BMP_INDICES_LENGTH; i++, offset+=2) {
-            temp1[i] = getShort(buffer, offset);
-        }
-        byte[] temp2 = new byte[BMPdataLength];  // BMPdata
-        System.arraycopy(buffer, offset, temp2, 0, BMPdataLength);
-        offset += BMPdataLength;
-        charCategoryTable = new CompactByteArray(temp1, temp2);
-
-        /* Read a category table for non-BMP characters. */
-        int[] temp3 = new int[nonBMPdataLength];
-        for (int i = 0; i < nonBMPdataLength; i++, offset+=4) {
-            temp3[i] = getInt(buffer, offset);
-        }
-        supplementaryCharCategoryTable = new SupplementaryCharacterData(temp3);
-
-        /* Read additional data */
-        if (additionalDataLength > 0) {
-            additionalData = new byte[additionalDataLength];
-            System.arraycopy(buffer, offset, additionalData, 0, additionalDataLength);
-        }
-
-        /* Set numCategories */
-        numCategories = stateTable.length / endStates.length;
-    }
-
-    protected byte[] readFile(final Module module, final String datafile)
-        throws IOException, MissingResourceException {
-
-        BufferedInputStream is;
-        try {
-            PrivilegedExceptionAction<BufferedInputStream> pa = () -> {
-                String pathName = "jdk.localedata".equals(module.getName()) ?
-                     "sun/text/resources/ext/" :
-                     "sun/text/resources/";
-                InputStream in = module.getResourceAsStream(pathName + datafile);
-                if (in == null) {
-                    // Try to load the file with "java.base" module instance. Assumption
-                    // here is that the fall back data files to be read should reside in
-                    // java.base.
-                    in = RuleBasedBreakIterator.class.getModule().getResourceAsStream("sun/text/resources/" + datafile);
-                }
-
-                return new BufferedInputStream(in);
-            };
-            is = AccessController.doPrivileged(pa);
-        } catch (PrivilegedActionException e) {
-            throw new InternalError(e.toString(), e);
-        }
-
-        int offset = 0;
-
-        /* First, read magic, version, and header_info. */
-        int len = LABEL_LENGTH + 5;
-        byte[] buf = new byte[len];
-        if (is.read(buf) != len) {
-            throw new MissingResourceException("Wrong header length",
-                                               datafile, "");
-        }
-
-        /* Validate the magic number. */
-        for (int i = 0; i < LABEL_LENGTH; i++, offset++) {
-            if (buf[offset] != LABEL[offset]) {
-                throw new MissingResourceException("Wrong magic number",
-                                                   datafile, "");
-            }
-        }
-
-        /* Validate the version number. */
-        if (buf[offset] != supportedVersion) {
-            throw new MissingResourceException("Unsupported version(" + buf[offset] + ")",
-                                               datafile, "");
-        }
-
-        /* Read data: totalDataSize + 8(for checksum) */
-        len = getInt(buf, ++offset);
-        buf = new byte[len];
-        if (is.read(buf) != len) {
-            throw new MissingResourceException("Wrong data length",
-                                               datafile, "");
-        }
-
-        is.close();
-
-        return buf;
-    }
-
-    byte[] getAdditionalData() {
-        return additionalData;
-    }
-
-    void setAdditionalData(byte[] b) {
-        additionalData = b;
-    }
-
-    //=======================================================================
-    // boilerplate
-    //=======================================================================
-    /**
-     * Clones this iterator.
-     * @return A newly-constructed RuleBasedBreakIterator with the same
-     * behavior as this one.
-     */
-    @Override
-    public Object clone() {
-        RuleBasedBreakIterator result = (RuleBasedBreakIterator) super.clone();
-        if (text != null) {
-            result.text = (CharacterIterator) text.clone();
-        }
-        return result;
-    }
-
-    /**
-     * Returns true if both BreakIterators are of the same class, have the same
-     * rules, and iterate over the same text.
-     */
-    @Override
-    public boolean equals(Object that) {
-        try {
-            if (that == null) {
-                return false;
-            }
-
-            RuleBasedBreakIterator other = (RuleBasedBreakIterator) that;
-            if (checksum != other.checksum) {
-                return false;
-            }
-            if (text == null) {
-                return other.text == null;
-            } else {
-                return text.equals(other.text);
-            }
-        }
-        catch(ClassCastException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns text
-     */
-    @Override
-    public String toString() {
-        return "[checksum=0x" + Long.toHexString(checksum) + ']';
-    }
-
-    /**
-     * Compute a hashcode for this BreakIterator
-     * @return A hash code
-     */
-    @Override
-    public int hashCode() {
-        return (int)checksum;
-    }
-
-    //=======================================================================
-    // BreakIterator overrides
-    //=======================================================================
-
-    /**
-     * Sets the current iteration position to the beginning of the text.
-     * (i.e., the CharacterIterator's starting offset).
-     * @return The offset of the beginning of the text.
-     */
-    @Override
-    public int first() {
-        CharacterIterator t = getText();
-
-        t.first();
-        return t.getIndex();
-    }
-
-    /**
-     * Sets the current iteration position to the end of the text.
-     * (i.e., the CharacterIterator's ending offset).
-     * @return The text's past-the-end offset.
-     */
-    @Override
-    public int last() {
-        CharacterIterator t = getText();
-
-        // I'm not sure why, but t.last() returns the offset of the last character,
-        // rather than the past-the-end offset
-        t.setIndex(t.getEndIndex());
-        return t.getIndex();
-    }
-
-    /**
-     * Advances the iterator either forward or backward the specified number of steps.
-     * Negative values move backward, and positive values move forward.  This is
-     * equivalent to repeatedly calling next() or previous().
-     * @param n The number of steps to move.  The sign indicates the direction
-     * (negative is backwards, and positive is forwards).
-     * @return The character offset of the boundary position n boundaries away from
-     * the current one.
-     */
-    @Override
-    public int next(int n) {
-        int result = current();
-        while (n > 0) {
-            result = handleNext();
-            --n;
-        }
-        while (n < 0) {
-            result = previous();
-            ++n;
-        }
-        return result;
-    }
-
-    /**
-     * Advances the iterator to the next boundary position.
-     * @return The position of the first boundary after this one.
-     */
-    @Override
-    public int next() {
-        return handleNext();
-    }
-
-    private int cachedLastKnownBreak = BreakIterator.DONE;
-
-    /**
-     * Advances the iterator backwards, to the last boundary preceding this one.
-     * @return The position of the last boundary position preceding this one.
-     */
-    @Override
-    public int previous() {
-        // if we're already sitting at the beginning of the text, return DONE
-        CharacterIterator text = getText();
-        if (current() == text.getBeginIndex()) {
-            return BreakIterator.DONE;
-        }
-
-        // set things up.  handlePrevious() will back us up to some valid
-        // break position before the current position (we back our internal
-        // iterator up one step to prevent handlePrevious() from returning
-        // the current position), but not necessarily the last one before
-        // where we started
-        int start = current();
-        int lastResult = cachedLastKnownBreak;
-        if (lastResult >= start || lastResult <= BreakIterator.DONE) {
-            getPrevious();
-            lastResult = handlePrevious();
-        } else {
-            //it might be better to check if handlePrevious() give us closer
-            //safe value but handlePrevious() is slow too
-            //So, this has to be done carefully
-            text.setIndex(lastResult);
-        }
-        int result = lastResult;
-
-        // iterate forward from the known break position until we pass our
-        // starting point.  The last break position before the starting
-        // point is our return value
-        while (result != BreakIterator.DONE && result < start) {
-            lastResult = result;
-            result = handleNext();
-        }
-
-        // set the current iteration position to be the last break position
-        // before where we started, and then return that value
-        text.setIndex(lastResult);
-        cachedLastKnownBreak = lastResult;
-        return lastResult;
-    }
-
-    /**
-     * Returns previous character
-     */
-    private int getPrevious() {
-        char c2 = text.previous();
-        if (Character.isLowSurrogate(c2) &&
-            text.getIndex() > text.getBeginIndex()) {
-            char c1 = text.previous();
-            if (Character.isHighSurrogate(c1)) {
-                return Character.toCodePoint(c1, c2);
-            } else {
-                text.next();
-            }
-        }
-        return (int)c2;
-    }
-
-    /**
-     * Returns current character
-     */
-    int getCurrent() {
-        char c1 = text.current();
-        if (Character.isHighSurrogate(c1) &&
-            text.getIndex() < text.getEndIndex()) {
-            char c2 = text.next();
-            text.previous();
-            if (Character.isLowSurrogate(c2)) {
-                return Character.toCodePoint(c1, c2);
-            }
-        }
-        return (int)c1;
-    }
-
-    /**
-     * Returns the count of next character.
-     */
-    private int getCurrentCodePointCount() {
-        char c1 = text.current();
-        if (Character.isHighSurrogate(c1) &&
-            text.getIndex() < text.getEndIndex()) {
-            char c2 = text.next();
-            text.previous();
-            if (Character.isLowSurrogate(c2)) {
-                return 2;
-            }
-        }
-        return 1;
-    }
-
-    /**
-     * Returns next character
-     */
-    int getNext() {
-        int index = text.getIndex();
-        int endIndex = text.getEndIndex();
-        if (index == endIndex ||
-            (index += getCurrentCodePointCount()) >= endIndex) {
-            return CharacterIterator.DONE;
-        }
-        text.setIndex(index);
-        return getCurrent();
-    }
-
-    /**
-     * Returns the position of next character.
-     */
-    private int getNextIndex() {
-        int index = text.getIndex() + getCurrentCodePointCount();
-        int endIndex = text.getEndIndex();
-        if (index > endIndex) {
-            return endIndex;
-        } else {
-            return index;
-        }
-    }
-
-    /**
-     * Throw IllegalArgumentException unless begin <= offset < end.
-     */
-    protected static final void checkOffset(int offset, CharacterIterator text) {
-        if (offset < text.getBeginIndex() || offset > text.getEndIndex()) {
-            throw new IllegalArgumentException("offset out of bounds");
-        }
-    }
-
-    /**
-     * Sets the iterator to refer to the first boundary position following
-     * the specified position.
-     * @offset The position from which to begin searching for a break position.
-     * @return The position of the first break after the current position.
-     */
-    @Override
-    public int following(int offset) {
-
-        CharacterIterator text = getText();
-        checkOffset(offset, text);
-
-        // Set our internal iteration position (temporarily)
-        // to the position passed in.  If this is the _beginning_ position,
-        // then we can just use next() to get our return value
-        text.setIndex(offset);
-        if (offset == text.getBeginIndex()) {
-            cachedLastKnownBreak = handleNext();
-            return cachedLastKnownBreak;
-        }
-
-        // otherwise, we have to sync up first.  Use handlePrevious() to back
-        // us up to a known break position before the specified position (if
-        // we can determine that the specified position is a break position,
-        // we don't back up at all).  This may or may not be the last break
-        // position at or before our starting position.  Advance forward
-        // from here until we've passed the starting position.  The position
-        // we stop on will be the first break position after the specified one.
-        int result = cachedLastKnownBreak;
-        if (result >= offset || result <= BreakIterator.DONE) {
-            result = handlePrevious();
-        } else {
-            //it might be better to check if handlePrevious() give us closer
-            //safe value but handlePrevious() is slow too
-            //So, this has to be done carefully
-            text.setIndex(result);
-        }
-        while (result != BreakIterator.DONE && result <= offset) {
-            result = handleNext();
-        }
-        cachedLastKnownBreak = result;
-        return result;
-    }
-
-    /**
-     * Sets the iterator to refer to the last boundary position before the
-     * specified position.
-     * @offset The position to begin searching for a break from.
-     * @return The position of the last boundary before the starting position.
-     */
-    @Override
-    public int preceding(int offset) {
-        // if we start by updating the current iteration position to the
-        // position specified by the caller, we can just use previous()
-        // to carry out this operation
-        CharacterIterator text = getText();
-        checkOffset(offset, text);
-        text.setIndex(offset);
-        return previous();
-    }
-
-    /**
-     * Returns true if the specified position is a boundary position.  As a side
-     * effect, leaves the iterator pointing to the first boundary position at
-     * or after "offset".
-     * @param offset the offset to check.
-     * @return True if "offset" is a boundary position.
-     */
-    @Override
-    public boolean isBoundary(int offset) {
-        CharacterIterator text = getText();
-        checkOffset(offset, text);
-        if (offset == text.getBeginIndex()) {
-            return true;
-        }
-
-        // to check whether this is a boundary, we can use following() on the
-        // position before the specified one and return true if the position we
-        // get back is the one the user specified
-        else {
-            return following(offset - 1) == offset;
-        }
-    }
-
-    /**
-     * Returns the current iteration position.
-     * @return The current iteration position.
-     */
-    @Override
-    public int current() {
-        return getText().getIndex();
-    }
-
-    /**
-     * Return a CharacterIterator over the text being analyzed.  This version
-     * of this method returns the actual CharacterIterator we're using internally.
-     * Changing the state of this iterator can have undefined consequences.  If
-     * you need to change it, clone it first.
-     * @return An iterator over the text being analyzed.
-     */
-    @Override
-    public CharacterIterator getText() {
-        // The iterator is initialized pointing to no text at all, so if this
-        // function is called while we're in that state, we have to fudge an
-        // iterator to return.
-        if (text == null) {
-            text = new StringCharacterIterator("");
-        }
-        return text;
-    }
-
-    /**
-     * Set the iterator to analyze a new piece of text.  This function resets
-     * the current iteration position to the beginning of the text.
-     * @param newText An iterator over the text to analyze.
-     */
-    @Override
-    public void setText(CharacterIterator newText) {
-        // Test iterator to see if we need to wrap it in a SafeCharIterator.
-        // The correct behavior for CharacterIterators is to allow the
-        // position to be set to the endpoint of the iterator.  Many
-        // CharacterIterators do not uphold this, so this is a workaround
-        // to permit them to use this class.
-        int end = newText.getEndIndex();
-        boolean goodIterator;
-        try {
-            newText.setIndex(end);  // some buggy iterators throw an exception here
-            goodIterator = newText.getIndex() == end;
-        }
-        catch(IllegalArgumentException e) {
-            goodIterator = false;
-        }
-
-        if (goodIterator) {
-            text = newText;
-        }
-        else {
-            text = new SafeCharIterator(newText);
-        }
-        text.first();
-
-        cachedLastKnownBreak = BreakIterator.DONE;
-    }
-
-
-    //=======================================================================
-    // implementation
-    //=======================================================================
-
-    /**
-     * This method is the actual implementation of the next() method.  All iteration
-     * vectors through here.  This method initializes the state machine to state 1
-     * and advances through the text character by character until we reach the end
-     * of the text or the state machine transitions to state 0.  We update our return
-     * value every time the state machine passes through a possible end state.
-     */
-    protected int handleNext() {
-        // if we're already at the end of the text, return DONE.
-        CharacterIterator text = getText();
-        if (text.getIndex() == text.getEndIndex()) {
-            return BreakIterator.DONE;
-        }
-
-        // no matter what, we always advance at least one character forward
-        int result = getNextIndex();
-        int lookaheadResult = 0;
-
-        // begin in state 1
-        int state = START_STATE;
-        int category;
-        int c = getCurrent();
-
-        // loop until we reach the end of the text or transition to state 0
-        while (c != CharacterIterator.DONE && state != STOP_STATE) {
-
-            // look up the current character's character category (which tells us
-            // which column in the state table to look at)
-            category = lookupCategory(c);
-
-            // if the character isn't an ignore character, look up a state
-            // transition in the state table
-            if (category != IGNORE) {
-                state = lookupState(state, category);
-            }
-
-            // if the state we've just transitioned to is a lookahead state,
-            // (but not also an end state), save its position.  If it's
-            // both a lookahead state and an end state, update the break position
-            // to the last saved lookup-state position
-            if (lookaheadStates[state]) {
-                if (endStates[state]) {
-                    result = lookaheadResult;
-                }
-                else {
-                    lookaheadResult = getNextIndex();
-                }
-            }
-
-            // otherwise, if the state we've just transitioned to is an accepting
-            // state, update the break position to be the current iteration position
-            else {
-                if (endStates[state]) {
-                    result = getNextIndex();
-                }
-            }
-
-            c = getNext();
-        }
-
-        // if we've run off the end of the text, and the very last character took us into
-        // a lookahead state, advance the break position to the lookahead position
-        // (the theory here is that if there are no characters at all after the lookahead
-        // position, that always matches the lookahead criteria)
-        if (c == CharacterIterator.DONE && lookaheadResult == text.getEndIndex()) {
-            result = lookaheadResult;
-        }
-
-        text.setIndex(result);
-        return result;
-    }
-
-    /**
-     * This method backs the iterator back up to a "safe position" in the text.
-     * This is a position that we know, without any context, must be a break position.
-     * The various calling methods then iterate forward from this safe position to
-     * the appropriate position to return.  (For more information, see the description
-     * of buildBackwardsStateTable() in RuleBasedBreakIterator.Builder.)
-     */
-    protected int handlePrevious() {
-        CharacterIterator text = getText();
-        int state = START_STATE;
-        int category = 0;
-        int lastCategory = 0;
-        int c = getCurrent();
-
-        // loop until we reach the beginning of the text or transition to state 0
-        while (c != CharacterIterator.DONE && state != STOP_STATE) {
-
-            // save the last character's category and look up the current
-            // character's category
-            lastCategory = category;
-            category = lookupCategory(c);
-
-            // if the current character isn't an ignore character, look up a
-            // state transition in the backwards state table
-            if (category != IGNORE) {
-                state = lookupBackwardState(state, category);
-            }
-
-            // then advance one character backwards
-            c = getPrevious();
-        }
-
-        // if we didn't march off the beginning of the text, we're either one or two
-        // positions away from the real break position.  (One because of the call to
-        // previous() at the end of the loop above, and another because the character
-        // that takes us into the stop state will always be the character BEFORE
-        // the break position.)
-        if (c != CharacterIterator.DONE) {
-            if (lastCategory != IGNORE) {
-                getNext();
-                getNext();
-            }
-            else {
-                getNext();
-            }
-        }
-        return text.getIndex();
-    }
-
-    /**
-     * Looks up a character's category (i.e., its category for breaking purposes,
-     * not its Unicode category)
-     */
-    protected int lookupCategory(int c) {
-        if (c < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
-            return charCategoryTable.elementAt((char)c);
-        } else {
-            return supplementaryCharCategoryTable.getValue(c);
-        }
-    }
-
-    /**
-     * Given a current state and a character category, looks up the
-     * next state to transition to in the state table.
-     */
-    protected int lookupState(int state, int category) {
-        return stateTable[state * numCategories + category];
-    }
-
-    /**
-     * Given a current state and a character category, looks up the
-     * next state to transition to in the backwards state table.
-     */
-    protected int lookupBackwardState(int state, int category) {
-        return backwardsStateTable[state * numCategories + category];
-    }
-
-    static long getLong(byte[] buf, int offset) {
-        long num = buf[offset]&0xFF;
-        for (int i = 1; i < 8; i++) {
-            num = num<<8 | (buf[offset+i]&0xFF);
-        }
-        return num;
-    }
-
-    static int getInt(byte[] buf, int offset) {
-        int num = buf[offset]&0xFF;
-        for (int i = 1; i < 4; i++) {
-            num = num<<8 | (buf[offset+i]&0xFF);
-        }
-        return num;
-    }
-
-    static short getShort(byte[] buf, int offset) {
-        short num = (short)(buf[offset]&0xFF);
-        num = (short)(num<<8 | (buf[offset+1]&0xFF));
-        return num;
-    }
-
-    /*
-     * This class exists to work around a bug in incorrect implementations
-     * of CharacterIterator, which incorrectly handle setIndex(endIndex).
-     * This iterator relies only on base.setIndex(n) where n is less than
-     * endIndex.
-     *
-     * One caveat:  if the base iterator's begin and end indices change
-     * the change will not be reflected by this wrapper.  Does that matter?
-     */
-    // TODO: Review this class to see if it's still required.
-    private static final class SafeCharIterator implements CharacterIterator,
-                                                           Cloneable {
-
-        private CharacterIterator base;
-        private int rangeStart;
-        private int rangeLimit;
-        private int currentIndex;
-
-        SafeCharIterator(CharacterIterator base) {
-            this.base = base;
-            this.rangeStart = base.getBeginIndex();
-            this.rangeLimit = base.getEndIndex();
-            this.currentIndex = base.getIndex();
-        }
-
-        @Override
-        public char first() {
-            return setIndex(rangeStart);
-        }
-
-        @Override
-        public char last() {
-            return setIndex(rangeLimit - 1);
-        }
-
-        @Override
-        public char current() {
-            if (currentIndex < rangeStart || currentIndex >= rangeLimit) {
-                return DONE;
-            }
-            else {
-                return base.setIndex(currentIndex);
-            }
-        }
-
-        @Override
-        public char next() {
-
-            currentIndex++;
-            if (currentIndex >= rangeLimit) {
-                currentIndex = rangeLimit;
-                return DONE;
-            }
-            else {
-                return base.setIndex(currentIndex);
-            }
-        }
-
-        @Override
-        public char previous() {
-
-            currentIndex--;
-            if (currentIndex < rangeStart) {
-                currentIndex = rangeStart;
-                return DONE;
-            }
-            else {
-                return base.setIndex(currentIndex);
-            }
-        }
-
-        @Override
-        public char setIndex(int i) {
-
-            if (i < rangeStart || i > rangeLimit) {
-                throw new IllegalArgumentException("Invalid position");
-            }
-            currentIndex = i;
-            return current();
-        }
-
-        @Override
-        public int getBeginIndex() {
-            return rangeStart;
-        }
-
-        @Override
-        public int getEndIndex() {
-            return rangeLimit;
-        }
-
-        @Override
-        public int getIndex() {
-            return currentIndex;
-        }
-
-        @Override
-        public Object clone() {
-
-            SafeCharIterator copy = null;
-            try {
-                copy = (SafeCharIterator) super.clone();
-            }
-            catch(CloneNotSupportedException e) {
-                throw new Error("Clone not supported: " + e);
-            }
-
-            CharacterIterator copyOfBase = (CharacterIterator) base.clone();
-            copy.base = copyOfBase;
-            return copy;
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.resources;
+
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+/**
+ * BreakIteratorResourceBundle is an abstract class for loading BreakIterator
+ * data (rules or dictionary) from each module. An implementation class must
+ * implement getBreakIteratorInfo() that returns an instance of the
+ * corresponding BreakIteratorInfo (basename).  The data name is taken from the
+ * BreakIteratorInfo instance.
+ *
+ * <p>For example, if the given key is "WordDictionary" and Locale is "th", the
+ * data name is taken from a BreakIteratorInfo_th and the key's value is
+ * "thai_dict".  Its data thai_dict is loaded from the Module of the
+ * implementation class of this class.
+ */
+
+public abstract class BreakIteratorResourceBundle extends ResourceBundle {
+    // If any keys that are not for data names are added to BreakIteratorInfo*,
+    // those keys must be added to NON_DATA_KEYS.
+    private static final Set<String> NON_DATA_KEYS = Set.of("BreakIteratorClasses");
+
+    private volatile Set<String> keys;
+
+    /**
+     * Returns an instance of the corresponding {@code BreakIteratorInfo} (basename).
+     * The instance shouldn't have its parent.
+     */
+    protected abstract ResourceBundle getBreakIteratorInfo();
+
+    @Override
+    protected Object handleGetObject(String key) {
+        if (NON_DATA_KEYS.contains(key)) {
+            return null;
+        }
+        ResourceBundle info = getBreakIteratorInfo();
+        if (!info.containsKey(key)) {
+            return null;
+        }
+        String path = getClass().getPackage().getName().replace('.', '/')
+                      + '/' + info.getString(key);
+        byte[] data;
+        try (InputStream is = getResourceAsStream(path)) {
+            data = is.readAllBytes();
+        } catch (Exception e) {
+            throw new InternalError("Can't load " + path, e);
+        }
+        return data;
+    }
+
+    private InputStream getResourceAsStream(String path) throws Exception {
+        PrivilegedExceptionAction<InputStream> pa;
+        pa = () -> getClass().getModule().getResourceAsStream(path);
+        InputStream is;
+        try {
+            is = AccessController.doPrivileged(pa);
+        } catch (PrivilegedActionException e) {
+            throw e.getException();
+        }
+        return is;
+    }
+
+    @Override
+    public Enumeration<String> getKeys() {
+        return Collections.enumeration(keySet());
+    }
+
+    @Override
+    protected Set<String> handleKeySet() {
+        if (keys == null) {
+            ResourceBundle info = getBreakIteratorInfo();
+            Set<String> k = info.keySet();
+            k.removeAll(NON_DATA_KEYS);
+            synchronized (this) {
+                if (keys == null) {
+                    keys = k;
+                }
+            }
+        }
+        return keys;
+    }
+}
--- a/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java	Thu Oct 27 21:22:57 2016 +0000
@@ -123,6 +123,14 @@
     }
 
     /**
+     * Gets a break iterator resources resource bundle, using
+     * privileges to allow accessing a sun.* package.
+     */
+    public ResourceBundle getBreakIteratorResources(Locale locale) {
+        return getBundle(type.getTextResourcesPackage() + ".BreakIteratorResources", locale);
+    }
+
+    /**
      * Gets a collation data resource bundle, using privileges
      * to allow accessing a sun.* package.
      */
--- a/jdk/src/java.base/share/lib/security/default.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/lib/security/default.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -32,8 +32,22 @@
     permission javax.smartcardio.CardPermission "*", "*";
     permission java.lang.RuntimePermission "loadLibrary.j2pcsc";
     permission java.lang.RuntimePermission
-                   "accessClassInPackage.sun.security.*";
-    permission java.util.PropertyPermission "*", "read";
+                   "accessClassInPackage.sun.security.jca";
+    permission java.lang.RuntimePermission
+                   "accessClassInPackage.sun.security.util";
+    permission java.util.PropertyPermission
+                   "javax.smartcardio.TerminalFactory.DefaultType", "read";
+    permission java.util.PropertyPermission "os.name", "read";
+    permission java.util.PropertyPermission "os.arch", "read";
+    permission java.util.PropertyPermission "sun.arch.data.model", "read";
+    permission java.util.PropertyPermission
+                   "sun.security.smartcardio.library", "read";
+    permission java.util.PropertyPermission
+                   "sun.security.smartcardio.t0GetResponse", "read";
+    permission java.util.PropertyPermission
+                   "sun.security.smartcardio.t1GetResponse", "read";
+    permission java.util.PropertyPermission
+                   "sun.security.smartcardio.t1StripLe", "read";
     // needed for looking up native PC/SC library
     permission java.io.FilePermission "<<ALL FILES>>","read";
     permission java.security.SecurityPermission "putProviderProperty.SunPCSC";
--- a/jdk/src/java.base/share/native/launcher/defines.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/native/launcher/defines.h	Thu Oct 27 21:22:57 2016 +0000
@@ -51,16 +51,6 @@
 static char* const_progname = NULL;
 #endif
 static const char* const_jargs[] = JAVA_ARGS;
-/*
- * ApplicationHome is prepended to each of these entries; the resulting
- * strings are concatenated (separated by PATH_SEPARATOR) and used as the
- * value of -cp option to the launcher.
- */
-#ifndef APP_CLASSPATH
-static const char* const_appclasspath[] = { NULL };
-#else
-static const char* const_appclasspath[] = APP_CLASSPATH;
-#endif /* APP_CLASSPATH */
 #else  /* !JAVA_ARGS */
 #define HAS_JAVA_ARGS JNI_FALSE
 static const char* const_progname = "java";
--- a/jdk/src/java.base/share/native/launcher/main.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/native/launcher/main.c	Thu Oct 27 21:22:57 2016 +0000
@@ -83,7 +83,7 @@
 int WINAPI
 WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
 {
-    int margc, appclassc;
+    int margc;
     char** margv;
     const jboolean const_javaw = JNI_TRUE;
 
@@ -93,7 +93,7 @@
 int
 main(int argc, char **argv)
 {
-    int margc, appclassc;
+    int margc;
     char** margv;
     const jboolean const_javaw = JNI_FALSE;
 #endif /* JAVAW */
@@ -148,14 +148,9 @@
         margv = args->elements;
     }
 #endif /* WIN32 */
-    if (const_appclasspath[0] == NULL) {
-        appclassc = 0;
-    } else {
-        appclassc = sizeof(const_appclasspath) / sizeof(char *);
-    }
     return JLI_Launch(margc, margv,
                    sizeof(const_jargs) / sizeof(char *), const_jargs,
-                   appclassc, const_appclasspath,
+                   0, NULL,
                    VERSION_STRING,
                    DOT_VERSION,
                    (const_progname != NULL) ? const_progname : *margv,
--- a/jdk/src/java.base/share/native/libjli/java.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/native/libjli/java.c	Thu Oct 27 21:22:57 2016 +0000
@@ -1664,19 +1664,21 @@
     AddOption(apphome, NULL);
 
     /* How big is the application's classpath? */
-    size = 40;                                 /* 40: "-Djava.class.path=" */
-    for (i = 0; i < cpathc; i++) {
-        size += (int)JLI_StrLen(home) + (int)JLI_StrLen(cpathv[i]) + 1; /* 1: separator */
+    if (cpathc > 0) {
+        size = 40;                                 /* 40: "-Djava.class.path=" */
+        for (i = 0; i < cpathc; i++) {
+            size += (int)JLI_StrLen(home) + (int)JLI_StrLen(cpathv[i]) + 1; /* 1: separator */
+        }
+        appcp = (char *)JLI_MemAlloc(size + 1);
+        JLI_StrCpy(appcp, "-Djava.class.path=");
+        for (i = 0; i < cpathc; i++) {
+            JLI_StrCat(appcp, home);                        /* c:\program files\myapp */
+            JLI_StrCat(appcp, cpathv[i]);           /* \lib\myapp.jar         */
+            JLI_StrCat(appcp, separator);           /* ;                      */
+        }
+        appcp[JLI_StrLen(appcp)-1] = '\0';  /* remove trailing path separator */
+        AddOption(appcp, NULL);
     }
-    appcp = (char *)JLI_MemAlloc(size + 1);
-    JLI_StrCpy(appcp, "-Djava.class.path=");
-    for (i = 0; i < cpathc; i++) {
-        JLI_StrCat(appcp, home);                        /* c:\program files\myapp */
-        JLI_StrCat(appcp, cpathv[i]);           /* \lib\myapp.jar         */
-        JLI_StrCat(appcp, separator);           /* ;                      */
-    }
-    appcp[JLI_StrLen(appcp)-1] = '\0';  /* remove trailing path separator */
-    AddOption(appcp, NULL);
     return JNI_TRUE;
 }
 
--- a/jdk/src/java.base/share/native/libnet/net_util.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/native/libnet/net_util.c	Thu Oct 27 21:22:57 2016 +0000
@@ -23,20 +23,19 @@
  * questions.
  */
 
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
 #include "net_util.h"
 
-int IPv6_supported() ;
-int reuseport_supported() ;
+#include "java_net_InetAddress.h"
+
+int IPv6_supported();
+int reuseport_supported();
 
 static int IPv6_available;
 static int REUSEPORT_available;
 
 JNIEXPORT jint JNICALL ipv6_available()
 {
-    return IPv6_available ;
+    return IPv6_available;
 }
 
 JNIEXPORT jint JNICALL reuseport_available()
@@ -206,11 +205,7 @@
     jobject iaObj;
 #ifdef AF_INET6
     if (him->sa_family == AF_INET6) {
-#ifdef WIN32
-        struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
-#else
         struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
-#endif
         jbyte *caddr = (jbyte *)&(him6->sin6_addr);
         if (NET_IsIPv4Mapped(caddr)) {
             int address;
@@ -218,7 +213,7 @@
             CHECK_NULL_RETURN(iaObj, NULL);
             address = NET_IPv4MappedToIPv4(caddr);
             setInetAddress_addr(env, iaObj, address);
-            setInetAddress_family(env, iaObj, IPv4);
+            setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
         } else {
             jint scope;
             jboolean ret;
@@ -227,7 +222,7 @@
             ret = setInet6Address_ipaddress(env, iaObj, (char *)&(him6->sin6_addr));
             if (ret == JNI_FALSE)
                 return NULL;
-            setInetAddress_family(env, iaObj, IPv6);
+            setInetAddress_family(env, iaObj, java_net_InetAddress_IPv6);
             scope = getScopeID(him);
             setInet6Address_scopeid(env, iaObj, scope);
         }
@@ -238,7 +233,7 @@
             struct sockaddr_in *him4 = (struct sockaddr_in *)him;
             iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
             CHECK_NULL_RETURN(iaObj, NULL);
-            setInetAddress_family(env, iaObj, IPv4);
+            setInetAddress_family(env, iaObj, java_net_InetAddress_IPv4);
             setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
             *port = ntohs(him4->sin_port);
         }
@@ -251,13 +246,10 @@
     jint family = AF_INET;
 
 #ifdef AF_INET6
-    family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
+    family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
+        AF_INET : AF_INET6;
     if (him->sa_family == AF_INET6) {
-#ifdef WIN32
-        struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
-#else
         struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
-#endif
         jbyte *caddrNew = (jbyte *)&(him6->sin6_addr);
         if (NET_IsIPv4Mapped(caddrNew)) {
             int addrNew;
--- a/jdk/src/java.base/share/native/libnet/net_util.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/share/native/libnet/net_util.h	Thu Oct 27 21:22:57 2016 +0000
@@ -36,12 +36,6 @@
 
 #define MAX_PACKET_LEN 65536
 
-#define IPv4 1
-#define IPv6 2
-
-#define NET_ERROR(env, ex, msg) \
-{ if (!(*env)->ExceptionOccurred(env)) JNU_ThrowByName(env, ex, msg); }
-
 #define NET_WAIT_READ    0x01
 #define NET_WAIT_WRITE   0x02
 #define NET_WAIT_CONNECT 0x04
@@ -127,45 +121,43 @@
 JNIEXPORT void JNICALL Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls);
 
 JNIEXPORT void JNICALL NET_ThrowNew(JNIEnv *env, int errorNum, char *msg);
+
 int NET_GetError();
 
 void NET_ThrowCurrent(JNIEnv *env, char *msg);
 
 jfieldID NET_GetFileDescriptorID(JNIEnv *env);
 
-JNIEXPORT jint JNICALL ipv6_available() ;
+JNIEXPORT jint JNICALL ipv6_available();
 
-JNIEXPORT jint JNICALL reuseport_available() ;
+JNIEXPORT jint JNICALL reuseport_available();
 
 JNIEXPORT int JNICALL
-NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port, struct sockaddr *him, int *len, jboolean v4MappedAddress);
+NET_InetAddressToSockaddr(JNIEnv *env, jobject iaObj, int port,
+                          struct sockaddr *him, int *len,
+                          jboolean v4MappedAddress);
 
 JNIEXPORT jobject JNICALL
 NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port);
 
 void platformInit();
+
 void parseExclusiveBindProperty(JNIEnv *env);
 
-void
-NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
+void NET_SetTrafficClass(struct sockaddr *him, int trafficClass);
 
-JNIEXPORT jint JNICALL
-NET_GetPortFromSockaddr(struct sockaddr *him);
+JNIEXPORT jint JNICALL NET_GetPortFromSockaddr(struct sockaddr *him);
 
 JNIEXPORT jint JNICALL
 NET_SockaddrEqualsInetAddress(JNIEnv *env,struct sockaddr *him, jobject iaObj);
 
-int
-NET_IsIPv4Mapped(jbyte* caddr);
+int NET_IsIPv4Mapped(jbyte* caddr);
 
-int
-NET_IPv4MappedToIPv4(jbyte* caddr);
+int NET_IPv4MappedToIPv4(jbyte* caddr);
 
-int
-NET_IsEqual(jbyte* caddr1, jbyte* caddr2);
+int NET_IsEqual(jbyte* caddr1, jbyte* caddr2);
 
-int
-NET_IsZeroAddr(jbyte* caddr);
+int NET_IsZeroAddr(jbyte* caddr);
 
 /* Socket operations
  *
@@ -191,9 +183,9 @@
 JNIEXPORT jint JNICALL
 NET_EnableFastTcpLoopback(int fd);
 
-int getScopeID (struct sockaddr *);
+int getScopeID(struct sockaddr *);
 
-int cmpScopeID (unsigned int, struct sockaddr *);
+int cmpScopeID(unsigned int, struct sockaddr *);
 
 unsigned short in_cksum(unsigned short *addr, int len);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/unix/conf/s390x/jvm.cfg	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,34 @@
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+# List of JVMs that can be used as an option to java, javac, etc.
+# Order is important -- first in this list is the default JVM.
+# NOTE that this both this file and its format are UNSUPPORTED and
+# WILL GO AWAY in a future release.
+#
+# You may also select a JVM in an arbitrary location with the
+# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported
+# and may not be available in a future release.
+#
+-server KNOWN
+-client IGNORE
--- a/jdk/src/java.base/unix/native/libnet/Inet4AddressImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/Inet4AddressImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,27 +22,17 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
+#include <ctype.h>
 #include <errno.h>
-#include <sys/time.h>
 #include <sys/types.h>
-#include <sys/socket.h>
+#include <netinet/in.h>
 #include <netinet/in_systm.h>
-#include <netinet/in.h>
 #include <netinet/ip.h>
 #include <netinet/ip_icmp.h>
-#include <netdb.h>
+#include <stdlib.h>
 #include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
+#include <sys/time.h>
 
-#ifdef _ALLBSD_SOURCE
-#include <unistd.h>
-#include <sys/param.h>
-#endif
-
-#include "jvm.h"
-#include "jni_util.h"
 #include "net_util.h"
 
 #include "java_net_Inet4AddressImpl.h"
@@ -293,13 +283,12 @@
     addr |= ((caddr[2] <<8) & 0xff00);
     addr |= (caddr[3] & 0xff);
     memset((char *) &him4, 0, sizeof(him4));
-    him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+    him4.sin_addr.s_addr = htonl(addr);
     him4.sin_family = AF_INET;
     sa = (struct sockaddr *) &him4;
     len = sizeof(him4);
 
-    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
-                               NI_NAMEREQD);
+    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
 
     if (!error) {
         ret = (*env)->NewStringUTF(env, host);
@@ -443,7 +432,7 @@
 
             if (!skip) {
                 struct addrinfo *next
-                    = (struct addrinfo*) malloc(sizeof(struct addrinfo));
+                    = (struct addrinfo *)malloc(sizeof(struct addrinfo));
                 if (!next) {
                     JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
                     ret = NULL;
@@ -528,13 +517,12 @@
     addr |= ((caddr[2] <<8) & 0xff00);
     addr |= (caddr[3] & 0xff);
     memset((void *) &him4, 0, sizeof(him4));
-    him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+    him4.sin_addr.s_addr = htonl(addr);
     him4.sin_family = AF_INET;
     sa = (struct sockaddr *) &him4;
     len = sizeof(him4);
 
-    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
-                        NI_NAMEREQD);
+    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
 
     if (!error) {
         ret = (*env)->NewStringUTF(env, host);
--- a/jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/Inet6AddressImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,29 +22,21 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
+#include <ctype.h>
 #include <errno.h>
+#include <stdlib.h>
+#include <string.h>
 #include <sys/time.h>
 #include <sys/types.h>
-#include <sys/socket.h>
 #include <netinet/in.h>
-#include <netdb.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <ctype.h>
-#ifdef MACOSX
+#include <netinet/icmp6.h>
+
+#if defined(_ALLBSD_SOURCE)
 #include <ifaddrs.h>
 #include <net/if.h>
-#include <unistd.h> /* gethostname */
 #endif
 
-#include "jvm.h"
-#include "jni_util.h"
 #include "net_util.h"
-#ifndef IPV6_DEFS_H
-#include <netinet/icmp6.h>
-#endif
 
 #include "java_net_Inet4AddressImpl.h"
 #include "java_net_Inet6AddressImpl.h"
@@ -504,24 +496,23 @@
         addr |= ((caddr[2] <<8) & 0xff00);
         addr |= (caddr[3] & 0xff);
         memset((void *) &him4, 0, sizeof(him4));
-        him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+        him4.sin_addr.s_addr = htonl(addr);
         him4.sin_family = AF_INET;
-        sa = (struct sockaddr *) &him4;
+        sa = (struct sockaddr *)&him4;
         len = sizeof(him4);
     } else {
         /*
          * For IPv6 address construct a sockaddr_in6 structure.
          */
         (*env)->GetByteArrayRegion(env, addrArray, 0, 16, caddr);
-        memset((void *) &him6, 0, sizeof(him6));
-        memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr) );
+        memset((void *)&him6, 0, sizeof(him6));
+        memcpy((void *)&(him6.sin6_addr), caddr, sizeof(struct in6_addr));
         him6.sin6_family = AF_INET6;
-        sa = (struct sockaddr *) &him6 ;
-        len = sizeof(him6) ;
+        sa = (struct sockaddr *)&him6;
+        len = sizeof(him6);
     }
 
-    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0,
-                        NI_NAMEREQD);
+    error = getnameinfo(sa, len, host, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
 
     if (!error) {
         ret = (*env)->NewStringUTF(env, host);
--- a/jdk/src/java.base/unix/native/libnet/NetworkInterface.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/NetworkInterface.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,55 +22,36 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
+#include <arpa/inet.h>
 #include <errno.h>
-#include <strings.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
 #include <net/if.h>
 #include <net/if_arp.h>
-
-#if defined(__solaris__)
-#include <sys/dlpi.h>
-#include <fcntl.h>
-#include <stropts.h>
-#include <sys/sockio.h>
-#endif
-
-#if defined(__linux__)
+#include <stdlib.h>
+#include <string.h>
 #include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <stdio.h>
-#endif
 
 #if defined(_AIX)
-#include <sys/ioctl.h>
 #include <netinet/in6_var.h>
 #include <sys/ndd_var.h>
 #include <sys/kinfo.h>
 #endif
 
-#if defined(_ALLBSD_SOURCE)
-#include <sys/param.h>
-#include <sys/ioctl.h>
+#if defined(__solaris__)
+#include <stropts.h>
+#include <sys/dlpi.h>
 #include <sys/sockio.h>
-#if defined(__APPLE__)
+#endif
+
+#if defined(_ALLBSD_SOURCE)
 #include <net/ethernet.h>
-#include <net/if_var.h>
 #include <net/if_dl.h>
-#include <netinet/in_var.h>
 #include <ifaddrs.h>
 #endif
-#endif
 
-#include "jvm.h"
-#include "jni_util.h"
 #include "net_util.h"
 
+#include "java_net_InetAddress.h"
+
 #if defined(__linux__)
     #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
 #elif defined(__solaris__)
@@ -332,7 +313,7 @@
 {
     netif *ifs, *curr;
 #if defined(AF_INET6)
-    int family = (getInetAddress_family(env, iaObj) == IPv4) ? AF_INET : AF_INET6;
+    int family = (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) ? AF_INET : AF_INET6;
 #else
     int family =  AF_INET;
 #endif
--- a/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/PlainDatagramSocketImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,29 +22,23 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 #include <errno.h>
-#include <netinet/in.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <sys/ioctl.h>
 
-#ifdef __solaris__
-#include <fcntl.h>
-#include <unistd.h>
-#include <stropts.h>
+#if defined(__solaris__)
+#include <sys/filio.h>
+#endif
 
-#ifndef BSD_COMP
-#define BSD_COMP
-#endif
-#endif
+#include "net_util.h"
+
+#include "java_net_PlainDatagramSocketImpl.h"
+#include "java_net_InetAddress.h"
+#include "java_net_NetworkInterface.h"
+#include "java_net_SocketOptions.h"
+
 #ifdef __linux__
-#include <unistd.h>
-#include <sys/sysctl.h>
-#include <sys/utsname.h>
-#include <netinet/ip.h>
-
 #define IPV6_MULTICAST_IF 17
 #ifndef SO_BSDCOMPAT
 #define SO_BSDCOMPAT  14
@@ -58,7 +52,11 @@
 #endif
 #endif  //  __linux__
 
-#include <sys/ioctl.h>
+#ifdef __solaris__
+#ifndef BSD_COMP
+#define BSD_COMP
+#endif
+#endif
 
 #ifndef IPTOS_TOS_MASK
 #define IPTOS_TOS_MASK 0x1e
@@ -67,12 +65,6 @@
 #define IPTOS_PREC_MASK 0xe0
 #endif
 
-#include "jvm.h"
-#include "jni_util.h"
-#include "net_util.h"
-#include "java_net_SocketOptions.h"
-#include "java_net_PlainDatagramSocketImpl.h"
-#include "java_net_NetworkInterface.h"
 /************************************************************************
  * PlainDatagramSocketImpl
  */
@@ -151,9 +143,6 @@
 JNIEXPORT void JNICALL
 Java_java_net_PlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
 
-#ifdef __linux__
-    struct utsname sysinfo;
-#endif
     pdsi_fdID = (*env)->GetFieldID(env, cls, "fd",
                                    "Ljava/io/FileDescriptor;");
     CHECK_NULL(pdsi_fdID);
@@ -550,7 +539,8 @@
 
     iaObj = NET_SockaddrToInetAddress(env, &rmtaddr.sa, &port);
 #ifdef AF_INET6
-    family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
+    family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
+        AF_INET : AF_INET6;
 #else
     family = AF_INET;
 #endif
@@ -1071,7 +1061,7 @@
      */
     for (i = 0; i < len; i++) {
         addr = (*env)->GetObjectArrayElement(env, addrArray, i);
-        if (getInetAddress_family(env, addr) == IPv4) {
+        if (getInetAddress_family(env, addr) == java_net_InetAddress_IPv4) {
             in.s_addr = htonl(getInetAddress_addr(env, addr));
             break;
         }
@@ -1970,7 +1960,7 @@
     ipv6_join_leave = ipv6_available();
 
 #ifdef __linux__
-    if (getInetAddress_family(env, iaObj) == IPv4) {
+    if (getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4) {
         ipv6_join_leave = JNI_FALSE;
     }
 #endif
@@ -2162,7 +2152,8 @@
         jbyte caddr[16];
         jint family;
         jint address;
-        family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
+        family = getInetAddress_family(env, iaObj) == java_net_InetAddress_IPv4 ?
+            AF_INET : AF_INET6;
         if (family == AF_INET) { /* will convert to IPv4-mapped address */
             memset((char *) caddr, 0, 16);
             address = getInetAddress_addr(env, iaObj);
--- a/jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/PlainSocketImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,32 +22,8 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include <errno.h>
 
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#if defined(__linux__)
-#include <sys/poll.h>
-#endif
-#include <netinet/tcp.h>        /* Defines TCP_NODELAY, needed for 2.6 */
-#include <netinet/in.h>
-#ifdef __linux__
-#include <netinet/ip.h>
-#endif
-#include <netdb.h>
-#include <stdlib.h>
-
-#ifdef __solaris__
-#include <fcntl.h>
-#endif
-#ifdef __linux__
-#include <unistd.h>
-#include <sys/sysctl.h>
-#endif
-
-#include "jvm.h"
-#include "jni_util.h"
 #include "net_util.h"
 
 #include "java_net_SocketOptions.h"
--- a/jdk/src/java.base/unix/native/libnet/SocketInputStream.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/SocketInputStream.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,20 +22,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
+#include <errno.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
 
-#include "jvm.h"
-#include "jni_util.h"
 #include "net_util.h"
 
 #include "java_net_SocketInputStream.h"
 
-/************************************************************************
+/*
  * SocketInputStream
  */
 
--- a/jdk/src/java.base/unix/native/libnet/SocketOutputStream.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/SocketOutputStream.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,15 +22,10 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
+#include <errno.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
 
-#include "jni_util.h"
-#include "jvm.h"
 #include "net_util.h"
 
 #include "java_net_SocketOutputStream.h"
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,60 +22,42 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
+#include <dlfcn.h>
 #include <errno.h>
+#include <net/if.h>
+#include <netinet/tcp.h> // defines TCP_NODELAY
+#include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/tcp.h>        /* Defines TCP_NODELAY, needed for 2.6 */
-#include <netinet/in.h>
-#include <net/if.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <dlfcn.h>
+#include <sys/ioctl.h>
 #include <sys/time.h>
 
-#ifndef _ALLBSD_SOURCE
-#include <values.h>
-#else
-#include <limits.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/ioctl.h>
-#ifndef MAXINT
-#define MAXINT INT_MAX
-#endif
-#endif
-
-#ifdef __solaris__
-#include <sys/filio.h>
-#include <sys/sockio.h>
-#include <stropts.h>
-#include <inet/nd.h>
-#endif
-
-#ifdef __linux__
-#include <sys/ioctl.h>
+#if defined(__linux__)
 #include <arpa/inet.h>
 #include <net/route.h>
 #include <sys/utsname.h>
+#endif
 
-#ifndef IPV6_FLOWINFO_SEND
+#if defined(__solaris__)
+#include <inet/nd.h>
+#include <limits.h>
+#include <stropts.h>
+#include <sys/filio.h>
+#include <sys/sockio.h>
+#endif
+
+#include "net_util.h"
+
+#include "java_net_SocketOptions.h"
+#include "java_net_InetAddress.h"
+
+#if defined(__linux__) && !defined(IPV6_FLOWINFO_SEND)
 #define IPV6_FLOWINFO_SEND      33
 #endif
 
-#endif
-
-#ifdef _AIX
-#include <sys/ioctl.h>
+#if defined(__solaris__) && !defined(MAXINT)
+#define MAXINT INT_MAX
 #endif
 
-#include "jni_util.h"
-#include "jvm.h"
-#include "net_util.h"
-
-#include "java_net_SocketOptions.h"
-
 /*
  * EXCLBIND socket options only on Solaris
  */
@@ -806,13 +788,15 @@
     family = getInetAddress_family(env, iaObj);
 #ifdef AF_INET6
     /* needs work. 1. family 2. clean up him6 etc deallocate memory */
-    if (ipv6_available() && !(family == IPv4 && v4MappedAddress == JNI_FALSE)) {
+    if (ipv6_available() && !(family == java_net_InetAddress_IPv4 &&
+                              v4MappedAddress == JNI_FALSE)) {
         struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
         jbyte caddr[16];
         jint address;
 
 
-        if (family == IPv4) { /* will convert to IPv4-mapped address */
+        if (family == java_net_InetAddress_IPv4) {
+            // convert to IPv4-mapped address
             memset((char *) caddr, 0, 16);
             address = getInetAddress_addr(env, iaObj);
             if (address == INADDR_ANY) {
@@ -906,7 +890,7 @@
 #else
         /* handle scope_id for solaris */
 
-        if (family != IPv4) {
+        if (family != java_net_InetAddress_IPv4) {
             if (ia6_scopeidID) {
                 him6->sin6_scope_id = getInet6Address_scopeid(env, iaObj);
             }
@@ -917,14 +901,14 @@
         {
             struct sockaddr_in *him4 = (struct sockaddr_in*)him;
             jint address;
-            if (family == IPv6) {
+            if (family == java_net_InetAddress_IPv6) {
               JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Protocol family unavailable");
               return -1;
             }
             memset((char *) him4, 0, sizeof(struct sockaddr_in));
             address = getInetAddress_addr(env, iaObj);
             him4->sin_port = htons((short) port);
-            him4->sin_addr.s_addr = (uint32_t) htonl(address);
+            him4->sin_addr.s_addr = htonl(address);
             him4->sin_family = AF_INET;
             *len = sizeof(struct sockaddr_in);
         }
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.h	Thu Oct 27 21:22:57 2016 +0000
@@ -26,13 +26,9 @@
 #ifndef NET_UTILS_MD_H
 #define NET_UTILS_MD_H
 
+#include <netdb.h>
+#include <sys/poll.h>
 #include <sys/socket.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <unistd.h>
-
-#include <sys/poll.h>
 
 int NET_Timeout(int s, long timeout);
 int NET_Timeout0(int s, long timeout, long currentTime);
--- a/jdk/src/java.base/windows/native/libnet/DualStackPlainDatagramSocketImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/DualStackPlainDatagramSocketImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,10 +22,8 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-#include <windows.h>
-#include <winsock2.h>
-#include "jni.h"
 #include "net_util.h"
+
 #include "java_net_DualStackPlainDatagramSocketImpl.h"
 
 /*
--- a/jdk/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,11 +22,10 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-#include <windows.h>
-#include <winsock2.h>
-#include "jni.h"
 #include "net_util.h"
+
 #include "java_net_DualStackPlainSocketImpl.h"
+#include "java_net_SocketOptions.h"
 
 #define SET_BLOCKING 0
 #define SET_NONBLOCKING 1
--- a/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -22,24 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include <malloc.h>
 
-#include <windows.h>
-#include <winsock2.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/types.h>
-#include <process.h>
-#include <iphlpapi.h>
-#include <icmpapi.h>
-#include <WinError.h>
+#include "net_util.h"
 
 #include "java_net_InetAddress.h"
 #include "java_net_Inet4AddressImpl.h"
-#include "net_util.h"
-#include "icmp.h"
-
 
 /*
  * Returns true if hostname is in dotted IP address format. Note that this
--- a/jdk/src/java.base/windows/native/libnet/Inet6AddressImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/Inet6AddressImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,38 +22,13 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include <malloc.h>
 
-#include <windows.h>
-#include <winsock2.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/types.h>
-#include <process.h>
-#include <iphlpapi.h>
-#include <icmpapi.h>
+#include "net_util.h"
 
 #include "java_net_InetAddress.h"
 #include "java_net_Inet4AddressImpl.h"
 #include "java_net_Inet6AddressImpl.h"
-#include "net_util.h"
-#include "icmp.h"
-
-#ifdef WIN32
-#ifndef _WIN64
-
-/* Retain this code a little longer to support building in
- * old environments.  _MSC_VER is defined as:
- *     1200 for MSVC++ 6.0
- *     1310 for Vc7
- */
-#if defined(_MSC_VER) && _MSC_VER < 1310
-#define sockaddr_in6 SOCKADDR_IN6
-#endif
-#endif
-#define uint32_t UINT32
-#endif
 
 /*
  * Inet6AddressImpl
@@ -300,7 +275,7 @@
         addr |= ((caddr[2] <<8) & 0xff00);
         addr |= (caddr[3] & 0xff);
         memset((char *) &him4, 0, sizeof(him4));
-        him4.sin_addr.s_addr = (uint32_t) htonl(addr);
+        him4.sin_addr.s_addr = htonl(addr);
         him4.sin_family = AF_INET;
         sa = (struct sockaddr *) &him4;
         len = sizeof(him4);
--- a/jdk/src/java.base/windows/native/libnet/NetworkInterface.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/NetworkInterface.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,17 +22,10 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
-#include <stdlib.h>
-#include <windows.h>
-#include <winsock2.h>           /* needed for htonl */
-#include <iprtrmib.h>
-#include <assert.h>
+#include "net_util.h"
+#include "NetworkInterface.h"
 
 #include "java_net_NetworkInterface.h"
-#include "jni_util.h"
-
-#include "NetworkInterface.h"
 
 /*
  * Windows implementation of the java.net.NetworkInterface native methods.
--- a/jdk/src/java.base/windows/native/libnet/NetworkInterface.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/NetworkInterface.h	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -26,7 +26,6 @@
 #ifndef NETWORK_INTERFACE_H
 #define NETWORK_INTERFACE_H
 
-#include <iphlpapi.h>
 #include "net_util.h"
 
 /*
--- a/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,19 +22,10 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
-#include <stdlib.h>
-#include <windows.h>
-#include <winsock2.h>           /* needed for htonl */
-#include <iprtrmib.h>
-#include <assert.h>
-#include <limits.h>
+#include "net_util.h"
+#include "NetworkInterface.h"
 
 #include "java_net_NetworkInterface.h"
-#include "jni_util.h"
-
-#include "NetworkInterface.h"
-#include "net_util.h"
 
 /*
  * Windows implementation of the java.net.NetworkInterface native methods.
--- a/jdk/src/java.base/windows/native/libnet/SocketInputStream.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/SocketInputStream.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,24 +22,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include <malloc.h>
 
-#include <windows.h>
-#include <winsock2.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/types.h>
+#include "net_util.h"
 
 #include "java_net_SocketInputStream.h"
 
-#include "net_util.h"
-#include "jni_util.h"
-
 /*************************************************************************
  * SocketInputStream
  */
-
 static jfieldID IO_fd_fdID;
 
 /*
--- a/jdk/src/java.base/windows/native/libnet/SocketOutputStream.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/SocketOutputStream.c	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,20 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include <malloc.h>
 
-#include <windows.h>
-#include <winsock2.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/types.h>
+#include "net_util.h"
 
 #include "java_net_SocketOutputStream.h"
 
-#include "net_util.h"
-#include "jni_util.h"
-
 /************************************************************************
  * SocketOutputStream
  */
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,15 +22,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include <malloc.h>
 
-#include <windows.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/types.h>
+#include "net_util.h"
+#include "NetworkInterface.h"
+
+#include "java_net_TwoStacksPlainDatagramSocketImpl.h"
+#include "java_net_SocketOptions.h"
+#include "java_net_NetworkInterface.h"
+#include "java_net_InetAddress.h"
 
 #ifndef IPTOS_TOS_MASK
 #define IPTOS_TOS_MASK 0x1e
@@ -39,14 +39,6 @@
 #define IPTOS_PREC_MASK 0xe0
 #endif
 
-#include "java_net_TwoStacksPlainDatagramSocketImpl.h"
-#include "java_net_SocketOptions.h"
-#include "java_net_NetworkInterface.h"
-
-#include "NetworkInterface.h"
-#include "jvm.h"
-#include "jni_util.h"
-#include "net_util.h"
 
 #define IN_CLASSD(i)    (((long)(i) & 0xf0000000) == 0xe0000000)
 #define IN_MULTICAST(i) IN_CLASSD(i)
@@ -439,7 +431,7 @@
     memset((char *)&lcladdr, 0, sizeof(lcladdr));
 
     family = getInetAddress_family(env, addressObj);
-    if (family == IPv6 && !ipv6_supported) {
+    if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Protocol family not supported");
         return;
@@ -561,13 +553,13 @@
     addr = getInetAddress_addr(env, address);
 
     family = getInetAddress_family(env, address);
-    if (family == IPv6 && !ipv6_supported) {
+    if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Protocol family not supported");
         return;
     }
 
-    fdc = family == IPv4? fd: fd1;
+    fdc = family == java_net_InetAddress_IPv4 ? fd : fd1;
 
     if (xp_or_later) {
         /* SIO_UDP_CONNRESET fixes a bug introduced in Windows 2000, which
@@ -605,12 +597,12 @@
     jint fd, len;
     SOCKETADDRESS addr;
 
-    if (family == IPv4) {
+    if (family == java_net_InetAddress_IPv4) {
         fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-        len = sizeof (struct sockaddr_in);
+        len = sizeof(struct sockaddr_in);
     } else {
         fdObj = (*env)->GetObjectField(env, this, pdsi_fd1ID);
-        len = sizeof (struct SOCKADDR_IN6);
+        len = sizeof(struct sockaddr_in6);
     }
 
     if (IS_NULL(fdObj)) {
@@ -678,7 +670,7 @@
     }
 
     family = getInetAddress_family(env, iaObj);
-    if (family == IPv4) {
+    if (family == java_net_InetAddress_IPv4) {
         fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
     } else {
         if (!ipv6_available()) {
@@ -906,7 +898,7 @@
         return 0;
     }
     setInetAddress_addr(env, addressObj, ntohl(remote_addr.sa4.sin_addr.s_addr));
-    setInetAddress_family(env, addressObj, IPv4);
+    setInetAddress_family(env, addressObj, java_net_InetAddress_IPv4);
 
     /* return port */
     return ntohs(remote_addr.sa4.sin_port);
@@ -1610,7 +1602,7 @@
 {
     jobject addr;
 
-    int ret = getInetAddrFromIf (env, IPv4, nif, &addr);
+    int ret = getInetAddrFromIf(env, java_net_InetAddress_IPv4, nif, &addr);
     if (ret == -1) {
         return -1;
     }
@@ -2285,9 +2277,9 @@
     len = sizeof(struct sockaddr_in);
 
     /* family==-1 when socket is not connected */
-    if ((family == IPv6) || (family == -1 && fd == -1)) {
+    if ((family == java_net_InetAddress_IPv6) || (family == -1 && fd == -1)) {
         fd = fd1; /* must be IPv6 only */
-        len = sizeof (struct SOCKADDR_IN6);
+        len = sizeof(struct sockaddr_in6);
     }
 
     if (fd == -1) {
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,23 +22,13 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
-#include <windows.h>
-#include <winsock2.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <malloc.h>
-#include <sys/types.h>
-
-#include "java_net_SocketOptions.h"
-#include "java_net_TwoStacksPlainSocketImpl.h"
-#include "java_net_InetAddress.h"
-#include "java_io_FileDescriptor.h"
-#include "java_lang_Integer.h"
 
 #include "net_util.h"
-#include "jni_util.h"
+
+#include "java_net_TwoStacksPlainSocketImpl.h"
+#include "java_net_SocketOptions.h"
+#include "java_net_InetAddress.h"
 
 /************************************************************************
  * TwoStacksPlainSocketImpl
@@ -413,7 +403,7 @@
 
     family = getInetAddress_family(env, iaObj);
 
-    if (family == IPv6 && !ipv6_supported) {
+    if (family == java_net_InetAddress_IPv6 && !ipv6_supported) {
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Protocol family not supported");
         return;
@@ -655,18 +645,18 @@
             return;
         }
         if (fd2 == fd) { /* v4 */
-            len = sizeof (struct sockaddr_in);
+            len = sizeof(struct sockaddr_in);
         } else {
-            len = sizeof (struct SOCKADDR_IN6);
+            len = sizeof(struct sockaddr_in6);
         }
         fd = fd2;
     } else {
         int ret;
         if (fd1 != -1) {
             fd = fd1;
-            len = sizeof (struct SOCKADDR_IN6);
+            len = sizeof(struct sockaddr_in6);
         } else {
-            len = sizeof (struct sockaddr_in);
+            len = sizeof(struct sockaddr_in);
         }
         if (timeout) {
             ret = NET_Timeout(fd, timeout);
@@ -728,7 +718,7 @@
         }
 
         setInetAddress_addr(env, socketAddressObj, ntohl(him.sa4.sin_addr.s_addr));
-        setInetAddress_family(env, socketAddressObj, IPv4);
+        setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv4);
         (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
     } else {
         /* AF_INET6 -> Inet6Address */
@@ -754,7 +744,7 @@
             return;
         }
         setInet6Address_ipaddress(env, socketAddressObj, (char *)&him.sa6.sin6_addr);
-        setInetAddress_family(env, socketAddressObj, IPv6);
+        setInetAddress_family(env, socketAddressObj, java_net_InetAddress_IPv6);
         setInet6Address_scopeid(env, socketAddressObj, him.sa6.sin6_scope_id);
 
     }
--- a/jdk/src/java.base/windows/native/libnet/icmp.h	Thu Oct 27 16:29:00 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#ifndef ICMP_H
-#define ICMP_H
-
-/*
- * Structure of an internet header, naked of options.
- *
- * We declare ip_len and ip_off to be short, rather than ushort_t
- * pragmatically since otherwise unsigned comparisons can result
- * against negative integers quite easily, and fail in subtle ways.
- */
-struct ip {
-        unsigned char   ip_hl:4,        /* header length */
-                        ip_v:4;         /* version */
-        unsigned char   ip_tos;                 /* type of service */
-        short   ip_len;                 /* total length */
-        unsigned short ip_id;                   /* identification */
-        short   ip_off;                 /* fragment offset field */
-#define IP_DF 0x4000                    /* don't fragment flag */
-#define IP_MF 0x2000                    /* more fragments flag */
-        unsigned char   ip_ttl;                 /* time to live */
-        unsigned char   ip_p;                   /* protocol */
-        unsigned short ip_sum;          /* checksum */
-        struct  in_addr ip_src, ip_dst; /* source and dest address */
-};
-
-/*
- * Structure of an icmp header.
- */
-struct icmp {
-        unsigned char   icmp_type;              /* type of message, see below */
-        unsigned char   icmp_code;              /* type sub code */
-        unsigned short icmp_cksum;              /* ones complement cksum of struct */
-        union {
-                unsigned char ih_pptr;          /* ICMP_PARAMPROB */
-                struct in_addr ih_gwaddr;       /* ICMP_REDIRECT */
-                struct ih_idseq {
-                        unsigned short icd_id;
-                        unsigned short icd_seq;
-                } ih_idseq;
-                int ih_void;
-
-                /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
-                struct ih_pmtu {
-                        unsigned short ipm_void;
-                        unsigned short ipm_nextmtu;
-                } ih_pmtu;
-
-                struct ih_rtradv {
-                        unsigned char irt_num_addrs;
-                        unsigned char irt_wpa;
-                        unsigned short irt_lifetime;
-                } ih_rtradv;
-        } icmp_hun;
-#define icmp_pptr       icmp_hun.ih_pptr
-#define icmp_gwaddr     icmp_hun.ih_gwaddr
-#define icmp_id         icmp_hun.ih_idseq.icd_id
-#define icmp_seq        icmp_hun.ih_idseq.icd_seq
-#define icmp_void       icmp_hun.ih_void
-#define icmp_pmvoid     icmp_hun.ih_pmtu.ipm_void
-#define icmp_nextmtu    icmp_hun.ih_pmtu.ipm_nextmtu
-        union {
-                struct id_ts {
-                        unsigned int its_otime;
-                        unsigned int its_rtime;
-                        unsigned int its_ttime;
-                } id_ts;
-                struct id_ip  {
-                        struct ip idi_ip;
-                        /* options and then 64 bits of data */
-                } id_ip;
-                unsigned int id_mask;
-                char    id_data[1];
-        } icmp_dun;
-#define icmp_otime      icmp_dun.id_ts.its_otime
-#define icmp_rtime      icmp_dun.id_ts.its_rtime
-#define icmp_ttime      icmp_dun.id_ts.its_ttime
-#define icmp_ip         icmp_dun.id_ip.idi_ip
-#define icmp_mask       icmp_dun.id_mask
-#define icmp_data       icmp_dun.id_data
-};
-
-#define ICMP_ECHOREPLY          0               /* echo reply */
-#define ICMP_ECHO               8               /* echo service */
-
-/*
- * ICMPv6 structures & constants
- */
-
-typedef struct icmp6_hdr {
-        u_char   icmp6_type;    /* type field */
-        u_char   icmp6_code;    /* code field */
-        u_short  icmp6_cksum;   /* checksum field */
-        union {
-                u_int icmp6_un_data32[1];       /* type-specific field */
-                u_short icmp6_un_data16[2];     /* type-specific field */
-                u_char  icmp6_un_data8[4];      /* type-specific field */
-        } icmp6_dataun;
-} icmp6_t;
-
-#define icmp6_data32    icmp6_dataun.icmp6_un_data32
-#define icmp6_data16    icmp6_dataun.icmp6_un_data16
-#define icmp6_data8     icmp6_dataun.icmp6_un_data8
-#define icmp6_pptr      icmp6_data32[0] /* parameter prob */
-#define icmp6_mtu       icmp6_data32[0] /* packet too big */
-#define icmp6_id        icmp6_data16[0] /* echo request/reply */
-#define icmp6_seq       icmp6_data16[1] /* echo request/reply */
-#define icmp6_maxdelay  icmp6_data16[0] /* mcast group membership */
-
-struct ip6_pseudo_hdr  /* for calculate the ICMPv6 checksum */
-{
-  struct in6_addr ip6_src;
-  struct in6_addr ip6_dst;
-  u_int       ip6_plen;
-  u_int       ip6_nxt;
-};
-
-#define ICMP6_ECHO_REQUEST      128
-#define ICMP6_ECHO_REPLY        129
-#define IPPROTO_ICMPV6          58
-#define IPV6_UNICAST_HOPS       4  /* Set/get IP unicast hop limit */
-
-
-#endif
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.c	Thu Oct 27 21:22:57 2016 +0000
@@ -22,12 +22,10 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include "net_util.h"
 
-#include <winsock2.h>
-#include <ws2tcpip.h>
-
-#include "net_util.h"
-#include "jni.h"
+#include "java_net_InetAddress.h"
+#include "java_net_SocketOptions.h"
 
 // Taken from mstcpip.h in Windows SDK 8.0 or newer.
 #define SIO_LOOPBACK_FAST_PATH              _WSAIOW(IOC_VENDOR,16)
@@ -593,7 +591,7 @@
 
 
 void dumpAddr (char *str, void *addr) {
-    struct SOCKADDR_IN6 *a = (struct SOCKADDR_IN6 *)addr;
+    struct sockaddr_in6 *a = (struct sockaddr_in6 *)addr;
     int family = a->sin6_family;
     printf ("%s\n", str);
     if (family == AF_INET) {
@@ -812,7 +810,7 @@
  *      0 if error
  *      > 0 interface index to use
  */
-jint getDefaultIPv6Interface(JNIEnv *env, struct SOCKADDR_IN6 *target_addr)
+jint getDefaultIPv6Interface(JNIEnv *env, struct sockaddr_in6 *target_addr)
 {
     int ret;
     DWORD b;
@@ -866,9 +864,9 @@
                           int *len, jboolean v4MappedAddress) {
     jint family, iafam;
     iafam = getInetAddress_family(env, iaObj);
-    family = (iafam == IPv4)? AF_INET : AF_INET6;
+    family = (iafam == java_net_InetAddress_IPv4)? AF_INET : AF_INET6;
     if (ipv6_available() && !(family == AF_INET && v4MappedAddress == JNI_FALSE)) {
-        struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
+        struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
         jbyte caddr[16];
         jint address, scopeid = 0;
         jint cached_scope_id = 0;
@@ -894,7 +892,7 @@
             cached_scope_id = (jint)(*env)->GetIntField(env, iaObj, ia6_cachedscopeidID);
         }
 
-        memset((char *)him6, 0, sizeof(struct SOCKADDR_IN6));
+        memset((char *)him6, 0, sizeof(struct sockaddr_in6));
         him6->sin6_port = (u_short) htons((u_short)port);
         memcpy((void *)&(him6->sin6_addr), caddr, sizeof(struct in6_addr) );
         him6->sin6_family = AF_INET6;
@@ -904,7 +902,7 @@
             (*env)->SetIntField(env, iaObj, ia6_cachedscopeidID, cached_scope_id);
         }
         him6->sin6_scope_id = scopeid != 0 ? scopeid : cached_scope_id;
-        *len = sizeof(struct SOCKADDR_IN6) ;
+        *len = sizeof(struct sockaddr_in6) ;
     } else {
         struct sockaddr_in *him4 = (struct sockaddr_in *)him;
         jint address;
@@ -964,12 +962,12 @@
 }
 
 int getScopeID(struct sockaddr *him) {
-    struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
+    struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
     return him6->sin6_scope_id;
 }
 
 int cmpScopeID(unsigned int scope, struct sockaddr *him) {
-    struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
+    struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)him;
     return him6->sin6_scope_id == scope;
 }
 
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.h	Thu Oct 27 21:22:57 2016 +0000
@@ -22,195 +22,10 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 #include <winsock2.h>
 #include <WS2tcpip.h>
-
-/* typedefs that were defined correctly for the first time
- * in Nov. 2001 SDK, which we need to include here.
- * Specifically, in6_addr and sockaddr_in6 (which is defined but
- * not correctly). When moving to a later SDK remove following
- * code between START and END
- */
-
-/* --- START --- */
-
-/* WIN64 already uses newer SDK */
-#ifdef _WIN64
-
-#define SOCKADDR_IN6 sockaddr_in6
-
-#else
-
-#ifdef _MSC_VER
-#define WS2TCPIP_INLINE __inline
-#else
-#define WS2TCPIP_INLINE extern inline /* GNU style */
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1310
-
-#define SOCKADDR_IN6 sockaddr_in6
-
-#else
-
-/*SO_REUSEPORT is not supported on Windows, define it to 0*/
-#define SO_REUSEPORT 0
-
-/* Retain this code a little longer to support building in
- * old environments.  _MSC_VER is defined as:
- *     1200 for MSVC++ 6.0
- *     1310 for Vc7
- */
-
-#define IPPROTO_IPV6    41
-#define IPV6_MULTICAST_IF 9
-
-struct in6_addr {
-    union {
-        u_char Byte[16];
-        u_short Word[8];
-    } u;
-};
-
-/*
-** Defines to match RFC 2553.
-*/
-#define _S6_un     u
-#define _S6_u8     Byte
-#define s6_addr    _S6_un._S6_u8
-
-/*
-** Defines for our implementation.
-*/
-#define s6_bytes   u.Byte
-#define s6_words   u.Word
-
-/* IPv6 socket address structure, RFC 2553 */
-
-struct SOCKADDR_IN6 {
-        short   sin6_family;    /* AF_INET6 */
-        u_short sin6_port;      /* Transport level port number */
-        u_long  sin6_flowinfo;  /* IPv6 flow information */
-        struct in6_addr sin6_addr; /* IPv6 address */
-        u_long sin6_scope_id;  /* set of interfaces for a scope */
-};
-
-
-/* Error codes from getaddrinfo() */
-
-#define EAI_AGAIN       WSATRY_AGAIN
-#define EAI_BADFLAGS    WSAEINVAL
-#define EAI_FAIL        WSANO_RECOVERY
-#define EAI_FAMILY      WSAEAFNOSUPPORT
-#define EAI_MEMORY      WSA_NOT_ENOUGH_MEMORY
-//#define EAI_NODATA      WSANO_DATA
-#define EAI_NONAME      WSAHOST_NOT_FOUND
-#define EAI_SERVICE     WSATYPE_NOT_FOUND
-#define EAI_SOCKTYPE    WSAESOCKTNOSUPPORT
-
-#define EAI_NODATA      EAI_NONAME
-
-/* Structure used in getaddrinfo() call */
-
-typedef struct addrinfo {
-    int ai_flags;              /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
-    int ai_family;             /* PF_xxx */
-    int ai_socktype;           /* SOCK_xxx */
-    int ai_protocol;           /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
-    size_t ai_addrlen;         /* Length of ai_addr */
-    char *ai_canonname;        /* Canonical name for nodename */
-    struct sockaddr *ai_addr;  /* Binary address */
-    struct addrinfo *ai_next;  /* Next structure in linked list */
-} ADDRINFO, FAR * LPADDRINFO;
-
-/* Flags used in "hints" argument to getaddrinfo() */
-
-#define AI_PASSIVE     0x1  /* Socket address will be used in bind() call */
-#define AI_CANONNAME   0x2  /* Return canonical name in first ai_canonname */
-#define AI_NUMERICHOST 0x4  /* Nodename must be a numeric address string */
-
-/* IPv6 Multicasting definitions */
-
-/* Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP */
-
-typedef struct ipv6_mreq {
-    struct in6_addr ipv6mr_multiaddr;  /* IPv6 multicast address */
-    unsigned int    ipv6mr_interface;  /* Interface index */
-} IPV6_MREQ;
-
-#define IPV6_ADD_MEMBERSHIP     12 /* Add an IP group membership */
-#define IPV6_DROP_MEMBERSHIP    13 /* Drop an IP group membership */
-#define IPV6_MULTICAST_LOOP     11 /* Set/get IP multicast loopback */
-
-WS2TCPIP_INLINE int
-IN6_IS_ADDR_MULTICAST(const struct in6_addr *a)
-{
-    return (a->s6_bytes[0] == 0xff);
-}
-
-WS2TCPIP_INLINE int
-IN6_IS_ADDR_LINKLOCAL(const struct in6_addr *a)
-{
-    return (a->s6_bytes[0] == 0xfe
-            && a->s6_bytes[1] == 0x80);
-}
-
-#define NI_MAXHOST  1025  /* Max size of a fully-qualified domain name */
-#define NI_MAXSERV    32  /* Max size of a service name */
-
-#define INET_ADDRSTRLEN  16 /* Max size of numeric form of IPv4 address */
-#define INET6_ADDRSTRLEN 46 /* Max size of numeric form of IPv6 address */
-
-/* Flags for getnameinfo() */
-
-#define NI_NOFQDN       0x01  /* Only return nodename portion for local hosts */
-#define NI_NUMERICHOST  0x02  /* Return numeric form of the host's address */
-#define NI_NAMEREQD     0x04  /* Error if the host's name not in DNS */
-#define NI_NUMERICSERV  0x08  /* Return numeric form of the service (port #) */
-#define NI_DGRAM        0x10  /* Service is a datagram service */
-
-
-#define IN6_IS_ADDR_V4MAPPED(a) \
-    (((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) &&      \
-    ((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) &&       \
-    ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0xffff))
-
-
-/* --- END --- */
-#endif /* end 'else older build environment' */
-
-#endif
-
-#if !INCL_WINSOCK_API_TYPEDEFS
-
-typedef
-int
-(WSAAPI * LPFN_GETADDRINFO)(
-    IN const char FAR * nodename,
-    IN const char FAR * servname,
-    IN const struct addrinfo FAR * hints,
-    OUT struct addrinfo FAR * FAR * res
-    );
-
-typedef
-void
-(WSAAPI * LPFN_FREEADDRINFO)(
-    IN struct addrinfo FAR * ai
-    );
-
-typedef
-int
-(WSAAPI * LPFN_GETNAMEINFO)(
-    IN  const struct sockaddr FAR * sa,
-    IN  int             salen,
-    OUT char FAR *      host,
-    IN  DWORD           hostlen,
-    OUT char FAR *      serv,
-    IN  DWORD           servlen,
-    IN  int             flags
-    );
-#endif
+#include <iphlpapi.h>
+#include <icmpapi.h>
 
 /* used to disable connection reset messages on Windows XP */
 #ifndef SIO_UDP_CONNRESET
@@ -229,13 +44,9 @@
 #define IPV6_V6ONLY     27 /* Treat wildcard bind as AF_INET6-only. */
 #endif
 
-#include "java_io_FileDescriptor.h"
-#include "java_net_SocketOptions.h"
-
 #define MAX_BUFFER_LEN          2048
 #define MAX_HEAP_BUFFER_LEN     65536
 
-
 /* true if SO_RCVTIMEO is supported by underlying provider */
 extern jboolean isRcvTimeoutSupported;
 
@@ -249,7 +60,7 @@
 typedef union {
     struct sockaddr     sa;
     struct sockaddr_in  sa4;
-    struct SOCKADDR_IN6 sa6;
+    struct sockaddr_in6 sa6;
 } SOCKETADDRESS;
 
 /*
@@ -264,7 +75,7 @@
 
 #define SOCKETADDRESS_COPY(DST,SRC) {                           \
     if ((SRC)->sa_family == AF_INET6) {                         \
-        memcpy ((DST), (SRC), sizeof (struct SOCKADDR_IN6));    \
+        memcpy ((DST), (SRC), sizeof (struct sockaddr_in6));    \
     } else {                                                    \
         memcpy ((DST), (SRC), sizeof (struct sockaddr_in));     \
     }                                                           \
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java	Thu Oct 27 21:22:57 2016 +0000
@@ -29,11 +29,9 @@
 
 import java.awt.*;
 import java.beans.*;
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.util.*;
 import java.util.concurrent.Callable;
-import sun.awt.AWTAccessor;
 
 import javax.accessibility.*;
 import javax.swing.*;
@@ -73,8 +71,20 @@
     }
 
     public void propertyChange(final PropertyChangeEvent evt) {
-        if (evt.getNewValue() == null) return;
-        focusChanged();
+        Object newValue = evt.getNewValue();
+        if (newValue == null) return;
+        // Don't post focus on things that don't matter, i.e. alert, colorchooser,
+        // desktoppane, dialog, directorypane, filechooser, filler, fontchoose,
+        // frame, glasspane, layeredpane, optionpane, panel, rootpane, separator,
+        // tooltip, viewport, window.
+        // List taken from initializeRoles() in JavaComponentUtilities.m.
+        if (newValue instanceof Accessible) {
+            AccessibleContext nvAC = ((Accessible) newValue).getAccessibleContext();
+            AccessibleRole nvRole = nvAC.getAccessibleRole();
+            if (!ignoredRoles.contains(roleKey(nvRole))) {
+                focusChanged();
+            }
+        }
     }
 
     private native void focusChanged();
@@ -683,9 +693,15 @@
             if (context == null) continue;
 
             if (whichChildren == JAVA_AX_VISIBLE_CHILDREN) {
-                if (!context.getAccessibleComponent().isVisible()) continue;
+                AccessibleComponent acomp = context.getAccessibleComponent();
+                if (acomp == null || !acomp.isVisible()) {
+                    continue;
+                }
             } else if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
-                if (!ac.getAccessibleSelection().isAccessibleChildSelected(i)) continue;
+                AccessibleSelection sel = ac.getAccessibleSelection();
+                if (sel == null || !sel.isAccessibleChildSelected(i)) {
+                    continue;
+                }
             }
 
             if (!allowIgnored) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java	Thu Oct 27 21:22:57 2016 +0000
@@ -39,7 +39,10 @@
 import static javax.accessibility.AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY;
 import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY;
 import static javax.accessibility.AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY;
+import static javax.accessibility.AccessibleContext.ACCESSIBLE_STATE_PROPERTY;
 import static javax.accessibility.AccessibleContext.ACCESSIBLE_TEXT_PROPERTY;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
 import sun.awt.AWTAccessor;
 
 
@@ -63,6 +66,9 @@
     private static native void valueChanged(long ptr);
     private static native void selectedTextChanged(long ptr);
     private static native void selectionChanged(long ptr);
+    private static native void menuOpened(long ptr);
+    private static native void menuClosed(long ptr);
+    private static native void menuItemSelected(long ptr);
 
     private Accessible accessible;
 
@@ -111,16 +117,45 @@
         public void propertyChange(PropertyChangeEvent e) {
             String name = e.getPropertyName();
             if ( ptr != 0 ) {
+                Object newValue = e.getNewValue();
+                Object oldValue = e.getOldValue();
                 if (name.compareTo(ACCESSIBLE_CARET_PROPERTY) == 0) {
                     selectedTextChanged(ptr);
                 } else if (name.compareTo(ACCESSIBLE_TEXT_PROPERTY) == 0 ) {
                     valueChanged(ptr);
                 } else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0 ) {
                     selectionChanged(ptr);
-                }  else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) {
-                    Object nv = e.getNewValue();
-                    if (nv instanceof AccessibleContext) {
-                        activeDescendant = (AccessibleContext)nv;
+                } else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) {
+                    if (newValue instanceof AccessibleContext) {
+                        activeDescendant = (AccessibleContext)newValue;
+                    }
+                } else if (name.compareTo(ACCESSIBLE_STATE_PROPERTY) == 0) {
+                    AccessibleContext thisAC = accessible.getAccessibleContext();
+                    AccessibleRole thisRole = thisAC.getAccessibleRole();
+                    Accessible parentAccessible = thisAC.getAccessibleParent();
+                    AccessibleRole parentRole = null;
+                    if (parentAccessible != null) {
+                        parentRole = parentAccessible.getAccessibleContext().getAccessibleRole();
+                    }
+                    // At least for now don't handle combo box menu state changes.
+                    // This may change when later fixing issues which currently
+                    // exist for combo boxes, but for now the following is only
+                    // for JPopupMenus, not for combobox menus.
+                    if (parentRole != AccessibleRole.COMBO_BOX) {
+                        if (thisRole == AccessibleRole.POPUP_MENU) {
+                            if ( newValue != null &&
+                                 ((AccessibleState)newValue) == AccessibleState.VISIBLE ) {
+                                    menuOpened(ptr);
+                            } else if ( oldValue != null &&
+                                        ((AccessibleState)oldValue) == AccessibleState.VISIBLE ) {
+                                menuClosed(ptr);
+                            }
+                        } else if (thisRole == AccessibleRole.MENU_ITEM) {
+                            if ( newValue != null &&
+                                 ((AccessibleState)newValue) == AccessibleState.FOCUSED ) {
+                                menuItemSelected(ptr);
+                            }
+                        }
                     }
                 }
             }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Thu Oct 27 21:22:57 2016 +0000
@@ -97,7 +97,7 @@
         int absY = locationOnScreen.y + y;
 
         responder.handleScrollEvent(x, y, absX, absY, modifierFlags, deltaX,
-                                    deltaY);
+                                    deltaY, NSEvent.SCROLL_PHASE_UNSUPPORTED);
     }
 
     public void handleKeyEvent(int eventType, int modifierFlags, String characters,
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Thu Oct 27 21:22:57 2016 +0000
@@ -44,6 +44,8 @@
     private final PlatformEventNotifier eventNotifier;
     private final boolean isNpapiCallback;
     private int lastKeyPressCode = KeyEvent.VK_UNDEFINED;
+    private final DeltaAccumulator deltaAccumulatorX = new DeltaAccumulator();
+    private final DeltaAccumulator deltaAccumulatorY = new DeltaAccumulator();
 
     CPlatformResponder(final PlatformEventNotifier eventNotifier,
                        final boolean isNpapiCallback) {
@@ -89,37 +91,37 @@
      */
     void handleScrollEvent(final int x, final int y, final int absX,
                            final int absY, final int modifierFlags,
-                           final double deltaX, final double deltaY) {
+                           final double deltaX, final double deltaY,
+                           final int scrollPhase) {
         int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
         final boolean isShift = (jmodifiers & InputEvent.SHIFT_DOWN_MASK) != 0;
 
+        int roundDeltaX = deltaAccumulatorX.getRoundedDelta(deltaX, scrollPhase);
+        int roundDeltaY = deltaAccumulatorY.getRoundedDelta(deltaY, scrollPhase);
+
         // Vertical scroll.
-        if (!isShift && deltaY != 0.0) {
-            dispatchScrollEvent(x, y, absX, absY, jmodifiers, deltaY);
+        if (!isShift && (deltaY != 0.0 || roundDeltaY != 0)) {
+            dispatchScrollEvent(x, y, absX, absY, jmodifiers, roundDeltaY, deltaY);
         }
         // Horizontal scroll or shirt+vertical scroll.
         final double delta = isShift && deltaY != 0.0 ? deltaY : deltaX;
-        if (delta != 0.0) {
+        final int roundDelta = isShift && roundDeltaY != 0 ? roundDeltaY : roundDeltaX;
+        if (delta != 0.0 || roundDelta != 0) {
             jmodifiers |= InputEvent.SHIFT_DOWN_MASK;
-            dispatchScrollEvent(x, y, absX, absY, jmodifiers, delta);
+            dispatchScrollEvent(x, y, absX, absY, jmodifiers, roundDelta, delta);
         }
     }
 
     private void dispatchScrollEvent(final int x, final int y, final int absX,
                                      final int absY, final int modifiers,
-                                     final double delta) {
+                                     final int roundDelta, final double delta) {
         final long when = System.currentTimeMillis();
         final int scrollType = MouseWheelEvent.WHEEL_UNIT_SCROLL;
         final int scrollAmount = 1;
-        int wheelRotation = (int) delta;
-        int signum = (int) Math.signum(delta);
-        if (signum * delta < 1) {
-            wheelRotation = signum;
-        }
         // invert the wheelRotation for the peer
         eventNotifier.notifyMouseWheelEvent(when, x, y, absX, absY, modifiers,
                                             scrollType, scrollAmount,
-                                            -wheelRotation, -delta, null);
+                                            -roundDelta, -delta, null);
     }
 
     /**
@@ -260,4 +262,46 @@
     void handleWindowFocusEvent(boolean gained, LWWindowPeer opposite) {
         eventNotifier.notifyActivation(gained, opposite);
     }
+
+    static class DeltaAccumulator {
+
+        static final double MIN_THRESHOLD = 0.1;
+        static final double MAX_THRESHOLD = 0.5;
+        double accumulatedDelta;
+
+        int getRoundedDelta(double delta, int scrollPhase) {
+
+            int roundDelta = (int) Math.round(delta);
+
+            if (scrollPhase == NSEvent.SCROLL_PHASE_UNSUPPORTED) { // mouse wheel
+                if (roundDelta == 0 && delta != 0) {
+                    roundDelta = delta > 0 ? 1 : -1;
+                }
+            } else { // trackpad
+                boolean begin = scrollPhase == NSEvent.SCROLL_PHASE_BEGAN;
+                boolean end = scrollPhase == NSEvent.SCROLL_MASK_PHASE_ENDED
+                        || scrollPhase == NSEvent.SCROLL_MASK_PHASE_CANCELLED;
+
+                if (begin) {
+                    accumulatedDelta = 0;
+                }
+
+                accumulatedDelta += delta;
+
+                double absAccumulatedDelta = Math.abs(accumulatedDelta);
+                if (absAccumulatedDelta > MAX_THRESHOLD) {
+                    roundDelta = (int) Math.round(accumulatedDelta);
+                    accumulatedDelta -= roundDelta;
+                }
+
+                if (end) {
+                    if (roundDelta == 0 && absAccumulatedDelta > MIN_THRESHOLD) {
+                        roundDelta = accumulatedDelta > 0 ? 1 : -1;
+                    }
+                }
+            }
+
+            return roundDelta;
+        }
+    }
 }
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java	Thu Oct 27 21:22:57 2016 +0000
@@ -194,7 +194,8 @@
 
         if (event.getType() == CocoaConstants.NSScrollWheel) {
             responder.handleScrollEvent(x, y, absX, absY, event.getModifierFlags(),
-                                        event.getScrollDeltaX(), event.getScrollDeltaY());
+                                        event.getScrollDeltaX(), event.getScrollDeltaY(),
+                                        event.getScrollPhase());
         } else {
             responder.handleMouseEvent(event.getType(), event.getModifierFlags(), event.getButtonNumber(),
                                        event.getClickCount(), x, y,
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java	Thu Oct 27 21:22:57 2016 +0000
@@ -32,6 +32,13 @@
  * JDK functionality.
  */
 final class NSEvent {
+
+    static final int SCROLL_PHASE_UNSUPPORTED = 1;
+    static final int SCROLL_PHASE_BEGAN = 2;
+    static final int SCROLL_PHASE_CONTINUED = 3;
+    static final int SCROLL_MASK_PHASE_CANCELLED = 4;
+    static final int SCROLL_MASK_PHASE_ENDED = 5;
+
     private int type;
     private int modifierFlags;
 
@@ -42,6 +49,7 @@
     private int y;
     private double scrollDeltaY;
     private double scrollDeltaX;
+    private int scrollPhase;
     private int absX;
     private int absY;
 
@@ -62,7 +70,7 @@
     // Called from native
     NSEvent(int type, int modifierFlags, int clickCount, int buttonNumber,
                    int x, int y, int absX, int absY,
-                   double scrollDeltaY, double scrollDeltaX) {
+                   double scrollDeltaY, double scrollDeltaX, int scrollPhase) {
         this.type = type;
         this.modifierFlags = modifierFlags;
         this.clickCount = clickCount;
@@ -73,6 +81,7 @@
         this.absY = absY;
         this.scrollDeltaY = scrollDeltaY;
         this.scrollDeltaX = scrollDeltaX;
+        this.scrollPhase = scrollPhase;
     }
 
     int getType() {
@@ -107,6 +116,10 @@
         return scrollDeltaX;
     }
 
+    int getScrollPhase() {
+        return scrollPhase;
+    }
+
     int getAbsX() {
         return absX;
     }
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m	Thu Oct 27 21:22:57 2016 +0000
@@ -383,7 +383,7 @@
     }
     
     static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
-    static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V");
+    static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
     jobject jEvent = JNFNewObject(env, jctor_NSEvent,
                                   [event type],
                                   [event modifierFlags],
@@ -392,7 +392,8 @@
                                   (jint)localPoint.x, (jint)localPoint.y,
                                   (jint)absP.x, (jint)absP.y,
                                   [event deltaY],
-                                  [event deltaX]);
+                                  [event deltaX],
+                                  [AWTToolkit scrollStateWithEvent: event]);
     CHECK_NULL(jEvent);
     
     static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTWindow.m	Thu Oct 27 21:22:57 2016 +0000
@@ -317,7 +317,7 @@
     [self setPropertiesForStyleBits:styleBits mask:MASK(_METHOD_PROP_BITMASK)];
 
     if (IS(self.styleBits, IS_POPUP)) {
-        [self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/]; 
+        [self.nsWindow setCollectionBehavior:(1 << 8) /*NSWindowCollectionBehaviorFullScreenAuxiliary*/];
     }
 
     return self;
@@ -330,7 +330,7 @@
 // returns id for the topmost window under mouse
 + (NSInteger) getTopmostWindowUnderMouseID {
     NSInteger result = -1;
-    
+
     NSRect screenRect = [[NSScreen mainScreen] frame];
     NSPoint nsMouseLocation = [NSEvent mouseLocation];
     CGPoint cgMouseLocation = CGPointMake(nsMouseLocation.x, screenRect.size.height - nsMouseLocation.y);
@@ -433,18 +433,18 @@
 // Tests wheather the corresponding Java paltform window is visible or not
 + (BOOL) isJavaPlatformWindowVisible:(NSWindow *)window {
     BOOL isVisible = NO;
-    
+
     if ([AWTWindow isAWTWindow:window] && [window delegate] != nil) {
         AWTWindow *awtWindow = (AWTWindow *)[window delegate];
         [AWTToolkit eventCountPlusPlus];
-        
+
         JNIEnv *env = [ThreadUtilities getJNIEnv];
         jobject platformWindow = [awtWindow.javaPlatformWindow jObjectWithEnv:env];
         if (platformWindow != NULL) {
             static JNF_MEMBER_CACHE(jm_isVisible, jc_CPlatformWindow, "isVisible", "()Z");
             isVisible = JNFCallBooleanMethod(env, platformWindow, jm_isVisible) == JNI_TRUE ? YES : NO;
             (*env)->DeleteLocalRef(env, platformWindow);
-            
+
         }
     }
     return isVisible;
@@ -577,7 +577,9 @@
 - (NSRect)windowWillUseStandardFrame:(NSWindow *)window
                         defaultFrame:(NSRect)newFrame {
 
-    return [self standardFrame];
+    return NSEqualSizes(NSZeroSize, [self standardFrame].size)
+                ? newFrame
+                : [self standardFrame];
 }
 
 // Hides/shows window's childs during iconify/de-iconify operation
@@ -1085,17 +1087,17 @@
      jdouble width, jdouble height)
 {
     JNF_COCOA_ENTER(env);
-    
+
     NSRect jrect = NSMakeRect(originX, originY, width, height);
-    
+
     NSWindow *nsWindow = OBJC(windowPtr);
     [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
-        
+
         NSRect rect = ConvertNSScreenRect(NULL, jrect);
         AWTWindow *window = (AWTWindow*)[nsWindow delegate];
         window.standardFrame = rect;
     }];
-    
+
     JNF_COCOA_EXIT(env);
 }
 
@@ -1366,7 +1368,7 @@
     } else {
         [JNFException raise:env as:kIllegalArgumentException reason:"unknown event type"];
     }
-    
+
 JNF_COCOA_EXIT(env);
 }
 
@@ -1476,7 +1478,7 @@
 
         if (CGDisplayRelease(aID) == kCGErrorSuccess) {
             NSUInteger styleMask = [AWTWindow styleMaskForStyleBits:window.styleBits];
-            [nsWindow setStyleMask:styleMask]; 
+            [nsWindow setStyleMask:styleMask];
             [nsWindow setLevel: window.preFullScreenLevel];
 
             // GraphicsDevice takes care of restoring pre full screen bounds
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.m	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.m	Thu Oct 27 21:22:57 2016 +0000
@@ -45,7 +45,7 @@
     self = [super init];
 
     if (nil != self) {
-        javaToMacKeyMap = [NSDictionary dictionaryWithObjectsAndKeys :
+        self.javaToMacKeyMap = [NSDictionary dictionaryWithObjectsAndKeys :
             [NSNumber numberWithInt : OSX_Delete], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_BACK_SPACE],
             [NSNumber numberWithInt : OSX_kVK_Tab], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_TAB],
             [NSNumber numberWithInt : OSX_kVK_Return], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ENTER],
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CTrayIcon.m	Thu Oct 27 21:22:57 2016 +0000
@@ -139,9 +139,9 @@
     jint clickCount;
 
     clickCount = [event clickCount];
-
+        
     static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
-    static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V");
+    static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDDI)V");
     jobject jEvent = JNFNewObject(env, jctor_NSEvent,
                                   [event type],
                                   [event modifierFlags],
@@ -150,7 +150,8 @@
                                   (jint)localPoint.x, (jint)localPoint.y,
                                   (jint)absP.x, (jint)absP.y,
                                   [event deltaY],
-                                  [event deltaX]);
+                                  [event deltaX],
+                                  [AWTToolkit scrollStateWithEvent: event]);
     CHECK_NULL(jEvent);
 
     static JNF_CLASS_CACHE(jc_TrayIcon, "sun/lwawt/macosx/CTrayIcon");
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m	Thu Oct 27 21:22:57 2016 +0000
@@ -66,7 +66,6 @@
 static JNF_MEMBER_CACHE(jf_ptr, sjc_CAccessible, "ptr", "J");
 static JNF_STATIC_MEMBER_CACHE(sjm_getCAccessible, sjc_CAccessible, "getCAccessible", "(Ljavax/accessibility/Accessible;)Lsun/lwawt/macosx/CAccessible;");
 
-
 static jobject sAccessibilityClass = NULL;
 
 // sAttributeNamesForRoleCache holds the names of the attributes to which each java
@@ -213,6 +212,24 @@
     NSAccessibilityPostNotification(self, NSAccessibilitySelectedChildrenChangedNotification);
 }
 
+- (void)postMenuOpened
+{
+    AWT_ASSERT_APPKIT_THREAD;
+    NSAccessibilityPostNotification(self, (NSString *)kAXMenuOpenedNotification);
+}
+
+- (void)postMenuClosed
+{
+    AWT_ASSERT_APPKIT_THREAD;
+    NSAccessibilityPostNotification(self, (NSString *)kAXMenuClosedNotification);
+}
+
+- (void)postMenuItemSelected
+{
+    AWT_ASSERT_APPKIT_THREAD;
+    NSAccessibilityPostNotification(self, (NSString *)kAXMenuItemSelectedNotification);
+}
+
 - (BOOL)isEqual:(id)anObject
 {
     if (![anObject isKindOfClass:[self class]]) return NO;
@@ -278,8 +295,7 @@
 + (jobject) getCAccessible:(jobject)jaccessible withEnv:(JNIEnv *)env {
     if (JNFIsInstanceOf(env, jaccessible, &sjc_CAccessible)) {
         return jaccessible;
-    }
-    else if (JNFIsInstanceOf(env, jaccessible, &sjc_Accessible)) {
+    } else if (JNFIsInstanceOf(env, jaccessible, &sjc_Accessible)) {
         return JNFCallStaticObjectMethod(env, sjm_getCAccessible, jaccessible);
     }
     return NULL;
@@ -368,6 +384,14 @@
     // must init freshly -alloc'd object
     [newChild initWithParent:parent withEnv:env withAccessible:jCAX withIndex:index withView:view withJavaRole:javaRole]; // must init new instance
 
+    // If creating a JPopupMenu (not a combobox popup list) need to fire menuOpened.
+    // This is the only way to know if the menu is opening; visible state change
+    // can't be caught because the listeners are not set up in time.
+    if ( [javaRole isEqualToString:@"popupmenu"] &&
+         ![[parent javaRole] isEqualToString:@"combobox"] ) {
+        [newChild postMenuOpened];
+    }
+
     // must hard retain pointer poked into Java object
     [newChild retain];
     JNFSetLongField(env, jCAX, jf_ptr, ptr_to_jlong(newChild));
@@ -634,6 +658,15 @@
                 return moreNames;
             }
         }
+        // popupmenu's return values not selected children
+        if ( [javaRole isEqualToString:@"popupmenu"] &&
+             ![[[self parent] javaRole] isEqualToString:@"combobox"] ) {
+            NSMutableArray *moreNames =
+                [[NSMutableArray alloc] initWithCapacity: [names count] + 1];
+            [moreNames addObjectsFromArray: names];
+            [moreNames addObject:NSAccessibilityValueAttribute];
+            return moreNames;
+        }
         return names;
 
     }  // end @synchronized
@@ -707,6 +740,7 @@
 
     return value;
 }
+
 - (BOOL)accessibilityIsChildrenAttributeSettable
 {
     return NO;
@@ -939,6 +973,13 @@
     if (fNSRole == nil) {
         NSString *javaRole = [self javaRole];
         fNSRole = [sRoles objectForKey:javaRole];
+        // The sRoles NSMutableDictionary maps popupmenu to Mac's popup button.
+        // JComboBox behavior currently relies on this.  However this is not the
+        // proper mapping for a JPopupMenu so fix that.
+        if ( [javaRole isEqualToString:@"popupmenu"] &&
+             ![[[self parent] javaRole] isEqualToString:@"combobox"] ) {
+             fNSRole = NSAccessibilityMenuRole;
+        }
         if (fNSRole == nil) {
             // this component has assigned itself a custom AccessibleRole not in the sRoles array
             fNSRole = javaRole;
@@ -947,6 +988,7 @@
     }
     return fNSRole;
 }
+
 - (BOOL)accessibilityIsRoleAttributeSettable
 {
     return NO;
@@ -1046,8 +1088,7 @@
 - (NSString *)accessibilitySubroleAttribute
 {
     NSString *value = nil;
-    if ([[self javaRole] isEqualToString:@"passwordtext"])
-    {
+    if ([[self javaRole] isEqualToString:@"passwordtext"]) {
         value = NSAccessibilitySecureTextFieldSubrole;
     }
     /*
@@ -1123,6 +1164,45 @@
 
     JNIEnv* env = [ThreadUtilities getJNIEnv];
 
+    // Need to handle popupmenus differently.
+    //
+    // At least for now don't handle combo box menus.
+    // This may change when later fixing issues which currently 
+    // exist for combo boxes, but for now the following is only
+    // for JPopupMenus, not for combobox menus.
+    id parent = [self parent];
+    if ( [[self javaRole] isEqualToString:@"popupmenu"] &&
+         ![[parent javaRole] isEqualToString:@"combobox"] ) {
+        NSArray *children =
+            [JavaComponentAccessibility childrenOfParent:self
+                                        withEnv:env
+                                        withChildrenCode:JAVA_AX_ALL_CHILDREN
+                                        allowIgnored:YES];
+        if ([children count] > 0) {
+            // handle case of AXMenuItem
+            // need to ask menu what is selected
+            NSArray *selectedChildrenOfMenu =
+            	[self accessibilitySelectedChildrenAttribute];
+            JavaComponentAccessibility *selectedMenuItem =
+            	[selectedChildrenOfMenu objectAtIndex:0];
+            if (selectedMenuItem != nil) {
+                jobject itemValue =
+                	JNFCallStaticObjectMethod( env,
+                                                   sjm_getAccessibleName,
+                                                   selectedMenuItem->fAccessible,
+                                                   selectedMenuItem->fComponent ); // AWT_THREADING Safe (AWTRunLoop)
+                if (itemValue == NULL) {
+                    return nil;
+                }
+                NSString* itemString = JNFJavaToNSString(env, itemValue);
+                (*env)->DeleteLocalRef(env, itemValue);
+                return itemString;
+            } else {
+            	return nil;
+            }
+        }
+    }
+
     // ask Java for the component's accessibleValue. In java, the "accessibleValue" just means a numerical value
     // a text value is taken care of in JavaTextAccessibility
 
@@ -1345,6 +1425,54 @@
 
 /*
  * Class:     sun_lwawt_macosx_CAccessible
+ * Method:    menuOpened
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuOpened
+(JNIEnv *env, jclass jklass, jlong element)
+{
+JNF_COCOA_ENTER(env);
+    [ThreadUtilities performOnMainThread:@selector(postMenuOpened)
+                     on:(JavaComponentAccessibility *)jlong_to_ptr(element)
+                     withObject:nil
+                     waitUntilDone:NO];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CAccessible
+ * Method:    menuClosed
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuClosed
+(JNIEnv *env, jclass jklass, jlong element)
+{
+JNF_COCOA_ENTER(env);
+    [ThreadUtilities performOnMainThread:@selector(postMenuClosed)
+                     on:(JavaComponentAccessibility *)jlong_to_ptr(element)
+                     withObject:nil
+                     waitUntilDone:NO];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CAccessible
+ * Method:    menuItemSelected
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_menuItemSelected
+(JNIEnv *env, jclass jklass, jlong element)
+{
+JNF_COCOA_ENTER(env);
+    [ThreadUtilities performOnMainThread:@selector(postMenuItemSelected)
+                     on:(JavaComponentAccessibility *)jlong_to_ptr(element)
+                     withObject:nil
+                     waitUntilDone:NO];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CAccessible
  * Method:    unregisterFromCocoaAXSystem
  * Signature: (I)V
  */
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.h	Thu Oct 27 21:22:57 2016 +0000
@@ -41,6 +41,7 @@
 @interface AWTToolkit : NSObject { }
 + (long) getEventCount;
 + (void) eventCountPlusPlus;
++ (jint) scrollStateWithEvent: (NSEvent*) event;
 @end
 
 /*
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m	Thu Oct 27 21:22:57 2016 +0000
@@ -43,6 +43,13 @@
 
 #import <JavaRuntimeSupport/JavaRuntimeSupport.h>
 
+// SCROLL PHASE STATE
+#define SCROLL_PHASE_UNSUPPORTED 1
+#define SCROLL_PHASE_BEGAN 2
+#define SCROLL_PHASE_CONTINUED 3
+#define SCROLL_PHASE_CANCELLED 4
+#define SCROLL_PHASE_ENDED 5
+
 int gNumberOfButtons;
 jint* gButtonDownMasks;
 
@@ -72,6 +79,23 @@
     eventCount++;
 }
 
++ (jint) scrollStateWithEvent: (NSEvent*) event {
+
+    if ([event type] != NSScrollWheel) {
+        return 0;
+    }
+    
+    NSEventPhase phase = [event phase];
+    NSEventPhase momentumPhase = [event momentumPhase];
+    
+    if (!phase && !momentumPhase) return SCROLL_PHASE_UNSUPPORTED;
+    switch (phase) {
+        case NSEventPhaseBegan: return SCROLL_PHASE_BEGAN;
+        case NSEventPhaseCancelled: return SCROLL_PHASE_CANCELLED;
+        case NSEventPhaseEnded: return SCROLL_PHASE_ENDED;
+        default: return SCROLL_PHASE_CONTINUED;
+    }
+}
 @end
 
 
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m	Thu Oct 27 21:22:57 2016 +0000
@@ -193,6 +193,44 @@
     return [sFontFamilyTable objectForKey:fontname];
 }
 
+static void addFont(CTFontUIFontType uiType, 
+                    NSMutableArray *allFonts,
+                    NSMutableDictionary* fontFamilyTable) {
+
+        CTFontRef font = CTFontCreateUIFontForLanguage(uiType, 0.0, NULL);
+        if (font == NULL) {
+            return;
+        }
+        CTFontDescriptorRef desc = CTFontCopyFontDescriptor(font);
+        if (desc == NULL) {
+            CFRelease(font);
+            return;
+        }
+        CFStringRef family = CTFontDescriptorCopyAttribute(desc, kCTFontFamilyNameAttribute);
+        if (family == NULL) {
+            CFRelease(desc);
+            CFRelease(font);
+            return;
+        }
+        CFStringRef name = CTFontDescriptorCopyAttribute(desc, kCTFontNameAttribute);
+        if (name == NULL) {
+            CFRelease(family);
+            CFRelease(desc);
+            CFRelease(font);
+            return;
+        }
+        [allFonts addObject:name];
+        [fontFamilyTable setObject:family forKey:name];
+#ifdef DEBUG
+        NSLog(@"name is : %@", (NSString*)name);
+        NSLog(@"family is : %@", (NSString*)family);
+#endif
+        CFRelease(family);
+        CFRelease(name);
+        CFRelease(desc);
+        CFRelease(font);
+}
+ 
 static NSArray*
 GetFilteredFonts()
 {
@@ -227,6 +265,16 @@
             }
         }
 
+        /*
+         * JavaFX registers these fonts and so JDK needs to do so as well.
+         * If this isn't done we will have mis-matched rendering, since
+         * although these may include fonts that are enumerated normally
+         * they also demonstrably includes fonts that are not.
+         */
+        addFont(kCTFontUIFontSystem, allFonts, fontFamilyTable);
+        addFont(kCTFontUIFontEmphasizedSystem, allFonts, fontFamilyTable);
+        addFont(kCTFontUIFontUserFixedPitch, allFonts, fontFamilyTable);
+
         sFilteredFonts = allFonts;
         sFontFamilyTable = fontFamilyTable;
     }
--- a/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -47,6 +47,10 @@
 #include <sizecalc.h>
 #import "ThreadUtilities.h"
 
+NSString* findScaledImageName(NSString *fileName,
+                              NSUInteger dotIndex,
+                              NSString *strToAppend);
+
 static NSScreen* SplashNSScreen()
 {
     return [[NSScreen screens] objectAtIndex: 0];
@@ -134,8 +138,8 @@
 }
 
 jboolean SplashGetScaledImageName(const char* jar, const char* file,
-                                    float *scaleFactor, char *scaledFile,
-                                    const size_t scaledImageLength) {
+                                  float *scaleFactor, char *scaledFile,
+                                  const size_t scaledImageLength) {
     *scaleFactor = 1;
 
     if(isSWTRunning()){
@@ -158,18 +162,14 @@
                                         options:NSBackwardsSearch];
         NSUInteger dotIndex = range.location;
         NSString *fileName2x = nil;
-        
-        if (dotIndex == NSNotFound) {
-            fileName2x = [fileName stringByAppendingString: @"@2x"];
-        } else {
-            fileName2x = [fileName substringToIndex: dotIndex];
-            fileName2x = [fileName2x stringByAppendingString: @"@2x"];
-            fileName2x = [fileName2x stringByAppendingString:
-                          [fileName substringFromIndex: dotIndex]];
+
+        fileName2x = findScaledImageName(fileName, dotIndex, @"@2x");
+        if(![[NSFileManager defaultManager]
+                fileExistsAtPath: fileName2x]) {
+            fileName2x = findScaledImageName(fileName, dotIndex, @"@200pct");
         }
-        
-        if ((fileName2x != nil) && (jar || [[NSFileManager defaultManager]
-                    fileExistsAtPath: fileName2x])){
+        if (jar || [[NSFileManager defaultManager]
+                fileExistsAtPath: fileName2x]){
             if (strlen([fileName2x UTF8String]) > scaledImageLength) {
                 [pool drain];
                 return JNI_FALSE;
@@ -458,3 +458,16 @@
     sendctl(splash, SPLASHCTL_RECONFIGURE);
 }
 
+NSString* findScaledImageName(NSString *fileName, NSUInteger dotIndex, NSString *strToAppend) {
+    NSString *fileName2x = nil;
+    if (dotIndex == NSNotFound) {
+        fileName2x = [fileName stringByAppendingString: strToAppend];
+    } else {
+        fileName2x = [fileName substringToIndex: dotIndex];
+        fileName2x = [fileName2x stringByAppendingString: strToAppend];
+        fileName2x = [fileName2x stringByAppendingString:
+                      [fileName substringFromIndex: dotIndex]];
+    }
+    return fileName2x;
+}
+
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1314,7 +1314,7 @@
         super(locale);
         this.canWriteCompressed = true;
         this.canWriteProgressive = true;
-        this.compressionTypes = new String[] {"LZW", "lzw"};
+        this.compressionTypes = new String[] {"LZW"};
         this.compressionType = compressionTypes[0];
     }
 
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifComboBoxUI.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifComboBoxUI.java	Thu Oct 27 21:22:57 2016 +0000
@@ -298,31 +298,24 @@
         public void paintIcon(Component c, Graphics g, int xo, int yo) {
             int w = getIconWidth();
             int h = getIconHeight();
-
-            g.setColor(lightShadow);
-            g.drawLine(xo, yo, xo+w-1, yo);
-            g.drawLine(xo, yo+1, xo+w-3, yo+1);
-            g.setColor(darkShadow);
-            g.drawLine(xo+w-2, yo+1, xo+w-1, yo+1);
+            int x1 = xo + w - 1;
+            int y1 = yo;
+            int x2 = xo + w / 2;
+            int y2 = yo + h - 1;
 
-            for ( int x = xo+1, y = yo+2, dx = w-6; y+1 < yo+h; y += 2 ) {
-                g.setColor(lightShadow);
-                g.drawLine(x, y,   x+1, y);
-                g.drawLine(x, y+1, x+1, y+1);
-                if ( dx > 0 ) {
-                    g.setColor(fill);
-                    g.drawLine(x+2, y,   x+1+dx, y);
-                    g.drawLine(x+2, y+1, x+1+dx, y+1);
-                }
-                g.setColor(darkShadow);
-                g.drawLine(x+dx+2, y,   x+dx+3, y);
-                g.drawLine(x+dx+2, y+1, x+dx+3, y+1);
-                x += 1;
-                dx -= 2;
-            }
+            g.setColor(fill);
+            g.fillPolygon(new int[]{xo, x1, x2}, new int[]{yo, y1, y2}, 3);
+            g.setColor(lightShadow);
+            g.drawLine(xo, yo, x1, y1);
 
+            g.drawLine(xo, yo + 1, x2, y2);
+            g.drawLine(xo, yo + 1, x1, y1 + 1);
+            g.drawLine(xo + 1, yo + 1, x2, y2 - 1);
             g.setColor(darkShadow);
-            g.drawLine(xo+(w/2), yo+h-1, xo+(w/2), yo+h-1);
+            g.drawLine(x1, y1 + 1, x2, y2);
+            g.drawLine(x1 - 1, y1 + 1, x2, y2 - 1);
+            g.drawLine(x1 - 1, y1 + 1, x1, y1 + 1); // corner
+            g.drawLine(x2, y2, x2, y2); // corner
 
         }
 
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifIconFactory.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifIconFactory.java	Thu Oct 27 21:22:57 2016 +0000
@@ -249,17 +249,11 @@
                 if (check) {
                     // draw check
                     g.setColor(foreground);
-                    g.drawLine(csize-2,1,csize-2,2);
-                    g.drawLine(csize-3,2,csize-3,3);
-                    g.drawLine(csize-4,3,csize-4,4);
-                    g.drawLine(csize-5,4,csize-5,6);
-                    g.drawLine(csize-6,5,csize-6,8);
-                    g.drawLine(csize-7,6,csize-7,10);
-                    g.drawLine(csize-8,7,csize-8,10);
-                    g.drawLine(csize-9,6,csize-9,9);
-                    g.drawLine(csize-10,5,csize-10,8);
-                    g.drawLine(csize-11,5,csize-11,7);
-                    g.drawLine(csize-12,6,csize-12,6);
+                    int[] xa = {csize - 12, csize - 8, csize - 7, csize - 4,
+                                csize - 2, csize - 2, csize - 8, csize - 10,
+                                csize - 11};
+                    int[] ya = new int[]{6, 10, 10, 4, 2, 1, 7, 5, 5};
+                    g.fillPolygon(xa, ya, 9);
                 }
                 g.translate(-x, -y);
                 g.setColor(oldColor);
@@ -301,50 +295,18 @@
 
             if (checkIn){
                 g.setColor(shadow);
-                g.drawLine(x+5,y+0,x+8,y+0);
-                g.drawLine(x+3,y+1,x+4,y+1);
-                g.drawLine(x+9,y+1,x+9,y+1);
-                g.drawLine(x+2,y+2,x+2,y+2);
-                g.drawLine(x+1,y+3,x+1,y+3);
-                g.drawLine(x,y+4,x,y+9);
-                g.drawLine(x+1,y+10,x+1,y+10);
-                g.drawLine(x+2,y+11,x+2,y+11);
+                g.drawArc(x, y, w - 1, h - 1, 45, 180);
                 g.setColor(highlight);
-                g.drawLine(x+3,y+12,x+4,y+12);
-                g.drawLine(x+5,y+13,x+8,y+13);
-                g.drawLine(x+9,y+12,x+10,y+12);
-                g.drawLine(x+11,y+11,x+11,y+11);
-                g.drawLine(x+12,y+10,x+12,y+10);
-                g.drawLine(x+13,y+9,x+13,y+4);
-                g.drawLine(x+12,y+3,x+12,y+3);
-                g.drawLine(x+11,y+2,x+11,y+2);
-                g.drawLine(x+10,y+1,x+10,y+1);
+                g.drawArc(x, y, w - 1, h - 1, 45, -180);
                 g.setColor(dot);
-                g.fillRect(x+4,y+5,6,4);
-                g.drawLine(x+5,y+4,x+8,y+4);
-                g.drawLine(x+5,y+9,x+8,y+9);
+                g.fillOval(x + 3, y + 3, 7, 7);
             }
             else {
                 g.setColor(highlight);
-                g.drawLine(x+5,y+0,x+8,y+0);
-                g.drawLine(x+3,y+1,x+4,y+1);
-                g.drawLine(x+9,y+1,x+9,y+1);
-                g.drawLine(x+2,y+2,x+2,y+2);
-                g.drawLine(x+1,y+3,x+1,y+3);
-                g.drawLine(x,y+4,x,y+9);
-                g.drawLine(x+1,y+10,x+1,y+10);
-                g.drawLine(x+2,y+11,x+2,y+11);
+                g.drawArc(x, y, w - 1, h - 1, 45, 180);
 
                 g.setColor(shadow);
-                g.drawLine(x+3,y+12,x+4,y+12);
-                g.drawLine(x+5,y+13,x+8,y+13);
-                g.drawLine(x+9,y+12,x+10,y+12);
-                g.drawLine(x+11,y+11,x+11,y+11);
-                g.drawLine(x+12,y+10,x+12,y+10);
-                g.drawLine(x+13,y+9,x+13,y+4);
-                g.drawLine(x+12,y+3,x+12,y+3);
-                g.drawLine(x+11,y+2,x+11,y+2);
-                g.drawLine(x+10,y+1,x+10,y+1);
+                g.drawArc(x, y, w - 1, h - 1, 45, -180);
 
             }
         }
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifScrollBarButton.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifScrollBarButton.java	Thu Oct 27 21:22:57 2016 +0000
@@ -117,95 +117,57 @@
 
         switch (direction) {
         case NORTH:
+            g.setColor(fill);
+            g.fillPolygon(new int[]{cx, 0, s - 1}, new int[]{0, s - 1, s - 1}, 3);
+            g.setColor(trail);
+            g.drawLine(cx, 0, s - 1, s - 2);
+            g.drawLine(0, s - 1, s - 1, s - 1);
+            g.drawLine(s - 1, s - 2, s - 1, s - 1); // corner
             g.setColor(lead);
-            g.drawLine(cx, 0, cx, 0);
-            for (int x = cx - 1, y = 1, dx = 1; y <= s - 2; y += 2) {
-                g.setColor(lead);
-                g.drawLine(x, y, x, y);
-                if (y >= (s - 2)) {
-                    g.drawLine(x, y + 1, x, y + 1);
-                }
-                g.setColor(fill);
-                g.drawLine(x + 1, y, x + dx, y);
-                if (y < (s - 2)) {
-                    g.drawLine(x, y + 1, x + dx + 1, y + 1);
-                }
-                g.setColor(trail);
-                g.drawLine(x + dx + 1, y, x + dx + 1, y);
-                if (y >= (s - 2)) {
-                    g.drawLine(x + 1, y + 1, x + dx + 1, y + 1);
-                }
-                dx += 2;
-                x -= 1;
-            }
+            g.drawLine(cx, 0, 0, s - 2);
+            g.drawLine(cx, 0, cx, 0); // corner
+            g.drawLine(0, s - 1, 0, s - 1); // corner
             break;
 
         case SOUTH:
+            g.setColor(fill);
+            g.fillPolygon(new int[]{0, s - 1, cx}, new int[]{1, 1, s}, 3);
             g.setColor(trail);
-            g.drawLine(cx, s, cx, s);
-            for (int x = cx - 1, y = s - 1, dx = 1; y >= 1; y -= 2) {
-                g.setColor(lead);
-                g.drawLine(x, y, x, y);
-                if (y <= 2) {
-                    g.drawLine(x, y - 1, x + dx + 1, y - 1);
-                }
-                g.setColor(fill);
-                g.drawLine(x + 1, y, x + dx, y);
-                if (y > 2) {
-                    g.drawLine(x, y - 1, x + dx + 1, y - 1);
-                }
-                g.setColor(trail);
-                g.drawLine(x + dx + 1, y, x + dx + 1, y);
-
-                dx += 2;
-                x -= 1;
-            }
+            g.drawLine(s - 1, 2, cx, s);
+            g.drawLine(s - 1, 2, s - 1, 2); // corner
+            g.setColor(lead);
+            g.drawLine(0, 2, cx, s);
+            g.drawLine(0, 1, s - 1, 1);
+            g.drawLine(0, 1, 0, 2);
+            g.setColor(trail);
+            g.drawLine(cx, s, cx, s); // corner
             break;
 
         case EAST:
+            g.setColor(fill);
+            g.fillPolygon(new int[]{1, s, 1}, new int[]{0, cy, s}, 3);
+            g.setColor(trail);
+            g.drawLine(1, s, s, cy);
+            g.drawLine(2, s, 2, s); // corner
             g.setColor(lead);
+            g.drawLine(1, 0, 1, s);
+            g.drawLine(2, 0, s, cy);
+            g.drawLine(2, 0, 2, 0); // corner
             g.drawLine(s, cy, s, cy);
-            for (int y = cy - 1, x = s - 1, dy = 1; x >= 1; x -= 2) {
-                g.setColor(lead);
-                g.drawLine(x, y, x, y);
-                if (x <= 2) {
-                    g.drawLine(x - 1, y, x - 1, y + dy + 1);
-                }
-                g.setColor(fill);
-                g.drawLine(x, y + 1, x, y + dy);
-                if (x > 2) {
-                    g.drawLine(x - 1, y, x - 1, y + dy + 1);
-                }
-                g.setColor(trail);
-                g.drawLine(x, y + dy + 1, x, y + dy + 1);
-
-                dy += 2;
-                y -= 1;
-            }
             break;
 
         case WEST:
+            g.setColor(fill);
+            g.fillPolygon(new int[]{0, s - 1, s - 1}, new int[]{cy, 0, s}, 3);
+            g.drawLine(s - 1, 0, s - 1, s);
             g.setColor(trail);
-            g.drawLine(0, cy, 0, cy);
-            for (int y = cy - 1, x = 1, dy = 1; x <= s - 2; x += 2) {
-                g.setColor(lead);
-                g.drawLine(x, y, x, y);
-                if (x >= (s - 2)) {
-                    g.drawLine(x + 1, y, x + 1, y);
-                }
-                g.setColor(fill);
-                g.drawLine(x, y + 1, x, y + dy);
-                if (x < (s - 2)) {
-                    g.drawLine(x + 1, y, x + 1, y + dy + 1);
-                }
-                g.setColor(trail);
-                g.drawLine(x, y + dy + 1, x, y + dy + 1);
-                if (x >= (s - 2)) {
-                    g.drawLine(x + 1, y + 1, x + 1, y + dy + 1);
-                }
-                dy += 2;
-                y -= 1;
-            }
+            g.drawLine(0, cy, s - 1, s);
+            g.drawLine(s - 1, 0, s - 1, s);
+            g.setColor(lead);
+            g.drawLine(0, cy, s - 2, 0);
+            g.drawLine(s - 2, 0, s - 1, 0); // corner
+            g.setColor(trail);
+            g.drawLine(0, cy, 0, cy); // corner
             break;
         }
     }
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AlawCodec.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -30,25 +30,26 @@
 import java.util.Vector;
 
 import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
 import javax.sound.sampled.AudioInputStream;
 import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.spi.FormatConversionProvider;
 
 /**
  * A-law encodes linear data, and decodes a-law data to linear data.
  *
  * @author Kara Kytle
  */
-public final class AlawCodec extends SunCodec {
+public final class AlawCodec extends FormatConversionProvider {
 
     /* Tables used for A-law decoding */
 
     private static final byte[] ALAW_TABH = new byte[256];
     private static final byte[] ALAW_TABL = new byte[256];
 
-    private static final AudioFormat.Encoding[] alawEncodings = { AudioFormat.Encoding.ALAW, AudioFormat.Encoding.PCM_SIGNED };
-
-    private static final short seg_end [] = {0xFF, 0x1FF, 0x3FF,
-                                             0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
+    private static final short seg_end[] = {
+            0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
+    };
 
     /**
      * Initializes the decode tables.
@@ -73,13 +74,14 @@
         }
     }
 
+    @Override
+    public AudioFormat.Encoding[] getSourceEncodings() {
+        return new Encoding[]{Encoding.ALAW, Encoding.PCM_SIGNED};
+    }
 
-    /**
-     * Constructs a new ALAW codec object.
-     */
-    public AlawCodec() {
-
-        super(alawEncodings, alawEncodings);
+    @Override
+    public AudioFormat.Encoding[] getTargetEncodings() {
+        return getSourceEncodings();
     }
 
     @Override
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatFormatConverter.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -562,8 +562,7 @@
 
     @Override
     public Encoding[] getTargetEncodings() {
-        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED,
-                Encoding.PCM_FLOAT };
+        return getSourceEncodings();
     }
 
     @Override
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -1034,6 +1034,7 @@
 
             // $$fb part of fix for 4679187: Clip.open() throws unexpected Exceptions
             Toolkit.isFullySpecifiedAudioFormat(format);
+            Toolkit.validateBuffer(format.getFrameSize(), bufferSize);
 
             byte[] newData = new byte[bufferSize];
             System.arraycopy(data, offset, newData, 0, bufferSize);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/PCMtoPCMCodec.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -30,32 +30,26 @@
 import java.util.Vector;
 
 import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
 import javax.sound.sampled.AudioInputStream;
 import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.spi.FormatConversionProvider;
 
 /**
  * Converts among signed/unsigned and little/big endianness of sampled.
  *
  * @author Jan Borgersen
  */
-public final class PCMtoPCMCodec extends SunCodec {
-
-    private static final AudioFormat.Encoding[] inputEncodings = {
-        AudioFormat.Encoding.PCM_SIGNED,
-        AudioFormat.Encoding.PCM_UNSIGNED,
-    };
+public final class PCMtoPCMCodec extends FormatConversionProvider {
 
-    private static final AudioFormat.Encoding[] outputEncodings = {
-        AudioFormat.Encoding.PCM_SIGNED,
-        AudioFormat.Encoding.PCM_UNSIGNED,
-    };
+    @Override
+    public AudioFormat.Encoding[] getSourceEncodings() {
+        return new Encoding[]{Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED};
+    }
 
-    /**
-     * Constructs a new PCMtoPCM codec object.
-     */
-    public PCMtoPCMCodec() {
-
-        super( inputEncodings, outputEncodings);
+    @Override
+    public AudioFormat.Encoding[] getTargetEncodings() {
+        return getSourceEncodings();
     }
 
     @Override
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftMixingClip.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/SoftMixingClip.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -363,9 +363,7 @@
             if (AudioFloatConverter.getConverter(format) == null)
                 throw new IllegalArgumentException("Invalid format : "
                         + format.toString());
-            if (bufferSize % format.getFrameSize() != 0)
-                throw new IllegalArgumentException(
-                        "Buffer size does not represent an integral number of sample frames!");
+            Toolkit.validateBuffer(format.getFrameSize(), bufferSize);
 
             if (data != null) {
                 this.data = Arrays.copyOf(data, data.length);
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/SunCodec.java	Thu Oct 27 16:29:00 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.media.sound;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.spi.FormatConversionProvider;
-
-/**
- * A codec can encode and/or decode audio data.  It provides an
- * AudioInputStream from which processed data may be read.
- * <p>
- * Its input format represents the format of the incoming
- * audio data, or the format of the data in the underlying stream.
- * <p>
- * Its output format represents the format of the processed, outgoing
- * audio data.  This is the format of the data which may be read from
- * the filtered stream.
- *
- * @author Kara Kytle
- */
-abstract class SunCodec extends FormatConversionProvider {
-
-    private final AudioFormat.Encoding[] inputEncodings;
-    private final AudioFormat.Encoding[] outputEncodings;
-
-    /**
-     * Constructs a new codec object.
-     */
-    SunCodec(final AudioFormat.Encoding[] inputEncodings,
-             final AudioFormat.Encoding[] outputEncodings) {
-        this.inputEncodings = inputEncodings;
-        this.outputEncodings = outputEncodings;
-    }
-
-    @Override
-    public final AudioFormat.Encoding[] getSourceEncodings() {
-        AudioFormat.Encoding[] encodings = new AudioFormat.Encoding[inputEncodings.length];
-        System.arraycopy(inputEncodings, 0, encodings, 0, inputEncodings.length);
-        return encodings;
-    }
-
-    @Override
-    public final AudioFormat.Encoding[] getTargetEncodings() {
-        AudioFormat.Encoding[] encodings = new AudioFormat.Encoding[outputEncodings.length];
-        System.arraycopy(outputEncodings, 0, encodings, 0, outputEncodings.length);
-        return encodings;
-    }
-}
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/Toolkit.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/Toolkit.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -149,6 +149,20 @@
         return (long) (((double) frames) / format.getFrameRate() * 1000000.0d);
     }
 
+    /**
+     * Throws an exception if the buffer size does not represent an integral
+     * number of sample frames.
+     */
+    static void validateBuffer(final int frameSize, final int bufferSize) {
+        if (bufferSize % frameSize == 0) {
+            return;
+        }
+        throw new IllegalArgumentException(String.format(
+                "Buffer size (%d) does not represent an integral number of "
+                        + "sample frames (%d)", bufferSize, frameSize));
+    }
+
+
     static void isFullySpecifiedAudioFormat(AudioFormat format) {
         if (!format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)
             && !format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED)
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/UlawCodec.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/UlawCodec.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -30,26 +30,26 @@
 import java.util.Vector;
 
 import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
 import javax.sound.sampled.AudioInputStream;
 import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.spi.FormatConversionProvider;
 
 /**
  * U-law encodes linear data, and decodes u-law data to linear data.
  *
  * @author Kara Kytle
  */
-public final class UlawCodec extends SunCodec {
+public final class UlawCodec extends FormatConversionProvider {
 
     /* Tables used for U-law decoding */
 
     private static final byte[] ULAW_TABH = new byte[256];
     private static final byte[] ULAW_TABL = new byte[256];
 
-    private static final AudioFormat.Encoding[] ulawEncodings = {AudioFormat.Encoding.ULAW,
-                                                                 AudioFormat.Encoding.PCM_SIGNED};
-
-    private static final short seg_end [] = {0xFF, 0x1FF, 0x3FF,
-                                             0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
+    private static final short seg_end[] = {
+            0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
+    };
 
     /**
      * Initializes the decode tables.
@@ -69,11 +69,14 @@
         }
     }
 
-    /**
-     * Constructs a new ULAW codec object.
-     */
-    public UlawCodec() {
-        super(ulawEncodings, ulawEncodings);
+    @Override
+    public AudioFormat.Encoding[] getSourceEncodings() {
+        return new Encoding[]{Encoding.ULAW, Encoding.PCM_SIGNED};
+    }
+
+    @Override
+    public AudioFormat.Encoding[] getTargetEncodings() {
+        return getSourceEncodings();
     }
 
     @Override
--- a/jdk/src/java.desktop/share/classes/java/awt/Component.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java	Thu Oct 27 21:22:57 2016 +0000
@@ -851,8 +851,8 @@
             {
                 comp.setGraphicsConfiguration(gc);
             }
-            public boolean requestFocus(Component comp, FocusEvent.Cause cause) {
-                return comp.requestFocus(cause);
+            public void requestFocus(Component comp, FocusEvent.Cause cause) {
+                comp.requestFocus(cause);
             }
             public boolean canBeFocusOwner(Component comp) {
                 return comp.canBeFocusOwner();
@@ -7511,8 +7511,51 @@
         requestFocusHelper(false, true);
     }
 
-    boolean requestFocus(FocusEvent.Cause cause) {
-        return requestFocusHelper(false, true, cause);
+
+    /**
+     * Requests by the reason of {@code cause} that this Component get the input
+     * focus, and that this Component's top-level ancestor become the
+     * focused Window. This component must be displayable, focusable, visible
+     * and all of its ancestors (with the exception of the top-level Window)
+     * must be visible for the request to be granted. Every effort will be
+     * made to honor the request; however, in some cases it may be
+     * impossible to do so. Developers must never assume that this
+     * Component is the focus owner until this Component receives a
+     * FOCUS_GAINED event.
+     * <p>
+     * The focus request effect may also depend on the provided
+     * cause value. If this request is succeed the {@code FocusEvent}
+     * generated in the result will receive the cause value specified as the
+     * argument of method. If this request is denied because this Component's
+     * top-level Window cannot become the focused Window, the request will be
+     * remembered and will be granted when the Window is later focused by the
+     * user.
+     * <p>
+     * This method cannot be used to set the focus owner to no Component at
+     * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}
+     * instead.
+     * <p>
+     * Because the focus behavior of this method is platform-dependent,
+     * developers are strongly encouraged to use
+     * {@code requestFocusInWindow(FocusEvent.Cause)} when possible.
+     *
+     * <p>Note: Not all focus transfers result from invoking this method. As
+     * such, a component may receive focus without this or any of the other
+     * {@code requestFocus} methods of {@code Component} being invoked.
+     *
+     * @param  cause the cause why the focus is requested
+     * @see FocusEvent
+     * @see FocusEvent.Cause
+     * @see #requestFocusInWindow(FocusEvent.Cause)
+     * @see java.awt.event.FocusEvent
+     * @see #addFocusListener
+     * @see #isFocusable
+     * @see #isDisplayable
+     * @see KeyboardFocusManager#clearGlobalFocusOwner
+     * @since 9
+     */
+    public void requestFocus(FocusEvent.Cause cause) {
+        requestFocusHelper(false, true, cause);
     }
 
     /**
@@ -7578,9 +7621,77 @@
         return requestFocusHelper(temporary, true);
     }
 
-    boolean requestFocus(boolean temporary, FocusEvent.Cause cause) {
+    /**
+     * Requests by the reason of {@code cause} that this {@code Component} get
+     * the input focus, and that this {@code Component}'s top-level ancestor
+     * become the focused {@code Window}. This component must be
+     * displayable, focusable, visible and all of its ancestors (with
+     * the exception of the top-level Window) must be visible for the
+     * request to be granted. Every effort will be made to honor the
+     * request; however, in some cases it may be impossible to do
+     * so. Developers must never assume that this component is the
+     * focus owner until this component receives a FOCUS_GAINED
+     * event. If this request is denied because this component's
+     * top-level window cannot become the focused window, the request
+     * will be remembered and will be granted when the window is later
+     * focused by the user.
+     * <p>
+     * This method returns a boolean value. If {@code false} is returned,
+     * the request is <b>guaranteed to fail</b>. If {@code true} is
+     * returned, the request will succeed <b>unless</b> it is vetoed, or an
+     * extraordinary event, such as disposal of the component's peer, occurs
+     * before the request can be granted by the native windowing system. Again,
+     * while a return value of {@code true} indicates that the request is
+     * likely to succeed, developers must never assume that this component is
+     * the focus owner until this component receives a FOCUS_GAINED event.
+     * <p>
+     * The focus request effect may also depend on the provided
+     * cause value. If this request is succeed the {FocusEvent}
+     * generated in the result will receive the cause value specified as the
+     * argument of the method.
+     * <p>
+     * This method cannot be used to set the focus owner to no component at
+     * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner}
+     * instead.
+     * <p>
+     * Because the focus behavior of this method is platform-dependent,
+     * developers are strongly encouraged to use
+     * {@code requestFocusInWindow} when possible.
+     * <p>
+     * Every effort will be made to ensure that {@code FocusEvent}s
+     * generated as a
+     * result of this request will have the specified temporary value. However,
+     * because specifying an arbitrary temporary state may not be implementable
+     * on all native windowing systems, correct behavior for this method can be
+     * guaranteed only for lightweight {@code Component}s.
+     * This method is not intended
+     * for general use, but exists instead as a hook for lightweight component
+     * libraries, such as Swing.
+     * <p>
+     * Note: Not all focus transfers result from invoking this method. As
+     * such, a component may receive focus without this or any of the other
+     * {@code requestFocus} methods of {@code Component} being invoked.
+     *
+     * @param temporary true if the focus change is temporary,
+     *        such as when the window loses the focus; for
+     *        more information on temporary focus changes see the
+     *<a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
+     *
+     * @param  cause the cause why the focus is requested
+     * @return {@code false} if the focus change request is guaranteed to
+     *         fail; {@code true} if it is likely to succeed
+     * @see FocusEvent
+     * @see FocusEvent.Cause
+     * @see #addFocusListener
+     * @see #isFocusable
+     * @see #isDisplayable
+     * @see KeyboardFocusManager#clearGlobalFocusOwner
+     * @since 9
+     */
+    protected boolean requestFocus(boolean temporary, FocusEvent.Cause cause) {
         return requestFocusHelper(temporary, true, cause);
     }
+
     /**
      * Requests that this Component get the input focus, if this
      * Component's top-level ancestor is already the focused
@@ -7629,7 +7740,59 @@
         return requestFocusHelper(false, false);
     }
 
-    boolean requestFocusInWindow(FocusEvent.Cause cause) {
+    /**
+     * Requests by the reason of {@code cause} that this Component get the input
+     * focus, if this Component's top-level ancestor is already the focused
+     * Window. This component must be displayable, focusable, visible
+     * and all of its ancestors (with the exception of the top-level
+     * Window) must be visible for the request to be granted. Every
+     * effort will be made to honor the request; however, in some
+     * cases it may be impossible to do so. Developers must never
+     * assume that this Component is the focus owner until this
+     * Component receives a FOCUS_GAINED event.
+     * <p>
+     * This method returns a boolean value. If {@code false} is returned,
+     * the request is <b>guaranteed to fail</b>. If {@code true} is
+     * returned, the request will succeed <b>unless</b> it is vetoed, or an
+     * extraordinary event, such as disposal of the Component's peer, occurs
+     * before the request can be granted by the native windowing system. Again,
+     * while a return value of {@code true} indicates that the request is
+     * likely to succeed, developers must never assume that this Component is
+     * the focus owner until this Component receives a FOCUS_GAINED event.
+     * <p>
+     * The focus request effect may also depend on the provided
+     * cause value. If this request is succeed the {@code FocusEvent}
+     * generated in the result will receive the cause value specified as the
+     * argument of the method.
+     * <p>
+     * This method cannot be used to set the focus owner to no Component at
+     * all. Use {@code KeyboardFocusManager.clearGlobalFocusOwner()}
+     * instead.
+     * <p>
+     * The focus behavior of this method can be implemented uniformly across
+     * platforms, and thus developers are strongly encouraged to use this
+     * method over {@code requestFocus(FocusEvent.Cause)} when possible.
+     * Code which relies on {@code requestFocus(FocusEvent.Cause)} may exhibit
+     * different focus behavior on different platforms.
+     *
+     * <p>Note: Not all focus transfers result from invoking this method. As
+     * such, a component may receive focus without this or any of the other
+     * {@code requestFocus} methods of {@code Component} being invoked.
+     *
+     * @param  cause the cause why the focus is requested
+     * @return {@code false} if the focus change request is guaranteed to
+     *         fail; {@code true} if it is likely to succeed
+     * @see #requestFocus(FocusEvent.Cause)
+     * @see FocusEvent
+     * @see FocusEvent.Cause
+     * @see java.awt.event.FocusEvent
+     * @see #addFocusListener
+     * @see #isFocusable
+     * @see #isDisplayable
+     * @see KeyboardFocusManager#clearGlobalFocusOwner
+     * @since 9
+     */
+    public boolean requestFocusInWindow(FocusEvent.Cause cause) {
         return requestFocusHelper(false, false, cause);
     }
 
--- a/jdk/src/java.desktop/share/classes/java/awt/DisplayMode.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/DisplayMode.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -142,6 +142,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public boolean equals(Object dm) {
         if (dm instanceof DisplayMode) {
             return equals((DisplayMode)dm);
@@ -153,9 +154,20 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public int hashCode() {
         return getWidth() + getHeight() + getBitDepth() * 7
             + getRefreshRate() * 13;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString() {
+        return getWidth() + "x" + getHeight() + "x" +
+               (getBitDepth() > 0 ? getBitDepth() + "bpp": "[Multi depth]")
+               + "@" + (getRefreshRate() > 0 ? getRefreshRate() + "Hz" :
+               "[Unknown refresh rate]");
+    }
 }
--- a/jdk/src/java.desktop/share/classes/java/awt/Font.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/Font.java	Thu Oct 27 21:22:57 2016 +0000
@@ -154,6 +154,10 @@
  * associated with a font face, each differing in size, style, transform
  * and font features.
  * <p>
+ * Glyphs may not always be rendered with the requested properties (e.g, font
+ * and style) due to platform limitations such as the absence of suitable
+ * platform fonts to implement a logical font.
+ * <p>
  * The {@link GraphicsEnvironment#getAllFonts() getAllFonts} method
  * of the {@code GraphicsEnvironment} class returns an
  * array of all font faces available in the system. These font faces are
--- a/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java	Thu Oct 27 21:22:57 2016 +0000
@@ -65,6 +65,16 @@
  * <PRE>
  * java -splash:filename.gif Test
  * </PRE>
+ * HiDPI scaled image is also supported.
+ * Unscaled image name i.e. filename.gif should be passed in
+ * {@code manifest.mf}/{@code -splash:} option for all image types irrespective of
+ * HiDPI and Non-HiDPI.
+ * Following is the naming convention for scaled images.
+ * Screen scale 1.25: filename@125pct.gif
+ * Screen scale 1.50: filename@150pct.gif
+ * Screen scale 2:    filename@200pct.gif and filename@2x.gif both are supported
+ * Screen scale 2.50: filename@250pct.gif
+ * Screen scale 3:    filename@300pct.gif and filename@3x.gif both are supported
  * The command line interface has higher precedence over the manifest
  * setting.
  * <p>
--- a/jdk/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadataNode.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadataNode.java	Thu Oct 27 21:22:57 2016 +0000
@@ -122,7 +122,7 @@
     }
 
     public Node item(int index) {
-        if (index < 0 || index > nodes.size()) {
+        if (index < 0 || index >= nodes.size()) {
             return null;
         }
         return nodes.get(index);
@@ -882,7 +882,7 @@
     }
 
     private void getElementsByTagName(String name, List<Node> l) {
-        if (nodeName.equals(name)) {
+        if (nodeName.equals(name) || "*".equals(name)) {
             l.add(this);
         }
 
--- a/jdk/src/java.desktop/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/sound/sampled/spi/FormatConversionProvider.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 
 package javax.sound.sampled.spi;
 
-import java.util.Objects;
+import java.util.stream.Stream;
 
 import javax.sound.sampled.AudioFormat;
 import javax.sound.sampled.AudioInputStream;
@@ -81,16 +81,8 @@
      *         {@code false}
      * @throws NullPointerException if {@code sourceEncoding} is {@code null}
      */
-    public boolean isSourceEncodingSupported(Encoding sourceEncoding) {
-        Objects.requireNonNull(sourceEncoding);
-        Encoding sourceEncodings[] = getSourceEncodings();
-
-        for(int i=0; i<sourceEncodings.length; i++) {
-            if( sourceEncoding.equals( sourceEncodings[i]) ) {
-                return true;
-            }
-        }
-        return false;
+    public boolean isSourceEncodingSupported(final Encoding sourceEncoding) {
+        return Stream.of(getSourceEncodings()).anyMatch(sourceEncoding::equals);
     }
 
     /**
@@ -103,16 +95,8 @@
      *         {@code false}
      * @throws NullPointerException if {@code targetEncoding} is {@code null}
      */
-    public boolean isTargetEncodingSupported(Encoding targetEncoding) {
-        Objects.requireNonNull(targetEncoding);
-        Encoding targetEncodings[] = getTargetEncodings();
-
-        for(int i=0; i<targetEncodings.length; i++) {
-            if( targetEncoding.equals( targetEncodings[i]) ) {
-                return true;
-            }
-        }
-        return false;
+    public boolean isTargetEncodingSupported(final Encoding targetEncoding) {
+        return Stream.of(getTargetEncodings()).anyMatch(targetEncoding::equals);
     }
 
     /**
@@ -137,17 +121,10 @@
      * @throws NullPointerException if {@code targetEncoding} or
      *         {@code sourceFormat} are {@code null}
      */
-    public boolean isConversionSupported(Encoding targetEncoding,
-                                         AudioFormat sourceFormat) {
-        Objects.requireNonNull(targetEncoding);
-        Encoding targetEncodings[] = getTargetEncodings(sourceFormat);
-
-        for(int i=0; i<targetEncodings.length; i++) {
-            if( targetEncoding.equals( targetEncodings[i]) ) {
-                return true;
-            }
-        }
-        return false;
+    public boolean isConversionSupported(final Encoding targetEncoding,
+                                         final AudioFormat sourceFormat) {
+        return Stream.of(getTargetEncodings(sourceFormat))
+                     .anyMatch(targetEncoding::equals);
     }
 
     /**
@@ -175,17 +152,11 @@
      * @throws NullPointerException if {@code targetFormat} or
      *         {@code sourceFormat} are {@code null}
      */
-    public boolean isConversionSupported(AudioFormat targetFormat,
-                                         AudioFormat sourceFormat) {
-
-        AudioFormat targetFormats[] = getTargetFormats( targetFormat.getEncoding(), sourceFormat );
-
-        for(int i=0; i<targetFormats.length; i++) {
-            if( targetFormat.matches( targetFormats[i] ) ) {
-                return true;
-            }
-        }
-        return false;
+    public boolean isConversionSupported(final AudioFormat targetFormat,
+                                         final AudioFormat sourceFormat) {
+        final Encoding targetEncoding = targetFormat.getEncoding();
+        return Stream.of(getTargetFormats(targetEncoding, sourceFormat))
+                     .anyMatch(targetFormat::matches);
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/TextUI.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/TextUI.java	Thu Oct 27 21:22:57 2016 +0000
@@ -46,7 +46,11 @@
      * @return the coordinates as a {@code Rectangle}
      * @exception BadLocationException  if the given position does not
      *   represent a valid location in the associated document
+     *
+     * @deprecated replaced by
+     *     {@link #modelToView2D(JTextComponent, int, Position.Bias)}
      */
+    @Deprecated(since = "9")
     public abstract Rectangle modelToView(JTextComponent t, int pos) throws BadLocationException;
 
     /**
@@ -59,7 +63,11 @@
      * @return the coordinates as a {@code Rectangle}
      * @exception BadLocationException  if the given position does not
      *   represent a valid location in the associated document
+     *
+     * @deprecated replaced by
+     *     {@link #modelToView2D(JTextComponent, int, Position.Bias)}
      */
+    @Deprecated(since = "9")
     public abstract Rectangle modelToView(JTextComponent t, int pos, Position.Bias bias) throws BadLocationException;
 
     /**
@@ -92,7 +100,11 @@
      *   should be in the same coordinate system as the mouse
      *   events.
      * @return the offset from the start of the document &gt;= 0
+     *
+     * @deprecated replaced by
+     *     {@link #viewToModel2D(JTextComponent, Point2D, Position.Bias[])}
      */
+    @Deprecated(since = "9")
     public abstract int viewToModel(JTextComponent t, Point pt);
 
     /**
@@ -110,7 +122,11 @@
      *
      * @return the location within the model that best represents the
      *         given point in the view &gt;= 0
+     *
+     * @deprecated replaced by
+     *     {@link #viewToModel2D(JTextComponent, Point2D, Position.Bias[])}
      */
+    @Deprecated(since = "9")
     public abstract int viewToModel(JTextComponent t, Point pt,
                                     Position.Bias[] biasReturn);
 
@@ -222,7 +238,11 @@
      * @return a {@code String} containing the tooltip
      * @see javax.swing.text.JTextComponent#getToolTipText
      * @since 1.4
+     *
+     * @deprecated replaced by
+     *     {@link #getToolTipText2D(JTextComponent, Point2D)}
      */
+    @Deprecated(since = "9")
     public String getToolTipText(JTextComponent t, Point pt) {
         return null;
     }
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java	Thu Oct 27 21:22:57 2016 +0000
@@ -28,6 +28,8 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.datatransfer.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
 import java.awt.im.InputContext;
 import java.beans.*;
 import java.io.*;
@@ -1047,7 +1049,12 @@
      * @exception BadLocationException  if the given position does not
      *   represent a valid location in the associated document
      * @see TextUI#modelToView
+     *
+     * @deprecated replaced by
+     *     {@link #modelToView2D(JTextComponent, int, Position.Bias)}
      */
+    @Deprecated(since = "9")
+    @Override
     public Rectangle modelToView(JTextComponent tc, int pos) throws BadLocationException {
         return modelToView(tc, pos, Position.Bias.Forward);
     }
@@ -1064,8 +1071,30 @@
      * @exception BadLocationException  if the given position does not
      *   represent a valid location in the associated document
      * @see TextUI#modelToView
+     *
+     * @deprecated replaced by
+     *     {@link #modelToView2D(JTextComponent, int, Position.Bias)}
      */
-    public Rectangle modelToView(JTextComponent tc, int pos, Position.Bias bias) throws BadLocationException {
+    @Deprecated(since = "9")
+    @Override
+    public Rectangle modelToView(JTextComponent tc, int pos, Position.Bias bias)
+            throws BadLocationException
+    {
+        return (Rectangle) modelToView(tc, pos, bias, false);
+    }
+
+    @Override
+    public Rectangle2D modelToView2D(JTextComponent tc, int pos,
+                                     Position.Bias bias)
+            throws BadLocationException
+    {
+        return modelToView(tc, pos, bias, true);
+    }
+
+    private Rectangle2D modelToView(JTextComponent tc, int pos,
+                                    Position.Bias bias, boolean useFPAPI)
+            throws BadLocationException
+    {
         Document doc = editor.getDocument();
         if (doc instanceof AbstractDocument) {
             ((AbstractDocument)doc).readLock();
@@ -1076,7 +1105,7 @@
                 rootView.setSize(alloc.width, alloc.height);
                 Shape s = rootView.modelToView(pos, alloc, bias);
                 if (s != null) {
-                  return s.getBounds();
+                    return useFPAPI ? s.getBounds2D() : s.getBounds();
                 }
             }
         } finally {
@@ -1099,7 +1128,12 @@
      * @return the offset from the start of the document &gt;= 0,
      *   -1 if not painted
      * @see TextUI#viewToModel
+     *
+     * @deprecated replaced by
+     *     {@link #viewToModel2D(JTextComponent, Point2D, Position.Bias[])}
      */
+    @Deprecated(since = "9")
+    @Override
     public int viewToModel(JTextComponent tc, Point pt) {
         return viewToModel(tc, pt, discardBias);
     }
@@ -1116,9 +1150,25 @@
      * @return the offset from the start of the document &gt;= 0,
      *   -1 if the component doesn't yet have a positive size.
      * @see TextUI#viewToModel
+     *
+     * @deprecated replaced by
+     *     {@link #viewToModel2D(JTextComponent, Point2D, Position.Bias[])}
      */
+    @Deprecated(since = "9")
+    @Override
     public int viewToModel(JTextComponent tc, Point pt,
                            Position.Bias[] biasReturn) {
+        return viewToModel(tc, pt.x, pt.y, biasReturn);
+    }
+
+    @Override
+    public int viewToModel2D(JTextComponent tc, Point2D pt,
+                             Position.Bias[] biasReturn) {
+        return viewToModel(tc, (float) pt.getX(), (float) pt.getY(), biasReturn);
+    }
+
+    private int viewToModel(JTextComponent tc, float x, float y,
+                            Position.Bias[] biasReturn) {
         int offs = -1;
         Document doc = editor.getDocument();
         if (doc instanceof AbstractDocument) {
@@ -1128,7 +1178,7 @@
             Rectangle alloc = getVisibleEditorRect();
             if (alloc != null) {
                 rootView.setSize(alloc.width, alloc.height);
-                offs = rootView.viewToModel(pt.x, pt.y, alloc, biasReturn);
+                offs = rootView.viewToModel(x, y, alloc, biasReturn);
             }
         } finally {
             if (doc instanceof AbstractDocument) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/multi/MultiTextUI.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/multi/MultiTextUI.java	Thu Oct 27 21:22:57 2016 +0000
@@ -38,6 +38,8 @@
 import javax.swing.JComponent;
 import java.awt.Graphics;
 import java.awt.Dimension;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
 import javax.accessibility.Accessible;
 
 /**
@@ -97,7 +99,11 @@
      *
      * @return the value obtained from the first UI, which is
      * the UI obtained from the default <code>LookAndFeel</code>
+     *
+     * @deprecated replaced by
+     *     {@link #modelToView2D(JTextComponent, int, Position.Bias)}
      */
+    @Deprecated(since = "9")
     public Rectangle modelToView(JTextComponent a, int b)
             throws BadLocationException {
         Rectangle returnValue =
@@ -113,7 +119,12 @@
      *
      * @return the value obtained from the first UI, which is
      * the UI obtained from the default <code>LookAndFeel</code>
+     *
+     * @deprecated replaced by
+     *     {@link #modelToView2D(JTextComponent, int, Position.Bias)}
      */
+    @Deprecated(since = "9")
+    @Override
     public Rectangle modelToView(JTextComponent a, int b, Position.Bias c)
             throws BadLocationException {
         Rectangle returnValue =
@@ -124,12 +135,24 @@
         return returnValue;
     }
 
+    @Override
+    public Rectangle2D modelToView2D(JTextComponent a, int b, Position.Bias c) throws BadLocationException {
+        Rectangle2D returnValue =
+            ((TextUI) (uis.elementAt(0))).modelToView2D(a,b,c);
+        for (int i = 1; i < uis.size(); i++) {
+            ((TextUI) (uis.elementAt(i))).modelToView2D(a,b,c);
+        }
+        return returnValue;
+    }
+
     /**
      * Invokes the <code>viewToModel</code> method on each UI handled by this object.
      *
      * @return the value obtained from the first UI, which is
      * the UI obtained from the default <code>LookAndFeel</code>
      */
+    @Deprecated(since = "9")
+    @Override
     public int viewToModel(JTextComponent a, Point b) {
         int returnValue =
             ((TextUI) (uis.elementAt(0))).viewToModel(a,b);
@@ -145,6 +168,8 @@
      * @return the value obtained from the first UI, which is
      * the UI obtained from the default <code>LookAndFeel</code>
      */
+    @Deprecated(since = "9")
+    @Override
     public int viewToModel(JTextComponent a, Point b, Position.Bias[] c) {
         int returnValue =
             ((TextUI) (uis.elementAt(0))).viewToModel(a,b,c);
@@ -154,6 +179,16 @@
         return returnValue;
     }
 
+    @Override
+    public int viewToModel2D(JTextComponent a, Point2D b, Position.Bias[] c) {
+        int returnValue =
+            ((TextUI) (uis.elementAt(0))).viewToModel2D(a,b,c);
+        for (int i = 1; i < uis.size(); i++) {
+            ((TextUI) (uis.elementAt(i))).viewToModel2D(a,b,c);
+        }
+        return returnValue;
+    }
+
     /**
      * Invokes the <code>getNextVisualPositionFrom</code> method on each UI handled by this object.
      *
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphPainter1.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphPainter1.java	Thu Oct 27 21:22:57 2016 +0000
@@ -98,26 +98,27 @@
         Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
 
         // determine the x coordinate to render the glyphs
-        int x = alloc.x;
+        float x = alloc.x;
         int p = v.getStartOffset();
         int[] justificationData = getJustificationData(v);
         if (p != p0) {
             text = v.getText(p, p0);
-            int width = Utilities.getTabbedTextWidth(v, text, metrics, x, expander, p,
-                                                     justificationData);
+            float width = Utilities.getTabbedTextWidth(v, text, metrics, x,
+                                                       expander, p,
+                                                       justificationData);
             x += width;
             SegmentCache.releaseSharedSegment(text);
         }
 
         // determine the y coordinate to render the glyphs
-        int y = alloc.y + metrics.getHeight() - metrics.getDescent();
+        float y = alloc.y + metrics.getHeight() - metrics.getDescent();
 
         // render the glyphs
         text = v.getText(p0, p1);
         g.setFont(metrics.getFont());
 
         Utilities.drawTabbedText(v, text, x, y, g, expander,p0,
-                                 justificationData);
+                                 justificationData, true);
         SegmentCache.releaseSharedSegment(text);
     }
 
@@ -210,9 +211,9 @@
         TabExpander expander = v.getTabExpander();
         Segment s = v.getText(p0, v.getEndOffset());
         int[] justificationData = getJustificationData(v);
-        int index = Utilities.getTabbedTextOffset(v, s, metrics, (int)x, (int)(x+len),
+        int index = Utilities.getTabbedTextOffset(v, s, metrics, x, (x+len),
                                                   expander, p0, false,
-                                                  justificationData);
+                                                  justificationData, true);
         SegmentCache.releaseSharedSegment(s);
         int p1 = p0 + index;
         return p1;
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphPainter2.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/GlyphPainter2.java	Thu Oct 27 21:22:57 2016 +0000
@@ -145,8 +145,9 @@
 
         // vertical at the baseline, should use slope and check if glyphs
         // are being rendered vertically.
-        alloc.setRect(alloc.getX() + locs[0], alloc.getY(), 1, alloc.getHeight());
-        return alloc;
+        Rectangle2D rect = new Rectangle2D.Float();
+        rect.setRect(alloc.getX() + locs[0], alloc.getY(), 1, alloc.getHeight());
+        return rect;
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java	Thu Oct 27 21:22:57 2016 +0000
@@ -49,6 +49,8 @@
 import java.awt.im.InputMethodRequests;
 import java.awt.font.TextHitInfo;
 import java.awt.font.TextAttribute;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
 
 import java.awt.print.Printable;
 import java.awt.print.PrinterException;
@@ -1370,12 +1372,38 @@
      * @exception BadLocationException if the given position does not
      *   represent a valid location in the associated document
      * @see TextUI#modelToView
+     *
+     * @deprecated replaced by
+     *     {@link #modelToView2D(int)}
      */
+    @Deprecated(since = "9")
     public Rectangle modelToView(int pos) throws BadLocationException {
         return getUI().modelToView(this, pos);
     }
 
     /**
+     * Converts the given location in the model to a place in
+     * the view coordinate system.
+     * The component must have a positive size for
+     * this translation to be computed (i.e. layout cannot
+     * be computed until the component has been sized).  The
+     * component does not have to be visible or painted.
+     *
+     * @param pos the position {@code >= 0}
+     * @return the coordinates as a rectangle, with (r.x, r.y) as the location
+     *   in the coordinate system, or null if the component does
+     *   not yet have a positive size.
+     * @exception BadLocationException if the given position does not
+     *   represent a valid location in the associated document
+     * @see TextUI#modelToView2D
+     *
+     * @since 9
+     */
+    public Rectangle2D modelToView2D(int pos) throws BadLocationException {
+        return getUI().modelToView2D(this, pos, Position.Bias.Forward);
+    }
+
+    /**
      * Converts the given place in the view coordinate system
      * to the nearest representative location in the model.
      * The component must have a positive size for
@@ -1388,12 +1416,36 @@
      *   or -1 if the component does not yet have a positive
      *   size.
      * @see TextUI#viewToModel
+     *
+     * @deprecated replaced by
+     *     {@link #viewToModel2D(Point2D)}
      */
+    @Deprecated(since = "9")
     public int viewToModel(Point pt) {
         return getUI().viewToModel(this, pt);
     }
 
     /**
+     * Converts the given place in the view coordinate system
+     * to the nearest representative location in the model.
+     * The component must have a positive size for
+     * this translation to be computed (i.e. layout cannot
+     * be computed until the component has been sized).  The
+     * component does not have to be visible or painted.
+     *
+     * @param pt the location in the view to translate
+     * @return the offset {@code >= 0} from the start of the document,
+     *   or {@code -1} if the component does not yet have a positive
+     *   size.
+     * @see TextUI#viewToModel2D
+     *
+     * @since 9
+     */
+    public int viewToModel2D(Point2D pt) {
+        return getUI().viewToModel2D(this, pt, new Position.Bias[1]);
+    }
+
+    /**
      * Transfers the currently selected range in the associated
      * text model to the system clipboard, removing the contents
      * from the model.  The current selection is reset.  Does nothing
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/ParagraphView.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/ParagraphView.java	Thu Oct 27 21:22:57 2016 +0000
@@ -27,6 +27,7 @@
 import java.util.Arrays;
 import java.awt.*;
 import java.awt.font.TextAttribute;
+import java.awt.geom.Rectangle2D;
 import javax.swing.event.*;
 import javax.swing.SizeRequirements;
 
@@ -888,10 +889,9 @@
             int height = r.height;
             int y = r.y;
             Shape loc = super.modelToView(pos, a, b);
-            r = loc.getBounds();
-            r.height = height;
-            r.y = y;
-            return r;
+            Rectangle2D bounds = loc.getBounds2D();
+            bounds.setRect(bounds.getX(), y, bounds.getWidth(), height);
+            return bounds;
         }
 
         /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PasswordView.java	Thu Oct 27 21:22:57 2016 +0000
@@ -26,7 +26,11 @@
 
 import sun.swing.SwingUtilities2;
 import java.awt.*;
+import java.awt.font.FontRenderContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import javax.swing.JPasswordField;
+import static javax.swing.text.PlainView.isFPMethodOverriden;
 
 /**
  * Implements a View suitable for use in JPasswordField
@@ -61,15 +65,40 @@
      * @param p1 the ending offset in the model &gt;= p0
      * @return the X location of the end of the range &gt;= 0
      * @exception BadLocationException if p0 or p1 are out of range
+     *
+     * @deprecated replaced by
+     *     {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
      */
+    @Deprecated(since = "9")
+    @Override
     protected int drawUnselectedText(Graphics g, int x, int y,
                                      int p0, int p1) throws BadLocationException {
+        return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
+    }
 
+    @Override
+    protected float drawUnselectedText(Graphics2D g, float x, float y,
+                                       int p0, int p1)
+            throws BadLocationException
+    {
+        return drawUnselectedTextImpl(g, x, y, p0, p1, true);
+    }
+
+    private float drawUnselectedTextImpl(Graphics g, float x, float y,
+                                         int p0, int p1,
+                                         boolean useFPAPI)
+            throws BadLocationException
+    {
         Container c = getContainer();
         if (c instanceof JPasswordField) {
             JPasswordField f = (JPasswordField) c;
-            if (! f.echoCharIsSet()) {
-                return super.drawUnselectedText(g, x, y, p0, p1);
+            if (!f.echoCharIsSet()) {
+                boolean useDrawUnselectedFPAPI = useFPAPI
+                        && drawUnselectedTextOverridden
+                        && g instanceof Graphics2D;
+                return (useDrawUnselectedFPAPI )
+                        ? super.drawUnselectedText((Graphics2D) g, x, y, p0, p1)
+                        : super.drawUnselectedText(g, (int) x, (int) y, p0, p1);
             }
             if (f.isEnabled()) {
                 g.setColor(f.getForeground());
@@ -79,8 +108,13 @@
             }
             char echoChar = f.getEchoChar();
             int n = p1 - p0;
+            boolean useEchoCharFPAPI = useFPAPI
+                    && drawEchoCharacterOverridden
+                    && g instanceof Graphics2D;
             for (int i = 0; i < n; i++) {
-                x = drawEchoCharacter(g, x, y, echoChar);
+                x = (useEchoCharFPAPI)
+                        ? drawEchoCharacter((Graphics2D) g, x, y, echoChar)
+                        : drawEchoCharacter(g, (int) x, (int) y, echoChar);
             }
         }
         return x;
@@ -100,20 +134,50 @@
      * @param p1 the ending offset in the model &gt;= p0
      * @return the X location of the end of the range &gt;= 0
      * @exception BadLocationException if p0 or p1 are out of range
+     *
+     * @deprecated replaced by
+     *     {@link #drawSelectedText(Graphics2D, float, float, int, int)}
      */
+    @Deprecated(since = "9")
+    @Override
     protected int drawSelectedText(Graphics g, int x,
                                    int y, int p0, int p1) throws BadLocationException {
+        return (int) drawSelectedTextImpl(g, x, y, p0, p1, false);
+    }
+
+    @Override
+    protected float drawSelectedText(Graphics2D g, float x, float y,
+                                     int p0, int p1) throws BadLocationException
+    {
+        return drawSelectedTextImpl(g, x, y, p0, p1, true);
+    }
+
+    private float drawSelectedTextImpl(Graphics g, float x, float y,
+                                       int p0, int p1,
+                                       boolean useFPAPI)
+            throws BadLocationException {
         g.setColor(selected);
         Container c = getContainer();
         if (c instanceof JPasswordField) {
             JPasswordField f = (JPasswordField) c;
-            if (! f.echoCharIsSet()) {
-                return super.drawSelectedText(g, x, y, p0, p1);
+            if (!f.echoCharIsSet()) {
+                boolean useDrawUnselectedFPAPI = useFPAPI
+                        && drawSelectedTextOverridden
+                        && g instanceof Graphics2D;
+                return (useFPAPI)
+                        ? super.drawSelectedText((Graphics2D) g, x, y, p0, p1)
+                        : super.drawSelectedText(g, (int) x, (int) y, p0, p1);
             }
             char echoChar = f.getEchoChar();
             int n = p1 - p0;
+            boolean useEchoCharFPAPI = useFPAPI
+                    && drawEchoCharacterOverridden
+                    && g instanceof Graphics2D;
             for (int i = 0; i < n; i++) {
-                x = drawEchoCharacter(g, x, y, echoChar);
+                x = (useEchoCharFPAPI)
+                        ? drawEchoCharacter((Graphics2D) g, x, y, echoChar)
+                        : drawEchoCharacter(g, (int) x, (int) y, echoChar);
+
             }
         }
         return x;
@@ -130,12 +194,13 @@
      * @param y the starting Y coordinate &gt;= 0
      * @param c the echo character
      * @return the updated X position &gt;= 0
+     *
+     * @deprecated replaced by
+     *     {@link #drawEchoCharacter(Graphics2D, float, float, char)}
      */
+    @Deprecated(since = "9")
     protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
-        ONE[0] = c;
-        SwingUtilities2.drawChars(Utilities.getJComponent(this),
-                                  g, ONE, 0, 1, x, y);
-        return x + g.getFontMetrics().charWidth(c);
+        return (int) drawEchoCharacterImpl(g, x, y, c, false);
     }
 
     /**
@@ -144,18 +209,29 @@
      * object is set to the appropriate foreground color for selected
      * or unselected text.
      *
-     * @implSpec This implementation calls
-     * {@link #drawEchoCharacter(Graphics, int, int, char)
-     *      drawEchoCharacter((Graphics) g, (int) x, (int) y, c)}.
-     *
      * @param g the graphics context
      * @param x the starting X coordinate {@code >= 0}
      * @param y the starting Y coordinate {@code >= 0}
      * @param c the echo character
      * @return the updated X position {@code >= 0}
+     *
+     * @since 9
      */
     protected float drawEchoCharacter(Graphics2D g, float x, float y, char c) {
-        return drawEchoCharacter((Graphics) g, (int) x, (int) y, c);
+        return drawEchoCharacterImpl(g, x, y, c, true);
+    }
+
+    private float drawEchoCharacterImpl(Graphics g, float x, float y,
+                                        char c, boolean useFPAPI) {
+        ONE[0] = c;
+        SwingUtilities2.drawChars(Utilities.getJComponent(this),
+                                  g, ONE, 0, 1, x, y);
+        if (useFPAPI) {
+            return x + g.getFontMetrics().charWidth(c);
+        } else {
+            FontRenderContext frc = g.getFontMetrics().getFontRenderContext();
+            return x + (float) g.getFont().getStringBounds(ONE, 0, 1, frc).getWidth();
+        }
     }
 
     /**
@@ -253,4 +329,23 @@
     }
 
     static char[] ONE = new char[1];
+
+    private final boolean drawEchoCharacterOverridden;
+
+    {
+        final Class<?> CLS = getClass();
+        final Class<?> INT = Integer.TYPE;
+        final Class<?> FP = Float.TYPE;
+        final Class<?> CHAR = Character.TYPE;
+
+        drawEchoCharacterOverridden = AccessController
+                .doPrivileged(new PrivilegedAction<Boolean>() {
+            @Override
+            public Boolean run() {
+                Class<?>[] intTypes = {Graphics.class, INT, INT, CHAR};
+                Class<?>[] fpTypes = {Graphics2D.class, FP, FP, CHAR};
+                return isFPMethodOverriden("drawEchoCharacter", CLS, intTypes, fpTypes);
+            }
+        });
+    }
 }
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java	Thu Oct 27 21:22:57 2016 +0000
@@ -24,11 +24,14 @@
  */
 package javax.swing.text;
 
-import java.util.Vector;
-import java.util.Properties;
 import java.awt.*;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.Rectangle2D;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Objects;
 import javax.swing.event.*;
+import java.lang.reflect.Module;
 
 /**
  * Implements View interface for a simple multi-line text view
@@ -61,17 +64,6 @@
     }
 
     /**
-     * Returns the tab size set for the document, defaulting to 8.
-     *
-     * @implSpec This implementation calls {@link #getTabSize() getTabSize()}.
-     *
-     * @return the tab size
-     */
-    protected float getFractionalTabSize() {
-        return getTabSize();
-    }
-
-    /**
      * Renders a line of text, suppressing whitespace at the end
      * and expanding any tabs.  This is implemented to make calls
      * to the methods <code>drawUnselectedText</code> and
@@ -84,8 +76,16 @@
      * @param y the starting Y position &gt;= 0
      * @see #drawUnselectedText
      * @see #drawSelectedText
+     *
+     * @deprecated replaced by
+     *     {@link #drawLine(int, Graphics2D, float, float)}
      */
+    @Deprecated(since = "9")
     protected void drawLine(int lineIndex, Graphics g, int x, int y) {
+        drawLineImpl(lineIndex, g, x, y);
+    }
+
+    private void drawLineImpl(int lineIndex, Graphics g, float x, float y) {
         Element line = getElement().getElement(lineIndex);
         Element elem;
 
@@ -112,22 +112,23 @@
      * {@code drawSelectedText} so that the way selected and
      * unselected text are rendered can be customized.
      *
-     * @implSpec This implementation calls
-     * {@link #drawLine(int, Graphics, int, int)
-     * drawLine(lineIndex, (Graphics)g, (int) x, (int) y)}.
-     *
      * @param lineIndex the line to draw {@code >= 0}
      * @param g the {@code Graphics} context
      * @param x the starting X position {@code >= 0}
      * @param y the starting Y position {@code >= 0}
      * @see #drawUnselectedText
      * @see #drawSelectedText
+     *
+     * @since 9
      */
     protected void drawLine(int lineIndex, Graphics2D g, float x, float y) {
-        drawLine(lineIndex, (Graphics)g, (int) x, (int) y);
+        drawLineImpl(lineIndex, g, x, y);
     }
 
-    private int drawElement(int lineIndex, Element elem, Graphics g, int x, int y) throws BadLocationException {
+    private float drawElement(int lineIndex, Element elem, Graphics g,
+                              float x, float y)
+                              throws BadLocationException
+    {
         int p0 = elem.getStartOffset();
         int p1 = elem.getEndOffset();
         p1 = Math.min(getDocument().getLength(), p1);
@@ -144,23 +145,23 @@
         } else {
             if (sel0 == sel1 || selected == unselected) {
                 // no selection, or it is invisible
-                x = drawUnselectedText(g, x, y, p0, p1);
+                x = callDrawUnselectedText(g, x, y, p0, p1);
             } else if ((p0 >= sel0 && p0 <= sel1) && (p1 >= sel0 && p1 <= sel1)) {
-                x = drawSelectedText(g, x, y, p0, p1);
+                x = callDrawSelectedText(g, x, y, p0, p1);
             } else if (sel0 >= p0 && sel0 <= p1) {
                 if (sel1 >= p0 && sel1 <= p1) {
-                    x = drawUnselectedText(g, x, y, p0, sel0);
-                    x = drawSelectedText(g, x, y, sel0, sel1);
-                    x = drawUnselectedText(g, x, y, sel1, p1);
+                    x = callDrawUnselectedText(g, x, y, p0, sel0);
+                    x = callDrawSelectedText(g, x, y, sel0, sel1);
+                    x = callDrawUnselectedText(g, x, y, sel1, p1);
                 } else {
-                    x = drawUnselectedText(g, x, y, p0, sel0);
-                    x = drawSelectedText(g, x, y, sel0, p1);
+                    x = callDrawUnselectedText(g, x, y, p0, sel0);
+                    x = callDrawSelectedText(g, x, y, sel0, p1);
                 }
             } else if (sel1 >= p0 && sel1 <= p1) {
-                x = drawSelectedText(g, x, y, p0, sel1);
-                x = drawUnselectedText(g, x, y, sel1, p1);
+                x = callDrawSelectedText(g, x, y, p0, sel1);
+                x = callDrawUnselectedText(g, x, y, sel1, p1);
             } else {
-                x = drawUnselectedText(g, x, y, p0, p1);
+                x = callDrawUnselectedText(g, x, y, p0, p1);
             }
         }
 
@@ -178,14 +179,36 @@
      * @param p1 the ending position in the model &gt;= 0
      * @return the X location of the end of the range &gt;= 0
      * @exception BadLocationException if the range is invalid
+     *
+     * @deprecated replaced by
+     *     {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
      */
+    @Deprecated(since = "9")
     protected int drawUnselectedText(Graphics g, int x, int y,
                                      int p0, int p1) throws BadLocationException {
+        return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
+    }
+
+    private float callDrawUnselectedText(Graphics g, float x, float y,
+                                         int p0, int p1)
+                                         throws BadLocationException
+    {
+        return drawUnselectedTextOverridden && (g instanceof Graphics2D)
+                ? drawUnselectedText((Graphics2D) g, x, y, p0, p1)
+                : drawUnselectedText(g, (int) x, (int) y, p0, p1);
+    }
+
+    private float drawUnselectedTextImpl(Graphics g, float x, float y,
+                                         int p0, int p1,
+                                         boolean useFPAPI)
+            throws BadLocationException
+    {
         g.setColor(unselected);
         Document doc = getDocument();
         Segment s = SegmentCache.getSharedSegment();
         doc.getText(p0, p1 - p0, s);
-        int ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0);
+        float ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0, null,
+                                             useFPAPI);
         SegmentCache.releaseSharedSegment(s);
         return ret;
     }
@@ -194,10 +217,6 @@
      * Renders the given range in the model as normal unselected
      * text.  Uses the foreground or disabled color to render the text.
      *
-     * @implSpec This implementation calls
-     * {@link #drawUnselectedText(Graphics, int, int, int, int)
-     * drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
-     *
      * @param g the graphics context
      * @param x the starting X coordinate {@code >= 0}
      * @param y the starting Y coordinate {@code >= 0}
@@ -205,10 +224,12 @@
      * @param p1 the ending position in the model {@code >= 0}
      * @return the X location of the end of the range {@code >= 0}
      * @exception BadLocationException if the range is invalid
+     *
+     * @since 9
      */
     protected float drawUnselectedText(Graphics2D g, float x, float y,
                                        int p0, int p1) throws BadLocationException {
-        return drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1);
+        return drawUnselectedTextImpl(g, x, y, p0, p1, true);
     }
 
     /**
@@ -224,14 +245,38 @@
      * @param p1 the ending position in the model &gt;= 0
      * @return the location of the end of the range
      * @exception BadLocationException if the range is invalid
+     *
+     * @deprecated replaced by
+     *     {@link #drawSelectedText(Graphics2D, float, float, int, int)}
      */
+    @Deprecated(since = "9")
     protected int drawSelectedText(Graphics g, int x,
-                                   int y, int p0, int p1) throws BadLocationException {
+                                   int y, int p0, int p1)
+                                   throws BadLocationException
+    {
+        return (int) drawSelectedTextImpl(g, x, y, p0, p1, false);
+    }
+
+    float callDrawSelectedText(Graphics g, float x, float y,
+                               int p0, int p1)
+                               throws BadLocationException
+    {
+        return drawSelectedTextOverridden && g instanceof Graphics2D
+                ? drawSelectedText((Graphics2D) g, x, y, p0, p1)
+                : drawSelectedText(g, (int) x, (int) y, p0, p1);
+    }
+
+    private float drawSelectedTextImpl(Graphics g, float x, float y,
+                                       int p0, int p1,
+                                       boolean useFPAPI)
+            throws BadLocationException
+    {
         g.setColor(selected);
         Document doc = getDocument();
         Segment s = SegmentCache.getSharedSegment();
         doc.getText(p0, p1 - p0, s);
-        int ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0);
+        float ret = Utilities.drawTabbedText(this, s, x, y, g, this, p0, null,
+                                             useFPAPI);
         SegmentCache.releaseSharedSegment(s);
         return ret;
     }
@@ -242,10 +287,6 @@
      * the hosting component.  It assumes the highlighter will render
      * the selected background.
      *
-     * @implSpec This implementation calls
-     * {@link #drawSelectedText(Graphics, int, int, int, int)
-     * drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
-     *
      * @param g the graphics context
      * @param x the starting X coordinate {@code >= 0}
      * @param y the starting Y coordinate {@code >= 0}
@@ -253,11 +294,12 @@
      * @param p1 the ending position in the model {@code >= 0}
      * @return the location of the end of the range
      * @exception BadLocationException if the range is invalid
+     *
+     * @since 9
      */
-
     protected float drawSelectedText(Graphics2D g, float x,
                                      float y, int p0, int p1) throws BadLocationException {
-        return drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1);
+        return drawSelectedTextImpl(g, x, y, p0, p1, true);
     }
 
     /**
@@ -287,7 +329,13 @@
             // The font changed, we need to recalculate the
             // longest line.
             calculateLongestLine();
-            tabSize = getTabSize() * metrics.charWidth('m');
+            if (useFloatingPointAPI) {
+                FontRenderContext frc = metrics.getFontRenderContext();
+                float tabWidth = (float) font.getStringBounds("m", frc).getWidth();
+                tabSize = getTabSize() * tabWidth;
+            } else {
+                tabSize = getTabSize() * metrics.charWidth('m');
+            }
         }
     }
 
@@ -388,7 +436,11 @@
                                               originalA, host, this);
                 }
             }
-            drawLine(line, g, x, y);
+            if (drawLineOverridden && (g instanceof Graphics2D)) {
+                drawLine(line, (Graphics2D) g, (float) x, (float) y);
+            } else {
+                drawLine(line, g, x, y);
+            }
             y += fontHeight;
             if (line == 0) {
                 // This should never really happen, in so far as if
@@ -435,6 +487,13 @@
         int p0 = line.getStartOffset();
         Segment s = SegmentCache.getSharedSegment();
         doc.getText(p0, pos - p0, s);
+
+        if (useFloatingPointAPI) {
+            float xOffs = Utilities.getTabbedTextWidth(s, metrics, (float) tabBase, this, p0);
+            SegmentCache.releaseSharedSegment(s);
+            return new Rectangle2D.Float(lineArea.x + xOffs, lineArea.y, 1, metrics.getHeight());
+        }
+
         int xOffs = Utilities.getTabbedTextWidth(s, metrics, tabBase, this,p0);
         SegmentCache.releaseSharedSegment(s);
 
@@ -456,14 +515,13 @@
      *  given point in the view &gt;= 0
      * @see View#viewToModel
      */
-    public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) {
+    public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
         // PENDING(prinz) properly calculate bias
         bias[0] = Position.Bias.Forward;
 
         Rectangle alloc = a.getBounds();
         Document doc = getDocument();
-        int x = (int) fx;
-        int y = (int) fy;
+
         if (y < alloc.y) {
             // above the area covered by this icon, so the position
             // is assumed to be the start of the coverage for this view.
@@ -481,7 +539,7 @@
             Element map = doc.getDefaultRootElement();
             int fontHeight = metrics.getHeight();
             int lineIndex = (fontHeight > 0 ?
-                                Math.abs((y - alloc.y) / fontHeight) :
+                                (int)Math.abs((y - alloc.y) / fontHeight) :
                                 map.getElementCount() - 1);
             if (lineIndex >= map.getElementCount()) {
                 return getEndOffset() - 1;
@@ -507,7 +565,7 @@
                     doc.getText(p0, p1 - p0, s);
                     tabBase = alloc.x;
                     int offs = p0 + Utilities.getTabbedTextOffset(s, metrics,
-                                                                  tabBase, x, this, p0);
+                                                                  tabBase, x, this, p0, true);
                     SegmentCache.releaseSharedSegment(s);
                     return offs;
                 } catch (BadLocationException e) {
@@ -586,7 +644,7 @@
         if (tabSize == 0) {
             return x;
         }
-        int ntabs = (((int) x) - tabBase) / tabSize;
+        float ntabs = (x - tabBase) / tabSize;
         return tabBase + ((ntabs + 1) * tabSize);
     }
 
@@ -758,6 +816,28 @@
         return w;
     }
 
+    static boolean isFPMethodOverriden(String method,
+                                Class<?> cls,
+                                Class<?>[] intTypes,
+                                Class<?>[] fpTypes)
+    {
+        Module thisModule = PlainView.class.getModule();
+        while (!thisModule.equals(cls.getModule())) {
+            try {
+                cls.getDeclaredMethod(method, fpTypes);
+                return true;
+            } catch (Exception e1) {
+                try {
+                    cls.getDeclaredMethod(method, intTypes);
+                    return false;
+                } catch (Exception e2) {
+                    cls = cls.getSuperclass();
+                }
+            }
+        }
+        return true;
+    }
+
     // --- member variables -----------------------------------------------
 
     /**
@@ -780,7 +860,7 @@
     Font font;
 
     Segment lineBuffer;
-    int tabSize;
+    float tabSize;
     int tabBase;
 
     int sel0;
@@ -796,4 +876,46 @@
      */
     int firstLineOffset;
 
+    final boolean drawLineOverridden;
+    final boolean drawSelectedTextOverridden;
+    final boolean drawUnselectedTextOverridden;
+    final boolean useFloatingPointAPI;
+
+    {
+        final Class<?> CLS = getClass();
+        final Class<?> INT = Integer.TYPE;
+        final Class<?> FP = Float.TYPE;
+
+        drawLineOverridden = AccessController
+                .doPrivileged(new PrivilegedAction<Boolean>() {
+            @Override
+            public Boolean run() {
+                Class<?>[] intTypes = {INT, Graphics.class, INT, INT};
+                Class<?>[] fpTypes = {INT, Graphics2D.class, FP, FP};
+                return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes);
+            }
+        });
+
+        drawUnselectedTextOverridden = AccessController
+                .doPrivileged(new PrivilegedAction<Boolean>() {
+            @Override
+            public Boolean run() {
+                Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
+                Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
+                return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes);
+            }
+        });
+
+        drawSelectedTextOverridden = AccessController
+                .doPrivileged(new PrivilegedAction<Boolean>() {
+            @Override
+            public Boolean run() {
+                Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
+                Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
+                return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes);
+            }
+        });
+
+        useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden;
+    }
 }
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/Utilities.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/Utilities.java	Thu Oct 27 21:22:57 2016 +0000
@@ -24,24 +24,23 @@
  */
 package javax.swing.text;
 
-import java.lang.reflect.Method;
-
 import java.awt.Component;
 import java.awt.Rectangle;
 import java.awt.Graphics;
 import java.awt.FontMetrics;
 import java.awt.Shape;
-import java.awt.Toolkit;
 import java.awt.Graphics2D;
-import java.awt.font.FontRenderContext;
-import java.awt.font.TextLayout;
 import java.awt.font.TextAttribute;
+import java.awt.geom.Rectangle2D;
 
 import java.text.*;
 import javax.swing.JComponent;
 import javax.swing.SwingConstants;
 import javax.swing.text.ParagraphView.Row;
 import sun.swing.SwingUtilities2;
+import static sun.swing.SwingUtilities2.drawChars;
+import static sun.swing.SwingUtilities2.getFontCharWidth;
+import static sun.swing.SwingUtilities2.getFontCharsWidth;
 
 /**
  * A collection of methods to deal with various text
@@ -78,7 +77,11 @@
      *   tabs will be expanded as a space character.
      * @param startOffset starting offset of the text in the document &gt;= 0
      * @return  the X location at the end of the rendered text
+     *
+     * @deprecated replaced by
+     * {@link #drawTabbedText(Segment, float, float, Graphics2D, TabExpander, int)}
      */
+    @Deprecated(since = "9")
     public static final int drawTabbedText(Segment s, int x, int y, Graphics g,
                                            TabExpander e, int startOffset) {
         return drawTabbedText(null, s, x, y, g, e, startOffset);
@@ -96,6 +99,8 @@
      *           tabs will be expanded as a space character.
      * @param startOffset starting offset of the text in the document {@code >= 0}
      * @return  the X location at the end of the rendered text
+     *
+     * @since 9
      */
     public static final float drawTabbedText(Segment s, float x, float y,
                                              Graphics2D g,
@@ -138,9 +143,19 @@
                                 Segment s, int x, int y, Graphics g,
                                 TabExpander e, int startOffset,
                                 int [] justificationData) {
+        return (int) drawTabbedText(view, s, x, y, g, e, startOffset,
+                                    justificationData, false);
+    }
+
+    static final float drawTabbedText(View view,
+                                Segment s, float x, float y, Graphics g,
+                                TabExpander e, int startOffset,
+                                int [] justificationData,
+                                boolean useFPAPI)
+    {
         JComponent component = getJComponent(view);
         FontMetrics metrics = SwingUtilities2.getFontMetrics(component, g);
-        int nextX = x;
+        float nextX = x;
         char[] txt = s.array;
         int txtOffset = s.offset;
         int flushLen = 0;
@@ -174,19 +189,19 @@
                     && i <= endJustifiableContent
                     )) {
                 if (flushLen > 0) {
-                    nextX = SwingUtilities2.drawChars(component, g, txt,
-                                                flushIndex, flushLen, x, y);
+                    nextX = drawChars(component, g, txt, flushIndex, flushLen, x, y);
                     flushLen = 0;
                 }
                 flushIndex = i + 1;
                 if (txt[i] == '\t') {
                     if (e != null) {
-                        nextX = (int) e.nextTabStop((float) nextX, startOffset + i - txtOffset);
+                        nextX = e.nextTabStop(nextX, startOffset + i - txtOffset);
                     } else {
-                        nextX += metrics.charWidth(' ');
+                        nextX += getFontCharWidth(' ', metrics, useFPAPI);
                     }
                 } else if (txt[i] == ' ') {
-                    nextX += metrics.charWidth(' ') + spaceAddon;
+                    float spaceWidth = getFontCharWidth(' ', metrics, useFPAPI);
+                    nextX += spaceWidth + spaceAddon;
                     if (i <= spaceAddonLeftoverEnd) {
                         nextX++;
                     }
@@ -194,8 +209,8 @@
                 x = nextX;
             } else if ((txt[i] == '\n') || (txt[i] == '\r')) {
                 if (flushLen > 0) {
-                    nextX = SwingUtilities2.drawChars(component, g, txt,
-                                                flushIndex, flushLen, x, y);
+                    nextX = drawChars(component, g, txt, flushIndex, flushLen,
+                                      x, y, useFPAPI);
                     flushLen = 0;
                 }
                 flushIndex = i + 1;
@@ -205,8 +220,7 @@
             }
         }
         if (flushLen > 0) {
-            nextX = SwingUtilities2.drawChars(component, g,txt, flushIndex,
-                                              flushLen, x, y);
+            nextX = drawChars(component, g,txt, flushIndex, flushLen, x, y, useFPAPI);
         }
         return nextX;
     }
@@ -223,7 +237,11 @@
      *   tabs will be expanded as a space character.
      * @param startOffset starting offset of the text in the document &gt;= 0
      * @return  the width of the text
+     *
+     * @deprecated replaced by
+     *     {@link #getTabbedTextWidth(Segment, FontMetrics, float, TabExpander, int)}
      */
+    @Deprecated(since = "9")
     public static final int getTabbedTextWidth(Segment s, FontMetrics metrics, int x,
                                                TabExpander e, int startOffset) {
         return getTabbedTextWidth(null, s, metrics, x, e, startOffset, null);
@@ -240,11 +258,13 @@
      *   tabs will be expanded as a space character.
      * @param startOffset starting offset of the text in the document {@code >= 0}
      * @return  the width of the text
+     *
+     * @since 9
      */
     public static final float getTabbedTextWidth(Segment s, FontMetrics metrics,
                                                  float x, TabExpander e,
                                                  int startOffset) {
-        return getTabbedTextWidth(s, metrics, (int) x, e, startOffset);
+        return getTabbedTextWidth(null, s, metrics, x, e, startOffset, null);
     }
 
     // In addition to the previous method it can extend spaces for
@@ -254,10 +274,32 @@
     // one:
     // @param justificationData justificationData for the row.
     // if null not justification is needed
-    static final int getTabbedTextWidth(View view, Segment s, FontMetrics metrics, int x,
+    static final int getTabbedTextWidth(View view, Segment s,
+                                        FontMetrics metrics, int x,
+                                        TabExpander e, int startOffset,
+                                        int[] justificationData)
+    {
+        return (int) getTabbedTextWidth(view, s, metrics, x, e, startOffset,
+                                        justificationData, false);
+
+    }
+
+    static final float getTabbedTextWidth(View view, Segment s,
+                                        FontMetrics metrics, float x,
                                         TabExpander e, int startOffset,
-                                        int[] justificationData) {
-        int nextX = x;
+                                        int[] justificationData)
+    {
+        return  getTabbedTextWidth(view, s, metrics, x, e, startOffset,
+                                   justificationData, true);
+
+    }
+
+    static final float getTabbedTextWidth(View view, Segment s,
+                                        FontMetrics metrics, float x,
+                                        TabExpander e, int startOffset,
+                                        int[] justificationData,
+                                        boolean useFPAPI) {
+        float nextX = x;
         char[] txt = s.array;
         int txtOffset = s.offset;
         int n = s.offset + s.count;
@@ -294,13 +336,13 @@
                 charCount = 0;
                 if (txt[i] == '\t') {
                     if (e != null) {
-                        nextX = (int) e.nextTabStop((float) nextX,
-                                                    startOffset + i - txtOffset);
+                        nextX = e.nextTabStop(nextX, startOffset + i - txtOffset);
                     } else {
-                        nextX += metrics.charWidth(' ');
+                        nextX += getFontCharWidth(' ', metrics, useFPAPI);
                     }
                 } else if (txt[i] == ' ') {
-                    nextX += metrics.charWidth(' ') + spaceAddon;
+                    float spaceWidth = getFontCharWidth(' ', metrics, useFPAPI);
+                    nextX += spaceWidth + spaceAddon;
                     if (i <= spaceAddonLeftoverEnd) {
                         nextX++;
                     }
@@ -308,13 +350,15 @@
             } else if(txt[i] == '\n') {
             // Ignore newlines, they take up space and we shouldn't be
             // counting them.
-                nextX += metrics.charsWidth(txt, i - charCount, charCount);
+                nextX += getFontCharsWidth(txt, i - charCount, charCount,
+                                           metrics, useFPAPI);
                 charCount = 0;
             } else {
                 charCount++;
         }
         }
-        nextX += metrics.charsWidth(txt, n - charCount, charCount);
+        nextX += getFontCharsWidth(txt, n - charCount, charCount,
+                                   metrics, useFPAPI);
         return nextX - x;
     }
 
@@ -334,7 +378,12 @@
      *   tabs will be expanded as a space character.
      * @param startOffset starting offset of the text in the document &gt;= 0
      * @return  the offset into the text &gt;= 0
+     *
+     * @deprecated replaced by
+     *     {@link #getTabbedTextOffset(Segment, FontMetrics, float, float,
+     *                                 TabExpander, int, boolean)}
      */
+    @Deprecated(since = "9")
     public static final int getTabbedTextOffset(Segment s, FontMetrics metrics,
                                              int x0, int x, TabExpander e,
                                              int startOffset) {
@@ -346,7 +395,7 @@
                                          int startOffset,
                                          int[] justificationData) {
         return getTabbedTextOffset(view, s, metrics, x0, x, e, startOffset, true,
-                                   justificationData);
+                                   justificationData, false);
     }
 
     /**
@@ -365,13 +414,19 @@
      * @param startOffset starting offset of the text in the document &gt;= 0
      * @param round whether or not to round
      * @return  the offset into the text &gt;= 0
+     *
+     * @deprecated replaced by
+     *     {@link #getTabbedTextOffset(Segment, FontMetrics, float, float,
+     *                                 TabExpander, int, boolean)}
      */
+    @Deprecated(since = "9")
     public static final int getTabbedTextOffset(Segment s,
                                                 FontMetrics metrics,
                                                 int x0, int x, TabExpander e,
                                                 int startOffset,
                                                 boolean round) {
-        return getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset, round, null);
+        return getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset,
+                                   round, null, false);
     }
 
     /**
@@ -390,6 +445,8 @@
      * @param startOffset starting offset of the text in the document {@code >= 0}
      * @param round whether or not to round
      * @return  the offset into the text {@code >= 0}
+     *
+     * @since 9
      */
     public static final int getTabbedTextOffset(Segment s,
                                                 FontMetrics metrics,
@@ -398,8 +455,8 @@
                                                 int startOffset,
                                                 boolean round)
     {
-        return getTabbedTextOffset(null, s, metrics, (int) x0, (int) x, e,
-                                   startOffset, round, null);
+        return getTabbedTextOffset(null, s, metrics, x0, x, e,
+                                   startOffset, round, null, true);
     }
 
     // In addition to the previous method it can extend spaces for
@@ -412,15 +469,16 @@
     static final int getTabbedTextOffset(View view,
                                          Segment s,
                                          FontMetrics metrics,
-                                         int x0, int x, TabExpander e,
+                                         float x0, float x, TabExpander e,
                                          int startOffset,
                                          boolean round,
-                                         int[] justificationData) {
+                                         int[] justificationData,
+                                         boolean useFPAPI) {
         if (x0 >= x) {
             // x before x0, return.
             return 0;
         }
-        int nextX = x0;
+        float nextX = x0;
         // s may be a shared segment, so it is copied prior to calling
         // the tab expander
         char[] txt = s.array;
@@ -456,19 +514,19 @@
                     )){
                 if (txt[i] == '\t') {
                     if (e != null) {
-                        nextX = (int) e.nextTabStop((float) nextX,
-                                                    startOffset + i - txtOffset);
+                        nextX = e.nextTabStop(nextX, startOffset + i - txtOffset);
                     } else {
-                        nextX += metrics.charWidth(' ');
+                        nextX += getFontCharWidth(' ', metrics, useFPAPI);
                     }
                 } else if (txt[i] == ' ') {
-                    nextX += metrics.charWidth(' ') + spaceAddon;
+                    nextX += getFontCharWidth(' ', metrics, useFPAPI);
+                    nextX += spaceAddon;
                     if (i <= spaceAddonLeftoverEnd) {
                         nextX++;
                     }
                 }
             } else {
-                nextX += metrics.charWidth(txt[i]);
+                nextX += getFontCharWidth(txt[i], metrics, useFPAPI);
             }
             if (x < nextX) {
                 // found the hit position... return the appropriate side
@@ -480,12 +538,15 @@
                 if (round) {
                     offset = i + 1 - txtOffset;
 
-                    int width = metrics.charsWidth(txt, txtOffset, offset);
-                    int span = x - x0;
+                    float width = getFontCharsWidth(txt, txtOffset, offset,
+                                                    metrics, useFPAPI);
+                    float span = x - x0;
 
                     if (span < width) {
                         while (offset > 0) {
-                            int nextWidth = offset > 1 ? metrics.charsWidth(txt, txtOffset, offset - 1) : 0;
+                            float charsWidth = getFontCharsWidth(txt, txtOffset,
+                                    offset - 1, metrics, useFPAPI);
+                            float nextWidth = offset > 1 ? charsWidth : 0;
 
                             if (span >= nextWidth) {
                                 if (span - nextWidth < width - span) {
@@ -502,7 +563,9 @@
                 } else {
                     offset = i - txtOffset;
 
-                    while (offset > 0 && metrics.charsWidth(txt, txtOffset, offset) > (x - x0)) {
+                    while (offset > 0 && getFontCharsWidth(txt, txtOffset, offset,
+                                                           metrics, useFPAPI)
+                            > (x - x0)) {
                         offset--;
                     }
                 }
@@ -528,15 +591,26 @@
      *   tabs will be expanded as a space character.
      * @param startOffset starting offset in the document of the text
      * @return  the offset into the given text
+     *
+     * @deprecated replaced by
+     *     {@link #getBreakLocation(Segment, FontMetrics, float, float,
+     *                              TabExpander, int)}
      */
+    @Deprecated(since = "9")
     public static final int getBreakLocation(Segment s, FontMetrics metrics,
                                              int x0, int x, TabExpander e,
                                              int startOffset) {
+        return getBreakLocation(s, metrics, x0, x, e, startOffset, false);
+    }
+
+    static final int getBreakLocation(Segment s, FontMetrics metrics,
+                                      float x0, float x, TabExpander e,
+                                      int startOffset, boolean useFPIAPI) {
         char[] txt = s.array;
         int txtOffset = s.offset;
         int txtCount = s.count;
-        int index = Utilities.getTabbedTextOffset(s, metrics, x0, x,
-                                                  e, startOffset, false);
+        int index = getTabbedTextOffset(null, s, metrics, x0, x, e, startOffset,
+                                        false, null, useFPIAPI);
 
         if (index >= txtCount - 1) {
             return txtCount;
@@ -577,11 +651,13 @@
      *        tabs will be expanded as a space character.
      * @param startOffset starting offset in the document of the text
      * @return  the offset into the given text
+     *
+     * @since 9
      */
     public static final int getBreakLocation(Segment s, FontMetrics metrics,
                                              float x0, float x, TabExpander e,
                                              int startOffset) {
-        return getBreakLocation(s, metrics, (int) x0, (int) x, e, startOffset);
+        return getBreakLocation(s, metrics, x0, x, e, startOffset, false);
     }
 
     /**
@@ -627,16 +703,16 @@
      * @exception BadLocationException if the offset is out of range
      */
     public static final int getRowEnd(JTextComponent c, int offs) throws BadLocationException {
-        Rectangle r = c.modelToView(offs);
+        Rectangle2D r = c.modelToView2D(offs);
         if (r == null) {
             return -1;
         }
         int n = c.getDocument().getLength();
         int lastOffs = offs;
-        int y = r.y;
-        while ((r != null) && (y == r.y)) {
+        double y = r.getY();
+        while ((r != null) && (y == r.getY())) {
             // Skip invisible elements
-            if (r.height !=0) {
+            if (r.getHeight() !=0) {
                 offs = lastOffs;
             }
             lastOffs += 1;
@@ -657,27 +733,44 @@
      * @return the position &gt;= 0 if the request can be computed, otherwise
      *  a value of -1 will be returned.
      * @exception BadLocationException if the offset is out of range
+     *
+     * @deprecated replaced by
+     *     {@link #getPositionAbove(JTextComponent, int, float)}
      */
-    public static final int getPositionAbove(JTextComponent c, int offs, int x) throws BadLocationException {
+    @Deprecated(since = "9")
+    public static final int getPositionAbove(JTextComponent c, int offs, int x)
+            throws BadLocationException
+    {
+        return getPositionAbove(c, offs, x, false);
+    }
+
+    static final int getPositionAbove(JTextComponent c, int offs, float x,
+                                      boolean useFPAPI) throws BadLocationException
+    {
         int lastOffs = getRowStart(c, offs) - 1;
         if (lastOffs < 0) {
             return -1;
         }
-        int bestSpan = Integer.MAX_VALUE;
-        int y = 0;
-        Rectangle r = null;
+        double bestSpan = Integer.MAX_VALUE;
+        double y = 0;
+        Rectangle2D r = null;
         if (lastOffs >= 0) {
-            r = c.modelToView(lastOffs);
-            y = r.y;
+            r = useFPAPI ? c.modelToView2D(lastOffs) : c.modelToView(lastOffs);
+            y = r.getY();
         }
-        while ((r != null) && (y == r.y)) {
-            int span = Math.abs(r.x - x);
+        while ((r != null) && (y == r.getY())) {
+            double span = Math.abs(r.getX() - x);
             if (span < bestSpan) {
                 offs = lastOffs;
                 bestSpan = span;
             }
             lastOffs -= 1;
-            r = (lastOffs >= 0) ? c.modelToView(lastOffs) : null;
+
+            if ((lastOffs >= 0)) {
+                r = useFPAPI ? c.modelToView2D(lastOffs) : c.modelToView(lastOffs);
+            } else {
+                r = null;
+            }
         }
         return offs;
     }
@@ -694,10 +787,12 @@
      * @return the position {@code >= 0} if the request can be computed, otherwise
      *  a value of -1 will be returned.
      * @exception BadLocationException if the offset is out of range
+     *
+     * @since 9
      */
     public static final int getPositionAbove(JTextComponent c, int offs, float x)
             throws BadLocationException {
-        return getPositionAbove(c, offs, (int) x);
+        return getPositionAbove(c, offs, x, true);
     }
 
     /**
@@ -712,28 +807,45 @@
      * @return the position &gt;= 0 if the request can be computed, otherwise
      *  a value of -1 will be returned.
      * @exception BadLocationException if the offset is out of range
+     *
+     * @deprecated replaced by
+     *     {@link #getPositionBelow(JTextComponent, int, float)}
      */
-    public static final int getPositionBelow(JTextComponent c, int offs, int x) throws BadLocationException {
+    @Deprecated(since = "9")
+    public static final int getPositionBelow(JTextComponent c, int offs, int x)
+            throws BadLocationException
+    {
+        return getPositionBelow(c, offs, x, false);
+    }
+
+    static final int getPositionBelow(JTextComponent c, int offs, float x,
+                                      boolean useFPAPI) throws BadLocationException
+    {
         int lastOffs = getRowEnd(c, offs) + 1;
         if (lastOffs <= 0) {
             return -1;
         }
-        int bestSpan = Integer.MAX_VALUE;
+        double bestSpan = Integer.MAX_VALUE;
         int n = c.getDocument().getLength();
-        int y = 0;
-        Rectangle r = null;
+        double y = 0;
+        Rectangle2D r = null;
         if (lastOffs <= n) {
-            r = c.modelToView(lastOffs);
-            y = r.y;
+            r = useFPAPI ? c.modelToView2D(lastOffs) : c.modelToView(lastOffs);
+            y = r.getY();
         }
-        while ((r != null) && (y == r.y)) {
-            int span = Math.abs(x - r.x);
+        while ((r != null) && (y == r.getY())) {
+            double span = Math.abs(x - r.getX());
             if (span < bestSpan) {
                 offs = lastOffs;
                 bestSpan = span;
             }
             lastOffs += 1;
-            r = (lastOffs <= n) ? c.modelToView(lastOffs) : null;
+
+            if (lastOffs <= n) {
+                r = useFPAPI ? c.modelToView2D(lastOffs) : c.modelToView(lastOffs);
+            } else {
+                r = null;
+            }
         }
         return offs;
     }
@@ -750,10 +862,12 @@
      * @return the position {@code >= 0} if the request can be computed, otherwise
      *  a value of -1 will be returned.
      * @exception BadLocationException if the offset is out of range
+     *
+     * @since 9
      */
     public static final int getPositionBelow(JTextComponent c, int offs, float x)
             throws BadLocationException {
-        return getPositionBelow(c, offs, (int) x);
+        return getPositionBelow(c, offs, x, true);
     }
 
     /**
@@ -1029,7 +1143,23 @@
      */
     static int drawComposedText(View view, AttributeSet attr, Graphics g,
                                 int x, int y, int p0, int p1)
-                                     throws BadLocationException {
+            throws BadLocationException
+    {
+        return (int) drawComposedText(view, attr, g, x, y, p0, p1, false);
+    }
+
+    static float drawComposedText(View view, AttributeSet attr, Graphics g,
+                                  float x, float y, int p0, int p1)
+            throws BadLocationException
+    {
+        return drawComposedText(view, attr, g, x, y, p0, p1, true);
+    }
+
+    static float drawComposedText(View view, AttributeSet attr, Graphics g,
+                                  float x, float y, int p0, int p1,
+                                  boolean useFPAPI)
+            throws BadLocationException
+    {
         Graphics2D g2d = (Graphics2D)g;
         AttributedString as = (AttributedString)attr.getAttribute(
             StyleConstants.ComposedTextAttribute);
@@ -1039,8 +1169,7 @@
             return x;
 
         AttributedCharacterIterator aci = as.getIterator(null, p0, p1);
-        return x + (int)SwingUtilities2.drawString(
-                             getJComponent(view), g2d,aci,x,y);
+        return x + SwingUtilities2.drawString(getJComponent(view), g2d, aci, x, y);
     }
 
     /**
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java	Thu Oct 27 21:22:57 2016 +0000
@@ -25,8 +25,12 @@
 package javax.swing.text;
 
 import java.awt.*;
+import java.awt.font.FontRenderContext;
 import java.lang.ref.SoftReference;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import javax.swing.event.*;
+import static javax.swing.text.PlainView.isFPMethodOverriden;
 
 /**
  * View of plain text (text with only one font and color)
@@ -87,17 +91,6 @@
     }
 
     /**
-     * Returns the tab size set for the document, defaulting to 8.
-     *
-     * @implSpec This implementation calls {@link #getTabSize() getTabSize()}.
-     *
-     * @return the tab size
-     */
-    protected float getFractionalTabSize() {
-        return getTabSize();
-    }
-
-    /**
      * Renders a line of text, suppressing whitespace at the end
      * and expanding any tabs.  This is implemented to make calls
      * to the methods <code>drawUnselectedText</code> and
@@ -111,8 +104,17 @@
      * @param y the starting Y position &gt;= 0
      * @see #drawUnselectedText
      * @see #drawSelectedText
+     *
+     * @deprecated replaced by
+     *     {@link #drawLine(int, int, Graphics2D, float, float)}
      */
+    @Deprecated(since = "9")
     protected void drawLine(int p0, int p1, Graphics g, int x, int y) {
+        drawLineImpl(p0, p1, g, x, y, false);
+    }
+
+    private void drawLineImpl(int p0, int p1, Graphics g, float x, float y,
+                              boolean useFPAPI) {
         Element lineMap = getElement();
         Element line = lineMap.getElement(lineMap.getElementIndex(p0));
         Element elem;
@@ -143,10 +145,6 @@
      * <code>drawSelectedText</code> so that the way selected and
      * unselected text are rendered can be customized.
      *
-     * @implSpec This implementation calls
-     * {@link #drawLine(int, int, Graphics, int, int)
-     * drawLine(p0, p1, (Graphics) g, (int) x, (int) y)}.
-     *
      * @param p0 the starting document location to use &gt;= 0
      * @param p1 the ending document location to use &gt;= p1
      * @param g the graphics context
@@ -154,12 +152,17 @@
      * @param y the starting Y position &gt;= 0
      * @see #drawUnselectedText
      * @see #drawSelectedText
+     *
+     * @since 9
      */
     protected void drawLine(int p0, int p1, Graphics2D g, float x, float y) {
-        drawLine(p0, p1, (Graphics) g, (int) x, (int) y);
+        drawLineImpl(p0, p1, g, x, y, true);
     }
 
-    private int drawText(Element elem, int p0, int p1, Graphics g, int x, int y) throws BadLocationException {
+    private float drawText(Element elem, int p0, int p1, Graphics g,
+                           float x, float y)
+            throws BadLocationException
+    {
         p1 = Math.min(getDocument().getLength(), p1);
         AttributeSet attr = elem.getAttributes();
 
@@ -171,23 +174,23 @@
         } else {
             if (sel0 == sel1 || selected == unselected) {
                 // no selection, or it is invisible
-                x = drawUnselectedText(g, x, y, p0, p1);
+                x = callDrawUnselectedText(g, x, y, p0, p1);
             } else if ((p0 >= sel0 && p0 <= sel1) && (p1 >= sel0 && p1 <= sel1)) {
-                x = drawSelectedText(g, x, y, p0, p1);
+                x = callDrawSelectedText(g, x, y, p0, p1);
             } else if (sel0 >= p0 && sel0 <= p1) {
                 if (sel1 >= p0 && sel1 <= p1) {
-                    x = drawUnselectedText(g, x, y, p0, sel0);
-                    x = drawSelectedText(g, x, y, sel0, sel1);
-                    x = drawUnselectedText(g, x, y, sel1, p1);
+                    x = callDrawUnselectedText(g, x, y, p0, sel0);
+                    x = callDrawSelectedText(g, x, y, sel0, sel1);
+                    x = callDrawUnselectedText(g, x, y, sel1, p1);
                 } else {
-                    x = drawUnselectedText(g, x, y, p0, sel0);
-                    x = drawSelectedText(g, x, y, sel0, p1);
+                    x = callDrawUnselectedText(g, x, y, p0, sel0);
+                    x = callDrawSelectedText(g, x, y, sel0, p1);
                 }
             } else if (sel1 >= p0 && sel1 <= p1) {
-                x = drawSelectedText(g, x, y, p0, sel1);
-                x = drawUnselectedText(g, x, y, sel1, p1);
+                x = callDrawSelectedText(g, x, y, p0, sel1);
+                x = callDrawUnselectedText(g, x, y, sel1, p1);
             } else {
-                x = drawUnselectedText(g, x, y, p0, p1);
+                x = callDrawUnselectedText(g, x, y, p0, p1);
             }
         }
 
@@ -205,14 +208,36 @@
      * @param p1 the ending position in the model &gt;= p0
      * @return the X location of the end of the range &gt;= 0
      * @exception BadLocationException if the range is invalid
+     *
+     * @deprecated replaced by
+     *     {@link #drawUnselectedText(Graphics2D, float, float, int, int)}
      */
+    @Deprecated(since = "9")
     protected int drawUnselectedText(Graphics g, int x, int y,
-                                     int p0, int p1) throws BadLocationException {
+                                     int p0, int p1) throws BadLocationException
+    {
+        return (int) drawUnselectedTextImpl(g, x, y, p0, p1, false);
+    }
+
+    private float callDrawUnselectedText(Graphics g, float x, float y,
+                                         int p0, int p1)
+                                         throws BadLocationException
+    {
+        return drawUnselectedTextOverridden && g instanceof Graphics2D
+                ? drawUnselectedText((Graphics2D) g, x, y, p0, p1)
+                : drawUnselectedText(g, (int) x, (int) y, p0, p1);
+    }
+
+    private float drawUnselectedTextImpl(Graphics g, float x, float y,
+                                         int p0, int p1, boolean useFPAPI)
+            throws BadLocationException
+    {
         g.setColor(unselected);
         Document doc = getDocument();
         Segment segment = SegmentCache.getSharedSegment();
         doc.getText(p0, p1 - p0, segment);
-        int ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0);
+        float ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0,
+                                             null, useFPAPI);
         SegmentCache.releaseSharedSegment(segment);
         return ret;
     }
@@ -221,10 +246,6 @@
      * Renders the given range in the model as normal unselected
      * text.
      *
-     * @implSpec This implementation calls
-     * {@link #drawUnselectedText(Graphics, int, int, int, int)
-     * drawUnselectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
-     *
      * @param g the graphics context
      * @param x the starting X coordinate &gt;= 0
      * @param y the starting Y coordinate &gt;= 0
@@ -232,10 +253,12 @@
      * @param p1 the ending position in the model &gt;= p0
      * @return the X location of the end of the range &gt;= 0
      * @exception BadLocationException if the range is invalid
+     *
+     * @since 9
      */
     protected float drawUnselectedText(Graphics2D g, float x, float y,
                                      int p0, int p1) throws BadLocationException {
-        return drawUnselectedText((Graphics) g, (int) x, (int) y, p0, p1);
+        return drawUnselectedTextImpl(g, x, y, p0, p1, true);
     }
     /**
      * Renders the given range in the model as selected text.  This
@@ -250,14 +273,37 @@
      * @param p1 the ending position in the model &gt;= p0
      * @return the location of the end of the range.
      * @exception BadLocationException if the range is invalid
+     *
+     * @deprecated replaced by
+     *     {@link #drawSelectedText(Graphics2D, float, float, int, int)}
      */
-    protected int drawSelectedText(Graphics g, int x,
-                                   int y, int p0, int p1) throws BadLocationException {
+    @Deprecated(since = "9")
+    protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
+            throws BadLocationException
+    {
+        return (int) drawSelectedTextImpl(g, x, y, p0, p1, false);
+    }
+
+    private float callDrawSelectedText(Graphics g, float x, float y,
+                                       int p0, int p1)
+                                       throws BadLocationException
+    {
+        return drawSelectedTextOverridden && g instanceof Graphics2D
+                ? drawSelectedText((Graphics2D) g, x, y, p0, p1)
+                : drawSelectedText(g, (int) x, (int) y, p0, p1);
+    }
+
+    private float drawSelectedTextImpl(Graphics g, float x, float y,
+                                       int p0, int p1,
+                                       boolean useFPAPI)
+            throws BadLocationException
+    {
         g.setColor(selected);
         Document doc = getDocument();
         Segment segment = SegmentCache.getSharedSegment();
         doc.getText(p0, p1 - p0, segment);
-        int ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0);
+        float ret = Utilities.drawTabbedText(this, segment, x, y, g, this, p0,
+                                             null, useFPAPI);
         SegmentCache.releaseSharedSegment(segment);
         return ret;
     }
@@ -268,10 +314,6 @@
      * the hosting component.  It assumes the highlighter will render
      * the selected background.
      *
-     * @implSpec This implementation calls
-     * {@link #drawSelectedText(Graphics, int, int, int, int)
-     * drawSelectedText((Graphics)g, (int) x, (int) y, p0, p1)}.
-     *
      * @param g the graphics context
      * @param x the starting X coordinate &gt;= 0
      * @param y the starting Y coordinate &gt;= 0
@@ -279,10 +321,12 @@
      * @param p1 the ending position in the model &gt;= p0
      * @return the location of the end of the range.
      * @exception BadLocationException if the range is invalid
+     *
+     * @since 9
      */
     protected float drawSelectedText(Graphics2D g, float x, float y,
                                      int p0, int p1) throws BadLocationException {
-        return drawSelectedText((Graphics) g, (int) x, (int) y, p0, p1);
+        return drawSelectedTextImpl(g, x, y, p0, p1, true);
     }
     /**
      * Gives access to a buffer that can be used to fetch
@@ -395,7 +439,13 @@
         Component host = getContainer();
         Font f = host.getFont();
         metrics = host.getFontMetrics(f);
-        tabSize = getTabSize() * metrics.charWidth('m');
+        if (useFloatingPointAPI) {
+            FontRenderContext frc = metrics.getFontRenderContext();
+            float tabWidth = (float) f.getStringBounds("m", frc).getWidth();
+            tabSize = getTabSize() * tabWidth;
+        } else {
+            tabSize = getTabSize() * metrics.charWidth('m');
+        }
     }
 
     // --- TabExpander methods ------------------------------------------
@@ -413,7 +463,7 @@
     public float nextTabStop(float x, int tabOffset) {
         if (tabSize == 0)
             return x;
-        int ntabs = ((int) x - tabBase) / tabSize;
+        float ntabs = (x - tabBase) / tabSize;
         return tabBase + ((ntabs + 1) * tabSize);
     }
 
@@ -591,7 +641,7 @@
     Segment lineBuffer;
     boolean widthChanging;
     int tabBase;
-    int tabSize;
+    float tabSize;
     boolean wordWrap;
 
     int sel0;
@@ -668,6 +718,7 @@
             int end = getEndOffset();
             int p0 = start;
             int[] lineEnds = getLineEnds();
+            boolean useDrawLineFP = drawLineOverridden && g instanceof Graphics2D;
             for (int i = 0; i < lineCount; i++) {
                 int p1 = (lineEnds == null) ? end :
                                              start + lineEnds[i];
@@ -677,8 +728,11 @@
                                   : p1;
                     dh.paintLayeredHighlights(g, p0, hOffset, a, host, this);
                 }
-                drawLine(p0, p1, g, x, y);
-
+                if (useDrawLineFP) {
+                    drawLine(p0, p1, (Graphics2D) g, (float) x, (float) y);
+                } else {
+                    drawLine(p0, p1, g, x, y);
+                }
                 p0 = p1;
                 y += metrics.getHeight();
             }
@@ -929,4 +983,47 @@
         int lineCount;
         SoftReference<int[]> lineCache = null;
     }
+
+    private final boolean drawLineOverridden;
+    private final boolean drawSelectedTextOverridden;
+    private final boolean drawUnselectedTextOverridden;
+    private final boolean useFloatingPointAPI;
+
+    {
+        final Class<?> CLS = getClass();
+        final Class<?> INT = Integer.TYPE;
+        final Class<?> FP = Float.TYPE;
+
+        drawLineOverridden = AccessController
+                .doPrivileged(new PrivilegedAction<Boolean>() {
+            @Override
+            public Boolean run() {
+                Class<?>[] intTypes = {INT, INT, Graphics.class, INT, INT};
+                Class<?>[] fpTypes = {INT, INT, Graphics2D.class, FP, FP};
+                return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes);
+            }
+        });
+
+        drawUnselectedTextOverridden = AccessController
+                .doPrivileged(new PrivilegedAction<Boolean>() {
+            @Override
+            public Boolean run() {
+                Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
+                Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
+                return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes);
+            }
+        });
+
+        drawSelectedTextOverridden = AccessController
+                .doPrivileged(new PrivilegedAction<Boolean>() {
+            @Override
+            public Boolean run() {
+                Class<?>[] intTypes = {Graphics.class, INT, INT, INT, INT};
+                Class<?>[] fpTypes = {Graphics2D.class, FP, FP, INT, INT};
+                return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes);
+            }
+        });
+
+        useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden;
+    }
 }
--- a/jdk/src/java.desktop/share/classes/module-info.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/module-info.java	Thu Oct 27 21:22:57 2016 +0000
@@ -88,6 +88,9 @@
     exports sun.awt to
         jdk.accessibility;
 
+    exports com.sun.awt to
+        jdk.desktop;
+
     uses java.awt.im.spi.InputMethodDescriptor;
     uses javax.accessibility.AccessibilityProvider;
     uses javax.imageio.spi.ImageInputStreamSpi;
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java	Thu Oct 27 21:22:57 2016 +0000
@@ -107,7 +107,7 @@
         /*
          * Requests focus to the component.
          */
-        boolean requestFocus(Component comp, Cause cause);
+        void requestFocus(Component comp, Cause cause);
         /*
          * Determines if the component can gain focus.
          */
@@ -1392,4 +1392,4 @@
         AWTAccessor.dropTargetContextAccessor = accessor;
     }
 
-}
\ No newline at end of file
+}
--- a/jdk/src/java.desktop/share/classes/sun/awt/IconInfo.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/IconInfo.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -103,7 +103,7 @@
         }
         this.scaledWidth = width;
         this.scaledHeight = height;
-        this.rawLength = getScaledRawLength();
+        this.rawLength = getScaledRawLength(width, height);
     }
 
     /*
@@ -112,14 +112,14 @@
     public void setScaledSize(int width, int height) {
         this.scaledWidth = width;
         this.scaledHeight = height;
-        this.rawLength = getScaledRawLength();
+        this.rawLength = getScaledRawLength(width, height);
     }
 
     /*
     * returns scaled raw length.
      */
-    private int getScaledRawLength() {
-        int scaledWidthAndHeight[] = getScaledWidthAndHeight(width, height);
+    private int getScaledRawLength(int w, int h) {
+        int scaledWidthAndHeight[] = getScaledWidthAndHeight(w, h);
         return scaledWidthAndHeight[0] * scaledWidthAndHeight[1] + 2;
     }
 
--- a/jdk/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java	Thu Oct 27 21:22:57 2016 +0000
@@ -142,8 +142,8 @@
     }
 
     // WARNING: Don't call it on the Toolkit thread.
-    public static boolean requestFocusFor(Component target, FocusEvent.Cause cause) {
-        return AWTAccessor.getComponentAccessor().requestFocus(target, cause);
+    public static void requestFocusFor(Component target, FocusEvent.Cause cause) {
+        AWTAccessor.getComponentAccessor().requestFocus(target, cause);
     }
 
     // WARNING: Don't call it on the Toolkit thread.
--- a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1512,9 +1512,9 @@
      */
     protected abstract boolean syncNativeQueue(final long timeout);
 
-    private boolean eventDispatched = false;
-    private boolean queueEmpty = false;
-    private final Object waitLock = "Wait Lock";
+    private boolean eventDispatched;
+    private boolean queueEmpty;
+    private final Object waitLock = new Object();
 
     private boolean isEQEmpty() {
         EventQueue queue = getSystemEventQueueImpl();
@@ -1531,10 +1531,11 @@
     @SuppressWarnings("serial")
     protected final boolean waitForIdle(final long timeout) {
         flushPendingEvents();
-        boolean queueWasEmpty = isEQEmpty();
-        queueEmpty = false;
-        eventDispatched = false;
-        synchronized(waitLock) {
+        final boolean queueWasEmpty;
+        synchronized (waitLock) {
+            queueWasEmpty = isEQEmpty();
+            queueEmpty = false;
+            eventDispatched = false;
             postEvent(AppContext.getAppContext(),
                       new PeerEvent(getSystemEventQueueImpl(), null, PeerEvent.LOW_PRIORITY_EVENT) {
                           @Override
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1902,11 +1902,7 @@
             clipRegion = devClip;
         } else if (usrClip instanceof Rectangle2D) {
             clipState = CLIP_RECTANGULAR;
-            if (usrClip instanceof Rectangle) {
-                clipRegion = devClip.getIntersection((Rectangle)usrClip);
-            } else {
-                clipRegion = devClip.getIntersection(usrClip.getBounds());
-            }
+            clipRegion = devClip.getIntersection((Rectangle2D) usrClip);
         } else {
             PathIterator cpi = usrClip.getPathIterator(null);
             int box[] = new int[4];
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/Region.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/Region.java	Thu Oct 27 21:22:57 2016 +0000
@@ -28,10 +28,13 @@
 import java.awt.Rectangle;
 import java.awt.Shape;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
 import java.awt.geom.RectangularShape;
 
 import sun.java2d.loops.TransformHelper;
 
+import static java.lang.Double.isNaN;
+
 /**
  * This class encapsulates a definition of a two dimensional region which
  * consists of a number of Y ranges each containing multiple X bands.
@@ -118,6 +121,34 @@
     }
 
     /**
+     * Returns the closest {@code int} to the argument, with ties rounding to
+     * negative infinity.
+     * <p>
+     * Special cases:
+     * <ul><li>If the argument is NaN, the result is 0.
+     * <li>If the argument is negative infinity or any value less than or
+     * equal to the value of {@code Integer.MIN_VALUE}, the result is
+     * equal to the value of {@code Integer.MIN_VALUE}.
+     * <li>If the argument is positive infinity or any value greater than or
+     * equal to the value of {@code Integer.MAX_VALUE}, the result is
+     * equal to the value of {@code Integer.MAX_VALUE}.</ul>
+     *
+     * @param   coordinate a floating-point value to be rounded to an integer
+     * @return  the value of the argument rounded to the nearest
+     *          {@code int} value.
+     */
+    public static int clipRound(final double coordinate) {
+        final double newv = coordinate - 0.5;
+        if (newv < Integer.MIN_VALUE) {
+            return Integer.MIN_VALUE;
+        }
+        if (newv > Integer.MAX_VALUE) {
+            return Integer.MAX_VALUE;
+        }
+        return (int) Math.ceil(newv);
+    }
+
+    /**
      * Multiply the scale factor {@code sv} and the value {@code v} with
      * appropriate clipping to the bounds of Integer resolution. If the answer
      * would be greater than {@code Integer.MAX_VALUE} then {@code
@@ -559,6 +590,33 @@
 
     /**
      * Returns a Region object that represents the intersection of
+     * this object with the specified Rectangle2D. The return value
+     * may be this same object if no clipping occurs.
+     */
+    public Region getIntersection(final Rectangle2D r) {
+        if (r instanceof Rectangle) {
+            return getIntersection((Rectangle) r);
+        }
+        return getIntersectionXYXY(r.getMinX(), r.getMinY(), r.getMaxX(),
+                                   r.getMaxY());
+    }
+
+    /**
+     * Returns a Region object that represents the intersection of
+     * this object with the specified rectangular area. The return
+     * value may be this same object if no clipping occurs.
+     */
+    public Region getIntersectionXYXY(double lox, double loy, double hix,
+                                      double hiy) {
+        if (isNaN(lox) || isNaN(loy) || isNaN(hix) || isNaN(hiy)) {
+            return EMPTY_REGION;
+        }
+        return getIntersectionXYXY(clipRound(lox), clipRound(loy),
+                                   clipRound(hix), clipRound(hiy));
+    }
+
+    /**
+     * Returns a Region object that represents the intersection of
      * this object with the specified rectangular area.  The return
      * value may be this same object if no clipping occurs.
      */
--- a/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java	Thu Oct 27 21:22:57 2016 +0000
@@ -30,6 +30,7 @@
 import static java.awt.RenderingHints.*;
 import java.awt.event.*;
 import java.awt.font.*;
+import java.awt.geom.Rectangle2D;
 import java.awt.geom.AffineTransform;
 import static java.awt.geom.AffineTransform.TYPE_FLIP;
 import static java.awt.geom.AffineTransform.TYPE_TRANSLATION;
@@ -723,10 +724,31 @@
                                  int length,
                                  int x,
                                  int y) {
+        return (int) drawChars(c, g, data, offset, length, x, y, false);
+    }
+
+    public static float drawChars(JComponent c, Graphics g,
+                                 char[] data,
+                                 int offset,
+                                 int length,
+                                 float x,
+                                 float y) {
+        return drawChars(c, g, data, offset, length, x, y, true);
+    }
+
+    public static float drawChars(JComponent c, Graphics g,
+                                 char[] data,
+                                 int offset,
+                                 int length,
+                                 float x,
+                                 float y,
+                                 boolean useFPAPI) {
         if ( length <= 0 ) { //no need to paint empty strings
             return x;
         }
-        int nextX = x + getFontMetrics(c, g).charsWidth(data, offset, length);
+        float nextX = x + getFontCharsWidth(data, offset, length,
+                                            getFontMetrics(c, g),
+                                            useFPAPI);
         if (isPrinting(g)) {
             Graphics2D g2d = getGraphics2D(g);
             if (g2d != null) {
@@ -766,8 +788,14 @@
         Object aaHint = (c == null)
                             ? null
                             : c.getClientProperty(KEY_TEXT_ANTIALIASING);
-        if (aaHint != null && (g instanceof Graphics2D)) {
-            Graphics2D g2 = (Graphics2D)g;
+
+        if (!(g instanceof Graphics2D)) {
+            g.drawChars(data, offset, length, (int) x, (int) y);
+            return nextX;
+        }
+
+        Graphics2D g2 = (Graphics2D) g;
+        if (aaHint != null) {
 
             Object oldContrast = null;
             Object oldAAValue = g2.getRenderingHint(KEY_TEXT_ANTIALIASING);
@@ -788,7 +816,7 @@
                 }
             }
 
-            g.drawChars(data, offset, length, x, y);
+            g2.drawString(new String(data, offset, length), x, y);
 
             if (oldAAValue != null) {
                 g2.setRenderingHint(KEY_TEXT_ANTIALIASING, oldAAValue);
@@ -798,19 +826,59 @@
             }
         }
         else {
-            g.drawChars(data, offset, length, x, y);
+            g2.drawString(new String(data, offset, length), x, y);
         }
         return nextX;
     }
 
+    public static float getFontCharWidth(char c, FontMetrics fm,
+                                         boolean useFPAPI)
+    {
+        return getFontCharsWidth(new char[]{c}, 0, 1, fm, useFPAPI);
+    }
+
+    public static float getFontCharsWidth(char[] data, int offset, int len,
+                                          FontMetrics fm,
+                                          boolean useFPAPI)
+    {
+        return len == 0 ? 0 : getFontStringWidth(new String(data, offset, len),
+                                                 fm, useFPAPI);
+    }
+
+    public static float getFontStringWidth(String data, FontMetrics fm,
+                                           boolean useFPAPI)
+    {
+        if (useFPAPI) {
+            Rectangle2D bounds = fm.getFont()
+                    .getStringBounds(data, fm.getFontRenderContext());
+            return (float) bounds.getWidth();
+        } else {
+            return fm.stringWidth(data);
+        }
+    }
+
     /*
      * see documentation for drawChars
      * returns the advance
      */
     public static float drawString(JComponent c, Graphics g,
                                    AttributedCharacterIterator iterator,
-                                   int x,
-                                   int y) {
+                                   int x, int y)
+    {
+        return drawStringImpl(c, g, iterator, x, y);
+    }
+
+    public static float drawString(JComponent c, Graphics g,
+                                   AttributedCharacterIterator iterator,
+                                   float x, float y)
+    {
+        return drawStringImpl(c, g, iterator, x, y);
+    }
+
+    private static float drawStringImpl(JComponent c, Graphics g,
+                                   AttributedCharacterIterator iterator,
+                                   float x, float y)
+    {
 
         float retVal;
         boolean isPrinting = isPrinting(g);
@@ -825,8 +893,8 @@
 
         Graphics2D g2d = getGraphics2D(g);
         if (g2d == null) {
-            g.drawString(iterator,x,y); //for the cases where advance
-                                        //matters it should not happen
+            g.drawString(iterator, (int)x, (int)y); //for the cases where advance
+                                                    //matters it should not happen
             retVal = x;
 
         } else {
--- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c	Thu Oct 27 21:22:57 2016 +0000
@@ -25,7 +25,12 @@
 
 #include "splashscreen_impl.h"
 #include "splashscreen_gfx_impl.h"
-
+#define BUFF_SIZE 1024
+#ifdef _MSC_VER
+# ifndef snprintf
+#       define snprintf _snprintf
+# endif
+#endif
 int splashIsVisible = 0;
 
 Splash *
@@ -392,5 +397,101 @@
 
 SPLASHEXPORT int
 SplashGetScaledImgNameMaxPstfixLen(const char *fileName){
-    return strlen(fileName) + strlen(".java-scale-200") + 1;
+    return strlen(fileName) + strlen("@100pct") + 1;
 }
+
+jboolean GetScaledImageName(const char *fileName, char *scaleImageName,
+        float *scaleFactor, const size_t scaledImageLength) {
+    if (*scaleFactor > 1.0) {
+        FILE *fp = NULL;
+        char scaledImgPct[BUFF_SIZE];
+        char scaledImgX[BUFF_SIZE];
+        char *scaledImageXName = NULL;
+        char *scaledImagePctName = malloc(scaledImageLength);
+        char *dupFileName = strdup(fileName);
+        char *fileExtension = strrchr(dupFileName, '.');
+        size_t lengthPct = 0;
+        size_t lengthX = 0;
+        int retValPct = 0;
+        int retValX = 0;
+        jboolean isPctScaledImage = (*scaleFactor * 100) != ((int) (*scaleFactor)) *100;
+        snprintf(scaledImgPct, BUFF_SIZE, "%s%d%s", "@",
+                (int) (*scaleFactor * 100), "pct");
+        if (!isPctScaledImage) {
+            scaledImageXName = malloc(scaledImageLength);
+            snprintf(scaledImgX, BUFF_SIZE, "%s%d%s", "@", (int) (*scaleFactor), "x");
+        }
+        /*File is missing extension */
+        if (fileExtension == NULL) {
+            lengthPct = strlen(dupFileName) +
+                    strlen(scaledImgPct) + 1;
+            if (!isPctScaledImage) {
+                lengthX = strlen(dupFileName) +
+                        strlen(scaledImgX) + 1;
+            }
+            if (lengthPct > scaledImageLength || lengthX > scaledImageLength) {
+                cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
+                return JNI_FALSE;
+            }
+            retValPct = snprintf(scaledImagePctName, lengthPct, "%s%s", dupFileName,
+                    scaledImgPct);
+            if (!isPctScaledImage) {
+                retValX = snprintf(scaledImageXName, lengthX, "%s%s", dupFileName,
+                        scaledImgX);
+            }
+            if ((retValPct < 0 || (retValPct > lengthPct - 1)) ||
+                    (retValX < 0 || (retValX > lengthX - 1))) {
+                cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
+                return JNI_FALSE;
+            }
+        } else {
+            int length_Without_Ext = fileExtension - dupFileName;
+            lengthPct = length_Without_Ext + strlen(scaledImgPct) +
+                    strlen(fileExtension) + 1;
+            if (!isPctScaledImage) {
+                lengthX = length_Without_Ext + strlen(scaledImgX) +
+                        strlen(fileExtension) + 1;
+            }
+            if (lengthPct > scaledImageLength || lengthX > scaledImageLength) {
+                cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
+                return JNI_FALSE;
+            }
+            retValPct = snprintf(scaledImagePctName, lengthPct, "%.*s%s%s",
+                    length_Without_Ext, dupFileName, scaledImgPct, fileExtension);
+            if (!isPctScaledImage) {
+                retValX = snprintf(scaledImageXName, lengthX, "%.*s%s%s",
+                        length_Without_Ext, dupFileName, scaledImgX, fileExtension);
+            }
+            if ((retValPct < 0 || (retValPct > lengthPct - 1)) ||
+                    (retValX < 0 || (retValX > lengthX - 1))) {
+                cleanUp(dupFileName, scaledImageXName, scaledImagePctName, scaleFactor);
+                return JNI_FALSE;
+            }
+        }
+        free(dupFileName);
+        if (!(fp = fopen(scaledImagePctName, "r"))) {
+            if (!isPctScaledImage && (fp = fopen(scaledImageXName, "r"))) {
+                fclose(fp);
+                strcpy(scaleImageName, scaledImageXName);
+                free(scaledImageXName);
+                free(scaledImagePctName);
+                return JNI_TRUE;
+            }
+            cleanUp(NULL, scaledImageXName, scaledImagePctName, scaleFactor);
+            return JNI_FALSE;
+        }
+        fclose(fp);
+        strcpy(scaleImageName, scaledImagePctName);
+        free(scaledImageXName);
+        free(scaledImagePctName);
+        return JNI_TRUE;
+    }
+    return JNI_FALSE;
+}
+
+void cleanUp(char *fName, char *xName, char *pctName, float *scaleFactor) {
+    *scaleFactor = 1;
+    free(fName);
+    free(xName);
+    free(pctName);
+}
--- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h	Thu Oct 27 21:22:57 2016 +0000
@@ -150,7 +150,9 @@
 void SplashCleanup(Splash * splash);
 void SplashSetScaleFactor(float scaleFactor);
 int  SplashGetScaledImgNameMaxPstfixLen(const char *fileName);
-
+void cleanUp(char *fName, char *xName, char *pctName, float *scaleFactor);
+jboolean GetScaledImageName(const char *fileName, char *scaledImgName,
+                  float *scaleFactor, const size_t scaledImageLength);
 typedef struct SplashStream {
     int (*read)(void* pStream, void* pData, int nBytes);
     int (*peek)(void* pStream);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java	Thu Oct 27 21:22:57 2016 +0000
@@ -301,7 +301,10 @@
     }
 
     private void resetWMSetInsets() {
-        wm_set_insets = null;
+        if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
+            currentInsets = new Insets(0, 0, 0, 0);
+            wm_set_insets = null;
+        }
     }
 
     public void handlePropertyNotify(XEvent xev) {
@@ -352,7 +355,7 @@
                         // and the initially guessed insets were wrong
                         handleCorrectInsets(in);
                     }
-                } else if (!dimensions.isClientSizeSet()) {
+                } else if (!insets_corrected || !dimensions.isClientSizeSet()) {
                     insets_corrected = true;
                     // initial insets were guessed correctly. Re-request
                     // frame bounds because they may be changed by WM if the
@@ -908,7 +911,6 @@
     public void setResizable(boolean resizable) {
         int fs = winAttr.functions;
         if (!isResizable() && resizable) {
-            currentInsets = new Insets(0, 0, 0, 0);
             resetWMSetInsets();
             if (!isEmbedded()) {
                 setReparented(false);
@@ -922,7 +924,6 @@
             winAttr.functions = fs;
             XWM.setShellResizable(this);
         } else if (isResizable() && !resizable) {
-            currentInsets = new Insets(0, 0, 0, 0);
             resetWMSetInsets();
             if (!isEmbedded()) {
                 setReparented(false);
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/Xrandr.h	Thu Oct 27 21:22:57 2016 +0000
@@ -118,6 +118,19 @@
     RRMode          *modes;
 } XRROutputInfo;
 
+typedef struct {
+    Time            timestamp;
+    int             x, y;
+    unsigned int    width, height;
+    RRMode          mode;
+    Rotation        rotation;
+    int             noutput;
+    RROutput        *outputs;
+    Rotation        rotations;
+    int             npossible;
+    RROutput        *possible;
+} XRRCrtcInfo;
+
 XRRScreenResources *XRRGetScreenResources (Display *dpy, Window window);
 
 void XRRFreeScreenResources (XRRScreenResources *resources);
@@ -126,6 +139,11 @@
                                                                RROutput output);
 void XRRFreeOutputInfo (XRROutputInfo *outputInfo);
 
+XRRCrtcInfo *XRRGetCrtcInfo (Display *dpy, XRRScreenResources *resources,
+                                                                   RRCrtc crtc);
+void XRRFreeCrtcInfo (XRRCrtcInfo *crtcInfo);
+
+
 /* internal representation is private to the library */
 typedef struct _XRRScreenConfiguration XRRScreenConfiguration;
 
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c	Thu Oct 27 21:22:57 2016 +0000
@@ -1667,6 +1667,11 @@
 
 typedef void (*XRRFreeOutputInfoType)(XRROutputInfo *outputInfo);
 
+typedef XRRCrtcInfo* (*XRRGetCrtcInfoType)(Display *dpy,
+                                    XRRScreenResources *resources, RRCrtc crtc);
+
+typedef void (*XRRFreeCrtcInfoType)(XRRCrtcInfo *crtcInfo);
+
 static XRRQueryVersionType               awt_XRRQueryVersion;
 static XRRGetScreenInfoType              awt_XRRGetScreenInfo;
 static XRRFreeScreenConfigInfoType       awt_XRRFreeScreenConfigInfo;
@@ -1680,6 +1685,8 @@
 static XRRFreeScreenResourcesType        awt_XRRFreeScreenResources;
 static XRRGetOutputInfoType              awt_XRRGetOutputInfo;
 static XRRFreeOutputInfoType             awt_XRRFreeOutputInfo;
+static XRRGetCrtcInfoType                awt_XRRGetCrtcInfo;
+static XRRFreeCrtcInfoType               awt_XRRFreeCrtcInfo;
 
 #define LOAD_XRANDR_FUNC(f) \
     do { \
@@ -1755,6 +1762,8 @@
     LOAD_XRANDR_FUNC(XRRFreeScreenResources);
     LOAD_XRANDR_FUNC(XRRGetOutputInfo);
     LOAD_XRANDR_FUNC(XRRFreeOutputInfo);
+    LOAD_XRANDR_FUNC(XRRGetCrtcInfo);
+    LOAD_XRANDR_FUNC(XRRFreeCrtcInfo);
 
     return JNI_TRUE;
 }
@@ -1895,7 +1904,49 @@
 
     AWT_LOCK();
 
-    if (screen < ScreenCount(awt_display)) {
+    if (usingXinerama && XScreenCount(awt_display) > 0) {
+        XRRScreenResources *res = awt_XRRGetScreenResources(awt_display,
+                                                    RootWindow(awt_display, 0));
+        if (res) {
+            if (res->noutput > screen) {
+                XRROutputInfo *output_info = awt_XRRGetOutputInfo(awt_display,
+                                                     res, res->outputs[screen]);
+                if (output_info) {
+                    if (output_info->crtc) {
+                        XRRCrtcInfo *crtc_info =
+                                    awt_XRRGetCrtcInfo (awt_display, res,
+                                                        output_info->crtc);
+                        if (crtc_info) {
+                            if (crtc_info->mode) {
+                                int i;
+                                for (i = 0; i < res->nmode; i++) {
+                                    XRRModeInfo *mode = &res->modes[i];
+                                    if (mode->id == crtc_info->mode) {
+                                        float rate = 0;
+                                        if (mode->hTotal && mode->vTotal) {
+                                             rate = ((float)mode->dotClock /
+                                                    ((float)mode->hTotal *
+                                                    (float)mode->vTotal));
+                                        }
+                                        displayMode = X11GD_CreateDisplayMode(
+                                                           env,
+                                                           mode->width,
+                                                           mode->height,
+                                                           BIT_DEPTH_MULTI,
+                                                           (int)(rate +.2));
+                                        break;
+                                    }
+                                }
+                            }
+                            awt_XRRFreeCrtcInfo(crtc_info);
+                        }
+                    }
+                    awt_XRRFreeOutputInfo(output_info);
+                }
+            }
+            awt_XRRFreeScreenResources(res);
+        }
+    } else {
 
         config = awt_XRRGetScreenInfo(awt_display,
                                       RootWindow(awt_display, screen));
@@ -1954,7 +2005,7 @@
                                                      res, res->outputs[screen]);
                 if (output_info) {
                     int i;
-                    for (i = 0; i < res->nmode; i++) {
+                    for (i = 0; i < output_info->nmode; i++) {
                         RRMode m = output_info->modes[i];
                         int j;
                         XRRModeInfo *mode;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c	Thu Oct 27 21:22:57 2016 +0000
@@ -35,9 +35,6 @@
 #include <jni_util.h>
 #include "awt.h"
 
-#define GTHREAD_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gthread-2.0", "0")
-#define GTHREAD_LIB JNI_LIB_NAME("gthread-2.0")
-
 #define GTK_TYPE_BORDER                 ((*fp_gtk_border_get_type)())
 
 #define G_TYPE_FUNDAMENTAL_SHIFT        (2)
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h	Thu Oct 27 21:22:57 2016 +0000
@@ -351,9 +351,6 @@
   guint ellipsize : 3;
 };
 
-
-typedef struct _GThreadFunctions GThreadFunctions;
-
 /**
  * Returns :
  * NULL if the GLib library is compatible with the given version, or a string
@@ -449,17 +446,6 @@
 static void (*fp_g_list_free) (GList *list);
 static void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func);
 
-/**
- * This function is available for GLIB > 2.20, so it MUST be
- * called within GLIB_CHECK_VERSION(2, 20, 0) check.
- */
-static gboolean (*fp_g_thread_get_initialized)(void);
-
-static void (*fp_g_thread_init)(GThreadFunctions *vtable);
-static void (*fp_gdk_threads_init)(void);
-static void (*fp_gdk_threads_enter)(void);
-static void (*fp_gdk_threads_leave)(void);
-
 static gboolean (*fp_gtk_show_uri)(GdkScreen *screen, const gchar *uri,
     guint32 timestamp, GError **error);
 
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c	Thu Oct 27 21:22:57 2016 +0000
@@ -35,6 +35,7 @@
 #include "awt.h"
 
 static void *gtk3_libhandle = NULL;
+static void *gthread_libhandle = NULL;
 
 static jmp_buf j;
 
@@ -87,6 +88,15 @@
     return result;
 }
 
+static void* dl_symbol_gthread(const char* name)
+{
+    void* result = dlsym(gthread_libhandle, name);
+    if (!result)
+        longjmp(j, NO_SYMBOL_EXCEPTION);
+
+    return result;
+}
+
 gboolean gtk3_check(const char* lib_name, gboolean load)
 {
     if (gtk3_libhandle != NULL) {
@@ -261,6 +271,13 @@
         return FALSE;
     }
 
+    gthread_libhandle = dlopen(GTHREAD_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
+    if (gthread_libhandle == NULL) {
+        gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL);
+        if (gthread_libhandle == NULL)
+            return FALSE;
+    }
+
     if (setjmp(j) == 0)
     {
         fp_gtk_check_version = dl_symbol("gtk_check_version");
@@ -530,8 +547,8 @@
 
         fp_g_path_get_dirname = dl_symbol("g_path_get_dirname");
 
-        fp_gdk_threads_enter = &empty;
-        fp_gdk_threads_leave = &empty;
+        fp_gdk_threads_enter = dl_symbol("gdk_threads_enter");
+        fp_gdk_threads_leave = dl_symbol("gdk_threads_leave");
 
         /**
          * Functions for sun_awt_X11_GtkFileDialogPeer.c
@@ -556,6 +573,9 @@
         dlclose(gtk3_libhandle);
         gtk3_libhandle = NULL;
 
+        dlclose(gthread_libhandle);
+        gthread_libhandle = NULL;
+
         return NULL;
     }
 
@@ -651,6 +671,7 @@
 
     dlerror();
     dlclose(gtk3_libhandle);
+    dlclose(gthread_libhandle);
     if ((gtk3_error = dlerror()) != NULL)
     {
         return FALSE;
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h	Thu Oct 27 21:22:57 2016 +0000
@@ -33,6 +33,9 @@
 #define TRUE            (!FALSE)
 #endif
 
+#define GTHREAD_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("gthread-2.0", "0")
+#define GTHREAD_LIB JNI_LIB_NAME("gthread-2.0")
+
 #define _G_TYPE_CIC(ip, gt, ct)       ((ct*) ip)
 #define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type)  \
                                     (_G_TYPE_CIC ((instance), (g_type), c_type))
@@ -555,6 +558,13 @@
 gboolean gtk_load(JNIEnv *env, GtkVersion version, gboolean verbose);
 gboolean gtk_check_version(GtkVersion version);
 
+typedef struct _GThreadFunctions GThreadFunctions;
+static gboolean (*fp_g_thread_get_initialized)(void);
+static void (*fp_g_thread_init)(GThreadFunctions *vtable);
+static void (*fp_gdk_threads_init)(void);
+static void (*fp_gdk_threads_enter)(void);
+static void (*fp_gdk_threads_leave)(void);
+
 extern GtkApi* gtk;
 
 #endif /* !_GTK_INTERFACE_H */
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XWindow.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XWindow.c	Thu Oct 27 21:22:57 2016 +0000
@@ -818,6 +818,32 @@
     }
     return awt_UseXKB;
 }
+
+/*
+ * Map a keycode to the corresponding keysym.
+ * This replaces the deprecated X11 function XKeycodeToKeysym
+ */
+KeySym
+keycodeToKeysym(Display *display, KeyCode keycode, int index) {
+    static int min_kc = -1;
+    static int max_kc;
+    if (min_kc == -1) {
+        (void) XDisplayKeycodes(display, &min_kc, &max_kc);
+    }
+    if (keycode < min_kc || keycode > max_kc || index < 0) {
+        return NoSymbol;
+    }
+    int num_syms;
+    KeySym *key_syms = XGetKeyboardMapping(display, keycode, 1, &num_syms);
+    if (index >= num_syms) {
+        XFree(key_syms);
+        return NoSymbol;
+    }
+    KeySym ks = key_syms[index];
+    XFree(key_syms);
+    return ks;
+}
+
 static Boolean
 isKPevent(XEvent *event)
 {
@@ -833,14 +859,14 @@
      */
     Boolean bsun = isXsunServer( event );
     Boolean bxkb = isXKBenabled( event->xkey.display );
-    return IsKeypadKey( XKeycodeToKeysym(event->xkey.display, event->xkey.keycode,(bsun && !bxkb ? 2 : 1) ) );
+    return IsKeypadKey( keycodeToKeysym(event->xkey.display, event->xkey.keycode,(bsun && !bxkb ? 2 : 1) ) );
 }
 static void
 dumpKeysymArray(XEvent *event) {
-    printf("    0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 0));
-    printf("    0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 1));
-    printf("    0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 2));
-    printf("    0x%X\n",XKeycodeToKeysym(event->xkey.display, event->xkey.keycode, 3));
+    printf("    0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 0));
+    printf("    0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 1));
+    printf("    0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 2));
+    printf("    0x%X\n",keycodeToKeysym(event->xkey.display, event->xkey.keycode, 3));
 }
 /*
  * In a next redesign, get rid of this code altogether.
@@ -855,20 +881,20 @@
     }
     if( isXsunServer( event ) && !awt_UseXKB) {
         if( (event->xkey.state & ShiftMask) ) { // shift modifier is on
-            *keysym = XKeycodeToKeysym(event->xkey.display,
+            *keysym = keycodeToKeysym(event->xkey.display,
                                    event->xkey.keycode, 3);
          }else {
-            *keysym = XKeycodeToKeysym(event->xkey.display,
+            *keysym = keycodeToKeysym(event->xkey.display,
                                    event->xkey.keycode, 2);
          }
     } else {
         if( (event->xkey.state & ShiftMask) || // shift modifier is on
             ((event->xkey.state & LockMask) && // lock modifier is on
              (awt_ModLockIsShiftLock)) ) {     // it is interpreted as ShiftLock
-            *keysym = XKeycodeToKeysym(event->xkey.display,
+            *keysym = keycodeToKeysym(event->xkey.display,
                                    event->xkey.keycode, 0);
         }else{
-            *keysym = XKeycodeToKeysym(event->xkey.display,
+            *keysym = keycodeToKeysym(event->xkey.display,
                                    event->xkey.keycode, 1);
         }
     }
@@ -903,7 +929,7 @@
        Perhaps using the index (modn in awt_MToolkit.c:setup_modifier_map)
        would be more correct.
      */
-    *keysym = XKeycodeToKeysym(event->xkey.display,
+    *keysym = keycodeToKeysym(event->xkey.display,
                                event->xkey.keycode, 2);
     if (originalKeysym != *keysym) {
         DTRACE_PRINTLN3("%s originalKeysym=0x%x, keysym=0x%x",
@@ -999,7 +1025,6 @@
     }
 }
 
-
 /* This function is called as the keyChar parameter of a call to
  * awt_post_java_key_event.  It depends on being called after adjustKeySym.
  *
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c	Thu Oct 27 21:22:57 2016 +0000
@@ -49,6 +49,9 @@
 
 #include <X11/XKBlib.h>
 
+// From XWindow.c
+extern KeySym keycodeToKeysym(Display *display, KeyCode keycode, int index);
+
 #if defined(DEBUG)
 static jmethodID lockIsHeldMID = NULL;
 
@@ -1286,7 +1289,7 @@
         // report arbitrarily false.
         return JNI_FALSE;
     } else {
-        long ks2 = XKeycodeToKeysym((Display*)jlong_to_ptr(display), kc7, 2);
+        long ks2 = keycodeToKeysym((Display*)jlong_to_ptr(display), kc7, 2);
         if( ks2 == XK_KP_7 ) {
             //XXX If some Xorg server would put XK_KP_7 in keysymarray[2] as well,
             //XXX for yet unknown to me reason, the sniffer would lie.
@@ -1915,12 +1918,13 @@
     XQueryKeymap( (Display *) jlong_to_ptr(display), (char *) jlong_to_ptr(vector));
 }
 
+// XKeycodeToKeysym is deprecated but for compatibility we keep the API.
 JNIEXPORT jlong JNICALL
 Java_sun_awt_X11_XlibWrapper_XKeycodeToKeysym(JNIEnv *env, jclass clazz,
                                               jlong display, jint keycode,
                                               jint index) {
     AWT_CHECK_HAVE_LOCK_RETURN(0);
-    return XKeycodeToKeysym((Display*) jlong_to_ptr(display), (unsigned int)keycode, (int)index);
+    return keycodeToKeysym((Display*)jlong_to_ptr(display), (unsigned int)keycode, (int)index);
 }
 
 JNIEXPORT jint JNICALL
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c	Thu Oct 27 21:22:57 2016 +0000
@@ -97,10 +97,7 @@
 
 void callback(DbusmenuMenuitem* mi, guint ts, jobject data) {
     JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);
-    (*env)->CallStaticVoidMethod(env, jTaskbarCls, jTaskbarCallback, data,
-            fp_dbusmenu_menuitem_property_get_int(mi, "toggle-state")
-            ? JNI_FALSE
-            : JNI_TRUE);
+    (*env)->CallStaticVoidMethod(env, jTaskbarCls, jTaskbarCallback, data);
 }
 
 /*
@@ -243,10 +240,9 @@
 
     if (!menu) {
         menu = fp_dbusmenu_menuitem_new();
+        fp_unity_launcher_entry_set_quicklist(entry, menu);
     }
 
-    fp_unity_launcher_entry_set_quicklist(entry, menu);
-
     GList* list = fp_dbusmenu_menuitem_take_children(menu);
     gtk->g_list_free_full(list, gtk->g_object_unref);
 
--- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c	Thu Oct 27 21:22:57 2016 +0000
@@ -753,6 +753,9 @@
         XMapRaised(splash->display, splash->window);
         SplashUpdateShape(splash);
         SplashRedrawWindow(splash);
+        //map the splash co-ordinates as per system scale
+        splash->x /= splash->scaleFactor;
+        splash->y /= splash->scaleFactor;
         SplashEventLoop(splash);
     }
     SplashUnlock(splash);
@@ -807,50 +810,6 @@
     return JNI_FALSE;
 #endif
     *scaleFactor = getNativeScaleFactor(NULL);
-    if (*scaleFactor == 2.0) {
-        size_t length = 0;
-        char *stringToAppend = ".java-scale2x";
-        char *dupFileName = strdup(fileName);
-        char *fileExtension = strrchr(dupFileName, '.');
-        if (fileExtension == NULL) {
-            length = strlen(dupFileName) + strlen(stringToAppend) + 1;
-            if (length > scaledImageNameLength) {
-                *scaleFactor = 1;
-                free(dupFileName);
-                return JNI_FALSE;
-            }
-            int retVal = snprintf(scaledImgName, length, "%s%s",
-                dupFileName, stringToAppend);
-            if (retVal < 0 || (retVal != length - 1)) {
-                free(dupFileName);
-                *scaleFactor = 1;
-                return JNI_FALSE;
-            }
-        } else {
-            int length_without_ext = fileExtension - dupFileName;
-            length = length_without_ext +
-                strlen(stringToAppend) + strlen(fileExtension) + 1;
-            if (length > scaledImageNameLength) {
-                *scaleFactor = 1;
-                free(dupFileName);
-                return JNI_FALSE;
-            }
-            int retVal = snprintf(scaledImgName, length, "%.*s%s%s",
-                length_without_ext, dupFileName, stringToAppend, fileExtension);
-            if (retVal < 0 || retVal != length - 1) {
-                free(dupFileName);
-                *scaleFactor = 1;
-                return JNI_FALSE;
-            }
-        }
-        free(dupFileName);
-        FILE *fp;
-        if (!(fp = fopen(scaledImgName, "r"))) {
-            *scaleFactor = 1;
-            return JNI_FALSE;
-        }
-        fclose(fp);
-        return JNI_TRUE;
-    }
-    return JNI_FALSE;
+    return GetScaledImageName(fileName, scaledImgName, scaleFactor, scaledImageNameLength);
 }
+
--- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c	Thu Oct 27 21:22:57 2016 +0000
@@ -535,6 +535,9 @@
     splash->hWnd = SplashCreateWindow(splash);
     if (splash->hWnd) {
         SplashRedrawWindow(splash);
+        //map the splash co-ordinates as per system scale
+        splash->x /= splash->scaleFactor;
+        splash->y /= splash->scaleFactor;
         SplashUnlock(splash);
         SplashMessagePump();
         SplashLock(splash);
@@ -582,55 +585,7 @@
     *scaleFactor = 1.0;
     GetScreenDpi(getPrimaryMonitor(), &dpiScaleX, &dpiScaleY);
     *scaleFactor = dpiScaleX > 0 ? dpiScaleX / 96 : *scaleFactor;
-    if (*scaleFactor > 1.0) {
-        char strDpi[BUFF_SIZE];
-        char *dupFileName = strdup(fileName);
-        char *fileExtension = strrchr(dupFileName, '.');
-        char *nameToAppend = ".scale-";
-        size_t length = 0;
-        int retVal = 0;
-        _snprintf(strDpi, BUFF_SIZE, "%d", (int)dpiScaleX);
-        /*File is missing extension */
-        if (fileExtension == NULL) {
-            length = strlen(dupFileName) + strlen(nameToAppend) +
-                strlen(strDpi) + 1;
-            if (length > scaledImageLength) {
-                *scaleFactor = 1;
-                free(dupFileName);
-                return JNI_FALSE;
-            }
-            retVal = _snprintf(scaleImageName, length, "%s%s%s", dupFileName,
-                nameToAppend, strDpi);
-            if (retVal < 0 || (retVal != length - 1)) {
-                *scaleFactor = 1;
-                free(dupFileName);
-                return JNI_FALSE;
-            }
-        }
-        else {
-            size_t length_Without_Ext = fileExtension - dupFileName;
-            length = length_Without_Ext + strlen(nameToAppend) + strlen(strDpi) +
-                strlen(fileExtension) + 1;
-            if (length > scaledImageLength) {
-                *scaleFactor = 1;
-                free(dupFileName);
-                return JNI_FALSE;
-            }
-            retVal = _snprintf(scaleImageName, length, "%.*s%s%s%s",
-                length_Without_Ext, dupFileName, nameToAppend, strDpi, fileExtension);
-            if (retVal < 0 || (retVal != length - 1)) {
-                *scaleFactor = 1;
-                free(dupFileName);
-                return JNI_FALSE;
-            }
-        }
-        free(dupFileName);
-        if (!(fp = fopen(scaleImageName, "r"))) {
-            *scaleFactor = 1;
-            return JNI_FALSE;
-        }
-        fclose(fp);
-        return JNI_TRUE;
-    }
-    return JNI_FALSE;
+    return GetScaledImageName(fileName, scaleImageName,
+        scaleFactor, scaledImageLength);
 }
+
--- a/jdk/src/java.rmi/share/classes/sun/rmi/server/Activation.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/Activation.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1970,6 +1970,11 @@
                 AccessController.doPrivileged(
                     new PrivilegedExceptionAction<Void>() {
                         public Void run() throws IOException {
+                            boolean disable = Boolean.getBoolean(
+                                    "sun.rmi.server.activation.disableErrRedirect");
+                            if (disable)
+                                return null;
+
                             File file =
                                 Files.createTempFile("rmid-err", null).toFile();
                             PrintStream errStream =
--- a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java	Thu Oct 27 21:22:57 2016 +0000
@@ -41,13 +41,13 @@
 
 import javax.accessibility.*;
 import com.sun.java.accessibility.util.*;
+import java.awt.geom.Rectangle2D;
 import sun.awt.AWTAccessor;
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
 
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
 
 /*
  * Note: This class has to be public.  It's loaded from the VM like this:
@@ -1754,7 +1754,7 @@
                     if (child instanceof JTextComponent) {
                         JTextComponent text = (JTextComponent) child;
                         try {
-                            r = text.modelToView(text.getCaretPosition());
+                            r = text.modelToView2D(text.getCaretPosition()).getBounds();
                             if (r != null) {
                                 Point p = text.getLocationOnScreen();
                                 r.translate(p.x, p.y);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.desktop/share/classes/jdk/awt/AWTUtils.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.awt;
+
+import java.awt.Component;
+import java.awt.Shape;
+
+import com.sun.awt.AWTUtilities;
+
+/**
+ * A class to allow access to JDK-specific utility methods.
+ * Methods in this class are always deprecated since a caller
+ * should be aware they may be removed and replaced in the future.
+ * Access using reflection is highly recommended.
+ * @since 9
+ */
+public final class AWTUtils {
+
+    /**
+     * No-one should be creating instances of this class.
+     */
+    private AWTUtils() {
+    }
+
+    /**
+     * Sets a 'mixing-cutout' shape for the given component.
+     *
+     * By default a lightweight component is treated as an opaque rectangle for
+     * the purposes of the Heavyweight/Lightweight Components Mixing feature.
+     * This method enables developers to set an arbitrary shape to be cut out
+     * from heavyweight components positioned underneath the lightweight
+     * component in the z-order.
+     * <p>
+     * The {@code shape} argument may have the following values:
+     * <ul>
+     * <li>{@code null} - reverts the default cutout shape (the rectangle equal
+     * to the component's {@code getBounds()})
+     * <li><i>empty-shape</i> - does not cut out anything from heavyweight
+     * components. This makes the given lightweight component effectively
+     * transparent. Note that descendants of the lightweight component still
+     * affect the shapes of heavyweight components.  An example of an
+     * <i>empty-shape</i> is {@code new Rectangle()}.
+     * <li><i>non-empty-shape</i> - the given shape will be cut out from
+     * heavyweight components.
+     * </ul>
+     * <p>
+     * The most common example when the 'mixing-cutout' shape is needed is a
+     * glass pane component. The {@link JRootPane#setGlassPane()} method
+     * automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape
+     * for the given glass pane component.  If a developer needs some other
+     * 'mixing-cutout' shape for the glass pane (which is rare), this must be
+     * changed manually after installing the glass pane to the root pane.
+     * <p>
+     * Note that the 'mixing-cutout' shape neither affects painting, nor the
+     * mouse events handling for the given component. It is used exclusively
+     * for the purposes of the Heavyweight/Lightweight Components Mixing
+     * feature.
+     *
+     * @param component the component that needs non-default
+     * 'mixing-cutout' shape
+     * @param shape the new 'mixing-cutout' shape
+     * @throws NullPointerException if the component argument is {@code null}
+     * @deprecated This API may be removed or replaced.
+     */
+    @Deprecated
+    @SuppressWarnings("deprecation")
+    public static void setComponentMixingCutoutShape(Component component,
+                                                     Shape shape) {
+
+        AWTUtilities.setComponentMixingCutoutShape(component, shape);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.desktop/share/classes/module-info.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Provides non-SE desktop APIs.
+ */
+
+module jdk.desktop {
+    requires public java.desktop;
+
+    exports jdk.awt;
+}
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java	Thu Oct 27 21:22:57 2016 +0000
@@ -80,6 +80,7 @@
     String fname, mname, ename;
     String zname = "";
     String rootjar = null;
+    Set<String> concealedPackages = new HashSet<>();
 
     private static final int BASE_VERSION = 0;
 
@@ -821,22 +822,21 @@
         return true;
     }
 
-    private static Set<String> findPackages(ZipFile zf) {
-        return zf.stream()
-                 .filter(e -> e.getName().endsWith(".class"))
-                 .map(e -> toPackageName(e))
-                 .filter(pkg -> pkg.length() > 0)
-                 .distinct()
-                 .collect(Collectors.toSet());
-    }
-
     private static String toPackageName(ZipEntry entry) {
         return toPackageName(entry.getName());
     }
 
     private static String toPackageName(String path) {
         assert path.endsWith(".class");
-        int index = path.lastIndexOf('/');
+        int index;
+        if (path.startsWith(VERSIONS_DIR)) {
+            index = path.indexOf('/', VERSIONS_DIR.length());
+            if (index <= 0) {
+                return "";
+            }
+            path = path.substring(index + 1);
+        }
+        index = path.lastIndexOf('/');
         if (index != -1) {
             return path.substring(0, index).replace('/', '.');
         } else {
@@ -875,7 +875,7 @@
                         entryMap.put(entryName, entry);
                 } else if (entries.add(entry)) {
                     jarEntries.add(entryName);
-                    if (entry.basename.endsWith(".class") && !entryName.startsWith(VERSIONS_DIR))
+                    if (entry.basename.endsWith(".class"))
                         packages.add(toPackageName(entry.basename));
                     if (isUpdate)
                         entryMap.put(entryName, entry);
@@ -1068,7 +1068,7 @@
                 }
 
                 jarEntries.add(name);
-                if (name.endsWith(".class") && !(name.startsWith(VERSIONS_DIR)))
+                if (name.endsWith(".class"))
                     packages.add(toPackageName(name));
             }
         }
@@ -1762,6 +1762,13 @@
     }
 
     /**
+     * Print a warning message
+     */
+    void warn(String s) {
+        err.println(s);
+    }
+
+    /**
      * Main routine to start program.
      */
     public static void main(String args[]) {
@@ -1975,24 +1982,30 @@
         ByteBuffer bb = ByteBuffer.wrap(moduleInfos.get(MODULE_INFO));
         ModuleDescriptor rd = ModuleDescriptor.read(bb);
 
-        Set<String> exports = rd.exports()
-                                .stream()
-                                .map(Exports::source)
-                                .collect(toSet());
-
-        Set<String> conceals = packages.stream()
-                                       .filter(p -> !exports.contains(p))
-                                       .collect(toSet());
+        concealedPackages = findConcealedPackages(rd);
 
         for (Map.Entry<String,byte[]> e: moduleInfos.entrySet()) {
             ModuleDescriptor vd = ModuleDescriptor.read(ByteBuffer.wrap(e.getValue()));
             if (!(isValidVersionedDescriptor(vd, rd)))
                 return false;
-            e.setValue(extendedInfoBytes(rd, vd, e.getValue(), conceals));
+            e.setValue(extendedInfoBytes(rd, vd, e.getValue(), concealedPackages));
         }
         return true;
     }
 
+    private Set<String> findConcealedPackages(ModuleDescriptor md){
+        Objects.requireNonNull(md);
+
+        Set<String> exports = md.exports()
+                .stream()
+                .map(Exports::source)
+                .collect(toSet());
+
+        return packages.stream()
+                .filter(p -> !exports.contains(p))
+                .collect(toSet());
+    }
+
     private static boolean isPlatformModule(String name) {
         return name.startsWith("java.") || name.startsWith("jdk.");
     }
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java	Thu Oct 27 21:22:57 2016 +0000
@@ -152,9 +152,13 @@
                     return;
                 }
                 if (fp.isPublicClass()) {
-                    main.error(Main.formatMsg("error.validator.new.public.class", entryName));
-                    isValid = false;
-                    return;
+                    if (!isConcealed(internalName)) {
+                        main.error(Main.formatMsg("error.validator.new.public.class", entryName));
+                        isValid = false;
+                        return;
+                    }
+                    main.warn(Main.formatMsg("warn.validator.concealed.public.class", entryName));
+                    debug("%s is a public class entry in a concealed package", entryName);
                 }
                 debug("%s is a non-public class entry", entryName);
                 fps.put(internalName, fp);
@@ -169,7 +173,7 @@
 
         // are the two classes/resources identical?
         if (fp.isIdentical(matchFp)) {
-            main.error(Main.formatMsg("error.validator.identical.entry", entryName));
+            main.warn(Main.formatMsg("warn.validator.identical.entry", entryName));
             return;  // it's okay, just takes up room
         }
         debug("sha1 not equal -- different bytes");
@@ -204,7 +208,7 @@
         }
         debug("%s is a resource", entryName);
 
-        main.error(Main.formatMsg("error.validator.resources.with.same.name", entryName));
+        main.warn(Main.formatMsg("warn.validator.resources.with.same.name", entryName));
         fps.put(internalName, fp);
         return;
     }
@@ -235,6 +239,15 @@
         return entryName.endsWith(".class") ? entryName.substring(0, entryName.length() - 6) : null;
     }
 
+    private boolean isConcealed(String internalName) {
+        if (main.concealedPackages.isEmpty()) {
+            return false;
+        }
+        int idx = internalName.lastIndexOf('/');
+        String pkgName = idx != -1 ? internalName.substring(0, idx).replace('/', '.') : "";
+        return main.concealedPackages.contains(pkgName);
+    }
+
     private void debug(String fmt, Object... args) {
         if (DEBUG) System.err.format(fmt, args);
     }
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties	Thu Oct 27 21:22:57 2016 +0000
@@ -99,16 +99,19 @@
         entry: {0}, is an isolated nested class
 error.validator.new.public.class=\
         entry: {0}, contains a new public class not found in base entries
-error.validator.identical.entry=\
-        warning - entry: {0} contains a class that is identical to an entry already in the jar
 error.validator.incompatible.class.version=\
         entry: {0}, has a class version incompatible with an earlier version
 error.validator.different.api=\
         entry: {0}, contains a class with different api from earlier version
-error.validator.resources.with.same.name=\
-         warning - entry: {0}, multiple resources with same name
 error.validator.names.mismatch=\
          entry: {0}, contains a class with internal name {1}, names do not match
+warn.validator.identical.entry=\
+        warning - entry: {0} contains a class that is identical to an entry already in the jar
+warn.validator.resources.with.same.name=\
+         warning - entry: {0}, multiple resources with same name
+warn.validator.concealed.public.class=\
+         warning - entry {0} is a public class in a concealed package, \n\
+         placing this jar on the class path will result in incompatible public interfaces
 out.added.manifest=\
         added manifest
 out.added.module-info=\
--- a/jdk/src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/jdi/ObjectReference.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -246,9 +246,9 @@
      * @throws java.lang.IllegalArgumentException if the method is not
      * a member of this object's class, if the size of the argument list
      * does not match the number of declared arguments for the method,
-     * if the method is a constructor or static intializer, or
+     * if the method is a constructor or static initializer, or
      * if {@link #INVOKE_NONVIRTUAL} is specified and the method is
-     * either abstract or a non-default interface member.
+     * abstract.
      * @throws {@link InvalidTypeException} if any argument in the
      * argument list is not assignable to the corresponding method argument
      * type.
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -347,10 +347,12 @@
                                          throws InvalidTypeException,
                                          InvocationException {
         /*
-         * Only default methods allowed for nonvirtual invokes
+         * For nonvirtual invokes, method must have a body
          */
-        if (isNonVirtual(options) && !method.isDefault()) {
-            throw new IllegalArgumentException("Not a default method");
+        if (isNonVirtual(options)) {
+            if (method.isAbstract()) {
+                throw new IllegalArgumentException("Abstract method");
+            }
         }
     }
 
--- a/jdk/src/jdk.jdi/share/classes/module-info.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jdi/share/classes/module-info.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
     exports com.sun.jdi.connect.spi;
     exports com.sun.jdi.event;
     exports com.sun.jdi.request;
-    exports com.sun.tools.jdi to jdk.hotspot.agent;
 
     uses com.sun.jdi.connect.Connector;
     uses com.sun.jdi.connect.spi.TransportService;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java	Thu Oct 27 21:22:57 2016 +0000
@@ -186,7 +186,7 @@
                    new PrintWriter(System.err, true));
         }
         try {
-            optionsHelper.handleOptions(this, args);
+            optionsHelper.handleOptionsNoUnhandled(this, args);
             if (options.help) {
                 optionsHelper.showHelp(PROGNAME);
                 return EXIT_OK;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java	Thu Oct 27 21:22:57 2016 +0000
@@ -466,7 +466,21 @@
             return pp;
         }
 
+        // used by jimage. Return unhandled arguments like "create", "describe".
         public List<String> handleOptions(T task, String[] args) throws BadArgs {
+            return handleOptions(task, args, true);
+        }
+
+        // used by jlink. No unhandled arguments like "create", "describe".
+        void handleOptionsNoUnhandled(T task, String[] args) throws BadArgs {
+            handleOptions(task, args, false);
+        }
+
+        // shared code that handles options for both jlink and jimage. jimage uses arguments like
+        // "create", "describe" etc. as "task names". Those arguments are unhandled here and returned
+        // as "unhandled arguments list". jlink does not want such arguments. "collectUnhandled" flag
+        // tells whether to allow for unhandled arguments or not.
+        private List<String> handleOptions(T task, String[] args, boolean collectUnhandled) throws BadArgs {
             // findbugs warning, copy instead of keeping a reference.
             command = Arrays.copyOf(args, args.length);
 
@@ -499,10 +513,10 @@
             String[] arr = new String[filteredArgs.size()];
             args = filteredArgs.toArray(arr);
 
-            List<String> rest = new ArrayList<>();
+            List<String> rest = collectUnhandled? new ArrayList<>() : null;
             // process options
             for (int i = 0; i < args.length; i++) {
-                if (!args[i].isEmpty() && args[i].charAt(0) == '-') {
+                if (args[i].charAt(0) == '-') {
                     String name = args[i];
                     PlugOption pluginOption = null;
                     Option<T> option = getOption(name);
@@ -539,7 +553,12 @@
                         i = args.length;
                     }
                 } else {
-                    rest.add(args[i]);
+                    if (collectUnhandled) {
+                        rest.add(args[i]);
+                    } else {
+                        throw new BadArgs("err.orphan.argument", args[i]).
+                            showUsage(true);
+                    }
                 }
             }
             return rest;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties	Thu Oct 27 21:22:57 2016 +0000
@@ -95,6 +95,7 @@
 err.dir.exists={0} already exists
 err.badpattern=bad pattern {0}
 err.unknown.option=unknown option: {0}
+err.orphan.argument=orphan argument: {0}
 err.missing.arg=no value given for {0}
 err.internal.error=internal error: {0} {1} {2}
 err.invalid.arg.for.option=invalid argument for option: {0}
--- a/jdk/src/jdk.jsobject/share/classes/netscape/javascript/JSObject.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/src/jdk.jsobject/share/classes/netscape/javascript/JSObject.java	Thu Oct 27 21:22:57 2016 +0000
@@ -156,6 +156,7 @@
      */
 
     @Deprecated(since = "9")
+    @SuppressWarnings("exports")
     public static JSObject getWindow(Applet applet) throws JSException {
         return ProviderLoader.callGetWindow(applet);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.localedata/share/classes/sun/text/resources/ext/BreakIteratorResources_th.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.text.resources.ext;
+
+import java.util.ResourceBundle;
+import sun.util.resources.BreakIteratorResourceBundle;
+
+public class BreakIteratorResources_th extends BreakIteratorResourceBundle {
+    @Override
+    protected ResourceBundle getBreakIteratorInfo() {
+        return new BreakIteratorInfo_th();
+    }
+}
--- a/jdk/test/ProblemList.txt	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/ProblemList.txt	Thu Oct 27 21:22:57 2016 +0000
@@ -134,8 +134,6 @@
 
 java/lang/instrument/BootClassPath/BootClassPathTest.sh         8072130 macosx-all
 
-java/lang/instrument/DaemonThread/TestDaemonThread.java         8167001 generic-all
-
 java/lang/management/MemoryMXBean/Pending.java                  8158837 generic-all
 java/lang/management/MemoryMXBean/PendingAllGC.sh               8158760 generic-all
 
--- a/jdk/test/TEST.groups	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/TEST.groups	Thu Oct 27 21:22:57 2016 +0000
@@ -158,6 +158,7 @@
 
 jdk_net = \
     java/net \
+    -java/net/httpclient \
     com/sun/net/httpserver \
     sun/net \
     jdk/net
--- a/jdk/test/com/sun/corba/serialization/ObjectStreamTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -42,13 +42,8 @@
 import java.util.Objects;
 import java.util.PropertyPermission;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.LongAdder;
 
-import javax.naming.CommunicationException;
-import javax.naming.InitialContext;
-import javax.naming.Context;
-import javax.naming.NamingException;
 import javax.rmi.CORBA.Util;
 import javax.rmi.PortableRemoteObject;
 
@@ -56,11 +51,9 @@
 import org.omg.CORBA_2_3.portable.OutputStream;
 import org.omg.CORBA_2_3.portable.InputStream;
 
-import jdk.test.lib.JDKToolFinder;
-import jdk.test.lib.JDKToolLauncher;
-
 import org.testng.Assert;
-import org.testng.annotations.AfterSuite;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 import org.testng.annotations.DataProvider;
 import org.testng.TestNG;
@@ -69,15 +62,13 @@
  * @test
  * @library /test/lib
  * @build jdk.test.lib.*
- * @compile  ObjectStreamTest.java  ObjectStreamTest$_Echo_Stub.java  ObjectStreamTest$_Server_Tie.java
- * @modules java.corba/com.sun.corba.se.impl.io java.base/java.io java.corba/com.sun.corba.se.impl.activation
+ * @compile  ObjectStreamTest.java  ObjectStreamTest$_Echo_Stub.java
+ *           ObjectStreamTest$_Server_Tie.java
+ * @modules java.corba/com.sun.corba.se.impl.io java.base/java.io
+ *          java.corba/com.sun.corba.se.impl.activation
  * @summary Tests of ReflectionFactory use in IIOP Serialization
- * @run testng/othervm
- *       -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
- *       -Djava.naming.provider.url=iiop://localhost:1050 ObjectStreamTest
- * @run testng/othervm/policy=security.policy
- *       -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
- *       -Djava.naming.provider.url=iiop://localhost:1050 ObjectStreamTest
+ * @run testng/othervm ObjectStreamTest
+ * @run testng/othervm/policy=security.policy ObjectStreamTest
  */
 
 @Test
@@ -92,12 +83,6 @@
         colorSet.add(Colors.GREEN);
     }
 
-    /**
-     * The process spawned to run orbd.
-     */
-    static Process orbdProcess;
-    static Thread orbThread;
-
     @DataProvider(name = "Objects")
     static Object[][] patterns() {
         BigInteger bigInteger = new BigInteger("8943892002309239");
@@ -141,7 +126,7 @@
      * @param value
      */
     @Test(dataProvider = "Objects")
-    static void factCheck(Serializable value) {
+    void factCheck(Serializable value) {
         Class<?> clazz = value.getClass();
         java.io.ObjectStreamClass sOSC = java.io.ObjectStreamClass.lookup(clazz);
         java.io.ObjectStreamField[] sFields = sOSC.getFields();
@@ -150,25 +135,33 @@
 
         Assert.assertEquals(sFields.length, cFields.length, "Different number of fields");
         for (int i = 0; i < sFields.length; i++) {
-            Assert.assertEquals(sFields[i].getName(), cFields[i].getName(), "different field names " + cFields[i].getName());
-            Assert.assertEquals(sFields[i].getType(), cFields[i].getType(), "different field types " + cFields[i].getName());
-            Assert.assertEquals(sFields[i].getTypeString(), cFields[i].getTypeString(), "different field typestrings " + cFields[i].getName());
+            Assert.assertEquals(sFields[i].getName(), cFields[i].getName(),
+                    "different field names " + cFields[i].getName());
+            Assert.assertEquals(sFields[i].getType(), cFields[i].getType(),
+                    "different field types " + cFields[i].getName());
+            Assert.assertEquals(sFields[i].getTypeString(), cFields[i].getTypeString(),
+                    "different field typestrings " + cFields[i].getName());
         }
 
         Assert.assertEquals(baseMethod("hasReadObjectMethod", sOSC, (Class<?>[]) null),
-                corbaMethod("hasReadObject", cOSC, (Class<?>[]) null), "hasReadObject: " + value.getClass());
+                corbaMethod("hasReadObject", cOSC, (Class<?>[]) null),
+                "hasReadObject: " + value.getClass());
 
         Assert.assertEquals(baseMethod("hasWriteObjectMethod", sOSC, (Class<?>[]) null),
-                corbaMethod("hasWriteObject", cOSC, (Class<?>[]) null), "hasWriteObject: " + value.getClass());
+                corbaMethod("hasWriteObject", cOSC, (Class<?>[]) null),
+                "hasWriteObject: " + value.getClass());
 
         Assert.assertEquals(baseMethod("hasWriteReplaceMethod", sOSC, (Class<?>[]) null),
-                corbaMethod("hasWriteReplaceMethod", cOSC, (Class<?>[]) null), "hasWriteReplace: " + value.getClass());
+                corbaMethod("hasWriteReplaceMethod", cOSC, (Class<?>[]) null),
+                "hasWriteReplace: " + value.getClass());
 
         Assert.assertEquals(baseMethod("hasReadResolveMethod", sOSC, (Class<?>[]) null),
-                corbaMethod("hasReadResolveMethod", cOSC, (Class<?>[]) null), "hasReadResolve: " + value.getClass());
+                corbaMethod("hasReadResolveMethod", cOSC, (Class<?>[]) null),
+                "hasReadResolve: " + value.getClass());
 
         Assert.assertEquals(baseMethod("getSerialVersionUID", sOSC, (Class<?>[]) null),
-                corbaMethod("getSerialVersionUID", cOSC, (Class<?>[]) null), "getSerialVersionUID: " + value.getClass());
+                corbaMethod("getSerialVersionUID", cOSC, (Class<?>[]) null),
+                "getSerialVersionUID: " + value.getClass());
 
     }
 
@@ -178,7 +171,7 @@
      * and deserialized using Util.readAny to equivalent objects.
      */
     @Test(dataProvider = "Objects", enabled = true, dependsOnMethods = {"factCheck"})
-    static void WriteValueObjectStreamTest01(Serializable value) throws Exception {
+    void WriteValueObjectStreamTest01(Serializable value) throws Exception {
         ORB orb = (ORB) ORB.init(new String[0], null);
 
         OutputStream out = (OutputStream) orb.create_output_stream();
@@ -193,15 +186,43 @@
     /**
      * Test that objects can be echoed to a server and come back equivalent.
      */
-    @Test(dataProvider = "Objects", enabled = false, dependsOnMethods = {"factCheck"})
-    static void echoObjects(Serializable value) throws Exception {
-        Context initialNamingContext = Server.init();
-        Echo echo = (Echo) PortableRemoteObject.narrow(
-                initialNamingContext.lookup(Server.serverID), Echo.class);
+    @Test(dataProvider = "Objects", enabled = true, dependsOnMethods = {"factCheck"})
+    void echoObjects(Serializable value) throws Exception {
+        Echo echo = getEchoStub();
         Object actual = echo.echo(value);
         checkEquals(actual, value);
     }
 
+
+    /**
+     * Initialize the ORB and the singleton Echo server stub.
+     * @return the stub for the Echo server.
+     * @throws RemoteException if an error occurs
+     */
+    synchronized Echo getEchoStub() throws RemoteException {
+        if (echoStub == null) {
+            ORB orb = (ORB) ORB.init(new String[0], null);
+            Echo server = new Server();
+            echoStub = (javax.rmi.CORBA.Stub) PortableRemoteObject.toStub(server);
+            echoStub.connect(orb);
+        }
+        return (Echo)echoStub;
+    }
+
+    /**
+     * The stub for the Echo Server class. Initialized on first use.
+     */
+    private javax.rmi.CORBA.Stub echoStub;
+
+    /**
+     * After all the tests run shutdown the orb.
+     */
+    @AfterClass
+    void shutdownOrb() {
+        ORB orb = (ORB) ORB.init(new String[0], null);
+        orb.shutdown(true);
+    }
+
     /**
      * Check if the value and result are equals, with some tests depending on the type.
      * @param expected the expected value
@@ -209,15 +230,18 @@
      */
     static void checkEquals(Object actual, Object expected) {
         Class<?> cl = expected.getClass();
-        Assert.assertEquals(actual.getClass(), cl, "type of value not equal to class of result");
+        Assert.assertEquals(actual.getClass(), cl,
+                "type of value not equal to class of result");
         try {
             if (cl.isArray() || !(cl.getDeclaredMethod("equals", cl) == null)) {
                 Assert.assertEquals(actual, expected, "echo'd object not equal");
             } else {
-                Assert.assertEquals(toString(actual), toString(expected), "toString values not equal");
+                Assert.assertEquals(toString(actual), toString(expected),
+                        "toString values not equal");
             }
         } catch (NoSuchMethodException ex) {
-            Assert.assertEquals(toString(actual), toString(expected), "toString values not equal");
+            Assert.assertEquals(toString(actual), toString(expected),
+                    "toString values not equal");
         }
     }
 
@@ -301,7 +325,9 @@
      * @param argClasses method arguments
      * @return the value returned from invoking the method
      */
-    static Object corbaMethod(String methodName, com.sun.corba.se.impl.io.ObjectStreamClass osc, Class<?>... argClasses) {
+    static Object corbaMethod(String methodName,
+                              com.sun.corba.se.impl.io.ObjectStreamClass osc,
+                              Class<?>... argClasses) {
         Class<?> oscClass = com.sun.corba.se.impl.io.ObjectStreamClass.class;
 
         try {
@@ -325,7 +351,8 @@
      * @param argClasses method arguments
      * @return the value returned from invoking the method
      */
-    static Object baseMethod(String methodName, java.io.ObjectStreamClass osc, Class<?>... argClasses) {
+    static Object baseMethod(String methodName, java.io.ObjectStreamClass osc,
+                             Class<?>... argClasses) {
         Class<?> oscClass = java.io.ObjectStreamClass.class;
 
         try {
@@ -342,7 +369,7 @@
     }
 
     /**
-     * Simple echo interface to check serialization/deserialization.
+     * Simple echo interface to check IIOP serialization/deserialization.
      */
     interface Echo extends Remote {
         Object echo(Object obj) throws RemoteException;
@@ -350,12 +377,6 @@
 
     static class Server extends PortableRemoteObject implements Echo {
 
-        public static final String serverID = "ObjectStreamTestServer";
-
-        private static Context initialNamingContext;
-
-        private static Server server;
-
         public Server() throws RemoteException {
             super();
         }
@@ -363,63 +384,8 @@
         public Object echo(Object obj) {
             return obj;
         }
-
-
-        public static Context init() {
-            if (initialNamingContext == null) {
-                try {
-                    startOrbd();
-                    Thread.sleep(5000L);        // Give it 5 seconds
-                } catch (Exception eex) {
-                    throw new RuntimeException("Orbd", eex);
-                }
-                for (int i = 0; i < 1; i++) {
-                    try {
-                        Thread.sleep(1L);
-                        initialNamingContext = new InitialContext();
-                        server = new Server();
-                        initialNamingContext.rebind(serverID, server);
-                    } catch (CommunicationException | InterruptedException cex) {
-                        System.out.printf("retry #%d sec: ex: %s%n", i, cex);
-                    } catch (NamingException ex) {
-                        throw new RuntimeException("can't initialize naming context", ex);
-                    } catch (RemoteException rex) {
-                        throw new RuntimeException("can't initialize server", rex);
-                    }
-                }
-            }
-            if (initialNamingContext == null) {
-                Assert.fail("Can't initialize the Orb, no naming context");
-            }
-            return initialNamingContext;
-        }
     }
 
-    static void startOrbd() throws Exception {
-        System.out.println("\nStarting orbd with NS port 1050 ");
-        JDKToolLauncher orbdLauncher = JDKToolLauncher.create("orbd")
-                        .addToolArg("-ORBInitialHost").addToolArg("localhost")
-                        .addToolArg("-ORBInitialPort").addToolArg("1050");
-
-        System.out.println("ObjectStreamTest: Executing: " + Arrays.asList(orbdLauncher.getCommand()));
-        ProcessBuilder pb = new ProcessBuilder(orbdLauncher.getCommand());
-
-        pb.redirectError(ProcessBuilder.Redirect.INHERIT);
-        orbdProcess = pb.start();
-    }
-
-    @AfterSuite
-    static void killOrbd() throws Exception {
-        if (orbdProcess != null) {
-            orbdProcess.destroyForcibly();
-            orbdProcess.waitFor();
-            System.out.printf("destroyed orbd, pid: %d, exitValue: %d%n",
-                    orbdProcess.getPid(), orbdProcess.exitValue());
-        }
-    }
-
-
-
     // Main can be used to run the tests from the command line with only testng.jar.
     @SuppressWarnings("raw_types")
     @Test(enabled = false)
--- a/jdk/test/com/sun/jdi/InterfaceMethodsTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/com/sun/jdi/InterfaceMethodsTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -25,7 +25,8 @@
  *  @test
  *  @bug 8031195
  *  @bug 8071657
- *  @summary  JDI: Add support for static and default methods in interfaces
+ *  @bug 8165827
+ *  @summary  JDI: Add support for static, private and default methods in interfaces
  *
  *  @modules jdk.jdi
  *  @run build TestScaffold VMConnection TargetListener TargetAdapter
@@ -35,11 +36,13 @@
 import com.sun.jdi.*;
 import com.sun.jdi.event.*;
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 
 public class InterfaceMethodsTest extends TestScaffold {
     private static final int RESULT_A = 1;
-    private static final int RESULT_B = 1;
-    private static final int RESULT_TARGET = 1;
+    private static final int RESULT_B = 2;
+    private static final int RESULT_TARGET = 3;
 
     static interface InterfaceA {
         static int staticMethodA() {
@@ -62,7 +65,10 @@
             System.out.println("-InterfaceA: default interface method C-");
             return RESULT_A;
         }
-
+        private int privateMethodA() {
+            System.out.println("-InterfaceA: private interface method A-");
+            return RESULT_A;
+        }
         int implementedMethod();
     }
 
@@ -76,16 +82,18 @@
             System.out.println("-InterfaceB: default interface method D-");
             return RESULT_B;
         }
-
         static int staticMethodB() {
             System.out.println("-InterfaceB: overridden static interface method B-");
             return RESULT_B;
         }
-
         static int staticMethodC() {
             System.out.println("-InterfaceB: static interface method C-");
             return RESULT_B;
         }
+        private int privateMethodB() {
+            System.out.println("-InterfaceB: private interface method B-");
+            return RESULT_B;
+        }
     }
 
     final static class TargetClass implements InterfaceB {
@@ -102,7 +110,7 @@
 
         @Override
         public int defaultMethodB() {
-            System.out.println("-TargetClass: overridden default interface method D");
+            System.out.println("-TargetClass: overridden default interface method B");
 
             return RESULT_TARGET;
         }
@@ -169,9 +177,18 @@
     }
 
     private void testInterfaceA(ObjectReference ref) {
+
+        ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEA_NAME).get(0);
+
+        /* Private method calls */
+
+        Method m = testLookup(ifaceClass, "privateMethodA", "()I", true, null); // should succeed
+
+        testInvokePos(m, ref, vm().mirrorOf(RESULT_A), false);
+        testInvokePos(m, ref, vm().mirrorOf(RESULT_A), true);
+
         // Test non-virtual calls on InterfaceA
 
-        ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEA_NAME).get(0);
         /* Default method calls */
 
         // invoke the InterfaceA's "defaultMethodA"
@@ -185,39 +202,48 @@
 
         // "defaultMethodD" from InterfaceB is not accessible from here
         testInvokeNeg(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B),
-                "Attempted to invoke non-existing method");
+                      "Attempted to invoke non-existing method");
 
-        // trying to invoke the asbtract method "implementedMethod"
+        // non-virtual invoke of the abstract method "implementedMethod" fails
         testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(TARGET_CLASS_NAME),
-                "Invocation of non-default methods is not supported");
-
+                      "Invocation of abstract methods is not supported");
 
         /* Static method calls */
 
-        // invoke interface static method A
+        // invoke static interface method A
         testInvokePos(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
 
         // invoking static method A on the instance fails because static method A is
         // not inherited by TargetClass.
         testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
-                "Invalid MethodID");
+                      "Invalid MethodID");
 
-        // invoke interface static method B
+        // invoke static interface method B
         testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
 
         // invoking static method B on the instance fails because static method B is
         // not inherited by TargetClass.
         testInvokeNeg(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A),
-                "Invalid MethodID");
+                      "Invalid MethodID");
 
         // try to invoke a virtual method
-        testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_A), true);
+        testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET), true);
     }
 
     private void testInterfaceB(ObjectReference ref) {
         // Test non-virtual calls on InterfaceB
         ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEB_NAME).get(0);
 
+        /* private method calls */
+
+        /* These should fail but won't because of JDK-8167416
+        testLookup(ifaceClass, "privateMethodA", "()I", true, NoSuchMethodError.class); // should fail
+        testLookup(ifaceClass, "privateMethodA", "()I", false, NoSuchMethodError.class); // should fail
+        */
+        Method m = testLookup(ifaceClass, "privateMethodB", "()I", true, null); // should succeed
+        testInvokePos(m, ref, vm().mirrorOf(RESULT_B), false);
+        testInvokePos(m, ref, vm().mirrorOf(RESULT_B), true);
+
         /* Default method calls */
 
         // invoke the inherited "defaultMethodA"
@@ -267,19 +293,21 @@
     private void testImplementationClass(ReferenceType targetClass, ObjectReference thisObject) {
         // Test invocations on the implementation object
 
+        // Note: private interface calls have already been tested
+
         /* Default method calls */
 
         // "defaultMethodA" is accessible and not overridden
-        testInvokePos(targetClass, thisObject, "defaultMethodA", "()I", vm().mirrorOf(RESULT_TARGET));
+        testInvokePos(targetClass, thisObject, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
 
         // "defaultMethodB" is accessible and overridden in TargetClass
         testInvokePos(targetClass, thisObject, "defaultMethodB", "()I", vm().mirrorOf(RESULT_TARGET));
 
         // "defaultMethodC" is accessible and overridden in InterfaceB
-        testInvokePos(targetClass, thisObject, "defaultMethodC", "()I", vm().mirrorOf(RESULT_TARGET));
+        testInvokePos(targetClass, thisObject, "defaultMethodC", "()I", vm().mirrorOf(RESULT_B));
 
         // "defaultMethodD" is accessible
-        testInvokePos(targetClass, thisObject, "defaultMethodD", "()I", vm().mirrorOf(RESULT_TARGET));
+        testInvokePos(targetClass, thisObject, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B));
 
 
         /* Non-default instance method calls */
@@ -314,11 +342,16 @@
                 "Static interface methods are not inheritable");
     }
 
+    // Non-virtual invocation
     private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
                                String methodSig, Value value) {
         testInvokePos(targetClass, ref, methodName, methodSig, value, false);
     }
 
+    // Lookup the named method in the targetClass and invoke on the given object (for instance methods)
+    // using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
+    // expected return value.
+    // Should succeed.
     private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
                                String methodSig, Value value, boolean virtual) {
         logInvocation(ref, methodName, methodSig, targetClass);
@@ -331,11 +364,31 @@
         }
     }
 
+    // Invoke the given Method on the given object (for instance methods)
+    // using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
+    // expected return value.
+    // Should succeed.
+    private void testInvokePos(Method method, ObjectReference ref, Value value, boolean virtual) {
+        logInvocation(ref, method.name(), method.signature(), method.declaringType());
+        try {
+            invoke(method.declaringType(), ref, method, value, virtual);
+            System.err.println("--- PASSED");
+        } catch (Exception e) {
+            System.err.println("--- FAILED");
+            failure("FAILED: Invocation failed with error message " + e.getLocalizedMessage());
+        }
+    }
+
+    // Non-virtual invocation - with lookup in targetClass
     private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
                                String methodSig, Value value, String msg) {
         testInvokeNeg(targetClass, ref, methodName, methodSig, value, msg, false);
     }
 
+    // Lookup the named method in the targetClass and invoke on the given object (for instance methods)
+    // using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
+    // expected return value.
+    // Should fail - with msg decribing why failure was expected
     private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
                                String methodSig, Value value, String msg, boolean virtual) {
         logInvocation(ref, methodName, methodSig, targetClass);
@@ -350,12 +403,17 @@
     }
 
     private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName,
-                        String methodSig, Value value, boolean virtual)
-    throws Exception {
+                        String methodSig, Value value, boolean virtual) throws Exception {
+
         Method method = getMethod(targetClass, methodName, methodSig);
         if (method == null) {
             throw new Exception("Can't find method: " + methodName  + " for class = " + targetClass);
         }
+        invoke(targetClass, ref, method, value, virtual);
+    }
+
+    private void invoke(ReferenceType targetClass, ObjectReference ref, Method method,
+                        Value value, boolean virtual) throws Exception {
 
         println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method);
         println(method.declaringType().toString());
@@ -365,7 +423,7 @@
             if (virtual) {
                 returnValue = invokeVirtual(ref, method);
             } else {
-                returnValue = invokeInstance(ref, method);
+                returnValue = invokeNonVirtual(ref, method);
             }
         } else {
             returnValue = invokeStatic(targetClass, method);
@@ -387,7 +445,7 @@
         }
     }
 
-    private Value invokeInstance(ObjectReference ref, Method method) throws Exception {
+    private Value invokeNonVirtual(ObjectReference ref, Method method) throws Exception {
         return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
     }
 
@@ -449,4 +507,58 @@
                     methodName + methodSig);
         }
     }
+
+    private Method testLookup(ReferenceType targetClass, String methodName, String methodSig,
+                              boolean declaredOnly, Class<?> expectedException) {
+
+        System.err.println("Looking up " + targetClass.name() + "." + methodName + methodSig);
+        try {
+            Method m = declaredOnly ?
+                lookupDeclaredMethod(targetClass, methodName, methodSig) :
+                lookupMethod(targetClass, methodName, methodSig);
+
+            if (expectedException == null) {
+                System.err.println("--- PASSED");
+                return m;
+            }
+            else {
+                System.err.println("--- FAILED");
+                failure("FAILED: lookup succeeded but expected exception "
+                        + expectedException.getSimpleName());
+                return null;
+            }
+        }
+        catch (Throwable t) {
+            if (t.getClass() != expectedException) {
+                System.err.println("--- FAILED");
+                failure("FAILED: got exception " + t + " but expected exception "
+                        + expectedException.getSimpleName());
+                return null;
+            }
+            else {
+                System.err.println("--- PASSED");
+                return null;
+            }
+        }
+    }
+
+    private Method lookupMethod(ReferenceType targetClass, String methodName, String methodSig) {
+        List methods = targetClass.allMethods();
+        Iterator iter = methods.iterator();
+        while (iter.hasNext()) {
+            Method method = (Method)iter.next();
+            if (method.name().equals(methodName) &&
+                method.signature().equals(methodSig)) {
+                return method;
+            }
+        }
+        throw new NoSuchMethodError();
+    }
+
+    private Method lookupDeclaredMethod(ReferenceType targetClass, String methodName, String methodSig) {
+        Method m = findMethod(targetClass, methodName, methodSig);
+        if (m == null)
+            throw new NoSuchMethodError();
+        return m;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/RequestFocusByCause/RequestFocusByCauseTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,151 @@
+/*
+ * 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 8154434
+  @summary Open the request focus methods of the java.awt.Component which accept
+           FocusEvent.Cause
+  @run main RequestFocusByCauseTest
+*/
+
+import java.awt.*;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+public class RequestFocusByCauseTest {
+    static boolean success;
+
+    public static void main(String[] args) throws Exception {
+        testRequestFocusCause();
+        testRequestFocusTemporaryCause();
+        testRequestFocusInWindowCause();
+        System.out.println("ok");
+    }
+
+    private static void testRequestFocusCause() throws AWTException {
+        Frame frame = new Frame();
+        Component c = new Button();
+        frame.add(new Button());
+        frame.add(c);
+        c.addFocusListener(new FocusListener() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                success = e.getCause() == FocusEvent.Cause.UNEXPECTED;
+            }
+
+            @Override
+            public void focusLost(FocusEvent e) {}
+        });
+        Robot robot = new Robot();
+
+        try {
+            frame.setVisible(true);
+            robot.waitForIdle();
+            robot.delay(200);
+            success = false;
+
+            c.requestFocus(FocusEvent.Cause.UNEXPECTED);
+            robot.waitForIdle();
+            robot.delay(200);
+            if(!success) {
+                throw new RuntimeException("request failed");
+            }
+        } finally {
+            frame.dispose();
+        }
+    }
+
+    private static void testRequestFocusTemporaryCause() throws AWTException {
+        Frame frame = new Frame();
+        frame.add(new Button() {
+            @Override
+            protected boolean requestFocus(boolean temporary,
+                                                       FocusEvent.Cause cause) {
+                success = cause == FocusEvent.Cause.ROLLBACK;
+                return super.requestFocus(temporary, cause);
+            }
+        });
+        Component c = new Button() {
+            @Override
+            public void requestFocus() {
+                super.requestFocus();
+                setFocusable(false);
+            }
+        };
+        frame.add(c);
+        Robot robot = new Robot();
+
+        try {
+            frame.setVisible(true);
+            robot.waitForIdle();
+            robot.delay(200);
+
+            success = false;
+            c.requestFocus();
+            robot.waitForIdle();
+            robot.delay(200);
+
+
+            if(!success) {
+                throw new RuntimeException("rollback request is not triggered");
+            }
+        } finally {
+            frame.dispose();
+        }
+    }
+
+    private static void testRequestFocusInWindowCause() throws AWTException {
+        Frame frame = new Frame();
+        Component c = new Button();
+        frame.add(new Button());
+        frame.add(c);
+        c.addFocusListener(new FocusListener() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                success = e.getCause() == FocusEvent.Cause.UNEXPECTED;
+            }
+
+            @Override
+            public void focusLost(FocusEvent e) {
+            }
+        });
+        Robot robot = new Robot();
+
+        try {
+            frame.setVisible(true);
+            robot.waitForIdle();
+            robot.delay(200);
+            success = false;
+
+            c.requestFocusInWindow(FocusEvent.Cause.UNEXPECTED);
+            robot.waitForIdle();
+            robot.delay(200);
+            if (!success) {
+                throw new RuntimeException("request in window failed");
+            }
+        } finally {
+            frame.dispose();
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/SetIconImagesCrashTest/SetIconImagesCrashTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,92 @@
+/*
+ * 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
+ * @key headful
+ * @bug 8166980
+ * @summary Test to check Window.setIconImages() does not result in crash when
+ * a frame is shown
+ * @run main/othervm SetIconImagesCrashTest
+ * @run main/othervm -Dsun.java2d.uiScale=2 SetIconImagesCrashTest
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Window;
+import java.awt.Frame;
+import java.util.List;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import javax.swing.SwingUtilities;
+
+public class SetIconImagesCrashTest {
+
+    public static void main(String[] args) throws Exception {
+
+        List<BufferedImage> imageList = new ArrayList<BufferedImage>();
+        imageList.add(new BufferedImage(200, 200,
+                                BufferedImage.TYPE_BYTE_BINARY));
+
+        for (int i = 0; i < 10; i++) {
+            Frame f = new Frame();
+            test(f, imageList);
+        }
+    }
+
+    public static void test(final Window window,
+            final List<BufferedImage> imageList) throws Exception {
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                for (BufferedImage image : imageList) {
+                    Graphics graphics = image.getGraphics();
+                    graphics.setColor(Color.RED);
+                    graphics.fillRect(
+                            0, 0, image.getWidth(), image.getHeight());
+                    graphics.dispose();
+                }
+
+                window.setIconImages(imageList);
+                window.setSize(200, 200);
+                window.setVisible(true);
+            }
+        });
+
+        while (!window.isVisible()) {
+            Thread.sleep((long) (20));
+        }
+
+        Thread.sleep((long) (50));
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                window.setVisible(false);
+                window.dispose();
+            }
+        });
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/FullScreen/CurrentDisplayModeTest/CurrentDisplayModeTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,52 @@
+/*
+ * 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 8022810
+ * @summary Device.getDisplayMode() doesn't report refresh rate on Linux in case
+ *          of dual screen
+ * @run main CurrentDisplayModeTest
+ */
+
+import java.awt.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CurrentDisplayModeTest {
+    public static void main(String[] args) {
+        GraphicsDevice[] screenDevices = GraphicsEnvironment.
+                               getLocalGraphicsEnvironment().getScreenDevices();
+        for (GraphicsDevice screenDevice : screenDevices) {
+            DisplayMode currentMode = screenDevice.getDisplayMode();
+            System.out.println("current mode " + currentMode);
+            Set<DisplayMode> set = new HashSet<>(
+                                 Arrays.asList(screenDevice.getDisplayModes()));
+            if (!set.contains(currentMode)) {
+                throw new RuntimeException("Mode " + currentMode +
+                        " is not found in the modes list " + set);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics/IncorrectFractionalClip/IncorrectFractionalClip.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,193 @@
+/*
+ * 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.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.Area;
+import java.awt.image.BufferedImage;
+import java.io.File;
+
+import javax.imageio.ImageIO;
+
+import static java.awt.RenderingHints.KEY_STROKE_CONTROL;
+import static java.awt.RenderingHints.VALUE_STROKE_PURE;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8167310
+ * @summary The clip should be correct if the scale is fractional
+ */
+public final class IncorrectFractionalClip {
+
+    private static final int SIZE = 128;
+
+    public static final Color RED = new Color(255, 0, 0, 100);
+
+    public static final Color GREEN = new Color(0, 255, 0, 100);
+
+    public static final Color WHITE = new Color(0, 0, 0, 0);
+
+    public static final BasicStroke STROKE = new BasicStroke(2.01f);
+
+    private static final double[] SCALES = {
+            0.1, 0.25, 0.4, 0.5, 0.6, 1, 1.4, 1.5, 1.6, 2.0, 2.4, 2.5, 2.6, 4
+    };
+
+    static BufferedImage bi;
+
+    static BufferedImage gold;
+
+    static BufferedImage redI;
+
+    static BufferedImage greenI;
+
+    public static void main(final String[] args) throws Exception {
+        bi = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
+        gold = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
+        redI = createImage(RED);
+        greenI = createImage(GREEN);
+
+        System.out.println("Will test fillRect");
+        test(0, true);
+        test(0, false);
+        System.out.println("Will test DrawImage");
+        test(1, true);
+        test(1, false);
+        System.out.println("Will test drawLine");
+        test(2, true);
+        test(2, false);
+    }
+
+    /**
+     * This method draws/fills a number of rectangle, images and lines. Each
+     * time the clip is set as one vertical/horizontal line. The resulted image
+     * should not have any overlapping of different colors. The clip is set via
+     * rectangle(test) and via shape(gold). Both images should be identical.
+     */
+    private static void test(final int testId, final boolean horiz)
+            throws Exception {
+        for (final double scale : SCALES) {
+            // Initialize the test and gold images
+            drawToImage(testId, horiz, scale, bi, /* Rectangle */ false);
+            drawToImage(testId, horiz, scale, gold, /* Shape */ true);
+            validate(bi, gold, testId);
+        }
+    }
+
+    private static void drawToImage(int testId, boolean horiz, double scale,
+                                    BufferedImage image, boolean shape) {
+        Graphics2D g = image.createGraphics();
+        g.setComposite(AlphaComposite.Src);
+        g.setColor(WHITE);
+        g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
+        g.setComposite(AlphaComposite.SrcOver);
+        g.setRenderingHint(KEY_STROKE_CONTROL, VALUE_STROKE_PURE);
+
+        // set the scale in one direction
+        if (horiz) {
+            g.scale(scale, 1);
+        } else {
+            g.scale(1, scale);
+        }
+        // cover all units in the user space to touch all pixels in the
+        // image after transform
+        final int destSize = (int) Math.ceil(SIZE / scale);
+        final int destW;
+        final int destH;
+        if (horiz) {
+            destW = destSize;
+            destH = SIZE;
+        } else {
+            destW = SIZE;
+            destH = destSize;
+        }
+        for (int step = 0; step < destSize; ++step) {
+            if (horiz) {
+                if (!shape) {
+                    g.setClip(step, 0, 1, SIZE);
+                } else{
+                    g.setClip(new Area(new Rectangle(step, 0, 1, SIZE)));
+                }
+            } else {
+                if (!shape) {
+                    g.setClip(0, step, SIZE, 1);
+                }else{
+                    g.setClip(new Area(new Rectangle(0, step, SIZE, 1)));
+                }
+            }
+            switch (testId) {
+                case 0:
+                    g.setColor(step % 2 == 0 ? RED : GREEN);
+                    g.fillRect(0, 0, destW, destH);
+                    break;
+                case 1:
+                    g.drawImage(step % 2 == 0 ? redI : greenI, 0, 0,
+                                destW, destH, null);
+                    break;
+                case 2:
+                    g.setColor(step % 2 == 0 ? RED : GREEN);
+                    g.setStroke(STROKE);
+                    if (horiz) {
+                        g.drawLine(step, 0, step, SIZE);
+                    } else {
+                        g.drawLine(0, step, SIZE, step);
+                    }
+                    break;
+                default:
+                    throw new RuntimeException();
+            }
+        }
+        g.dispose();
+    }
+
+    private static void validate(final BufferedImage bi, BufferedImage gold,
+                                 final int testID) throws Exception {
+        for (int x = 0; x < SIZE; ++x) {
+            for (int y = 0; y < SIZE; ++y) {
+                int rgb = bi.getRGB(x, y);
+                int goldRGB = gold.getRGB(x, y);
+                if ((rgb != GREEN.getRGB() && rgb != RED.getRGB())
+                        || rgb != goldRGB) {
+                    ImageIO.write(bi, "png", new File("image.png"));
+                    ImageIO.write(gold, "png", new File("gold.png"));
+                    throw new RuntimeException("Test failed.");
+                }
+            }
+        }
+    }
+
+    private static BufferedImage createImage(final Color color) {
+        BufferedImage bi = new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB);
+        Graphics2D g = bi.createGraphics();
+        g.setComposite(AlphaComposite.Src);
+        g.setColor(color);
+        g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
+        g.dispose();
+        return bi;
+    }
+}
--- a/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/awt/KeyboardFocusmanager/TypeAhead/SubMenuShowTest/SubMenuShowTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -23,7 +23,7 @@
 
 /*
   test
-  @bug       6380743
+  @bug       6380743 8158380
   @summary   Submenu should be shown by mnemonic key press.
   @author    anton.tarasov@...: area=awt.focus
   @run       applet SubMenuShowTest.html
@@ -55,6 +55,8 @@
 
     public void init() {
         robot = Util.createRobot();
+        robot.setAutoDelay(200);
+        robot.setAutoWaitForIdle(true);
 
         // Create instructions for the user here, as well as set up
         // the environment -- set the layout manager, add buttons,
@@ -85,35 +87,24 @@
             });
 
         frame.setVisible(true);
-        Util.waitForIdle(robot);
 
         boolean isMacOSX = (OSInfo.getOSType() == OSInfo.OSType.MACOSX);
         if (isMacOSX) {
             robot.keyPress(KeyEvent.VK_CONTROL);
-            robot.delay(20);
         }
         robot.keyPress(KeyEvent.VK_ALT);
-        robot.delay(20);
         robot.keyPress(KeyEvent.VK_F);
-        robot.delay(20);
         robot.keyRelease(KeyEvent.VK_F);
-        robot.delay(20);
         robot.keyRelease(KeyEvent.VK_ALT);
+
         if (isMacOSX) {
             robot.keyRelease(KeyEvent.VK_CONTROL);
-            robot.delay(20);
         }
-        Util.waitForIdle(robot);
 
         robot.keyPress(KeyEvent.VK_M);
-        robot.delay(20);
         robot.keyRelease(KeyEvent.VK_M);
-        Util.waitForIdle(robot);
-
         robot.keyPress(KeyEvent.VK_SPACE);
-        robot.delay(20);
         robot.keyRelease(KeyEvent.VK_SPACE);
-        Util.waitForIdle(robot);
 
         if (!Util.waitForCondition(activated, 2000)) {
             throw new TestFailedException("a submenu wasn't activated by mnemonic key press");
--- a/jdk/test/java/awt/List/ActionEventTest/ActionEventTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/awt/List/ActionEventTest/ActionEventTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -24,7 +24,7 @@
 /*
  * @test
  * @key headful
- * @bug 6191390
+ * @bug 6191390 8158380
  * @summary Verify that ActionEvent is received with correct modifiers set.
  * @run main ActionEventTest
  */
@@ -45,6 +45,8 @@
     public ActionEventTest() {
         try {
             robot = new Robot();
+            robot.setAutoDelay(100);
+            robot.setAutoWaitForIdle(true);
         } catch(AWTException e) {
             throw new RuntimeException(e.getMessage());
         }
@@ -56,7 +58,6 @@
         setLayout(new FlowLayout());
         pack();
         setVisible(true);
-        robot.waitForIdle();
     }
 
     void performTest() {
@@ -86,11 +87,9 @@
         // Press Enter on list item, to generate action event.
         robot.keyPress(KeyEvent.VK_ENTER);
         robot.keyRelease(KeyEvent.VK_ENTER);
-        robot.waitForIdle();
         robot.keyRelease(KeyEvent.VK_ALT);
         robot.keyRelease(KeyEvent.VK_SHIFT);
         robot.keyRelease(KeyEvent.VK_CONTROL);
-        robot.waitForIdle();
     }
 
     public static void main(String args[]) {
--- a/jdk/test/java/awt/Modal/InvisibleParentTest/InvisibleParentTest.html	Thu Oct 27 16:29:00 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-<!--
-  Copyright (c) 2013, 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.
--->
-
-<html>
-<!--  
-  @test
-  @bug 6401700 6412803
-  @requires (os.family != "windows")
-  @summary Tests that modal dialog is shown on the screen and 
-iconified/restored correctly if its parent window is invisible
-  @author artem.ananiev: area=awt.modal
-  @run applet/manual=yesno InvisibleParentTest.html
-  -->
-<head>
-<title> InvisibleParentTest </title>
-</head>
-<body>
-
-<h1>InvisibleParentTest<br>Bug ID: 6401700, 6412803</h1>
-
-<p> See the dialog box (usually in upper left corner) for instructions</p>
-
-<APPLET CODE="InvisibleParentTest.class" WIDTH=200 HEIGHT=200></APPLET>
-</body>
-</html>
--- a/jdk/test/java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/awt/Modal/InvisibleParentTest/InvisibleParentTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,214 +22,187 @@
  */
 
 /*
-  test
-  @bug 6401700 6412803
-  @summary Tests that modal dialog is shown on the screen and
-iconified/restored correctly if some of its blocked windows are invisible
-  @author artem.ananiev: area=awt.modal
-  @run applet/manual=yesno InvisibleParentTest.html
-*/
-
-import java.applet.Applet;
-import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Component;
+ * @test
+ * @key headful
+ * @bug 6401700 6412803 8058950
+ * @summary  Tests that modal dialog is shown on the screen and
+ * iconified/restored correctly if some of its blocked windows are invisible
+ * @requires (os.family == "linux" | os.family == "solaris")
+ * @run main/manual InvisibleParentTest
+ */
 import java.awt.Dialog;
 import java.awt.Frame;
-import java.awt.TextArea;
-import java.awt.Window;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class InvisibleParentTest {
 
-public class InvisibleParentTest extends Applet
-{
-    public void init()
-    {
-        setLayout(new BorderLayout());
+    public static void main(String args[]) throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+        TestUI test = new TestUI(latch);
+
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    test.createUI();
+                } catch (Exception ex) {
+                    throw new RuntimeException("Exception while creating test UI");
+                }
+            }
+        });
+
+        boolean status = latch.await(5, TimeUnit.MINUTES);
 
-        String[] instructions =
-        {
-            "If your system is Windows, press PASS button.",
-            "When the test starts two windows should appear: frame G1 and",
-            "    dialog D1. Another one frame F1 should be minimized.",
-            "    If the dialog is not shown (minimizied), press FAIL button.",
-            "Then minimize frame G1 and restore F1. If the dialog D1 is not",
-            "    restored together with F1, press FAIL, else PASS"
-        };
-        Sysout.createDialogWithInstructions( instructions );
+        if (!status) {
+            System.out.println("Test timed out.");
+        }
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    test.disposeUI();
+                } catch (Exception ex) {
+                    throw new RuntimeException("Exception while disposing test UI");
+                }
+            }
+        });
+
+        if (test.testResult == false) {
+            throw new RuntimeException("Test Failed.");
+        }
+    }
+}
+
+class TestUI {
+
+    private static JFrame mainFrame;
+    private static JPanel mainControlPanel;
+
+    private static JTextArea instructionTextArea;
+
+    private static JPanel resultButtonPanel;
+    private static JButton passButton;
+    private static JButton failButton;
+
+    private static GridBagLayout layout;
+    private final CountDownLatch latch;
+    public boolean testResult = false;
+
+    public TestUI(CountDownLatch latch) throws Exception {
+        this.latch = latch;
     }
 
-    public void start ()
-    {
-        Button b;
+    public final void createUI() throws Exception {
+
+        mainFrame = new JFrame("InvisibleParentTest");
+        mainFrame.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
+
+        layout = new GridBagLayout();
+        mainControlPanel = new JPanel(layout);
+        resultButtonPanel = new JPanel(layout);
+
+        GridBagConstraints gbc = new GridBagConstraints();
+
+        // Create Test instructions
+        String instructions
+                = "When the test starts two windows should appear: frame G1 and\n"
+                + "    dialog D1. Another one frame F1 should be minimized.\n"
+                + "    If the dialog is not shown (minimizied), press FAIL button.\n"
+                + "Then minimize frame G1 and restore F1. If the dialog D1 is not\n"
+                + "    restored together with F1, press FAIL, else PASS";
 
-        setSize (200,200);
-        setVisible(true);
-        validate();
+        instructionTextArea = new JTextArea();
+        instructionTextArea.setText(instructions);
+        instructionTextArea.setEditable(false);
+        instructionTextArea.setBorder(BorderFactory.
+                createTitledBorder("Test Instructions"));
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        mainControlPanel.add(instructionTextArea, gbc);
+
+        // Create resultButtonPanel with Pass, Fail buttons
+        passButton = new JButton("Pass");
+        passButton.setActionCommand("Pass");
+        passButton.addActionListener((ActionEvent e) -> {
+            System.out.println("Pass Button pressed!");
+            testResult = true;
+            latch.countDown();
 
-        Component c = this;
-        while ((c != null) && !(c instanceof Window))
-        {
-            c = c.getParent();
-        }
-        if (c != null)
-        {
-            ((Window)c).setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
-        }
+        });
+
+        failButton = new JButton("Fail");
+        failButton.setActionCommand("Fail");
+        failButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                System.out.println("Fail Button pressed!");
+                testResult = false;
+                latch.countDown();
+            }
+        });
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        resultButtonPanel.add(passButton, gbc);
+        gbc.gridx = 1;
+        gbc.gridy = 0;
+        resultButtonPanel.add(failButton, gbc);
 
+        gbc.gridx = 0;
+        gbc.gridy = 1;
+        mainControlPanel.add(resultButtonPanel, gbc);
+
+        mainFrame.add(mainControlPanel);
+
+        mainFrame.pack();
+        mainFrame.setVisible(true);
+
+        // Create AWT frames and modal dialog
+        createAWTComponents();
+    }
+
+    public void disposeUI() {
+        mainFrame.setVisible(false);
+        mainFrame.dispose();
+    }
+
+    private void createAWTComponents() {
         Frame f1 = new Frame("F1");
         f1.setBounds(100, 300, 100, 100);
         f1.setVisible(true);
+
+        try {
+            Thread.sleep(500);
+        } catch (Exception ex) {
+        }
+
         f1.setExtendedState(Frame.ICONIFIED);
 
         Frame g1 = new Frame("G1");
         g1.setBounds(150, 350, 100, 100);
         g1.setVisible(true);
 
-        final Dialog d1 = new Dialog((Frame)null, "D1", Dialog.ModalityType.APPLICATION_MODAL);
+        final Dialog d1 = new Dialog((Frame) null, "D1", Dialog.ModalityType.APPLICATION_MODAL);
         d1.setBounds(200, 400, 100, 100);
-        new Thread(new Runnable()
-        {
-            public void run()
-            {
+        new Thread(new Runnable() {
+            public void run() {
                 d1.setVisible(true);
             }
         }).start();
     }
 }
 
-/****************************************************
- Standard Test Machinery
- DO NOT modify anything below -- it's a standard
-  chunk of code whose purpose is to make user
-  interaction uniform, and thereby make it simpler
-  to read and understand someone else's test.
- ****************************************************/
-
-/**
- This is part of the standard test machinery.
- It creates a dialog (with the instructions), and is the interface
-  for sending text messages to the user.
- To print the instructions, send an array of strings to Sysout.createDialog
-  WithInstructions method.  Put one line of instructions per array entry.
- To display a message for the tester to see, simply call Sysout.println
-  with the string to be displayed.
- This mimics System.out.println but works within the test harness as well
-  as standalone.
- */
-
-class Sysout
-{
-    private static TestDialog dialog;
-
-    public static void createDialogWithInstructions( String[] instructions )
-    {
-        dialog = new TestDialog( new Frame(), "Instructions" );
-        dialog.printInstructions( instructions );
-        dialog.setVisible(true);
-        println( "Any messages for the tester will display here." );
-    }
-
-    public static void createDialog( )
-    {
-        dialog = new TestDialog( new Frame(), "Instructions" );
-        String[] defInstr = { "Instructions will appear here. ", "" } ;
-        dialog.printInstructions( defInstr );
-        dialog.setVisible(true);
-        println( "Any messages for the tester will display here." );
-    }
-
-
-    public static void printInstructions( String[] instructions )
-    {
-        dialog.printInstructions( instructions );
-    }
-
-
-    public static void println( String messageIn )
-    {
-        dialog.displayMessage( messageIn );
-    }
-
-}// Sysout  class
-
-/**
-  This is part of the standard test machinery.  It provides a place for the
-   test instructions to be displayed, and a place for interactive messages
-   to the user to be displayed.
-  To have the test instructions displayed, see Sysout.
-  To have a message to the user be displayed, see Sysout.
-  Do not call anything in this dialog directly.
-  */
-class TestDialog extends Dialog
-{
-
-    TextArea instructionsText;
-    TextArea messageText;
-    int maxStringLength = 80;
-
-    //DO NOT call this directly, go through Sysout
-    public TestDialog( Frame frame, String name )
-    {
-        super( frame, name );
-        setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
-        int scrollBoth = TextArea.SCROLLBARS_BOTH;
-        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
-        add( "North", instructionsText );
-
-        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
-        add("Center", messageText);
-
-        pack();
-
-        setVisible(true);
-    }// TestDialog()
-
-    //DO NOT call this directly, go through Sysout
-    public void printInstructions( String[] instructions )
-    {
-        //Clear out any current instructions
-        instructionsText.setText( "" );
-
-        //Go down array of instruction strings
-
-        String printStr, remainingStr;
-        for( int i=0; i < instructions.length; i++ )
-        {
-            //chop up each into pieces maxSringLength long
-            remainingStr = instructions[ i ];
-            while( remainingStr.length() > 0 )
-            {
-                //if longer than max then chop off first max chars to print
-                if( remainingStr.length() >= maxStringLength )
-                {
-                    //Try to chop on a word boundary
-                    int posOfSpace = remainingStr.
-                        lastIndexOf( ' ', maxStringLength - 1 );
-
-                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
-
-                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
-                    remainingStr = remainingStr.substring( posOfSpace + 1 );
-                }
-                //else just print
-                else
-                {
-                    printStr = remainingStr;
-                    remainingStr = "";
-                }
-
-                instructionsText.append( printStr + "\n" );
-
-            }// while
-
-        }// for
-
-    }//printInstructions()
-
-    //DO NOT call this directly, go through Sysout
-    public void displayMessage( String messageIn )
-    {
-        messageText.append( messageIn + "\n" );
-        System.out.println(messageIn);
-    }
-
-}// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Robot/WaitForIdleSyncroizedOnString/WaitForIdleSyncroizedOnString.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,63 @@
+/*
+ * 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.awt.Robot;
+import java.util.concurrent.CountDownLatch;
+
+import javax.swing.SwingUtilities;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8166673
+ */
+public final class WaitForIdleSyncroizedOnString {
+
+    private static final String WAIT_LOCK = "Wait Lock";
+
+    private static volatile boolean passed = true;
+
+    public static void main(final String[] args) throws Exception {
+        CountDownLatch go = new CountDownLatch(1);
+        Robot r = new Robot();
+        SwingUtilities.invokeLater(() -> System.out.println("some work"));
+        Thread t = new Thread(() -> {
+            synchronized (WAIT_LOCK) {
+                go.countDown();
+                try {
+                    Thread.sleep(30000);
+                    passed = false;
+                } catch (InterruptedException e) {
+                    System.out.println("e = " + e);
+                }
+            }
+        });
+        t.start();
+        go.await();
+        r.waitForIdle();
+        t.interrupt();
+        if (!passed) {
+            throw new RuntimeException("Test failed");
+        }
+    }
+}
--- a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -43,7 +43,7 @@
 /**
  * @test
  * @key headful
- * @bug 8043869 8075244 8078082 8145173
+ * @bug 8043869 8075244 8078082 8145173 8151787
  * @summary Tests the HiDPI splash screen support for windows and MAC
  * @modules java.desktop/sun.java2d
  * @run main MultiResolutionSplashTest GENERATE_IMAGES
@@ -56,27 +56,20 @@
 
     private static final int IMAGE_WIDTH = 300;
     private static final int IMAGE_HEIGHT = 200;
+    private static boolean isMac;
 
-    private static final ImageInfo[] macTests = {
+    static {
+        isMac = System.getProperty("os.name").contains("OS X");
+    }
+    private static final ImageInfo[] tests = {
         new ImageInfo("splash1.png", "splash1@2x.png", Color.BLUE, Color.GREEN),
         new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
         new ImageInfo("splash3.", "splash3@2x.", Color.YELLOW, Color.RED)
     };
-    private static final ImageInfo[] windowsTests = {
-        new ImageInfo("splash1.png", "splash1.scale-120.png", Color.BLUE, Color.GREEN),
-        new ImageInfo("splash2", "splash2.scale-120", Color.WHITE, Color.BLACK),
-        new ImageInfo("splash3.", "splash3.scale-120.", Color.YELLOW, Color.RED)
-    };
-    private static ImageInfo[] tests;
 
     public static void main(String[] args) throws Exception {
 
         String test = args[0];
-        tests = windowsTests;
-        String osName = System.getProperty("os.name");
-        if (osName.contains("OS X")) {
-            tests = macTests;
-        }
         switch (test) {
             case "GENERATE_IMAGES":
                 generateImages();
@@ -104,12 +97,10 @@
         Rectangle splashBounds = splashScreen.getBounds();
         int screenX = (int) splashBounds.getCenterX();
         int screenY = (int) splashBounds.getCenterY();
-
         if (splashBounds.width != IMAGE_WIDTH) {
             throw new RuntimeException(
                     "SplashScreen#getBounds has wrong width");
         }
-
         if (splashBounds.height != IMAGE_HEIGHT) {
             throw new RuntimeException(
                     "SplashScreen#getBounds has wrong height");
@@ -117,7 +108,6 @@
 
         Robot robot = new Robot();
         Color splashScreenColor = robot.getPixelColor(screenX, screenY);
-
         float scaleFactor = getScaleFactor();
         Color testColor = (1 < scaleFactor) ? test.color2x : test.color1x;
 
@@ -129,7 +119,6 @@
 
     static void testFocus() throws Exception {
 
-        System.out.println("Focus Test!");
         Robot robot = new Robot();
         robot.setAutoDelay(50);
 
@@ -150,18 +139,18 @@
 
         frame.dispose();
 
-        if(!textField.getText().equals("ab")){
+        if (!textField.getText().equals("ab")) {
             throw new RuntimeException("Focus is lost!");
         }
     }
 
-    static boolean compare(Color c1, Color c2){
+    static boolean compare(Color c1, Color c2) {
         return compare(c1.getRed(), c2.getRed())
                 && compare(c1.getGreen(), c2.getGreen())
                 && compare(c1.getBlue(), c2.getBlue());
     }
 
-    static boolean compare(int n, int m){
+    static boolean compare(int n, int m) {
         return Math.abs(n - m) <= 50;
     }
 
@@ -177,10 +166,7 @@
             public void paint(Graphics g) {
                 float scaleFactor = 1;
                 if (g instanceof SunGraphics2D) {
-                    scaleFactor = (float)GraphicsEnvironment.
-                            getLocalGraphicsEnvironment().
-                            getDefaultScreenDevice().getDefaultConfiguration().
-                            getDefaultTransform().getScaleX();
+                    scaleFactor = getScreenScaleFactor();
                 }
                 scaleFactors[0] = scaleFactor;
                 dialog.setVisible(false);
@@ -197,23 +183,30 @@
     static void generateImages() throws Exception {
         for (ImageInfo test : tests) {
             generateImage(test.name1x, test.color1x, 1);
-            generateImage(test.name2x, test.color2x, 2);
+            generateImage(test.name2x, test.color2x, getScreenScaleFactor());
         }
     }
 
-    static void generateImage(String name, Color color, int scale) throws Exception {
+    static void generateImage(String name, Color color, float scale) throws Exception {
         File file = new File(name);
         if (file.exists()) {
             return;
         }
-        BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT,
-                BufferedImage.TYPE_INT_RGB);
+        BufferedImage image = new BufferedImage((int) (scale * IMAGE_WIDTH),
+                (int) (scale * IMAGE_HEIGHT), BufferedImage.TYPE_INT_RGB);
         Graphics g = image.getGraphics();
         g.setColor(color);
-        g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT);
+        g.fillRect(0, 0, (int) (scale * IMAGE_WIDTH), (int) (scale * IMAGE_HEIGHT));
         ImageIO.write(image, "png", file);
     }
 
+    static float getScreenScaleFactor() {
+        return (float) GraphicsEnvironment.
+                getLocalGraphicsEnvironment().
+                getDefaultScreenDevice().getDefaultConfiguration().
+                getDefaultTransform().getScaleX();
+    }
+
     static class ImageInfo {
 
         final String name1x;
@@ -223,9 +216,32 @@
 
         public ImageInfo(String name1x, String name2x, Color color1x, Color color2x) {
             this.name1x = name1x;
-            this.name2x = name2x;
+            if (!isMac) {
+                float scale = getScreenScaleFactor();
+                StringBuffer buff = new StringBuffer();
+                if (scale - (int) scale > 0) {
+                    buff.append("@").append((int) (scale * 100)).append("pct");
+                } else {
+                    buff.append("@").append((int) scale).append("x");
+                }
+                StringBuffer buffer = new StringBuffer();
+                String[] splitStr = name1x.split("\\.");
+                if (splitStr.length == 2) {
+                    this.name2x = buffer.append(splitStr[0]).append(buff)
+                            .append(".").append(splitStr[1]).toString();
+                } else {
+                    if (name1x.indexOf(".") > 0) {
+                        this.name2x = buffer.append(splitStr[0]).append(buff).append(".").toString();
+                    } else {
+                        this.name2x = buffer.append(splitStr[0]).append(buff).toString();
+                    }
+                }
+            } else {
+                this.name2x = name2x;
+            }
             this.color1x = color1x;
             this.color2x = color2x;
         }
     }
 }
+
--- a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -44,7 +44,7 @@
 import javax.imageio.ImageIO;
 
 /**
- * @test @bug 8145174
+ * @test @bug 8145174 8151787
  * @summary HiDPI splash screen support on Linux
  * @modules java.desktop/sun.java2d
  * @run main UnixMultiResolutionSplashTest
@@ -55,9 +55,9 @@
     private static final int IMAGE_HEIGHT = 200;
     private static int inx = 0;
     private static final ImageInfo[] tests = {
-        new ImageInfo("splash1.png", "splash1.java-scale2x.png", Color.BLUE, Color.GREEN),
-        new ImageInfo("splash2", "splash2.java-scale2x", Color.WHITE, Color.BLACK),
-        new ImageInfo("splash3.", "splash3.java-scale2x.", Color.YELLOW, Color.RED)
+        new ImageInfo("splash1.png", "splash1@200pct.png", Color.BLUE, Color.GREEN),
+        new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
+        new ImageInfo("splash3.", "splash3@200pct.", Color.YELLOW, Color.RED)
     };
 
     public static void main(String[] args) throws Exception {
@@ -96,8 +96,6 @@
         Rectangle splashBounds = splashScreen.getBounds();
         int screenX = (int) splashBounds.getCenterX();
         int screenY = (int) splashBounds.getCenterY();
-        System.out.println(screenX);
-        System.out.println(screenY);
         Robot robot = new Robot();
         Color splashScreenColor = robot.getPixelColor(screenX, screenY);
 
--- a/jdk/test/java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/awt/TrayIcon/TrayIconEventModifiers/TrayIconEventModifiersTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,7 +21,11 @@
  * questions.
  */
 
-import java.awt.*;
+import java.awt.EventQueue;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.SystemTray;
+import java.awt.TrayIcon;
 import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
@@ -31,9 +35,10 @@
 
 /*
  * @test
+ * @bug 8161473
+ * @key headful
  * @summary Check if MouseEvent has the proper modifiers when
  *          TrayIcon is clicked pressing the modifier keys
- * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
  * @library /java/awt/patchlib
  * @library ../../../../lib/testlibrary ../
  * @build java.desktop/java.awt.Helper
@@ -213,6 +218,7 @@
                 mousePressed = false;
 
                 robot.keyPress(keyTypes[j]);
+                robot.waitForIdle();
                 robot.mousePress(buttonTypes[i]);
 
                 if (! mousePressed) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/* @bug      8166897
+   @summary  Some font overlap in the Optionpane dialog.
+   @run      main ChangeWindowResizabiltyTest
+*/
+
+import java.awt.*;
+
+public class ChangeWindowResizabiltyTest {
+    public static void main(String[] args) throws Exception {
+        Robot robot = new Robot();
+        for(int i = 0; i < 10; i++) {
+            Dialog dialog = new Dialog((Frame) null);
+            Component panel = new Panel();
+            panel.setPreferredSize(new Dimension(200, 100));
+            dialog.add(panel);
+            dialog.pack();
+            dialog.setVisible(true);
+
+            dialog.setResizable(false);
+            robot.waitForIdle();
+            robot.delay(200);
+
+            System.out.println(panel.getLocationOnScreen());
+            System.out.println(dialog.getLocationOnScreen());
+            if (panel.getLocationOnScreen().y <
+                       dialog.getLocationOnScreen().y + dialog.getInsets().top) {
+                dialog.dispose();
+                throw new RuntimeException(
+                        "Wrong content position after setResizable(false)");
+            }
+
+            dialog.setResizable(true);
+            robot.waitForIdle();
+            robot.delay(200);
+            System.out.println(panel.getLocationOnScreen());
+            System.out.println(dialog.getLocationOnScreen());
+            if (panel.getLocationOnScreen().y <
+                    dialog.getLocationOnScreen().y + dialog.getInsets().top) {
+                dialog.dispose();
+                throw new RuntimeException(
+                        "Wrong content position after setResizable(true)");
+            }
+
+            dialog.dispose();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/event/KeyEvent/RobotCrash/RobotCrash.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,92 @@
+/*
+ * 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
+ * @key headful
+ * @bug 8165555
+ * @summary VM crash after creating Robot second time and accessing key codes in
+ *          single JVM mode.
+ * @run main RobotCrash
+ */
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.SwingUtilities;
+
+public class RobotCrash implements Runnable {
+
+    private Frame frame;
+
+    public void robotKeyPressTest() throws Exception {
+
+        SwingUtilities.invokeAndWait(() -> {
+            frame = new Frame();
+            frame.setSize(300, 300);
+            frame.setVisible(true);
+        });
+
+        Robot robot = new Robot();
+        robot.waitForIdle();
+        Point pt = frame.getLocationOnScreen();
+        robot.mouseMove(((int) pt.getX() + frame.getWidth()) / 2,
+                ((int) pt.getY() + frame.getHeight()) / 2);
+        robot.waitForIdle();
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle();
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle();
+        robot.keyPress(KeyEvent.VK_ENTER);
+        robot.waitForIdle();
+        robot.keyRelease(KeyEvent.VK_ENTER);
+        robot.waitForIdle();
+
+        SwingUtilities.invokeAndWait(() -> {
+            frame.dispose();
+        });
+    }
+
+    @Override
+    public void run() {
+        try {
+            robotKeyPressTest();
+        } catch (Exception e) {
+            throw new RuntimeException("Test Failed" + e.getMessage());
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        for (int i = 0; i < 10; i++) {
+            Thread t1 = new Thread(new RobotCrash());
+            t1.start();
+            t1.join();
+            Thread t2 = new Thread(new RobotCrash());
+            t2.start();
+            t2.join();
+            Thread.sleep(1000);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/jdk/TestJDKAWTUtils.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8167126
+ */
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.Rectangle;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+public class TestJDKAWTUtils {
+
+    static JFrame f;
+    public static void main(String[] args) throws Exception {
+
+        SwingUtilities.invokeAndWait(() -> {
+            f = new JFrame("test");
+            JPanel p = new JPanel();
+            JButton b = new JButton("Hello");
+            b.setFont(new Font(Font.DIALOG, Font.PLAIN, 80));
+            p.setLayout(new BorderLayout());
+            p.add("Center", b);
+            f.getContentPane().add(p);
+            f.pack();
+            f.setVisible(true);
+            Rectangle r = new Rectangle(0, 0, 50, 50);
+            jdk.awt.AWTUtils.setComponentMixingCutoutShape(b, r);
+        });
+        Thread.sleep(2000);
+        SwingUtilities.invokeAndWait(() -> f.dispose());
+    }
+}
--- a/jdk/test/java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,9 @@
 
 /*
   @test
-  @bug 8037776
+  @key headful
+  @bug 8037776 8167288
   @summary tests that the WarningWindow is properly disposed
-  @author Petr Pchelko
   @library ../../regtesthelpers/process
   @build ProcessResults ProcessCommunicator
   @run main WarningWindowDisposeTest
@@ -45,13 +45,17 @@
     public static void main(String[] args) {
         final AtomicBoolean passed = new AtomicBoolean(false);
         new Thread(() -> {
-            try {
-                Thread.sleep(5000);
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Test FAILED!", e);
-            }
-            if (!passed.get()) {
-                throw new RuntimeException("Test FAILED! The child process never exits");
+            for (int trial = 0; trial < 5; ++trial) {
+                try {
+                    Thread.sleep(2000);
+                } catch (InterruptedException e) {
+                    throw new RuntimeException("Test FAILED!", e);
+                }
+                if (passed.get()) {
+                    break;
+                } else if (trial == 4) {
+                    throw new RuntimeException("Child process never exits");
+                }
             }
         }, "TimeoutThread").start();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/IsParallelCapable.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,114 @@
+/*
+ * 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 8165793
+ * @summary Test ClassLoader.isParallelCapable() method
+ * @run main IsParallelCapable
+ */
+
+import java.util.stream.Stream;
+
+public class IsParallelCapable {
+    public abstract static class TestCL extends ClassLoader {
+        static {
+            ClassLoader.registerAsParallelCapable();
+        }
+        public abstract boolean expectCapable();
+        public Class findClass(String name) throws ClassNotFoundException {
+            throw new ClassNotFoundException("Why are you using this?");
+        }
+    }
+
+    public static class ParaCL extends TestCL {
+        static {
+            ClassLoader.registerAsParallelCapable();
+        }
+        @Override
+        public boolean expectCapable() { return true; }
+    }
+
+    public static class NonParaCL extends TestCL {
+        @Override
+        public boolean expectCapable() {
+            // Doesn't call registerAsParallelCapable()
+            return false;
+        }
+    }
+
+    public static class NonParaSubCL1 extends ParaCL {
+        @Override
+        public boolean expectCapable() {
+            // Doesn't call registerAsParallelCapable()
+            return false;
+        }
+    }
+
+    public static class NonParaSubCL2 extends NonParaCL {
+        static {
+            ClassLoader.registerAsParallelCapable();
+        }
+        @Override
+        public boolean expectCapable() {
+            // Superclass is not parallel capable
+            return false;
+        }
+    }
+
+    public static class ParaSubCL extends ParaCL {
+        static {
+            ClassLoader.registerAsParallelCapable();
+        }
+        @Override
+        public boolean expectCapable() { return true; }
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!ClassLoader.getSystemClassLoader().isParallelCapable()) {
+            throw new RuntimeException("System classloader not parallel capable!?");
+        }
+
+        Stream.of(ParaCL.class,
+                  NonParaCL.class,
+                  NonParaSubCL1.class,
+                  NonParaSubCL2.class,
+                  ParaSubCL.class)
+                .forEach(IsParallelCapable::testClassLoaderClass);
+    }
+
+    private static void testClassLoaderClass(Class<? extends TestCL> klazz) {
+        try {
+            TestCL cl = (TestCL)klazz.newInstance();
+            if (cl.expectCapable() != cl.isParallelCapable()) {
+                throw new RuntimeException(klazz + " expectCapable: " +
+                        cl.expectCapable() + ", isParallelCapable: " +
+                        cl.isParallelCapable());
+            } else {
+                System.out.println(klazz + " passed");
+            }
+        } catch (InstantiationException |  IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
--- a/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThreadLauncher.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/lang/instrument/DaemonThread/TestDaemonThreadLauncher.java	Thu Oct 27 21:22:57 2016 +0000
@@ -29,7 +29,7 @@
 public class TestDaemonThreadLauncher {
     public static void main(String args[]) throws Exception {
         for(int i=0; i<50; i++) {
-            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-javaagent:DummyAgent.jar", "TestDaemonThread", ".");
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-javaagent:DummyAgent.jar", "TestDaemonThread", ".");
             OutputAnalyzer analyzer = ProcessTools.executeProcess(pb);
             analyzer.shouldNotContain("ASSERTION FAILED");
             analyzer.shouldHaveExitValue(0);
--- a/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/lang/management/MemoryMXBean/LowMemoryTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
  * @modules java.management
  * @build jdk.testlibrary.* LowMemoryTest MemoryUtil RunUtil
  * @run main/timeout=600 LowMemoryTest
+ * @requires vm.gc == "null"
  * @requires vm.opt.ExplicitGCInvokesConcurrent != "true"
  * @requires vm.opt.ExplicitGCInvokesConcurrentAndUnloadsClasses != "true"
  * @requires vm.opt.DisableExplicitGC != "true"
--- a/jdk/test/java/rmi/activation/Activatable/checkActivateRef/CheckActivateRef.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkActivateRef/CheckActivateRef.java	Thu Oct 27 21:22:57 2016 +0000
@@ -40,7 +40,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivateMe CheckActivateRef_Stub
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivateMe CheckActivateRef_Stub
  * @run main/othervm/policy=security.policy/timeout=240 -Djava.rmi.server.ignoreStubClasses=true CheckActivateRef
  * @run main/othervm/policy=security.policy/timeout=240 -Djava.rmi.server.ignoreStubClasses=false CheckActivateRef
  * @key intermittent
@@ -118,7 +119,7 @@
 
             // start an rmid.
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/checkActivateRef/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkActivateRef/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -2,4 +2,6 @@
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.rmi.server.useDynamicProxies=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/checkActivateRef/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkActivateRef/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -38,4 +38,6 @@
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
 
   permission java.lang.RuntimePermission "getClassLoader";
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java	Thu Oct 27 21:22:57 2016 +0000
@@ -32,7 +32,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID MyRMI CheckAnnotations_Stub
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider MyRMI CheckAnnotations_Stub
  * @run main/othervm/policy=security.policy/timeout=480 CheckAnnotations
  */
 
@@ -77,7 +78,7 @@
 
             // start an rmid.
             RMID.removeLog();
-            rmid = RMID.createRMID(rmidOut, rmidErr, false);
+            rmid = RMID.createRMIDOnEphemeralPort(rmidOut, rmidErr, false);
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
@@ -228,6 +229,7 @@
                 return false;
             }
 
+
             // just make sure that last two strings are what we expect.
             if (execOut.equals("ExecGroup-" + iteration)
                 && (new String(destOut.substring(0,4)).equals("out" +
--- a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -28,4 +28,7 @@
 
   // test needs to export rmid and communicate with objects on arbitrary ports
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/CheckImplClassLoader.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/CheckImplClassLoader.java	Thu Oct 27 21:22:57 2016 +0000
@@ -31,7 +31,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider
  *     MyRMI ActivatableImpl ActivatableImpl ActivatableImpl_Stub
  * @run main/othervm/policy=security.policy/timeout=150 CheckImplClassLoader
  */
@@ -80,7 +81,7 @@
                 TestParams.defaultSecurityManager);
 
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             System.err.println("Create activation group in this VM");
--- a/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -39,4 +39,7 @@
 
   // test needs to export rmid and communicate with objects on arbitrary ports
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/CheckRegisterInLog.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/CheckRegisterInLog.java	Thu Oct 27 21:22:57 2016 +0000
@@ -31,7 +31,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary
  *     ActivateMe CheckRegisterInLog_Stub
  * @run main/othervm/policy=security.policy/timeout=240 CheckRegisterInLog
  */
@@ -99,7 +100,7 @@
              * Start up activation system daemon "rmid".
              */
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -31,4 +31,7 @@
 
   // allow exporting object with non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java	Thu Oct 27 21:22:57 2016 +0000
@@ -31,7 +31,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivateMe
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivateMe
  * @run main/othervm/policy=security.policy/timeout=240 CreatePrivateActivatable
  */
 
@@ -103,7 +104,7 @@
 
             // start an rmid.
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -31,4 +31,7 @@
 
   // allow exporting object with non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/DownloadParameterClass.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/DownloadParameterClass.java	Thu Oct 27 21:22:57 2016 +0000
@@ -35,7 +35,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary
  *     Foo FooReceiverImpl FooReceiverImpl_Stub Bar
  * @run main/othervm/policy=security.policy/timeout=240 DownloadParameterClass
  */
@@ -90,7 +91,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/manual.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/manual.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -34,4 +34,7 @@
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -35,4 +35,7 @@
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/ElucidateNoSuchMethod.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/ElucidateNoSuchMethod.java	Thu Oct 27 21:22:57 2016 +0000
@@ -31,7 +31,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivateMe ElucidateNoSuchMethod_Stub
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivateMe ElucidateNoSuchMethod_Stub
  * @run main/othervm/policy=security.policy/timeout=240 ElucidateNoSuchMethod
  */
 
@@ -91,7 +92,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,7 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -37,4 +37,7 @@
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ExtLoadedImplTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ExtLoadedImplTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -37,7 +37,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
             Properties p = new Properties();
             p.put("java.security.policy",
--- a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh	Thu Oct 27 21:22:57 2016 +0000
@@ -27,7 +27,7 @@
 # loader, the context class loader should remain unchanged (i.e., not be
 # set to the impl's class loader) when the impl is activated.
 # @library ../../../testlibrary
-# @build TestLibrary RMID ActivationLibrary
+# @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary
 # @build ExtLoadedImplTest ExtLoadedImpl ExtLoadedImpl_Stub CheckLoader
 # @run shell ext.sh
 
--- a/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java	Thu Oct 27 21:22:57 2016 +0000
@@ -31,7 +31,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary
  *     ActivateMe ForceLogSnapshot_Stub
  * @run main/othervm/policy=security.policy/timeout=640 ForceLogSnapshot
  */
@@ -129,7 +130,7 @@
                 SNAPSHOT_INTERVAL;
 
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.addOptions(new String[] {option, "-Djava.compiler="});
             rmid.start();
 
--- a/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -31,4 +31,7 @@
 
   // allow exporting object with non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/inactiveGroup/InactiveGroup.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/inactiveGroup/InactiveGroup.java	Thu Oct 27 21:22:57 2016 +0000
@@ -33,7 +33,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary ActivateMe InactiveGroup_Stub
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary ActivateMe InactiveGroup_Stub
  * @run main/othervm/policy=security.policy/timeout=240 InactiveGroup
  */
 
@@ -101,7 +102,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/inactiveGroup/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/inactiveGroup/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/inactiveGroup/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/inactiveGroup/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -31,4 +31,7 @@
 
   // allow exporting object with non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/lookupActivationSystem/LookupActivationSystem.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/lookupActivationSystem/LookupActivationSystem.java	Thu Oct 27 21:22:57 2016 +0000
@@ -33,7 +33,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary
  * @run main/othervm/timeout=240 LookupActivationSystem
  */
 
@@ -55,7 +56,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             System.err.println("look up activation system");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/lookupActivationSystem/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,4 @@
+grant {
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
+};
--- a/jdk/test/java/rmi/activation/Activatable/nestedActivate/NestedActivate.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/nestedActivate/NestedActivate.java	Thu Oct 27 21:22:57 2016 +0000
@@ -31,7 +31,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary ActivateMe NestedActivate_Stub
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary ActivateMe NestedActivate_Stub
  * @run main/othervm/policy=security.policy/timeout=240 NestedActivate
  */
 
@@ -101,7 +102,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/nestedActivate/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/nestedActivate/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/nestedActivate/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/nestedActivate/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -31,4 +31,7 @@
 
   // allow exporting of non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/NonExistentActivatable.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/NonExistentActivatable.java	Thu Oct 27 21:22:57 2016 +0000
@@ -32,7 +32,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary
  *     ActivateMe NonExistentActivatable_Stub
  * @run main/othervm/policy=security.policy/timeout=240 NonExistentActivatable
  */
@@ -91,7 +92,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -32,4 +32,6 @@
   // allow exporting object with non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
 
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/restartCrashedService/RestartCrashedService.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartCrashedService/RestartCrashedService.java	Thu Oct 27 21:22:57 2016 +0000
@@ -32,7 +32,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivateMe RestartCrashedService_Stub
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivateMe RestartCrashedService_Stub
  * @run main/othervm/policy=security.policy/timeout=240 RestartCrashedService
  */
 
@@ -119,7 +120,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/restartCrashedService/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartCrashedService/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/restartCrashedService/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartCrashedService/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -28,4 +28,7 @@
 
   // test needs to export rmid and communicate with objects on arbitrary ports
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/restartLatecomer/RestartLatecomer.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartLatecomer/RestartLatecomer.java	Thu Oct 27 21:22:57 2016 +0000
@@ -31,7 +31,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary
  *     RestartLatecomer RestartLatecomer_Stub
  * @run main/othervm/policy=security.policy/timeout=240 RestartLatecomer
  */
@@ -166,7 +167,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/restartLatecomer/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartLatecomer/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/restartLatecomer/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartLatecomer/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -33,4 +33,7 @@
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/restartService/RestartService.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartService/RestartService.java	Thu Oct 27 21:22:57 2016 +0000
@@ -32,7 +32,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary ActivateMe RestartService_Stub
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary ActivateMe RestartService_Stub
  * @run main/othervm/policy=security.policy/timeout=240 RestartService
  */
 
@@ -129,7 +130,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/Activatable/restartService/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartService/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/restartService/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/restartService/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -33,4 +33,7 @@
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java	Thu Oct 27 21:22:57 2016 +0000
@@ -32,7 +32,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider
  *     TestSecurityManager RegisteringActivatable ShutdownGracefully_Stub
  * @run main/othervm/policy=security.policy/timeout=700 ShutdownGracefully
  */
@@ -76,7 +77,7 @@
 
             // start an rmid.
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
 
             // rmid needs to run with a security manager that
             // simulates a log problem; rmid should also snapshot
--- a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -2,4 +2,6 @@
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=java.lang.SecurityManager";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Ddummyname=dummyvalue";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -25,4 +25,7 @@
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/unregisterInactive/UnregisterInactive.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/unregisterInactive/UnregisterInactive.java	Thu Oct 27 21:22:57 2016 +0000
@@ -32,7 +32,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary ActivateMe UnregisterInactive_Stub
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary ActivateMe UnregisterInactive_Stub
  * @run main/othervm/policy=security.policy/timeout=240 UnregisterInactive
  */
 
@@ -89,7 +90,7 @@
 
         try {
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
             System.err.println("Creating descriptor");
 
--- a/jdk/test/java/rmi/activation/Activatable/unregisterInactive/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/unregisterInactive/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/Activatable/unregisterInactive/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/Activatable/unregisterInactive/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -28,4 +28,7 @@
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java	Thu Oct 27 21:22:57 2016 +0000
@@ -35,7 +35,8 @@
  *          java.rmi/sun.rmi.server
  *          java.rmi/sun.rmi.transport
  *          java.rmi/sun.rmi.transport.tcp
- * @build TestLibrary RMID ActivationLibrary
+ *          java.base/sun.nio.ch
+ * @build TestLibrary RMID RMIDSelectorProvider ActivationLibrary
  *     ActivateMe ActivateFails_Stub ShutdownThread
  * @run main/othervm/java.security.policy=security.policy/timeout=240 ActivateFails
  */
@@ -93,7 +94,7 @@
              * First run "rmid" and wait for it to start up.
              */
             RMID.removeLog();
-            rmid = RMID.createRMID();
+            rmid = RMID.createRMIDOnEphemeralPort();
             rmid.start();
 
             /* Cause activation groups to have a security policy that will
--- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/rmid.security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/rmid.security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -1,4 +1,6 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission java.lang.RuntimePermission "selectorProvider";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -28,4 +28,7 @@
 
   // test needs to export rmid and communicate with objects on arbitrary ports
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  permission java.lang.RuntimePermission "selectorProvider";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
 };
--- a/jdk/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java	Thu Oct 27 21:22:57 2016 +0000
@@ -51,6 +51,8 @@
 import java.rmi.registry.LocateRegistry;
 import java.rmi.registry.Registry;
 import java.rmi.server.UnicastRemoteObject;
+import static java.net.StandardSocketOptions.SO_REUSEADDR;
+import static java.net.StandardSocketOptions.SO_REUSEPORT;
 
 public class RmidViaInheritedChannel implements Callback {
     private static final Object lock = new Object();
@@ -185,6 +187,15 @@
                  */
                 channel = ServerSocketChannel.open();
                 ServerSocket serverSocket = channel.socket();
+
+                // Enable SO_REUSEADDR before binding
+                serverSocket.setOption(SO_REUSEADDR, true);
+
+                // Enable SO_REUSEPORT, if supported, before binding
+                if (serverSocket.supportedOptions().contains(SO_REUSEPORT)) {
+                    serverSocket.setOption(SO_REUSEPORT, true);
+                }
+
                 serverSocket.bind(
                      new InetSocketAddress(InetAddress.getLocalHost(),
                      TestLibrary.RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT));
--- a/jdk/test/java/rmi/testlibrary/JavaVM.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/testlibrary/JavaVM.java	Thu Oct 27 21:22:57 2016 +0000
@@ -21,8 +21,11 @@
  * questions.
  */
 
+import java.io.BufferedReader;
+import java.io.DataInputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.StringTokenizer;
@@ -39,8 +42,8 @@
     protected Process vm = null;
 
     private String classname = "";
-    private String args = "";
-    private String options = "";
+    protected String args = "";
+    protected String options = "";
     private OutputStream outputStream = System.out;
     private OutputStream errorStream = System.err;
     private String policyFileName = null;
@@ -113,7 +116,7 @@
     /**
      * Exec the VM as specified in this object's constructor.
      */
-    public void start() throws IOException {
+    private void start0() throws IOException {
 
         if (vm != null)
             throw new IllegalStateException("JavaVM already started");
@@ -152,12 +155,50 @@
         mesg("command = " + Arrays.asList(javaCommand).toString());
 
         vm = Runtime.getRuntime().exec(javaCommand);
+    }
 
-        /* output from the execed process may optionally be captured. */
+    public void start() throws IOException {
+        start0();
+
+        /* output from the exec'ed process may optionally be captured. */
         outPipe = StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
         errPipe = StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
     }
 
+    public int startAndGetPort() throws IOException {
+        start0();
+
+        int port = -1;
+        if (options.contains("java.nio.channels.spi.SelectorProvider=RMIDSelectorProvider")) {
+            // Obtain the server socket channel's ephemeral port number of the
+            // child rmid process.
+            BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(vm.getInputStream()));
+            String s;
+            while ((s = reader.readLine()) != null) {
+                System.out.println(s);
+                int i = s.indexOf(RMID.EPHEMERAL_MSG);
+                if (i != -1) {
+                    String v = s.substring(RMID.EPHEMERAL_MSG.length());
+                    port = Integer.valueOf(v);
+                    break;
+                }
+            }
+            if (port == -1) {
+                // something failed
+                reader = new BufferedReader(new InputStreamReader(vm.getErrorStream()));
+                while ((s = reader.readLine()) != null)
+                    System.err.println(s);
+            }
+        }
+
+        /* output from the exec'ed process may optionally be captured. */
+        outPipe = StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
+        errPipe = StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
+
+        return port;
+    }
+
     public void destroy() {
         if (vm != null) {
             vm.destroy();
--- a/jdk/test/java/rmi/testlibrary/RMID.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/testlibrary/RMID.java	Thu Oct 27 21:22:57 2016 +0000
@@ -49,20 +49,31 @@
 
     public static String MANAGER_OPTION="-Djava.security.manager=";
 
-    /** Test port for rmid */
-    private final int port;
+    /**
+     * Test port for rmid.
+     *
+     * May initially be 0, which means that the child rmid process will choose
+     * an ephemeral port and report it back to the parent process. This field
+     * will then be set to the child rmid's ephemeral port value.
+     */
+    private volatile int port;
+    //private final boolean ephemeralPort
 
     /** Initial log name */
     protected static String log = "log";
     /** rmid's logfile directory; currently must be "." */
     protected static String LOGDIR = ".";
 
+    /** The output message from the child rmid process that directly precedes
+     * the ephemeral port number.*/
+    public static final String EPHEMERAL_MSG = "RmidSelectorProvider-listening-On:";
+
     private static void mesg(Object mesg) {
         System.err.println("RMID: " + mesg.toString());
     }
 
     /** make test options and arguments */
-    private static String makeOptions(boolean debugExec) {
+    private static String makeOptions(int port, boolean debugExec) {
 
         String options = " -Dsun.rmi.server.activation.debugExec=" +
             debugExec;
@@ -87,6 +98,17 @@
         // to avoid spurious timeouts on slow machines.
         options += " -Dsun.rmi.activation.execTimeout=60000";
 
+        if (port == 0) {
+            // Ephemeral port, so have the rmid child process create the
+            // server socket channel and report its port number, over stdin.
+            options += " -classpath " + TestParams.testClassPath;
+            options += " --add-exports=java.base/sun.nio.ch=ALL-UNNAMED";
+            options += " -Djava.nio.channels.spi.SelectorProvider=RMIDSelectorProvider";
+
+            // Disable redirection of System.err to /tmp
+            options += " -Dsun.rmi.server.activation.disableErrRedirect=true";
+        }
+
         return options;
     }
 
@@ -107,7 +129,8 @@
         String args =
             " -log " + (new File(LOGDIR, log)).getAbsolutePath();
 
-        if (includePortArg) {
+        // 0 = ephemeral port, do not include an explicit port number
+        if (includePortArg && port != 0) {
             args += " -port " + port;
         }
 
@@ -160,7 +183,7 @@
                                   boolean debugExec, boolean includePortArg,
                                   int port)
     {
-        String options = makeOptions(debugExec);
+        String options = makeOptions(port, debugExec);
         String args = makeArgs(includePortArg, port);
         RMID rmid = new RMID("sun.rmi.server.Activation", options, args,
                              out, err, port);
@@ -169,6 +192,17 @@
         return rmid;
     }
 
+    public static RMID createRMIDOnEphemeralPort() {
+        return createRMID(System.out, System.err, true, true, 0);
+    }
+
+    public static RMID createRMIDOnEphemeralPort(OutputStream out,
+                                                 OutputStream err,
+                                                 boolean debugExec)
+    {
+        return createRMID(out, err, debugExec, true, 0);
+    }
+
 
     /**
      * Private constructor. RMID instances should be created
@@ -247,7 +281,10 @@
         // a well recognized exception (port already in use...).
 
         mesg("Starting rmid on port " + port + ".");
-        super.start();
+        int p = super.startAndGetPort();
+        if (p != -1)
+            port = p;
+        mesg("Started rmid on port " + port + ".");
 
         // int slopFactor = 1;
         // try {
@@ -271,8 +308,11 @@
 
             try {
                 int status = vm.exitValue();
+                waitFor(TIMEOUT_SHUTDOWN_MS);
                 TestLibrary.bomb("Rmid process exited with status " + status + " after " +
                     (System.currentTimeMillis() - startTime) + "ms.");
+            } catch (InterruptedException | TimeoutException e) {
+                mesg(e);
             } catch (IllegalThreadStateException ignore) { }
 
             // The rmid process is alive; check to see whether
@@ -307,6 +347,8 @@
      */
     public void restart() throws IOException {
         destroy();
+        options = makeOptions(port, true);
+        args = makeArgs(true, port);
         start();
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/testlibrary/RMIDSelectorProvider.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,107 @@
+/*
+ * 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.*;
+import java.net.InetSocketAddress;
+import java.net.ProtocolFamily;
+import java.nio.channels.Channel;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.Pipe;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.spi.AbstractSelector;
+import java.nio.channels.spi.SelectorProvider;
+import static java.net.StandardSocketOptions.SO_REUSEADDR;
+import static java.net.StandardSocketOptions.SO_REUSEPORT;
+
+/**
+ * A SelectorProvider, that can be loaded by the child rmid process, whose
+ * inheritedChannel method will create a new server socket channel and report
+ * it back to the parent process, over stdout.
+ */
+public class RMIDSelectorProvider extends SelectorProvider {
+
+    private final SelectorProvider provider;
+    private ServerSocketChannel channel;
+
+    public RMIDSelectorProvider() {
+        provider = sun.nio.ch.DefaultSelectorProvider.create();
+    }
+
+    public DatagramChannel openDatagramChannel()
+        throws IOException
+    {
+        return provider.openDatagramChannel();
+    }
+
+    public DatagramChannel openDatagramChannel(ProtocolFamily family)
+        throws IOException
+    {
+        return provider.openDatagramChannel(family);
+    }
+
+    public Pipe openPipe()
+        throws IOException
+    {
+        return provider.openPipe();
+    }
+
+    public AbstractSelector openSelector()
+        throws IOException
+    {
+        return provider.openSelector();
+    }
+
+    public ServerSocketChannel openServerSocketChannel()
+        throws IOException
+    {
+        return provider.openServerSocketChannel();
+    }
+
+    public SocketChannel openSocketChannel()
+        throws IOException
+    {
+        return provider.openSocketChannel();
+    }
+
+    public synchronized Channel inheritedChannel() throws IOException {
+        System.out.println("RMIDSelectorProvider.inheritedChannel");
+        if (channel == null) {
+            // Create and bind a new server socket channel
+            channel = ServerSocketChannel.open();
+
+            // Enable SO_REUSEADDR before binding
+            channel.setOption(SO_REUSEADDR, true);
+
+            // Enable SO_REUSEPORT, if supported, before binding
+            if (channel.supportedOptions().contains(SO_REUSEPORT)) {
+                channel.setOption(SO_REUSEPORT, true);
+            }
+
+            channel.bind(new InetSocketAddress(0));
+
+            System.out.println(RMID.EPHEMERAL_MSG + channel.socket().getLocalPort());
+        }
+        return channel;
+    }
+}
--- a/jdk/test/java/rmi/testlibrary/TestParams.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/rmi/testlibrary/TestParams.java	Thu Oct 27 21:22:57 2016 +0000
@@ -34,6 +34,7 @@
     /** variables that hold value property values */
     public static final String testSrc;
     public static final String testClasses;
+    public static final String testClassPath;
 
     /** name of default security policy for test JVM */
     public static final String defaultPolicy;
@@ -57,6 +58,7 @@
     static {
         testSrc = TestLibrary.getProperty("test.src", ".");
         testClasses = TestLibrary.getProperty("test.classes", ".");
+        testClassPath = TestLibrary.getProperty("test.class.path", ".");
 
         String dp = TestLibrary.getProperty("java.security.policy", null);
         if (dp == null) {
--- a/jdk/test/java/util/Arrays/ParallelPrefix.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/util/Arrays/ParallelPrefix.java	Thu Oct 27 21:22:57 2016 +0000
@@ -26,7 +26,6 @@
  * @summary unit test for Arrays.ParallelPrefix().
  * @author Tristan Yan
  * @run testng ParallelPrefix
- * @key intermittent
  */
 
 import java.util.Arrays;
--- a/jdk/test/java/util/PluggableLocale/BreakIteratorProviderTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/util/PluggableLocale/BreakIteratorProviderTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -89,7 +89,7 @@
             String[] jresResult = new String[4];
             if (jreSupportsLocale) {
                 for (int i = 0; i < 4; i++) {
-                    jresResult[i] = "sun.util.locale.provider."+classNames[i];
+                    jresResult[i] = "sun.text." + classNames[i];
                 }
             }
 
--- a/jdk/test/java/util/PluggableLocale/BreakIteratorProviderTest.sh	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/java/util/PluggableLocale/BreakIteratorProviderTest.sh	Thu Oct 27 21:22:57 2016 +0000
@@ -1,6 +1,6 @@
 #!/bin/sh
 # 
-# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 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
@@ -23,6 +23,6 @@
 #
 #
 # @test
-# @bug 4052440 8062588
+# @bug 4052440 8062588 8165804
 # @summary BreakIteratorProvider tests
 # @run shell ExecTest.sh foo BreakIteratorProviderTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/ImageCompressionTypesTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,71 @@
+/*
+ * 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     6294607
+  * @summary Test verifies whether ImageWriteParam.getCompressionTypes()
+  *          returns any duplicate compression type for ImageIO plugins.
+  * @run     main ImageCompressionTypesTest
+  */
+
+import java.util.Iterator;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriteParam;
+import javax.imageio.ImageWriter;
+
+public class ImageCompressionTypesTest {
+
+    static ImageWriter writer = null;
+
+    public ImageCompressionTypesTest(String format) {
+        Iterator it = ImageIO.getImageWritersByFormatName(format);
+        while (it.hasNext()) {
+            writer = (ImageWriter) it.next();
+            break;
+        }
+        ImageWriteParam param = writer.getDefaultWriteParam();
+
+        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+        System.out.println("Checking compression types for : " + format);
+        String compTypes[] = param.getCompressionTypes();
+        if (compTypes.length > 1) {
+            for (int i = 0; i < compTypes.length; i++) {
+                for (int j = i + 1; j < compTypes.length; j++) {
+                    if (compTypes[i].equalsIgnoreCase(compTypes[j])) {
+                        throw new RuntimeException("Duplicate compression"
+                                + " type exists for image format " + format);
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(String args[]) {
+        final String[] formats = {"bmp", "png", "gif", "jpg", "tiff"};
+        for (String format : formats) {
+            new ImageCompressionTypesTest(format);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/metadata/GetElementsByTagNameTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,73 @@
+/*
+ * 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     8167281
+ * @summary Test verifies that Element.getElementsByTagName("*") is not empty
+ *          for valid image.
+ * @run     main GetElementsByTagNameTest
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+import org.w3c.dom.Element;
+
+public class GetElementsByTagNameTest {
+
+    public static void main(String[] args) throws IOException {
+        // Generate some trivial image and save it to a temporary array
+        ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+        ImageIO.write(new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB),
+                "gif", tmp);
+
+        // Read the stream
+        ImageInputStream in = new MemoryCacheImageInputStream(
+                new ByteArrayInputStream(tmp.toByteArray()));
+        ImageReader reader = ImageIO.getImageReaders(in).next();
+        reader.setInput(in);
+
+        // Retrieve standard image metadata tree
+        IIOMetadata meta = reader.getImageMetadata(0);
+        if (meta == null || !meta.isStandardMetadataFormatSupported()) {
+            throw new Error("Test failure: Missing metadata");
+        }
+        Element root = (Element) meta.
+                getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
+
+        // Test getElementsByTagName("*")
+        if (root.getElementsByTagName("*").getLength() == 0) {
+            throw new RuntimeException("getElementsByTagName(\"*\") returns"
+                    + " nothing");
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/metadata/NthItemNodeListTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug     8167281
+ * @summary Test verifies that accessing nth item in NodeList doesn't throw
+ *          IndexOutOfBoundsException.
+ * @run     main NthItemNodeListTest
+ */
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import javax.imageio.stream.ImageInputStream;
+import javax.imageio.stream.MemoryCacheImageInputStream;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class NthItemNodeListTest {
+
+    public static void main(String[] args) throws IOException {
+        // Generate some trivial image and save it to a temporary array
+        ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+        ImageIO.write(new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB),
+                "gif", tmp);
+
+        // Read it back in
+        ImageInputStream in = new MemoryCacheImageInputStream(
+                new ByteArrayInputStream(tmp.toByteArray()));
+        ImageReader reader = ImageIO.getImageReaders(in).next();
+        reader.setInput(in);
+
+        // Retrieve standard image metadata tree
+        IIOMetadata meta = reader.getImageMetadata(0);
+        if (meta == null || !meta.isStandardMetadataFormatSupported()) {
+            throw new Error("Test failure: Missing metadata");
+        }
+        Element root = (Element) meta.
+                getAsTree(IIOMetadataFormatImpl.standardMetadataFormatName);
+
+        NodeList nodeList = root.
+                getElementsByTagName(root.getFirstChild().getNodeName());
+        /*
+         * Accessing the nth node should return null and not throw
+         * IndexOutOfBoundsException.
+         */
+        Node n = (nodeList.item(nodeList.getLength()));
+    }
+}
+
--- a/jdk/test/javax/print/attribute/Services_getDocFl.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/javax/print/attribute/Services_getDocFl.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 
 /*
  * @test
- * @bug 4901243 8040139
+ * @bug 4901243 8040139 8167291
  * @summary JPG, GIF, and PNG DocFlavors (URL) should be supported if Postscript is supported.
  * @run main Services_getDocFl
 */
@@ -58,6 +58,7 @@
             pngImagesSupported = false;
             gifImagesSupported = false;
             jpgImagesSupported = false;
+            psSupported = false;
             for (int j=0; j<flavors.length; j++) {
                 System.out.println(flavors[j]);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/Clip/OpenNonIntegralNumberOfSampleframes.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,105 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.LineUnavailableException;
+
+/**
+ * @test
+ * @bug 8167435
+ */
+public final class OpenNonIntegralNumberOfSampleframes {
+
+    /**
+     * We will try to use all formats, in this case all our providers will be
+     * covered by supported/unsupported formats.
+     */
+    private static final List<AudioFormat> formats = new ArrayList<>(2900);
+
+    private static final Encoding[] encodings = {
+            Encoding.ALAW, Encoding.ULAW, Encoding.PCM_SIGNED,
+            Encoding.PCM_UNSIGNED, Encoding.PCM_FLOAT
+    };
+
+    private static final int[] sampleRates = {
+            8000, 11025, 16000, 32000, 44100
+    };
+
+    private static final int[] sampleBits = {
+            4, 8, 11, 16, 20, 24, 32, 48, 64, 128
+    };
+
+    private static final int[] channels = {
+            1, 2, 3, 4, 5, 6
+    };
+
+    static {
+        for (final Boolean end : new boolean[]{false, true}) {
+            for (final int sampleSize : sampleBits) {
+                for (final int sampleRate : sampleRates) {
+                    for (final int channel : channels) {
+                        final int frameSize = ((sampleSize + 7) / 8) * channel;
+                        if (frameSize == 1) {
+                            // frameSize=1 is ok for any buffers, skip it
+                            continue;
+                        }
+                        for (final Encoding enc : encodings) {
+                            formats.add(
+                                    new AudioFormat(enc, sampleRate, sampleSize,
+                                                    channel, frameSize,
+                                                    sampleRate, end));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public static void main(final String[] args) {
+        for (final AudioFormat af : formats) {
+            try (Clip clip = AudioSystem.getClip()) {
+                final int bufferSize = af.getFrameSize() + 1;
+                try {
+                    clip.open(af, new byte[100], 0, bufferSize);
+                } catch (final IllegalArgumentException ignored) {
+                    // expected exception
+                    continue;
+                } catch (final LineUnavailableException e) {
+                    // should not occur, we passed incorrect bufferSize
+                    e.printStackTrace();
+                }
+                System.err.println("af = " + af);
+                System.err.println("bufferSize = " + bufferSize);
+                throw new RuntimeException("Expected exception is not thrown");
+            } catch (final LineUnavailableException ignored) {
+                // the test is not applicable
+            }
+        }
+    }
+}
--- a/jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/javax/swing/JMenuItem/8139169/ScreenMenuBarInputTwice.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 8139169
+ * @bug 8139169 8158390
  * @summary verifies if TextArea gets input twice due to Apple's Screen Menubar
  * @requires (os.family=="mac")
  * @library ../../regtesthelpers
@@ -65,15 +65,13 @@
 
     public static void main(String[] args) throws Exception {
         robot = new Robot();
+        robot.setAutoDelay(200);
+        robot.setAutoWaitForIdle(true);
         createUIWithSeperateMenuBar();
-        robot.delay(2000);
         shortcutTestCase();
-        robot.delay(2000);
         cleanUp();
         createUIWithIntegratedMenuBar();
-        robot.delay(2000);
         menuTestCase();
-        robot.delay(2000);
         cleanUp();
     }
 
@@ -188,7 +186,6 @@
         robot.keyRelease(VK_COMMA);
         robot.keyRelease(VK_SHIFT);
         robot.keyRelease(VK_META);
-        robot.delay(2000);
         checkText(textArea.getText());
     }
 
@@ -198,13 +195,10 @@
         robot.mouseMove(mousePoint.x, mousePoint.y);
         robot.mousePress(InputEvent.BUTTON1_MASK);
         robot.mouseRelease(InputEvent.BUTTON1_MASK);
-        robot.delay(2000);
         mousePoint = Util.getCenterPoint(menuItem);
         robot.mouseMove(mousePoint.x, mousePoint.y);
-        robot.delay(2000);
         robot.mousePress(InputEvent.BUTTON1_MASK);
         robot.mouseRelease(InputEvent.BUTTON1_MASK);
-        robot.delay(2000);
         checkText(textArea.getText());
     }
 
--- a/jdk/test/javax/swing/JTextArea/ScrollbarFlicker/ScrollFlickerTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/javax/swing/JTextArea/ScrollbarFlicker/ScrollFlickerTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -29,8 +29,6 @@
 
 import javax.swing.*;
 import java.awt.*;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
 
 public class ScrollFlickerTest {
 
@@ -56,18 +54,19 @@
         robot.delay(200);
 
         SwingUtilities.invokeAndWait(() -> {
-            scroll.getViewport().addChangeListener((e) -> cnt++);
             Insets insets = scroll.getInsets();
             scroll.setSize(insets.left + insets.right +
                     scroll.getVerticalScrollBar().getPreferredSize().width, 50);
             scroll.revalidate();
         });
-
+        robot.delay(200);
+        SwingUtilities.invokeAndWait(() ->
+                          scroll.getViewport().addChangeListener((e) -> cnt++));
         robot.delay(1000);
 
         SwingUtilities.invokeLater(frame::dispose);
 
-        if (cnt > 2) {
+        if (cnt > 0) {
             throw new RuntimeException("Scroll bar flickers");
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/basic/BasicScrollPaneUI/8166591/TooMuchWheelRotationEventsTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,189 @@
+/*
+ * 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.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @bug 8166591
+ * @key headful
+ * @summary [macos 10.12] Trackpad scrolling of text on OS X 10.12 Sierra
+ *    is very fast (Trackpad, Retina only)
+ * @run main/manual/othervm TooMuchWheelRotationEventsTest
+ */
+public class TooMuchWheelRotationEventsTest {
+
+    private static volatile boolean testResult = false;
+    private static volatile CountDownLatch countDownLatch;
+    private static final String INSTRUCTIONS = "INSTRUCTIONS:\n"
+            + "Try to check the issue on Mac OS X 10.12 Sierra with trackpad"
+            + " on Retina display.\n"
+            + "\n"
+            + "If the trackpad is not supported, press PASS\n"
+            + "\n"
+            + "Use the trackpad to slightly scroll the JTextArea horizontally and vertically.\n"
+            + "If the text area is scrolled too fast press FAIL, else press PASS.";
+
+    public static void main(String args[]) throws Exception {
+        countDownLatch = new CountDownLatch(1);
+
+        SwingUtilities.invokeLater(TooMuchWheelRotationEventsTest::createUI);
+        countDownLatch.await(15, TimeUnit.MINUTES);
+
+        if (!testResult) {
+            throw new RuntimeException("Test fails!");
+        }
+    }
+
+    private static void createUI() {
+
+        final JFrame mainFrame = new JFrame("Trackpad scrolling test");
+        GridBagLayout layout = new GridBagLayout();
+        JPanel mainControlPanel = new JPanel(layout);
+        JPanel resultButtonPanel = new JPanel(layout);
+
+        GridBagConstraints gbc = new GridBagConstraints();
+
+        JPanel testPanel = createTestPanel();
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        mainControlPanel.add(testPanel, gbc);
+
+        JTextArea instructionTextArea = new JTextArea();
+        instructionTextArea.setText(INSTRUCTIONS);
+        instructionTextArea.setEditable(false);
+        instructionTextArea.setBackground(Color.white);
+
+        gbc.gridx = 0;
+        gbc.gridy = 1;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        mainControlPanel.add(instructionTextArea, gbc);
+
+        JButton passButton = new JButton("Pass");
+        passButton.setActionCommand("Pass");
+        passButton.addActionListener((ActionEvent e) -> {
+            testResult = true;
+            mainFrame.dispose();
+            countDownLatch.countDown();
+
+        });
+
+        JButton failButton = new JButton("Fail");
+        failButton.setActionCommand("Fail");
+        failButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                mainFrame.dispose();
+                countDownLatch.countDown();
+            }
+        });
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        resultButtonPanel.add(passButton, gbc);
+
+        gbc.gridx = 1;
+        gbc.gridy = 0;
+        resultButtonPanel.add(failButton, gbc);
+
+        gbc.gridx = 0;
+        gbc.gridy = 2;
+        mainControlPanel.add(resultButtonPanel, gbc);
+
+        mainFrame.add(mainControlPanel);
+        mainFrame.pack();
+
+        mainFrame.addWindowListener(new WindowAdapter() {
+
+            @Override
+            public void windowClosing(WindowEvent e) {
+                mainFrame.dispose();
+                countDownLatch.countDown();
+            }
+        });
+        mainFrame.setVisible(true);
+    }
+
+    private static JPanel createTestPanel() {
+        JPanel panel = new JPanel();
+        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+        JTextArea textArea = new JTextArea(20, 20);
+        textArea.setText(getLongString());
+        JScrollPane scrollPane = new JScrollPane(textArea);
+        panel.add(scrollPane);
+        return panel;
+    }
+
+    private static String getLongString() {
+
+        String lowCaseString = getLongString('a', 'z');
+        String upperCaseString = getLongString('A', 'Z');
+        String digitsString = getLongString('0', '9');
+
+        int repeat = 30;
+        StringBuilder lowCaseBuilder = new StringBuilder();
+        StringBuilder upperCaseBuilder = new StringBuilder();
+        StringBuilder digitsBuilder = new StringBuilder();
+
+        for (int i = 0; i < repeat; i++) {
+            lowCaseBuilder.append(lowCaseString).append(' ');
+            upperCaseBuilder.append(upperCaseString).append(' ');
+            digitsBuilder.append(digitsString).append(' ');
+        }
+
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < 200; i++) {
+            builder.append(upperCaseBuilder).append('\n')
+                    .append(lowCaseBuilder).append('\n')
+                    .append(digitsBuilder).append("\n\n\n");
+        }
+
+        return builder.toString();
+    }
+
+    private static String getLongString(char c1, char c2) {
+
+        char[] chars = new char[c2 - c1 + 1];
+        for (char i = c1; i <= c2; i++) {
+            chars[i - c1] = i;
+        }
+        return new String(chars);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/plaf/motif/8165485/MotifHiDPIIconsTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,189 @@
+/*
+ * 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.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @bug 8165485
+ * @summary Bad rendering of Swing UI controls with Motif L&F on HiDPI display
+ * @run main/manual/othervm -Dsun.java2d.uiScale=2
+ * -Dswing.defaultlaf=com.sun.java.swing.plaf.motif.MotifLookAndFeel MotifHiDPIIconsTest
+ */
+public class MotifHiDPIIconsTest {
+
+    private static volatile boolean testResult = false;
+    private static volatile CountDownLatch countDownLatch;
+    private static final String INSTRUCTIONS = "INSTRUCTIONS:\n"
+            + "Check that the icons are painted smoothly on Swing UI controls:\n"
+            + "  - JRadioButton\n"
+            + "  - JCheckBox\n"
+            + "  - JComboBox\n"
+            + "  - JScrollPane (vertical and horizontal scroll bars)\n"
+            + "\n"
+            + "If so, press PASS, else press FAIL.\n";
+
+    public static void main(String args[]) throws Exception {
+        countDownLatch = new CountDownLatch(1);
+
+        SwingUtilities.invokeLater(MotifHiDPIIconsTest::createUI);
+        countDownLatch.await(15, TimeUnit.MINUTES);
+
+        if (!testResult) {
+            throw new RuntimeException("Test fails!");
+        }
+    }
+
+    private static void createUI() {
+
+        final JFrame mainFrame = new JFrame("Motif L&F icons test");
+        GridBagLayout layout = new GridBagLayout();
+        JPanel mainControlPanel = new JPanel(layout);
+        JPanel resultButtonPanel = new JPanel(layout);
+
+        GridBagConstraints gbc = new GridBagConstraints();
+
+
+        JPanel testPanel = createJPanel();
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        mainControlPanel.add(testPanel, gbc);
+
+        JTextArea instructionTextArea = new JTextArea();
+        instructionTextArea.setText(INSTRUCTIONS);
+        instructionTextArea.setEditable(false);
+        instructionTextArea.setBackground(Color.white);
+
+        gbc.gridx = 0;
+        gbc.gridy = 1;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        mainControlPanel.add(instructionTextArea, gbc);
+
+        JButton passButton = new JButton("Pass");
+        passButton.setActionCommand("Pass");
+        passButton.addActionListener((ActionEvent e) -> {
+            testResult = true;
+            mainFrame.dispose();
+            countDownLatch.countDown();
+
+        });
+
+        JButton failButton = new JButton("Fail");
+        failButton.setActionCommand("Fail");
+        failButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                mainFrame.dispose();
+                countDownLatch.countDown();
+            }
+        });
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        resultButtonPanel.add(passButton, gbc);
+
+        gbc.gridx = 1;
+        gbc.gridy = 0;
+        resultButtonPanel.add(failButton, gbc);
+
+        gbc.gridx = 0;
+        gbc.gridy = 2;
+        mainControlPanel.add(resultButtonPanel, gbc);
+
+        mainFrame.add(mainControlPanel);
+        mainFrame.pack();
+
+        mainFrame.addWindowListener(new WindowAdapter() {
+
+            @Override
+            public void windowClosing(WindowEvent e) {
+                mainFrame.dispose();
+                countDownLatch.countDown();
+            }
+        });
+        mainFrame.setVisible(true);
+    }
+
+    private static JPanel createJPanel() {
+        JPanel panel = new JPanel();
+        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+
+        JPanel iconPanel = new JPanel(new FlowLayout());
+        JRadioButton radioButton = new JRadioButton();
+        radioButton.setSelected(false);
+        iconPanel.add(radioButton);
+        radioButton = new JRadioButton();
+        radioButton.setSelected(true);
+        iconPanel.add(radioButton);
+        panel.add(iconPanel);
+
+        iconPanel = new JPanel(new FlowLayout());
+        JCheckBox checkBox = new JCheckBox();
+        checkBox.setSelected(false);
+        iconPanel.add(checkBox);
+        checkBox = new JCheckBox();
+        checkBox.setSelected(true);
+        iconPanel.add(checkBox);
+        panel.add(iconPanel);
+
+        iconPanel = new JPanel(new FlowLayout());
+        JComboBox<String> comboBox = new JComboBox(new String[]{"111", "222"});
+        iconPanel.add(comboBox);
+        panel.add(iconPanel);
+
+        iconPanel = new JPanel(new FlowLayout());
+        JTextArea textArea = new JTextArea(3, 7);
+        textArea.setText("AAA");
+        JScrollPane scrollPane = new JScrollPane(textArea);
+        scrollPane.setHorizontalScrollBarPolicy(
+                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
+        scrollPane.setVerticalScrollBarPolicy(
+                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+        iconPanel.add(scrollPane);
+        panel.add(iconPanel);
+
+        return panel;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/Caret/8163124/CaretFloatingPointAPITest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,447 @@
+/*
+ * 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.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.TextUI;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Caret;
+import javax.swing.text.DefaultHighlighter;
+import javax.swing.text.Document;
+import javax.swing.text.Highlighter;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.Position;
+
+/*
+ * @test
+ * @bug 8163175
+ * @summary PlainView.modelToView() method should return Rectangle2D
+ * @run main/manual CaretFloatingPointAPITest
+ */
+public class CaretFloatingPointAPITest {
+
+    private static volatile boolean testResult = false;
+    private static volatile CountDownLatch countDownLatch;
+    private static final String INSTRUCTIONS = "INSTRUCTIONS:\n\n"
+            + "Verify that cursor position is not rounded on HiDPI display.\n\n"
+            + "If the display does not support HiDPI mode press PASS.\n\n"
+            + "1. Press the Right-Arrow key several times to move the red caret"
+            + " in the text field.\n"
+            + "2. Check that the caret has the same position between chars"
+            + " in diffrent locations.\n\n"
+            + "If so, press PASS, else press FAIL.\n";
+
+    public static void main(String args[]) throws Exception {
+        countDownLatch = new CountDownLatch(1);
+
+        SwingUtilities.invokeLater(CaretFloatingPointAPITest::createUI);
+        countDownLatch.await(15, TimeUnit.MINUTES);
+
+        if (!testResult) {
+            throw new RuntimeException("Test fails!");
+        }
+    }
+
+    private static void createUI() {
+
+        final JFrame mainFrame = new JFrame("Metal L&F icons test");
+        GridBagLayout layout = new GridBagLayout();
+        JPanel mainControlPanel = new JPanel(layout);
+        JPanel resultButtonPanel = new JPanel(layout);
+
+        GridBagConstraints gbc = new GridBagConstraints();
+
+        JTextField textField = new JTextField("aaaaaaaaaaaaaaaaaaaaaaa");
+        Dimension size = new Dimension(400, 100);
+        textField.setPreferredSize(size);
+        textField.setFont(textField.getFont().deriveFont(28.0f));
+        textField.setCaretColor(Color.RED);
+        textField.setCaret(new CustomCaret());
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+        gbc.insets = new Insets(5, 15, 5, 15);
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        mainControlPanel.add(textField, gbc);
+
+        JTextArea instructionTextArea = new JTextArea();
+        instructionTextArea.setText(INSTRUCTIONS);
+        instructionTextArea.setEditable(false);
+        instructionTextArea.setBackground(Color.white);
+
+        gbc.gridx = 0;
+        gbc.gridy = 1;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+        mainControlPanel.add(instructionTextArea, gbc);
+
+        JButton passButton = new JButton("Pass");
+        passButton.setActionCommand("Pass");
+        passButton.addActionListener((ActionEvent e) -> {
+            testResult = true;
+            mainFrame.dispose();
+            countDownLatch.countDown();
+
+        });
+
+        JButton failButton = new JButton("Fail");
+        failButton.setActionCommand("Fail");
+        failButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                mainFrame.dispose();
+                countDownLatch.countDown();
+            }
+        });
+
+        gbc.gridx = 0;
+        gbc.gridy = 0;
+
+        resultButtonPanel.add(passButton, gbc);
+
+        gbc.gridx = 1;
+        gbc.gridy = 0;
+        resultButtonPanel.add(failButton, gbc);
+
+        gbc.gridx = 0;
+        gbc.gridy = 2;
+        mainControlPanel.add(resultButtonPanel, gbc);
+
+        mainFrame.add(mainControlPanel);
+        mainFrame.pack();
+
+        mainFrame.addWindowListener(new WindowAdapter() {
+
+            @Override
+            public void windowClosing(WindowEvent e) {
+                mainFrame.dispose();
+                countDownLatch.countDown();
+            }
+        });
+        mainFrame.setVisible(true);
+    }
+
+    static class CustomCaret implements Caret {
+
+        private JTextComponent component;
+        private boolean visible;
+        private boolean selectionVisible = true;
+        int blinkRate;
+        int dot;
+        int mark;
+        Position.Bias dotBias;
+        Position.Bias markBias;
+        Object selectionTag;
+        Point2D magicCaretPosition;
+
+        private MouseListener mouseListener = new CaretMouseListener();
+
+        @Override
+        public void install(JTextComponent c) {
+            this.component = c;
+            c.addMouseListener(mouseListener);
+        }
+
+        @Override
+        public void deinstall(JTextComponent c) {
+            c.removeMouseListener(mouseListener);
+            this.component = null;
+        }
+
+        @Override
+        public void paint(Graphics g) {
+
+            if (component == null) {
+                return;
+            }
+
+            int dot = getDot();
+            Rectangle2D r = null;
+            try {
+                r = component.modelToView2D(dot);
+            } catch (BadLocationException e) {
+                return;
+            }
+
+            if (r == null) {
+                return;
+            }
+
+            Rectangle2D cr = getCaretRectangle(r);
+            repaint(cr.getBounds());
+
+            g.setColor(component.getCaretColor());
+            float cx = (float) cr.getX();
+            float cy = (float) cr.getY();
+            float cw = (float) cr.getWidth();
+            float ch = (float) cr.getHeight();
+            float c = cx + cw / 2;
+
+            Graphics2D g2d = (Graphics2D) g;
+            g2d.draw(new Line2D.Float(c, cy, c, cy + ch));
+            g2d.draw(new Line2D.Float(cx, cy, cx + cw, cy));
+            g2d.draw(new Line2D.Float(cx, cy + ch, cx + cw, cy + ch));
+        }
+
+        void repaint(Rectangle r) {
+            component.repaint(r);
+        }
+
+        Rectangle2D getCaretRectangle(Rectangle2D r) {
+            int d = 3;
+            double cx = r.getX() - d;
+            double cy = r.getY();
+            double cw = 2 * d;
+            double ch = r.getHeight();
+            return new Rectangle2D.Double(cx, cy, cw, ch);
+        }
+
+        @Override
+        public void addChangeListener(ChangeListener l) {
+        }
+
+        @Override
+        public void removeChangeListener(ChangeListener l) {
+        }
+
+        @Override
+        public boolean isVisible() {
+            return visible;
+        }
+
+        @Override
+        public void setVisible(boolean v) {
+            this.visible = true;
+        }
+
+        @Override
+        public boolean isSelectionVisible() {
+            return selectionVisible;
+        }
+
+        @Override
+        public void setSelectionVisible(boolean v) {
+            this.selectionVisible = v;
+            updateSelection();
+        }
+
+        @Override
+        public void setMagicCaretPosition(Point p) {
+            magicCaretPosition = p;
+        }
+
+        @Override
+        public Point getMagicCaretPosition() {
+            if (magicCaretPosition != null) {
+                return new Point((int) magicCaretPosition.getX(),
+                                 (int) magicCaretPosition.getY());
+            }
+            return null;
+        }
+
+        @Override
+        public void setBlinkRate(int rate) {
+            this.blinkRate = rate;
+        }
+
+        @Override
+        public int getBlinkRate() {
+            return blinkRate;
+        }
+
+        @Override
+        public int getDot() {
+            return dot;
+        }
+
+        @Override
+        public int getMark() {
+            return mark;
+        }
+
+        @Override
+        public void setDot(int dot) {
+            setDot(dot, Position.Bias.Forward);
+        }
+
+        private void setDot(int dot, Position.Bias bias) {
+            handleSetDot(dot, bias);
+            updateSelection();
+        }
+
+        @Override
+        public void moveDot(int dot) {
+            moveDot(dot, Position.Bias.Forward);
+        }
+
+        private void moveDot(int dot, Position.Bias bias) {
+            changeCaretPosition(dot, bias);
+            updateSelection();
+        }
+
+        void handleSetDot(int dot, Position.Bias dotBias) {
+
+            if (component == null) {
+                return;
+            }
+
+            Document doc = component.getDocument();
+            if (doc != null) {
+                dot = Math.min(dot, doc.getLength());
+            }
+
+            dot = Math.max(dot, 0);
+
+            if (dot == 0) {
+                dotBias = Position.Bias.Forward;
+            }
+
+            mark = dot;
+
+            if (this.dot != dot || this.dotBias != dotBias) {
+                changeCaretPosition(dot, dotBias);
+                updateSelection();
+            }
+
+            this.markBias = this.dotBias;
+        }
+
+        void changeCaretPosition(int dot, Position.Bias dotBias) {
+            this.dot = dot;
+            this.dotBias = dotBias;
+            setMagicCaretPosition(null);
+            SwingUtilities.invokeLater(this::repaintNewCaret);
+        }
+
+        private void updateSelection() {
+            Highlighter h = component.getHighlighter();
+            if (h != null) {
+                int p0 = Math.min(dot, mark);
+                int p1 = Math.max(dot, mark);
+
+                if (p0 == p1 || !selectionVisible) {
+                    if (selectionTag != null) {
+                        h.removeHighlight(selectionTag);
+                        selectionTag = null;
+                    }
+                } else {
+                    try {
+                        if (selectionTag != null) {
+                            h.changeHighlight(selectionTag, p0, p1);
+                        } else {
+                            Highlighter.HighlightPainter p = getSelectionPainter();
+                            selectionTag = h.addHighlight(p0, p1, p);
+                        }
+                    } catch (BadLocationException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }
+        }
+
+        void repaintNewCaret() {
+            if (component != null) {
+                TextUI mapper = component.getUI();
+                Document doc = component.getDocument();
+                if ((mapper != null) && (doc != null)) {
+                    Rectangle2D newLoc;
+                    try {
+                        newLoc = mapper.modelToView2D(component, this.dot, this.dotBias);
+                    } catch (BadLocationException e) {
+                        newLoc = null;
+                    }
+                    if (newLoc != null) {
+                        adjustVisibility(newLoc.getBounds());
+                        if (getMagicCaretPosition() == null) {
+                            setMagicCaretPosition(new Point((int) newLoc.getX(),
+                                                            (int) newLoc.getY()));
+                        }
+                    }
+                    damage(newLoc.getBounds());
+                }
+            }
+        }
+
+        protected Highlighter.HighlightPainter getSelectionPainter() {
+            return DefaultHighlighter.DefaultPainter;
+        }
+
+        protected void adjustVisibility(Rectangle nloc) {
+            if (component == null) {
+                return;
+            }
+            if (SwingUtilities.isEventDispatchThread()) {
+                component.scrollRectToVisible(nloc);
+            } else {
+                SwingUtilities.invokeLater(() -> {
+                    component.scrollRectToVisible(nloc);
+                });
+            }
+        }
+
+        protected synchronized void damage(Rectangle r) {
+            if (r != null && component != null) {
+                component.repaint(r);
+            }
+        }
+
+        private class CaretMouseListener extends MouseAdapter {
+
+            @Override
+            public void mousePressed(MouseEvent e) {
+                Point pt = new Point(e.getX(), e.getY());
+                Position.Bias[] biasRet = new Position.Bias[1];
+                int pos = component.getUI().viewToModel(component, pt, biasRet);
+                if (biasRet[0] == null) {
+                    biasRet[0] = Position.Bias.Forward;
+                }
+                if (pos >= 0) {
+                    setDot(pos);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/JTextComponent/8156217/TextSelectionTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,108 @@
+/*
+ * 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.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.text.JTextComponent;
+
+/**
+ * @test
+ * @bug 8156217
+ * @summary Selected text is shifted on HiDPI display
+ * @run main/manual/othervm -Dsun.java2d.uiScale=2 TextSelectionTest
+ */
+public class TextSelectionTest {
+
+    private static final String INSTRUCTIONS = "This is a manual test.\n"
+            + "\n"
+            + "Select the current text from the end to the beginning.\n"
+            + "\n"
+            + "If the text is slightly shiftted from one side to another\n"
+            + "and back during selection press Fail.\n"
+            + "Otherwise, press Pass.";
+
+    private static final CountDownLatch latch = new CountDownLatch(1);
+    private static volatile boolean passed = false;
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(TextSelectionTest::createAndShowGUI);
+        latch.await(3, TimeUnit.MINUTES);
+        System.out.println("passed: " + passed);
+        if (!passed) {
+            throw new RuntimeException("Test fails!");
+        }
+    }
+
+    private static void createAndShowGUI() {
+
+        JFrame frame = new JFrame("Follow the instructions below:");
+        frame.setSize(700, 500);
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        JPanel panel = new JPanel(new BorderLayout());
+        JTextComponent textComponent = new JTextArea(INSTRUCTIONS);
+        textComponent.setEditable(false);
+        Font font = textComponent.getFont();
+        font = font.deriveFont(24.0f);
+        textComponent.setFont(font);
+        panel.add(textComponent, BorderLayout.CENTER);
+
+        JPanel buttonsPanel = new JPanel(new FlowLayout());
+        JButton passButton = new JButton("Pass");
+        passButton.addActionListener((e) -> {
+            passed = true;
+            latch.countDown();
+            frame.dispose();
+        });
+        JButton failsButton = new JButton("Fail");
+        failsButton.addActionListener((e) -> {
+            passed = false;
+            latch.countDown();
+            frame.dispose();
+        });
+
+        buttonsPanel.add(passButton);
+        buttonsPanel.add(failsButton);
+        panel.add(buttonsPanel, BorderLayout.SOUTH);
+
+        frame.getContentPane().add(panel);
+
+        frame.addWindowListener(new WindowAdapter() {
+
+            @Override
+            public void windowClosing(WindowEvent e) {
+                latch.countDown();
+            }
+        });
+        frame.setVisible(true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/View/8156217/FPMethodCalledTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,499 @@
+/*
+ * 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.awt.FlowLayout;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Robot;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+import javax.swing.plaf.metal.MetalTextFieldUI;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Element;
+import javax.swing.text.PasswordView;
+import javax.swing.text.PlainView;
+import javax.swing.text.View;
+import javax.swing.text.WrappedPlainView;
+
+/**
+ * @test
+ * @bug 8156217
+ * @key headful
+ * @summary Selected text is shifted on HiDPI display
+ * @run main FPMethodCalledTest
+ */
+public class FPMethodCalledTest {
+
+    private static JFrame frame;
+    private static JTextField textField;
+
+    public static void main(String[] args) throws Exception {
+
+        for (Test test : TESTS) {
+            test(test);
+        }
+    }
+
+    static void test(final Test test) throws Exception {
+        try {
+            Robot robot = new Robot();
+            robot.setAutoDelay(50);
+            SwingUtilities.invokeAndWait(() -> {
+                createAndShowGUI(test);
+            });
+
+            robot.waitForIdle();
+
+            SwingUtilities.invokeAndWait(() -> {
+                textField.select(1, 3);
+            });
+
+            robot.waitForIdle();
+
+            SwingUtilities.invokeAndWait(() -> {
+                Resultable resultable = test.resultable;
+                if (!resultable.getResult()) {
+                    throw new RuntimeException("Test fails for: " + resultable);
+                }
+            });
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (frame != null) {
+                    frame.dispose();
+                }
+            });
+        }
+    }
+
+    static void createAndShowGUI(Test test) {
+
+        try {
+            UIManager.setLookAndFeel(new MetalLookAndFeel());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        frame = new JFrame();
+        frame.setSize(300, 300);
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        JPanel panel = new JPanel(new FlowLayout());
+
+        String text = "AAAAAAA";
+        textField = test.isPasswordField()
+                ? new JPasswordField(text)
+                : new JTextField(text);
+
+        textField.setUI(new MetalTextFieldUI() {
+
+            @Override
+            public View create(Element elem) {
+                return test.createView(elem);
+            }
+        });
+
+        panel.add(textField);
+        frame.getContentPane().add(panel);
+        frame.setVisible(true);
+    }
+
+    private static final Test[] TESTS = {
+        new Test() {
+            @Override
+            View createView(Element elem) {
+                PlainViewINTAPI view = new PlainViewINTAPI(elem);
+                resultable = view;
+                return view;
+            }
+        },
+        new Test() {
+            @Override
+            View createView(Element elem) {
+                PlainViewFPAPI view = new PlainViewFPAPI(elem);
+                resultable = view;
+                return view;
+            }
+        },
+        new Test() {
+            @Override
+            View createView(Element elem) {
+                PlainViewMixedAPI view = new PlainViewMixedAPI(elem);
+                resultable = view;
+                return view;
+            }
+        },
+        new Test() {
+            @Override
+            View createView(Element elem) {
+                WrappedPlainViewINTAPI view = new WrappedPlainViewINTAPI(elem);
+                resultable = view;
+                return view;
+            }
+        },
+        new Test() {
+            @Override
+            View createView(Element elem) {
+                WrappedPlainViewFPAPI view = new WrappedPlainViewFPAPI(elem);
+                resultable = view;
+                return view;
+            }
+        },
+        new Test() {
+            @Override
+            View createView(Element elem) {
+                WrappedPlainViewMixedAPI view = new WrappedPlainViewMixedAPI(elem);
+                resultable = view;
+                return view;
+            }
+        },
+        new Test(true) {
+
+            @Override
+            View createView(Element elem) {
+                PasswordViewINTAPI view = new PasswordViewINTAPI(elem);
+                resultable = view;
+                return view;
+            }
+        },
+        new Test(true) {
+
+            @Override
+            View createView(Element elem) {
+                PasswordViewFPAPI view = new PasswordViewFPAPI(elem);
+                resultable = view;
+                return view;
+            }
+        },
+        new Test(true) {
+
+            @Override
+            View createView(Element elem) {
+                PasswordViewMixedAPI view = new PasswordViewMixedAPI(elem);
+                resultable = view;
+                return view;
+            }
+        }
+    };
+
+    static interface Resultable {
+
+        boolean getResult();
+    }
+
+    static abstract class Test {
+
+        Resultable resultable;
+        final boolean isPasswordField;
+
+        public Test() {
+            this(false);
+        }
+
+        public Test(boolean isPasswordField) {
+            this.isPasswordField = isPasswordField;
+        }
+
+        boolean isPasswordField() {
+            return isPasswordField;
+        }
+
+        abstract View createView(Element elem);
+    }
+
+    static class PlainViewINTAPI extends PlainView implements Resultable {
+
+        boolean drawLine = false;
+        boolean drawSelected = false;
+        boolean drawUnselected = false;
+
+        public PlainViewINTAPI(Element elem) {
+            super(elem);
+        }
+
+        @Override
+        protected void drawLine(int lineIndex, Graphics g, int x, int y) {
+            drawLine = true;
+            super.drawLine(lineIndex, g, x, y);
+        }
+
+        @Override
+        protected int drawSelectedText(Graphics g, int x, int y,
+                int p0, int p1) throws BadLocationException {
+            drawSelected = true;
+            return super.drawSelectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        protected int drawUnselectedText(Graphics g, int x, int y,
+                int p0, int p1) throws BadLocationException {
+            drawUnselected = true;
+            return super.drawUnselectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        public boolean getResult() {
+            return drawLine && drawSelected && drawUnselected;
+        }
+    }
+
+    static class PlainViewFPAPI extends PlainView implements Resultable {
+
+        boolean drawLine = false;
+        boolean drawSelected = false;
+        boolean drawUnselected = false;
+
+        public PlainViewFPAPI(Element elem) {
+            super(elem);
+        }
+
+        @Override
+        protected void drawLine(int lineIndex, Graphics2D g, float x, float y) {
+            drawLine = true;
+            super.drawLine(lineIndex, g, x, y);
+        }
+
+        @Override
+        protected float drawSelectedText(Graphics2D g, float x, float y,
+                int p0, int p1) throws BadLocationException {
+            drawSelected = true;
+            return super.drawSelectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        protected float drawUnselectedText(Graphics2D g, float x, float y,
+                int p0, int p1) throws BadLocationException {
+            drawUnselected = true;
+            return super.drawUnselectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        public boolean getResult() {
+            return drawSelected;
+        }
+    }
+
+    static class PlainViewMixedAPI extends PlainView implements Resultable {
+
+        boolean isIntMethodCalled = false;
+        boolean isFPMethodCalled = false;
+
+        public PlainViewMixedAPI(Element elem) {
+            super(elem);
+        }
+
+        @Override
+        protected int drawSelectedText(Graphics g, int x, int y,
+                int p0, int p1) throws BadLocationException {
+            isIntMethodCalled = true;
+            return super.drawSelectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        protected float drawSelectedText(Graphics2D g, float x, float y,
+                int p0, int p1) throws BadLocationException {
+            isFPMethodCalled = true;
+            return super.drawSelectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        public boolean getResult() {
+            return !isIntMethodCalled && isFPMethodCalled;
+        }
+    }
+
+    static class WrappedPlainViewINTAPI extends WrappedPlainView implements Resultable {
+
+        boolean drawLine = false;
+        boolean drawSelected = false;
+        boolean drawUnselected = false;
+
+        public WrappedPlainViewINTAPI(Element elem) {
+            super(elem);
+        }
+
+        @Override
+        protected void drawLine(int p0, int p1, Graphics g, int x, int y) {
+            drawLine = true;
+            super.drawLine(p0, p1, g, x, y);
+        }
+
+        @Override
+        protected int drawSelectedText(Graphics g, int x, int y,
+                int p0, int p1) throws BadLocationException {
+            drawSelected = true;
+            return super.drawSelectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        protected int drawUnselectedText(Graphics g, int x, int y,
+                int p0, int p1) throws BadLocationException {
+            drawUnselected = true;
+            return super.drawUnselectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        public boolean getResult() {
+            return drawLine && drawSelected && drawUnselected;
+        }
+    }
+
+    static class WrappedPlainViewFPAPI extends WrappedPlainView implements Resultable {
+
+        boolean drawLine = false;
+        boolean drawSelected = false;
+        boolean drawUnselected = false;
+
+        public WrappedPlainViewFPAPI(Element elem) {
+            super(elem);
+        }
+
+        @Override
+        protected void drawLine(int p0, int p1, Graphics2D g, float x, float y) {
+            drawLine = true;
+            super.drawLine(p0, p1, g, x, y);
+        }
+
+        @Override
+        protected float drawSelectedText(Graphics2D g, float x, float y,
+                int p0, int p1) throws BadLocationException {
+            drawSelected = true;
+            return super.drawSelectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        protected float drawUnselectedText(Graphics2D g, float x, float y,
+                int p0, int p1) throws BadLocationException {
+            drawUnselected = true;
+            return super.drawUnselectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        public boolean getResult() {
+            return drawLine && drawSelected && drawUnselected;
+        }
+    }
+
+    static class WrappedPlainViewMixedAPI extends WrappedPlainView implements Resultable {
+
+        boolean isIntMethodCalled = false;
+        boolean isFPMethodCalled = false;
+
+        public WrappedPlainViewMixedAPI(Element elem) {
+            super(elem);
+        }
+
+        @Override
+        protected int drawUnselectedText(Graphics g, int x, int y,
+                int p0, int p1) throws BadLocationException {
+            isIntMethodCalled = true;
+            return super.drawUnselectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        protected float drawUnselectedText(Graphics2D g, float x, float y,
+                int p0, int p1) throws BadLocationException {
+            isFPMethodCalled = true;
+            return super.drawUnselectedText(g, x, y, p0, p1);
+        }
+
+        @Override
+        public boolean getResult() {
+            return !isIntMethodCalled && isFPMethodCalled;
+        }
+    }
+
+    static class PasswordViewINTAPI extends PasswordView implements Resultable {
+
+        boolean isIntMethodCalled = false;
+
+        public PasswordViewINTAPI(Element elem) {
+            super(elem);
+
+        }
+
+        @Override
+        protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
+            isIntMethodCalled = true;
+            return super.drawEchoCharacter(g, x, y, c);
+        }
+
+        @Override
+        public boolean getResult() {
+            return isIntMethodCalled;
+        }
+    }
+
+    static class PasswordViewFPAPI extends PasswordView implements Resultable {
+
+        boolean isFPMethodCalled = false;
+
+        public PasswordViewFPAPI(Element elem) {
+            super(elem);
+
+        }
+
+        @Override
+        protected float drawEchoCharacter(Graphics2D g, float x, float y, char c) {
+            isFPMethodCalled = true;
+            return super.drawEchoCharacter(g, x, y, c);
+        }
+
+        @Override
+        public boolean getResult() {
+            return isFPMethodCalled;
+        }
+    }
+
+    static class PasswordViewMixedAPI extends PasswordView implements Resultable {
+
+        boolean isIntMethodCalled = false;
+        boolean isFPMethodCalled = false;
+
+        public PasswordViewMixedAPI(Element elem) {
+            super(elem);
+
+        }
+
+        @Override
+        protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
+            isIntMethodCalled = true;
+            return super.drawEchoCharacter(g, x, y, c);
+        }
+
+        @Override
+        protected float drawEchoCharacter(Graphics2D g, float x, float y, char c) {
+            isFPMethodCalled = true;
+            return super.drawEchoCharacter(g, x, y, c);
+        }
+
+        @Override
+        public boolean getResult() {
+            return !isIntMethodCalled && isFPMethodCalled;
+        }
+    }
+}
--- a/jdk/test/sun/security/smartcardio/TestChannel.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/sun/security/smartcardio/TestChannel.java	Thu Oct 27 21:22:57 2016 +0000
@@ -23,11 +23,12 @@
 
 /*
  * @test
- * @bug 6239117
+ * @bug 6239117 8168851
  * @summary test logical channels work
  * @author Andreas Sterbenz
  * @modules java.smartcardio/javax.smartcardio
  * @run main/manual TestChannel
+ * @run main/othervm/manual/java.security.policy==test.policy TestChannel
  */
 
 // This test requires special hardware.
--- a/jdk/test/sun/security/smartcardio/TestControl.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/sun/security/smartcardio/TestControl.java	Thu Oct 27 21:22:57 2016 +0000
@@ -23,11 +23,12 @@
 
 /*
  * @test
- * @bug 6239117 6470320
+ * @bug 6239117 6470320 8168851
  * @summary test if transmitControlCommand() works
  * @author Andreas Sterbenz
  * @modules java.smartcardio/javax.smartcardio
  * @run main/manual TestControl
+ * @run main/othervm/manual/java.security.policy==test.policy TestControl
  */
 
 // This test requires special hardware.
--- a/jdk/test/sun/security/smartcardio/TestDefault.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/sun/security/smartcardio/TestDefault.java	Thu Oct 27 21:22:57 2016 +0000
@@ -23,11 +23,12 @@
 
 /*
  * @test
- * @bug 6327047
+ * @bug 6327047 8168851
  * @summary verify that TerminalFactory.getDefault() works
  * @author Andreas Sterbenz
  * @modules java.smartcardio/javax.smartcardio
  * @run main/manual TestDefault
+ * @run main/othervm/manual/java.security.policy==test.policy TestDefault
  */
 
 // This test requires special hardware.
--- a/jdk/test/sun/security/smartcardio/TestDirect.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/sun/security/smartcardio/TestDirect.java	Thu Oct 27 21:22:57 2016 +0000
@@ -23,10 +23,11 @@
 
 /*
  * @test
- * @bug 8046343
+ * @bug 8046343 8168851
  * @summary Make sure that direct protocol is available
  * @modules java.smartcardio/javax.smartcardio
  * @run main/manual TestDirect
+ * @run main/othervm/manual/java.security.policy==test.policy TestDirect
  */
 
 // This test requires special hardware.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/smartcardio/test.policy	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,3 @@
+grant codebase "file:${test.classes}/*" {
+    permission javax.smartcardio.CardPermission "*", "connect,getBasicChannel,reset,transmitControl";
+};
--- a/jdk/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -29,31 +29,22 @@
 /*
  * @test
  * @bug 4392475
+ * @library /javax/net/ssl/templates
  * @summary Calling setWantClientAuth(true) disables anonymous suites
  * @run main/othervm/timeout=180 AnonCipherWithWantClientAuth
  */
 
-import java.io.*;
-import java.net.*;
-import javax.net.ssl.*;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.security.Security;
 
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+
 public class AnonCipherWithWantClientAuth {
 
     /*
-     * =============================================================
-     * Set the various variables needed for the tests, then
-     * specify what tests to run on each side.
-     */
-
-    /*
-     * Should we run the client or server in a separate thread?
-     * Both sides can throw exceptions, but do you have a preference
-     * as to which side should be the main thread.
-     */
-    static boolean separateServerThread = false;
-
-    /*
      * Where do we find the keystores?
      */
     static String pathToStores = "../../../../javax/net/ssl/etc";
@@ -61,106 +52,7 @@
     static String trustStoreFile = "truststore";
     static String passwd = "passphrase";
 
-    /*
-     * Is the server ready to serve?
-     */
-    volatile static boolean serverReady = false;
-
-    /*
-     * Turn on SSL debugging?
-     */
-    static boolean debug = false;
-
-    /*
-     * If the client or server is doing some kind of object creation
-     * that the other side depends on, and that thread prematurely
-     * exits, you may experience a hang.  The test harness will
-     * terminate all hung threads after its timeout has expired,
-     * currently 3 minutes by default, but you might try to be
-     * smart about it....
-     */
-
-    /*
-     * Define the server side of the test.
-     *
-     * If the server prematurely exits, serverReady will be set to true
-     * to avoid infinite hangs.
-     */
-    void doServerSide() throws Exception {
-        SSLServerSocketFactory sslssf =
-            (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
-        SSLServerSocket sslServerSocket =
-            (SSLServerSocket) sslssf.createServerSocket(serverPort);
-        serverPort = sslServerSocket.getLocalPort();
-        String ciphers[]={"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
-                          "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
-                          "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"};
-        sslServerSocket.setEnabledCipherSuites(ciphers);
-        sslServerSocket.setWantClientAuth(true);
-        /*
-         * Signal Client, we're ready for his connect.
-         */
-        serverReady = true;
-
-        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
-
-        sslIS.read();
-        sslOS.write(85);
-        sslOS.flush();
-
-        sslSocket.close();
-    }
-
-    /*
-     * Define the client side of the test.
-     *
-     * If the server prematurely exits, serverReady will be set to true
-     * to avoid infinite hangs.
-     */
-    void doClientSide() throws Exception {
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        SSLSocketFactory sslsf =
-            (SSLSocketFactory) SSLSocketFactory.getDefault();
-        SSLSocket sslSocket = (SSLSocket)
-            sslsf.createSocket("localhost", serverPort);
-        String ciphers[] = {"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
-                            "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"};
-        sslSocket.setEnabledCipherSuites(ciphers);
-        sslSocket.setUseClientMode(true);
-
-        InputStream sslIS = sslSocket.getInputStream();
-        OutputStream sslOS = sslSocket.getOutputStream();
-
-        sslOS.write(280);
-        sslOS.flush();
-        sslIS.read();
-
-        sslSocket.close();
-    }
-
-    /*
-     * =============================================================
-     * The remainder is just support stuff
-     */
-
-    // use any free port by default
-    volatile int serverPort = 0;
-
-    volatile Exception serverException = null;
-    volatile Exception clientException = null;
-
     public static void main(String[] args) throws Exception {
-        // reset security properties to make sure that the algorithms
-        // and keys used in this test are not disabled.
         Security.setProperty("jdk.tls.disabledAlgorithms", "");
         Security.setProperty("jdk.certpath.disabledAlgorithms", "");
 
@@ -170,100 +62,84 @@
         String trustFilename =
             System.getProperty("test.src", "./") + "/" + pathToStores +
                 "/" + trustStoreFile;
-
-        System.setProperty("javax.net.ssl.keyStore", keyFilename);
-        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
-        System.setProperty("javax.net.ssl.trustStore", trustFilename);
-        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
-
-        if (debug)
-            System.setProperty("javax.net.debug", "all");
+        SSLTest.setup(keyFilename, trustFilename, passwd);
 
-        /*
-         * Start the tests.
-         */
-        new AnonCipherWithWantClientAuth();
-    }
-
-    Thread clientThread = null;
-    Thread serverThread = null;
+        new SSLTest()
+            .setServerPeer(test -> {
+                SSLServerSocketFactory sslssf =
+                        (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+                SSLServerSocket sslServerSocket =
+                        (SSLServerSocket) sslssf.createServerSocket(SSLTest.FREE_PORT);
+                test.setServerPort(sslServerSocket.getLocalPort());
+                SSLTest.print("Server is listening on port "
+                        + test.getServerPort());
 
-    /*
-     * Primary constructor, used to drive remainder of the test.
-     *
-     * Fork off the other side, then do your work.
-     */
-    AnonCipherWithWantClientAuth () throws Exception {
-        if (separateServerThread) {
-            startServer(true);
-            startClient(false);
-        } else {
-            startClient(true);
-            startServer(false);
-        }
+                String ciphers[] = {
+                        "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+                        "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+                        "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" };
+                sslServerSocket.setEnabledCipherSuites(ciphers);
+                sslServerSocket.setWantClientAuth(true);
+
+                // Signal the client, the server is ready to accept connection.
+                test.signalServerReady();
 
-        /*
-         * Wait for other side to close down.
-         */
-        if (separateServerThread) {
-            serverThread.join();
-        } else {
-            clientThread.join();
-        }
+                // Try to accept a connection in 30 seconds.
+                SSLSocket sslSocket = SSLTest.accept(sslServerSocket);
+                if (sslSocket == null) {
+                    // Ignore the test case if no connection within 30 seconds.
+                    SSLTest.print("No incoming client connection in 30 seconds."
+                            + " Ignore in server side.");
+                    return;
+                }
+                SSLTest.print("Server accepted connection");
 
-        /*
-         * When we get here, the test is pretty much over.
-         *
-         * If the main thread excepted, that propagates back
-         * immediately.  If the other thread threw an exception, we
-         * should report back.
-         */
-        if (serverException != null)
-            throw serverException;
-        if (clientException != null)
-            throw clientException;
-    }
+                // handle the connection
+                try {
+                    // Is it the expected client connection?
+                    //
+                    // Naughty test cases or third party routines may try to
+                    // connection to this server port unintentionally.  In
+                    // order to mitigate the impact of unexpected client
+                    // connections and avoid intermittent failure, it should
+                    // be checked that the accepted connection is really linked
+                    // to the expected client.
+                    boolean clientIsReady = test.waitForClientSignal();
 
-    void startServer(boolean newThread) throws Exception {
-        if (newThread) {
-            serverThread = new Thread() {
-                public void run() {
-                    try {
-                        doServerSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our server thread just died.
-                         */
-                        System.err.println("Server died...");
-                        serverReady = true;
-                        serverException = e;
+                    if (clientIsReady) {
+                        // Run the application in server side.
+                        SSLTest.print("Run server application");
+
+                        InputStream sslIS = sslSocket.getInputStream();
+                        OutputStream sslOS = sslSocket.getOutputStream();
+
+                        sslIS.read();
+                        sslOS.write(85);
+                        sslOS.flush();
+                    } else {
+                        System.out.println(
+                                "The client is not the expected one or timeout. "
+                                        + "Ignore in server side.");
                     }
+                } finally {
+                    sslSocket.close();
+                    sslServerSocket.close();
                 }
-            };
-            serverThread.start();
-        } else {
-            doServerSide();
-        }
-    }
+            })
+            .setClientApplication((socket, test) -> {
+                String ciphers[] = {
+                        "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+                        "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5" };
+                socket.setEnabledCipherSuites(ciphers);
+                socket.setUseClientMode(true);
 
-    void startClient(boolean newThread) throws Exception {
-        if (newThread) {
-            clientThread = new Thread() {
-                public void run() {
-                    try {
-                        doClientSide();
-                    } catch (Exception e) {
-                        /*
-                         * Our client thread just died.
-                         */
-                        System.err.println("Client died...");
-                        clientException = e;
-                    }
-                }
-            };
-            clientThread.start();
-        } else {
-            doClientSide();
-        }
+                InputStream sslIS = socket.getInputStream();
+                OutputStream sslOS = socket.getOutputStream();
+
+                sslOS.write(280);
+                sslOS.flush();
+                sslIS.read();
+            })
+            .runTest();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/mmrjar/ConcealedPackage.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,225 @@
+/*
+ * 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 8146486
+ * @summary Fail to create a MR modular JAR with a versioned entry in
+ *          base-versioned empty package
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.FileUtils
+ * @run testng ConcealedPackage
+ */
+
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.testlibrary.FileUtils;
+
+public class ConcealedPackage {
+    private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+           .orElseThrow(() -> new RuntimeException("jar tool not found"));
+    private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac")
+            .orElseThrow(() -> new RuntimeException("javac tool not found"));
+    private final String linesep = System.lineSeparator();
+    private final Path userdir;
+    private final ByteArrayOutputStream outbytes = new ByteArrayOutputStream();
+    private final PrintStream out = new PrintStream(outbytes, true);
+    private final ByteArrayOutputStream errbytes = new ByteArrayOutputStream();
+    private final PrintStream err = new PrintStream(errbytes, true);
+
+    public ConcealedPackage() throws IOException {
+        Path testsrc = Paths.get(System.getProperty("test.src"));
+        userdir = Paths.get(System.getProperty("user.dir", "."));
+
+        // compile the classes directory
+        Path source = testsrc.resolve("src").resolve("classes");
+        Path destination = Paths.get("classes");
+        javac(source, destination);
+
+        // compile the mr9 directory including module-info.java
+        source = testsrc.resolve("src").resolve("mr9");
+        destination = Paths.get("mr9");
+        javac(source, destination);
+
+        // move module-info.class for later use
+        Files.move(destination.resolve("module-info.class"),
+                Paths.get("module-info.class"));
+    }
+
+    private void javac(Path source, Path destination) throws IOException {
+        String[] args = Stream.concat(
+                Stream.of("-d", destination.toString()),
+                Files.walk(source)
+                        .map(Path::toString)
+                        .filter(s -> s.endsWith(".java"))
+        ).toArray(String[]::new);
+        JAVAC_TOOL.run(System.out, System.err, args);
+    }
+
+    private int jar(String cmd) {
+        outbytes.reset();
+        errbytes.reset();
+        return JAR_TOOL.run(out, err, cmd.split(" +"));
+    }
+
+    @AfterClass
+    public void cleanup() throws IOException {
+        Files.walk(userdir, 1)
+                .filter(p -> !p.equals(userdir))
+                .forEach(p -> {
+                    try {
+                        if (Files.isDirectory(p)) {
+                            FileUtils.deleteFileTreeWithRetry(p);
+                        } else {
+                            FileUtils.deleteFileIfExistsWithRetry(p);
+                        }
+                    } catch (IOException x) {
+                        throw new UncheckedIOException(x);
+                    }
+                });
+    }
+
+    // updates a valid multi-release jar with a new public class in
+    // versioned section and fails
+    @Test
+    public void test1() {
+        // successful build of multi-release jar
+        int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 p/Hi.class");
+        Assert.assertEquals(rc, 0);
+
+        jar("-tf mmr.jar");
+
+        String s = new String(outbytes.toByteArray());
+        Set<String> actual = Arrays.stream(s.split(linesep)).collect(Collectors.toSet());
+        Set<String> expected = Set.of(
+                "META-INF/",
+                "META-INF/MANIFEST.MF",
+                "p/",
+                "p/Hi.class",
+                "META-INF/versions/9/p/Hi.class"
+        );
+        Assert.assertEquals(actual, expected);
+
+        // failed build because of new public class
+        rc = jar("-uf mmr.jar --release 9 -C mr9 p/internal/Bar.class");
+        Assert.assertEquals(rc, 1);
+
+        s = new String(errbytes.toByteArray());
+        Assert.assertTrue(s.contains("p/internal/Bar.class, contains a new public "
+                + "class not found in base entries")
+        );
+    }
+
+    // updates a valid multi-release jar with a module-info class and new
+    // concealed public class in versioned section and succeeds
+    @Test
+    public void test2() {
+        // successful build of multi-release jar
+        int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 p/Hi.class");
+        Assert.assertEquals(rc, 0);
+
+        // successful build because of module-info and new public class
+        rc = jar("-uf mmr.jar module-info.class --release 9 -C mr9 p/internal/Bar.class");
+        Assert.assertEquals(rc, 0);
+
+        String s = new String(errbytes.toByteArray());
+        Assert.assertTrue(s.contains("p/internal/Bar.class is a public class in a "
+                        + "concealed package, \nplacing this jar on the class path "
+                        + "will result in incompatible public interfaces")
+        );
+
+        jar("-tf mmr.jar");
+
+        s = new String(outbytes.toByteArray());
+        Set<String> actual = Arrays.stream(s.split(linesep)).collect(Collectors.toSet());
+        Set<String> expected = Set.of(
+                "META-INF/",
+                "META-INF/MANIFEST.MF",
+                "p/",
+                "p/Hi.class",
+                "META-INF/versions/9/p/Hi.class",
+                "META-INF/versions/9/p/internal/Bar.class",
+                "module-info.class"
+        );
+        Assert.assertEquals(actual, expected);
+    }
+
+    // jar tool fails building mmr.jar because of new public class
+    @Test
+    public void test3() {
+        int rc = jar("-cf mmr.jar -C classes . --release 9 -C mr9 .");
+        Assert.assertEquals(rc, 1);
+
+        String s = new String(errbytes.toByteArray());
+        Assert.assertTrue(s.contains("p/internal/Bar.class, contains a new public "
+                + "class not found in base entries")
+        );
+    }
+
+    // jar tool succeeds building mmr.jar because of concealed package
+    @Test
+    public void test4() {
+        int rc = jar("-cf mmr.jar module-info.class -C classes . " +
+                "--release 9 module-info.class -C mr9 .");
+        Assert.assertEquals(rc, 0);
+
+        String s = new String(errbytes.toByteArray());
+        Assert.assertTrue(s.contains("p/internal/Bar.class is a public class in a "
+                + "concealed package, \nplacing this jar on the class path "
+                + "will result in incompatible public interfaces")
+        );
+
+        jar("-tf mmr.jar");
+
+        s = new String(outbytes.toByteArray());
+        Set<String> actual = Arrays.stream(s.split(linesep)).collect(Collectors.toSet());
+        Set<String> expected = Set.of(
+                "META-INF/",
+                "META-INF/MANIFEST.MF",
+                "module-info.class",
+                "META-INF/versions/9/module-info.class",
+                "p/",
+                "p/Hi.class",
+                "META-INF/versions/9/p/",
+                "META-INF/versions/9/p/Hi.class",
+                "META-INF/versions/9/p/internal/",
+                "META-INF/versions/9/p/internal/Bar.class"
+        );
+        Assert.assertEquals(actual, expected);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/mmrjar/src/classes/p/Hi.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,30 @@
+/*
+ * 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 p;
+
+public class Hi {
+    public void sayHi() {
+        System.out.println("Hi");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/mmrjar/src/mr9/module-info.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module m1 {
+    exports p;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/mmrjar/src/mr9/p/Hi.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,30 @@
+/*
+ * 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 p;
+
+public class Hi {
+    public void sayHi() {
+        System.out.println("Hello");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/mmrjar/src/mr9/p/internal/Bar.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,31 @@
+/*
+ * 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 p.internal;
+
+public class Bar {
+    @Override
+    public String toString() {
+        return "p.internal.Bar";
+    }
+}
--- a/jdk/test/tools/jlink/JLinkTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/tools/jlink/JLinkTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -109,19 +109,16 @@
                     .modulePath(helper.defaultModulePath())
                     .output(helper.createNewImageDir(moduleName))
                     .addMods("leaf1")
-                    .option("")
                     .call().assertSuccess();
             JImageGenerator.getJLinkTask()
                     .modulePath(helper.defaultModulePath())
                     .addMods("leaf1")
                     .option("--output")
-                    .option("")
                     .call().assertFailure("Error: no value given for --output");
             JImageGenerator.getJLinkTask()
                     .modulePath("")
                     .output(helper.createNewImageDir(moduleName))
                     .addMods("leaf1")
-                    .option("")
                     .call().assertFailure("Error: no value given for --module-path");
         }
 
@@ -132,7 +129,6 @@
                     .modulePath(helper.defaultModulePath())
                     .output(helper.createNewImageDir(moduleName))
                     .addMods("m")
-                    .option("")
                     .call().assertSuccess();
             moduleName = "mod";
             jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
@@ -140,7 +136,6 @@
                     .modulePath(helper.defaultModulePath())
                     .output(helper.createNewImageDir(moduleName))
                     .addMods("m")
-                    .option("")
                     .call().assertSuccess();
         }
 
@@ -282,18 +277,21 @@
             helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: Invalid compression level invalid");
         }
 
-        // @file
+        // orphan argument - JDK-8166810
         {
-            Path path = Paths.get("embedded.properties");
-            Files.write(path, Collections.singletonList("--strip-debug --add-modules " +
-                    "toto.unknown --compress UNKNOWN\n"));
-            String[] userOptions = {"@", path.toAbsolutePath().toString()};
-            String moduleName = "configembeddednocompresscomposite2";
+            String[] userOptions = {"--compress", "2", "foo" };
+            String moduleName = "orphanarg1";
             helper.generateDefaultJModule(moduleName, "composite2");
-            Path imageDir = helper.generateDefaultImage(userOptions, moduleName).assertSuccess();
-            helper.checkImage(imageDir, moduleName, null, null);
+            helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: orphan argument: foo");
         }
 
+        // orphan argument - JDK-8166810
+        {
+            String[] userOptions = {"--output", "foo", "bar" };
+            String moduleName = "orphanarg2";
+            helper.generateDefaultJModule(moduleName, "composite2");
+            helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: orphan argument: bar");
+        }
     }
 
     private static void testCompress(Helper helper, String moduleName, String... userOptions) throws IOException {
--- a/jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/IncludeLocalesPluginTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -40,7 +40,7 @@
 
 /*
  * @test
- * @bug 8152143 8152704 8155649
+ * @bug 8152143 8152704 8155649 8165804
  * @summary IncludeLocalesPlugin tests
  * @author Naoto Sato
  * @library ../../lib
@@ -236,6 +236,7 @@
                 "/jdk.localedata/sun/text/resources/ext/thai_dict",
                 "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th",
                 "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class",
+                "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class",
                 "/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class",
                 "/jdk.localedata/sun/text/resources/ext/FormatData_ja.class",
                 "/jdk.localedata/sun/text/resources/ext/FormatData_th.class",
@@ -261,6 +262,7 @@
                 "/jdk.localedata/sun/text/resources/ext/thai_dict",
                 "/jdk.localedata/sun/text/resources/ext/WordBreakIteratorData_th",
                 "/jdk.localedata/sun/text/resources/ext/BreakIteratorInfo_th.class",
+                "/jdk.localedata/sun/text/resources/ext/BreakIteratorResources_th.class",
                 "/jdk.localedata/sun/text/resources/ext/FormatData_th.class"),
             List.of(
                 "/jdk.localedata/sun/text/resources/ext/FormatData_en_GB.class",
@@ -431,13 +433,23 @@
 
         for (Object[] data : testData) {
             // create image for each test data
-            System.out.println("Invoking jlink with \"" + data[INCLUDE_LOCALES_OPTION] + "\"");
-            Result result = JImageGenerator.getJLinkTask()
+            Result result;
+            if (data[INCLUDE_LOCALES_OPTION].toString().isEmpty()) {
+                System.out.println("Invoking jlink with no --include-locales option");
+                result = JImageGenerator.getJLinkTask()
+                    .modulePath(helper.defaultModulePath())
+                    .output(helper.createNewImageDir(moduleName))
+                    .addMods((String) data[ADDMODS_OPTION])
+                    .call();
+            } else {
+                System.out.println("Invoking jlink with \"" + data[INCLUDE_LOCALES_OPTION] + "\"");
+                result = JImageGenerator.getJLinkTask()
                     .modulePath(helper.defaultModulePath())
                     .output(helper.createNewImageDir(moduleName))
                     .addMods((String) data[ADDMODS_OPTION])
                     .option((String) data[INCLUDE_LOCALES_OPTION])
                     .call();
+            }
 
             String errorMsg = (String) data[ERROR_MESSAGE];
             if (errorMsg.isEmpty()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/classpath/JavaClassPathTest.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,131 @@
+/*
+ * 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.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import jdk.testlibrary.OutputAnalyzer;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+import static jdk.testlibrary.ProcessTools.*;
+
+/**
+ * @test
+ * @bug 8168205
+ * @summary Test the default class path if -Djava.class.path is set
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * @build CompilerUtils jdk.testlibrary.*
+ * @run testng JavaClassPathTest
+ */
+
+public class JavaClassPathTest {
+    private static final Path SRC_DIR = Paths.get(System.getProperty("test.src"),
+                                                  "src");
+    private static final Path MODS_DIR = Paths.get("mods");
+    private static final String TEST_MODULE = "m";
+    private static final String TEST_MAIN = "jdk.test.Main";
+
+    @BeforeTest
+    public void setup() throws Exception {
+        boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE),
+                                                 MODS_DIR.resolve(TEST_MODULE));
+        assertTrue(compiled, "module " + TEST_MODULE + " did not compile");
+
+        // add the class and a resource to the current working directory
+        Path file = Paths.get("jdk/test/Main.class");
+        Files.createDirectories(file.getParent());
+        Files.copy(MODS_DIR.resolve(TEST_MODULE).resolve(file), file);
+
+        Path res = Paths.get("jdk/test/res.properties");
+        Files.createFile(res);
+    }
+
+    @DataProvider(name = "classpath")
+    public Object[][] classpath() {
+        return new Object[][]{
+            // true indicates that class path default to current working directory
+            { "",                              true  },
+            { "-Djava.class.path",             true  },
+            { "-Djava.class.path=",            true  },
+            { "-Djava.class.path=.",           true  },
+        };
+    }
+
+    @Test(dataProvider = "classpath")
+    public void testUnnamedModule(String option, boolean expected) throws Throwable {
+        List<String> args = new ArrayList<>();
+        if (!option.isEmpty()) {
+            args.add(option);
+        }
+        args.add(TEST_MAIN);
+        args.add(Boolean.toString(expected));
+
+        assertTrue(execute(args).getExitValue() == 0);
+    }
+
+    @DataProvider(name = "moduleAndClassPath")
+    public Object[][] moduleAndClassPath() {
+        return new Object[][]{
+            // true indicates that class path default to current working directory
+            { "",                              false  },
+            { "-Djava.class.path",             false  },
+            { "-Djava.class.path=",            false  },
+            { "-Djava.class.path=.",           true   },
+        };
+    }
+
+    @Test(dataProvider = "moduleAndClassPath")
+    public void testNamedModule(String option, boolean expected) throws Throwable {
+        List<String> args = new ArrayList<>();
+        if (!option.isEmpty()) {
+            args.add(option);
+        }
+        args.add("--module-path");
+        args.add(MODS_DIR.toString());
+        args.add("-m");
+        args.add(TEST_MODULE + "/" + TEST_MAIN);
+        args.add(Boolean.toString(expected));
+
+        assertTrue(execute(args).getExitValue() == 0);
+    }
+
+    private OutputAnalyzer execute(List<String> options) throws Throwable {
+        ProcessBuilder pb =
+            createJavaProcessBuilder(options.toArray(new String[0]));
+        Map<String,String> env = pb.environment();
+        // remove CLASSPATH environment variable
+        String value = env.remove("CLASSPATH");
+        return executeCommand(pb)
+                    .outputTo(System.out)
+                    .errorTo(System.out);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/classpath/src/m/jdk/test/Main.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test;
+
+import java.net.URL;
+
+public class Main {
+    static final String JAVA_CLASS_PATH = "java.class.path";
+
+    public static void main(String[] args) throws Exception {
+        String value = System.getProperty(JAVA_CLASS_PATH);
+        if (value == null) {
+            throw new RuntimeException(JAVA_CLASS_PATH + " is expected non-null" +
+                " for compatibility");
+        }
+
+        boolean expected = args[0].equals("true");
+        ClassLoader loader = ClassLoader.getSystemClassLoader();
+        URL url = loader.getResource("jdk/test/res.properties");
+        if ((expected && url == null) || (!expected && url != null)) {
+            throw new RuntimeException("URL: " + url + " expected non-null: " + expected);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/modules/classpath/src/m/module-info.java	Thu Oct 27 21:22:57 2016 +0000
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module m {
+}
+
--- a/jdk/test/tools/pack200/MultiRelease.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/tools/pack200/MultiRelease.java	Thu Oct 27 21:22:57 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,7 @@
         } else {
             System.out.println("All tests(" + pass + ") passes");
         }
+        Utils.cleanup();
     }
 
     /*
--- a/jdk/test/tools/pack200/Utils.java	Thu Oct 27 16:29:00 2016 +0000
+++ b/jdk/test/tools/pack200/Utils.java	Thu Oct 27 21:22:57 2016 +0000
@@ -94,7 +94,7 @@
         }
         File srcDir = new File(getVerifierDir(), "src");
         List<File> javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT));
-        File tmpFile = File.createTempFile("javac", ".tmp");
+        File tmpFile = File.createTempFile("javac", ".tmp", new File("."));
         XCLASSES.mkdirs();
         FileOutputStream fos = null;
         PrintStream ps = null;
@@ -208,6 +208,10 @@
                 Utils.createFilter(".idx")));
         toDelete.addAll(Utils.findFiles(new File("."),
                 Utils.createFilter(".gidx")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".tmp")));
+        toDelete.addAll(Utils.findFiles(new File("."),
+                Utils.createFilter(".class")));
         for (File f : toDelete) {
             f.delete();
         }